diff options
Diffstat (limited to 'protocol/iwrap/suart.S')
| -rw-r--r-- | protocol/iwrap/suart.S | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/protocol/iwrap/suart.S b/protocol/iwrap/suart.S new file mode 100644 index 000000000..1b0290963 --- /dev/null +++ b/protocol/iwrap/suart.S | |||
| @@ -0,0 +1,156 @@ | |||
| 1 | ;---------------------------------------------------------------------------; | ||
| 2 | ; Software implemented UART module ; | ||
| 3 | ; (C)ChaN, 2005 (http://elm-chan.org/) ; | ||
| 4 | ;---------------------------------------------------------------------------; | ||
| 5 | ; Bit rate settings: | ||
| 6 | ; | ||
| 7 | ; 1MHz 2MHz 4MHz 6MHz 8MHz 10MHz 12MHz 16MHz 20MHz | ||
| 8 | ; 2.4kbps 138 - - - - - - - - | ||
| 9 | ; 4.8kbps 68 138 - - - - - - - | ||
| 10 | ; 9.6kbps 33 68 138 208 - - - - - | ||
| 11 | ; 19.2kbps - 33 68 102 138 173 208 - - | ||
| 12 | ; 38.4kbps - - 33 50 68 85 102 138 172 | ||
| 13 | ; 57.6kbps - - 21 33 44 56 68 91 114 | ||
| 14 | ; 115.2kbps - - - - 21 27 33 44 56 | ||
| 15 | |||
| 16 | .nolist | ||
| 17 | #include <avr/io.h> | ||
| 18 | .list | ||
| 19 | |||
| 20 | #define BPS 102 /* Bit delay. (see above table) */ | ||
| 21 | #define BIDIR 0 /* 0:Separated Tx/Rx, 1:Shared Tx/Rx */ | ||
| 22 | |||
| 23 | #define OUT_1 sbi _SFR_IO_ADDR(SUART_OUT_PORT), SUART_OUT_BIT /* Output 1 */ | ||
| 24 | #define OUT_0 cbi _SFR_IO_ADDR(SUART_OUT_PORT), SUART_OUT_BIT /* Output 0 */ | ||
| 25 | #define SKIP_IN_1 sbis _SFR_IO_ADDR(SUART_IN_PIN), SUART_IN_BIT /* Skip if 1 */ | ||
| 26 | #define SKIP_IN_0 sbic _SFR_IO_ADDR(SUART_IN_PIN), SUART_IN_BIT /* Skip if 0 */ | ||
| 27 | |||
| 28 | |||
| 29 | |||
| 30 | #ifdef SPM_PAGESIZE | ||
| 31 | .macro _LPMI reg | ||
| 32 | lpm \reg, Z+ | ||
| 33 | .endm | ||
| 34 | .macro _MOVW dh,dl, sh,sl | ||
| 35 | movw \dl, \sl | ||
| 36 | .endm | ||
| 37 | #else | ||
| 38 | .macro _LPMI reg | ||
| 39 | lpm | ||
| 40 | mov \reg, r0 | ||
| 41 | adiw ZL, 1 | ||
| 42 | .endm | ||
| 43 | .macro _MOVW dh,dl, sh,sl | ||
| 44 | mov \dl, \sl | ||
| 45 | mov \dh, \sh | ||
| 46 | .endm | ||
| 47 | #endif | ||
| 48 | |||
| 49 | |||
| 50 | |||
| 51 | ;---------------------------------------------------------------------------; | ||
| 52 | ; Transmit a byte in serial format of N81 | ||
| 53 | ; | ||
| 54 | ;Prototype: void xmit (uint8_t data); | ||
| 55 | ;Size: 16 words | ||
| 56 | |||
| 57 | .global xmit | ||
| 58 | .func xmit | ||
| 59 | xmit: | ||
| 60 | #if BIDIR | ||
| 61 | ldi r23, BPS-1 ;Pre-idle time for bidirectional data line | ||
| 62 | 5: dec r23 ; | ||
| 63 | brne 5b ;/ | ||
| 64 | #endif | ||
| 65 | in r0, _SFR_IO_ADDR(SREG) ;Save flags | ||
| 66 | |||
| 67 | com r24 ;C = start bit | ||
| 68 | ldi r25, 10 ;Bit counter | ||
| 69 | cli ;Start critical section | ||
| 70 | |||
| 71 | 1: ldi r23, BPS-1 ;----- Bit transferring loop | ||
| 72 | 2: dec r23 ;Wait for a bit time | ||
| 73 | brne 2b ;/ | ||
| 74 | brcs 3f ;MISO = bit to be sent | ||
| 75 | OUT_1 ; | ||
| 76 | 3: brcc 4f ; | ||
| 77 | OUT_0 ;/ | ||
| 78 | 4: lsr r24 ;Get next bit into C | ||
| 79 | dec r25 ;All bits sent? | ||
| 80 | brne 1b ; no, coutinue | ||
| 81 | |||
| 82 | out _SFR_IO_ADDR(SREG), r0 ;End of critical section | ||
| 83 | ret | ||
| 84 | .endfunc | ||
| 85 | |||
| 86 | |||
| 87 | |||
| 88 | ;---------------------------------------------------------------------------; | ||
| 89 | ; Receive a byte | ||
| 90 | ; | ||
| 91 | ;Prototype: uint8_t rcvr (void); | ||
| 92 | ;Size: 19 words | ||
| 93 | |||
| 94 | .global rcvr | ||
| 95 | .func rcvr | ||
| 96 | rcvr: | ||
| 97 | in r0, _SFR_IO_ADDR(SREG) ;Save flags | ||
| 98 | |||
| 99 | ldi r24, 0x80 ;Receiving shift reg | ||
| 100 | cli ;Start critical section | ||
| 101 | |||
| 102 | 1: SKIP_IN_1 ;Wait for idle | ||
| 103 | rjmp 1b | ||
| 104 | 2: SKIP_IN_0 ;Wait for start bit | ||
| 105 | rjmp 2b | ||
| 106 | ldi r25, BPS/2 ;Wait for half bit time | ||
| 107 | 3: dec r25 | ||
| 108 | brne 3b | ||
| 109 | |||
| 110 | 4: ldi r25, BPS ;----- Bit receiving loop | ||
| 111 | 5: dec r25 ;Wait for a bit time | ||
| 112 | brne 5b ;/ | ||
| 113 | lsr r24 ;Next bit | ||
| 114 | SKIP_IN_0 ;Get a data bit into r24.7 | ||
| 115 | ori r24, 0x80 | ||
| 116 | brcc 4b ;All bits received? no, continue | ||
| 117 | |||
| 118 | out _SFR_IO_ADDR(SREG), r0 ;End of critical section | ||
| 119 | ret | ||
| 120 | .endfunc | ||
| 121 | |||
| 122 | |||
| 123 | ; Not wait for start bit. This should be called after detecting start bit. | ||
| 124 | .global recv | ||
| 125 | .func recv | ||
| 126 | recv: | ||
| 127 | in r0, _SFR_IO_ADDR(SREG) ;Save flags | ||
| 128 | |||
| 129 | ldi r24, 0x80 ;Receiving shift reg | ||
| 130 | cli ;Start critical section | ||
| 131 | |||
| 132 | ;1: SKIP_IN_1 ;Wait for idle | ||
| 133 | ; rjmp 1b | ||
| 134 | ;2: SKIP_IN_0 ;Wait for start bit | ||
| 135 | ; rjmp 2b | ||
| 136 | ldi r25, BPS/2 ;Wait for half bit time | ||
| 137 | 3: dec r25 | ||
| 138 | brne 3b | ||
| 139 | |||
| 140 | 4: ldi r25, BPS ;----- Bit receiving loop | ||
| 141 | 5: dec r25 ;Wait for a bit time | ||
| 142 | brne 5b ;/ | ||
| 143 | lsr r24 ;Next bit | ||
| 144 | SKIP_IN_0 ;Get a data bit into r24.7 | ||
| 145 | ori r24, 0x80 | ||
| 146 | brcc 4b ;All bits received? no, continue | ||
| 147 | |||
| 148 | ldi r25, BPS/2 ;Wait for half bit time | ||
| 149 | 6: dec r25 | ||
| 150 | brne 6b | ||
| 151 | 7: SKIP_IN_1 ;Wait for stop bit | ||
| 152 | rjmp 7b | ||
| 153 | |||
| 154 | out _SFR_IO_ADDR(SREG), r0 ;End of critical section | ||
| 155 | ret | ||
| 156 | .endfunc | ||
