|
@@ -0,0 +1,156 @@
|
|
|
|
|
+;---------------------------------------------------------------------------;
|
|
|
|
|
+; Software implemented UART module ;
|
|
|
|
|
+; (C)ChaN, 2005 (http://elm-chan.org/) ;
|
|
|
|
|
+;---------------------------------------------------------------------------;
|
|
|
|
|
+; Bit rate settings:
|
|
|
|
|
+;
|
|
|
|
|
+; 1MHz 2MHz 4MHz 6MHz 8MHz 10MHz 12MHz 16MHz 20MHz
|
|
|
|
|
+; 2.4kbps 138 - - - - - - - -
|
|
|
|
|
+; 4.8kbps 68 138 - - - - - - -
|
|
|
|
|
+; 9.6kbps 33 68 138 208 - - - - -
|
|
|
|
|
+; 19.2kbps - 33 68 102 138 173 208 - -
|
|
|
|
|
+; 38.4kbps - - 33 50 68 85 102 138 172
|
|
|
|
|
+; 57.6kbps - - 21 33 44 56 68 91 114
|
|
|
|
|
+; 115.2kbps - - - - 21 27 33 44 56
|
|
|
|
|
+
|
|
|
|
|
+.nolist
|
|
|
|
|
+#include <avr/io.h>
|
|
|
|
|
+.list
|
|
|
|
|
+
|
|
|
|
|
+#define BPS 44 /* Bit delay. (see above table) */
|
|
|
|
|
+#define BIDIR 0 /* 0:Separated Tx/Rx, 1:Shared Tx/Rx */
|
|
|
|
|
+
|
|
|
|
|
+#define OUT_1 sbi _SFR_IO_ADDR(SUART_OUT_PORT), SUART_OUT_BIT /* Output 1 */
|
|
|
|
|
+#define OUT_0 cbi _SFR_IO_ADDR(SUART_OUT_PORT), SUART_OUT_BIT /* Output 0 */
|
|
|
|
|
+#define SKIP_IN_1 sbis _SFR_IO_ADDR(SUART_IN_PIN), SUART_IN_BIT /* Skip if 1 */
|
|
|
|
|
+#define SKIP_IN_0 sbic _SFR_IO_ADDR(SUART_IN_PIN), SUART_IN_BIT /* Skip if 0 */
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+#ifdef SPM_PAGESIZE
|
|
|
|
|
+.macro _LPMI reg
|
|
|
|
|
+ lpm \reg, Z+
|
|
|
|
|
+.endm
|
|
|
|
|
+.macro _MOVW dh,dl, sh,sl
|
|
|
|
|
+ movw \dl, \sl
|
|
|
|
|
+.endm
|
|
|
|
|
+#else
|
|
|
|
|
+.macro _LPMI reg
|
|
|
|
|
+ lpm
|
|
|
|
|
+ mov \reg, r0
|
|
|
|
|
+ adiw ZL, 1
|
|
|
|
|
+.endm
|
|
|
|
|
+.macro _MOVW dh,dl, sh,sl
|
|
|
|
|
+ mov \dl, \sl
|
|
|
|
|
+ mov \dh, \sh
|
|
|
|
|
+.endm
|
|
|
|
|
+#endif
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+;---------------------------------------------------------------------------;
|
|
|
|
|
+; Transmit a byte in serial format of N81
|
|
|
|
|
+;
|
|
|
|
|
+;Prototype: void xmit (uint8_t data);
|
|
|
|
|
+;Size: 16 words
|
|
|
|
|
+
|
|
|
|
|
+.global xmit
|
|
|
|
|
+.func xmit
|
|
|
|
|
+xmit:
|
|
|
|
|
+#if BIDIR
|
|
|
|
|
+ ldi r23, BPS-1 ;Pre-idle time for bidirectional data line
|
|
|
|
|
+5: dec r23 ;
|
|
|
|
|
+ brne 5b ;/
|
|
|
|
|
+#endif
|
|
|
|
|
+ in r0, _SFR_IO_ADDR(SREG) ;Save flags
|
|
|
|
|
+
|
|
|
|
|
+ com r24 ;C = start bit
|
|
|
|
|
+ ldi r25, 10 ;Bit counter
|
|
|
|
|
+ cli ;Start critical section
|
|
|
|
|
+
|
|
|
|
|
+1: ldi r23, BPS-1 ;----- Bit transferring loop
|
|
|
|
|
+2: dec r23 ;Wait for a bit time
|
|
|
|
|
+ brne 2b ;/
|
|
|
|
|
+ brcs 3f ;MISO = bit to be sent
|
|
|
|
|
+ OUT_1 ;
|
|
|
|
|
+3: brcc 4f ;
|
|
|
|
|
+ OUT_0 ;/
|
|
|
|
|
+4: lsr r24 ;Get next bit into C
|
|
|
|
|
+ dec r25 ;All bits sent?
|
|
|
|
|
+ brne 1b ; no, coutinue
|
|
|
|
|
+
|
|
|
|
|
+ out _SFR_IO_ADDR(SREG), r0 ;End of critical section
|
|
|
|
|
+ ret
|
|
|
|
|
+.endfunc
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+;---------------------------------------------------------------------------;
|
|
|
|
|
+; Receive a byte
|
|
|
|
|
+;
|
|
|
|
|
+;Prototype: uint8_t rcvr (void);
|
|
|
|
|
+;Size: 19 words
|
|
|
|
|
+
|
|
|
|
|
+.global rcvr
|
|
|
|
|
+.func rcvr
|
|
|
|
|
+rcvr:
|
|
|
|
|
+ in r0, _SFR_IO_ADDR(SREG) ;Save flags
|
|
|
|
|
+
|
|
|
|
|
+ ldi r24, 0x80 ;Receiving shift reg
|
|
|
|
|
+ cli ;Start critical section
|
|
|
|
|
+
|
|
|
|
|
+1: SKIP_IN_1 ;Wait for idle
|
|
|
|
|
+ rjmp 1b
|
|
|
|
|
+2: SKIP_IN_0 ;Wait for start bit
|
|
|
|
|
+ rjmp 2b
|
|
|
|
|
+ ldi r25, BPS/2 ;Wait for half bit time
|
|
|
|
|
+3: dec r25
|
|
|
|
|
+ brne 3b
|
|
|
|
|
+
|
|
|
|
|
+4: ldi r25, BPS ;----- Bit receiving loop
|
|
|
|
|
+5: dec r25 ;Wait for a bit time
|
|
|
|
|
+ brne 5b ;/
|
|
|
|
|
+ lsr r24 ;Next bit
|
|
|
|
|
+ SKIP_IN_0 ;Get a data bit into r24.7
|
|
|
|
|
+ ori r24, 0x80
|
|
|
|
|
+ brcc 4b ;All bits received? no, continue
|
|
|
|
|
+
|
|
|
|
|
+ out _SFR_IO_ADDR(SREG), r0 ;End of critical section
|
|
|
|
|
+ ret
|
|
|
|
|
+.endfunc
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+; Not wait for start bit. This should be called after detecting start bit.
|
|
|
|
|
+.global recv
|
|
|
|
|
+.func recv
|
|
|
|
|
+recv:
|
|
|
|
|
+ in r0, _SFR_IO_ADDR(SREG) ;Save flags
|
|
|
|
|
+
|
|
|
|
|
+ ldi r24, 0x80 ;Receiving shift reg
|
|
|
|
|
+ cli ;Start critical section
|
|
|
|
|
+
|
|
|
|
|
+;1: SKIP_IN_1 ;Wait for idle
|
|
|
|
|
+; rjmp 1b
|
|
|
|
|
+;2: SKIP_IN_0 ;Wait for start bit
|
|
|
|
|
+; rjmp 2b
|
|
|
|
|
+ ldi r25, BPS/2 ;Wait for half bit time
|
|
|
|
|
+3: dec r25
|
|
|
|
|
+ brne 3b
|
|
|
|
|
+
|
|
|
|
|
+4: ldi r25, BPS ;----- Bit receiving loop
|
|
|
|
|
+5: dec r25 ;Wait for a bit time
|
|
|
|
|
+ brne 5b ;/
|
|
|
|
|
+ lsr r24 ;Next bit
|
|
|
|
|
+ SKIP_IN_0 ;Get a data bit into r24.7
|
|
|
|
|
+ ori r24, 0x80
|
|
|
|
|
+ brcc 4b ;All bits received? no, continue
|
|
|
|
|
+
|
|
|
|
|
+ ldi r25, BPS/2 ;Wait for half bit time
|
|
|
|
|
+6: dec r25
|
|
|
|
|
+ brne 6b
|
|
|
|
|
+7: SKIP_IN_1 ;Wait for stop bit
|
|
|
|
|
+ rjmp 7b
|
|
|
|
|
+
|
|
|
|
|
+ out _SFR_IO_ADDR(SREG), r0 ;End of critical section
|
|
|
|
|
+ ret
|
|
|
|
|
+.endfunc
|