\r
uart_soft\r
\r
+ v0.2\r
+\r
copyright John Steggall 2009\r
\r
*/\r
*/\r
\r
#include <avr/io.h>\r
+#include "SoftUARTConf.h"\r
\r
-/* BITLENGTH is the time for a bit cycle worked out at F_CPU / BAUD. Gives a rough but usable figure. Wouldn't like to try\r
- * anything faster than 9600! */\r
-#define BITLENGTH 833\r
\r
#define SFT_TX_EN 7\r
\r
.byte 0\r
rxBitcount:\r
.byte 0\r
+ \r
+ .global status\r
status:\r
.byte 0\r
\r
.section .text\r
\r
+\r
+ .global RX_PIN_INT\r
+\r
/*********************************************\r
* External interrupt\r
* \r
* RX pin has gone low.\r
*/\r
- .global INT0_vect\r
-\r
-INT0_vect:\r
+RX_PIN_INT:\r
push r16\r
lds r16,SREG\r
push r16\r
\r
- lds r16,PIND\r
+#if (RXPORT>=32)\r
+ lds r16,RXPORT\r
sbrc r16,0 // anti glitch\r
+\r
+#else\r
+ sbic RXPORT,0\r
+#endif\r
+\r
rjmp ignore\r
nop\r
nop\r
nop\r
nop\r
- lds r16,PIND\r
- sbrc r16,0 // just make sure\r
+\r
+#if (RXPORT>=32)\r
+ lds r16,RXPORT\r
+ sbrc r16,0 // anti glitch\r
+\r
+#else\r
+ sbic RXPORT,0\r
+#endif\r
+\r
rjmp ignore\r
\r
push r17\r
\r
// grab timer value\r
- lds r16,TCNT3L \r
- lds r17,TCNT3H\r
+ lds r16,TC_COUNTL \r
+ lds r17,TC_COUNTH\r
\r
// set trigger for RX timer (will need to add a little more though)\r
- sts OCR3CH,r17\r
- sts OCR3CL,r16\r
+ sts TC_RX_COMPH,r17\r
+ sts TC_RX_COMPL,r16\r
\r
pop r17\r
\r
\r
\r
// turn off interrupt, will get annoying.\r
- cbi 0x1D,0\r
+ cbi EXTI_MASK_REG,EXTI_MASK_BIT\r
\r
// turn on interrupt on compare match\r
- sbi 0x18,OCF3C\r
- lds r16,TIMSK3\r
- ori r16,(1<<OCIE3C)\r
- sts TIMSK3,r16\r
+\r
+ sbi TC_INTFLAG_REG,TC_RX_IF_BIT //------------------------\r
+\r
+ lds r16,TC_INT_MASK_REG\r
+ ori r16,(1<<TC_RX_COMPEN)\r
+ sts TC_INT_MASK_REG,r16\r
\r
ignore:\r
pop r16\r
\r
lds r16,txShifter\r
\r
- lds r17, PORTD\r
-\r
+#if (TXPORT>=32)\r
+ lds r17, TXPORT\r
sbrs r16,0\r
- andi r17,0xFD\r
+ andi r17,~(1<<TXPIN)\r
sbrc r16,0\r
- ori r17,0x02\r
+ ori r17,(1<<TXPIN)\r
+ sts TXPORT,r17\r
\r
- sts PORTD,r17\r
+#else\r
+ sbrs r16,0\r
+ cbi TXPORT,TXPIN\r
+ sbrc r16,0\r
+ sbi TXPORT,TXPIN\r
\r
- lsr r16\r
- ori r16,0x80\r
+#endif\r
+ sec\r
+ ror r16\r
\r
txout:\r
sts txShifter,r16\r
ori r17,SF_UART_TX // set TXC/DRE flag\r
sts status,r17\r
\r
- lds r16,TIMSK3\r
- andi r16,~(1<<OCIE3B)\r
- sts TIMSK3,r16\r
+ lds r16,TC_INT_MASK_REG\r
+ andi r16,~(1<<TC_TX_COMPEN)\r
+ sts TC_INT_MASK_REG,r16\r
\r
rjmp lastBitOut // over and out\r
\r
ldi r18,3 // set counter to 3\r
ldi r17,0\r
\r
-// cbi 0x0B,1 // marker\r
+#ifdef DEBUG\r
+\r
+#if RXPORT>64\r
+ lds r16,RXPORT\r
+ andi r16,~(1<<TXPIN)\r
+ sts TXPORT,r16\r
+#else\r
+ cbi TXPORT,TXPIN // marker\r
+#endif\r
+#endif\r
\r
loopGetBit:\r
- lds r16,PIND \r
- sbrc r16,0\r
+\r
+#if (RXPORT>=32)\r
+ lds r16,RXPORT\r
+ sbrs r16,RXPIN\r
+#else \r
+ sbic RXPORT,RXPIN\r
+\r
+#endif\r
+\r
inc r17\r
dec r18\r
nop\r
nop\r
brne loopGetBit\r
\r
-// sbi 0x0B,1 // marker\r
+#ifdef DEBUG\r
+\r
+#if RXPORT>64\r
+ lds r16,RXPORT\r
+ ori r16,1<<TXPIN\r
+ sts r16\r
+\r
+#else\r
+ sbi TXPORT,TXPIN // marker\r
+\r
+#endif\r
+#endif\r
+\r
\r
lds r16,rxShifter\r
lsr r16\r
\r
lastBitRX:\r
lds r17,status // store status\r
- lds r16,PIND // get status of stop bit\r
- sbrc r16,0\r
+\r
+#if (RXPORT>=32)\r
+ lds r16,RXPORT\r
+ sbrc r16,RXPIN\r
+\r
+#else\r
+ sbic RXPORT,RXPIN \r
+\r
+#endif\r
+\r
ori r17,0x02 // set flag if stop bit was high\r
sts status,r17\r
\r
\r
// switch interrupt back on to get another go\r
\r
- sbi 0x1C,0 // clear interrupt flag\r
- sbi 0x1D,0 // enable external interrupt 0 (RX)\r
+ sbi EXTI_FLAG_REG,EXTI_MASK_BIT // clear interrupt flag\r
+ sbi EXTI_MASK_REG,EXTI_MASK_BIT // enable external interrupt 0 (RX)\r
\r
// switch off rx bit timer\r
- lds r16,TIMSK3\r
- andi r16,~(1<<OCIE3C)\r
- sts TIMSK3,r16\r
+ lds r16,TC_INT_MASK_REG\r
+ andi r16,~(1<<TC_RX_COMPEN)\r
+ sts TC_INT_MASK_REG,r16\r
\r
rjmp lastBitOut // loud and clear\r
\r
rx1stbit:\r
- lds r16,TCNT3L\r
- lds r17,TCNT3H\r
+ lds r16,TC_COUNTL\r
+ lds r17,TC_COUNTH\r
\r
subi r16,lo8(BITLENGTH / 2)\r
sbci r17,hi8(BITLENGTH / 2)\r
sbci r17,hi8(0xFFFF - BITLENGTH)\r
\r
skipOverflow:\r
- sts OCR3CH,r17\r
- sts OCR3CL,r17\r
+ sts TC_RX_COMPH,r17\r
+ sts TC_RX_COMPL,r17\r
rjmp lastBitOut\r
\r
\r
\r
SoftUART_Init:\r
\r
- lds r18,PORTD\r
+#if (TXPORT>=32)\r
+ lds r18,TXPORT\r
ori r18,0x02\r
- sts PORTD,r18\r
- lds r18,DDRD\r
+ sts TXPORT,r18\r
+\r
+ lds r18,TXDIR_REG\r
ori r18,0x02\r
- sts DDRD,r18\r
+ sts TXDIR_REG,r18\r
+\r
+#else\r
+ sbi TXPORT,TXPIN\r
+ sbi TXDIR_REG,TXPIN\r
+\r
+#endif\r
\r
ldi r18,(1<<SFT_TX_EN)|SF_UART_TX\r
sts status,r18\r
\r
// Start timer 3\r
ldi r18,0b00001001 // ctc count mode, clock div 1\r
- sts TCCR3B,r18\r
+ sts TC_CTRLB,r18\r
\r
- // Interrupt on low level INT0\r
- sbi 0x1C,0\r
- sbi 0x1D,0\r
+ // Interrupt on pin change INT0\r
+ sbi EXTI_FLAG_REG,EXTI_MASK_BIT\r
+ sbi EXTI_MASK_REG,EXTI_MASK_BIT\r
\r
ret\r
\r
\r
/*********************************************\r
- * char SoftUART_TxByte(char)\r
+ * char SoftUART_RxByte(char)\r
*\r
* starts a byte send and returns the byte to be sent\r
*/\r
SoftUART_TxByte:\r
lds r18,status\r
sbrs r18,SFT_TX_EN\r
- rjmp uart_putchar_end\r
+ rjmp SoftUART_TxByte_end\r
\r
andi r18,0xFE // clear tx empty flag\r
sts status,r18\r
sts txBitcount,r18\r
\r
// grab timer value\r
-\r
- lds r18,TCNT3L\r
- lds r19,TCNT3H\r
+ cli // Atomic section start\r
+ lds r18,TC_COUNTL\r
+ lds r19,TC_COUNTH\r
\r
// drop down tx line for start bit\r
- lds r20, PORTD\r
- andi r20,0xFD\r
- sts PORTD,r20\r
- \r
+\r
+#if (TXPORT>=32)\r
+ lds r20, TXPORT\r
+ andi r20,~(1<<TXPIN)\r
+ sts TXPORT,r20\r
+\r
+#else\r
+ cbi TXPORT,TXPIN\r
+#endif\r
+\r
// set trigger for tx timer\r
- cli\r
- sts OCR3BH,r19\r
- sts OCR3BL,r18\r
- sei\r
+ sts TC_TX_COMPH,r19\r
+ sts TC_TX_COMPL,r18\r
+ sei // Atomic section end\r
\r
// clear interrupt flag and enable tx interrupt\r
- sbi 0x18,OCF3B\r
- lds r18,TIMSK3\r
- ori r18,(1<<OCIE3B)\r
- sts TIMSK3,r18\r
\r
-uart_putchar_end:\r
+ sbi TC_INTFLAG_REG,TC_TX_IF_BIT\r
+\r
+ lds r18,TC_INT_MASK_REG\r
+ ori r18,(1<<TC_TX_COMPEN)\r
+ sts TC_INT_MASK_REG,r18\r
+\r
+SoftUART_TxByte_end:\r
ret\r
\r
\r