aboutsummaryrefslogtreecommitdiff
path: root/protocol/iwrap/suart.S
diff options
context:
space:
mode:
Diffstat (limited to 'protocol/iwrap/suart.S')
-rw-r--r--protocol/iwrap/suart.S156
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
59xmit:
60#if BIDIR
61 ldi r23, BPS-1 ;Pre-idle time for bidirectional data line
625: 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
711: ldi r23, BPS-1 ;----- Bit transferring loop
722: dec r23 ;Wait for a bit time
73 brne 2b ;/
74 brcs 3f ;MISO = bit to be sent
75 OUT_1 ;
763: brcc 4f ;
77 OUT_0 ;/
784: 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
96rcvr:
97 in r0, _SFR_IO_ADDR(SREG) ;Save flags
98
99 ldi r24, 0x80 ;Receiving shift reg
100 cli ;Start critical section
101
1021: SKIP_IN_1 ;Wait for idle
103 rjmp 1b
1042: SKIP_IN_0 ;Wait for start bit
105 rjmp 2b
106 ldi r25, BPS/2 ;Wait for half bit time
1073: dec r25
108 brne 3b
109
1104: ldi r25, BPS ;----- Bit receiving loop
1115: 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
126recv:
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
1373: dec r25
138 brne 3b
139
1404: ldi r25, BPS ;----- Bit receiving loop
1415: 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
1496: dec r25
150 brne 6b
1517: 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