|
|
@@ -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 |