aboutsummaryrefslogtreecommitdiff
path: root/protocol/serial_soft.c
diff options
context:
space:
mode:
Diffstat (limited to 'protocol/serial_soft.c')
-rw-r--r--protocol/serial_soft.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/protocol/serial_soft.c b/protocol/serial_soft.c
index beddc353c..3c9c914ed 100644
--- a/protocol/serial_soft.c
+++ b/protocol/serial_soft.c
@@ -48,8 +48,20 @@ POSSIBILITY OF SUCH DAMAGE.
48 48
49#define WAIT_US (1000000/SERIAL_BAUD) 49#define WAIT_US (1000000/SERIAL_BAUD)
50 50
51/* debug for signal timing, see debug pin with oscilloscope */
52#ifdef SERIAL_SOFT_DEBUG
53 #define SERIAL_SOFT_DEBUG_INIT() (DDRD |= 1<<7)
54 #define SERIAL_SOFT_DEBUG_TGL() (PORTD ^= 1<<7)
55#else
56 #define SERIAL_SOFT_DEBUG_INIT()
57 #define SERIAL_SOFT_DEBUG_TGL()
58#endif
59
60
51void serial_init(void) 61void serial_init(void)
52{ 62{
63 SERIAL_SOFT_DEBUG_INIT();
64
53 SERIAL_RXD_INIT(); 65 SERIAL_RXD_INIT();
54 SERIAL_TXD_INIT(); 66 SERIAL_TXD_INIT();
55} 67}
@@ -60,6 +72,7 @@ static uint8_t rbuf[RBUF_SIZE];
60static uint8_t rbuf_head = 0; 72static uint8_t rbuf_head = 0;
61static uint8_t rbuf_tail = 0; 73static uint8_t rbuf_tail = 0;
62 74
75
63uint8_t serial_recv(void) 76uint8_t serial_recv(void)
64{ 77{
65 uint8_t data = 0; 78 uint8_t data = 0;
@@ -72,6 +85,18 @@ uint8_t serial_recv(void)
72 return data; 85 return data;
73} 86}
74 87
88int16_t serial_recv2(void)
89{
90 uint8_t data = 0;
91 if (rbuf_head == rbuf_tail) {
92 return -1;
93 }
94
95 data = rbuf[rbuf_tail];
96 rbuf_tail = (rbuf_tail + 1) % RBUF_SIZE;
97 return data;
98}
99
75void serial_send(uint8_t data) 100void serial_send(uint8_t data)
76{ 101{
77 /* signal state: IDLE: ON, START: OFF, STOP: ON, DATA0: OFF, DATA1: ON */ 102 /* signal state: IDLE: ON, START: OFF, STOP: ON, DATA0: OFF, DATA1: ON */
@@ -103,22 +128,36 @@ void serial_send(uint8_t data)
103/* detect edge of start bit */ 128/* detect edge of start bit */
104ISR(SERIAL_RXD_VECT) 129ISR(SERIAL_RXD_VECT)
105{ 130{
131 SERIAL_SOFT_DEBUG_TGL()
106 SERIAL_RXD_INT_ENTER() 132 SERIAL_RXD_INT_ENTER()
107 133
108 uint8_t data = 0; 134 uint8_t data = 0;
135
109#ifdef SERIAL_BIT_ORDER_MSB 136#ifdef SERIAL_BIT_ORDER_MSB
110 uint8_t mask = 0x80; 137 uint8_t mask = 0x80;
111#else 138#else
112 uint8_t mask = 0x01; 139 uint8_t mask = 0x01;
113#endif 140#endif
141
142#ifdef SERIAL_PARITY_ODD
143 uint8_t parity = 0;
144#elif defined(SERIAL_PARITY_EVEN)
145 uint8_t parity = 1;
146#endif
147
114 /* to center of start bit */ 148 /* to center of start bit */
115 _delay_us(WAIT_US/2); 149 _delay_us(WAIT_US/2);
150 SERIAL_SOFT_DEBUG_TGL()
116 do { 151 do {
117 /* to center of next bit */ 152 /* to center of next bit */
118 _delay_us(WAIT_US); 153 _delay_us(WAIT_US);
119 154
155 SERIAL_SOFT_DEBUG_TGL()
120 if (SERIAL_RXD_READ()) { 156 if (SERIAL_RXD_READ()) {
121 data |= mask; 157 data |= mask;
158#if defined(SERIAL_PARITY_EVEN) || defined(SERIAL_PARITY_ODD)
159 parity ^= 1;
160#endif
122 } 161 }
123#ifdef SERIAL_BIT_ORDER_MSB 162#ifdef SERIAL_BIT_ORDER_MSB
124 mask >>= 1; 163 mask >>= 1;
@@ -126,14 +165,27 @@ ISR(SERIAL_RXD_VECT)
126 mask <<= 1; 165 mask <<= 1;
127#endif 166#endif
128 } while (mask); 167 } while (mask);
168
169#if defined(SERIAL_PARITY_EVEN) || defined(SERIAL_PARITY_ODD)
170 /* to center of parity bit */
171 _delay_us(WAIT_US);
172 if (SERIAL_RXD_READ()) { parity ^= 1; }
173 SERIAL_SOFT_DEBUG_TGL()
174#endif
175
129 /* to center of stop bit */ 176 /* to center of stop bit */
130 _delay_us(WAIT_US); 177 _delay_us(WAIT_US);
131 178
132 uint8_t next = (rbuf_head + 1) % RBUF_SIZE; 179 uint8_t next = (rbuf_head + 1) % RBUF_SIZE;
180#if defined(SERIAL_PARITY_EVEN) || defined(SERIAL_PARITY_ODD)
181 if (parity && next != rbuf_tail) {
182#else
133 if (next != rbuf_tail) { 183 if (next != rbuf_tail) {
184#endif
134 rbuf[rbuf_head] = data; 185 rbuf[rbuf_head] = data;
135 rbuf_head = next; 186 rbuf_head = next;
136 } 187 }
137 188
138 SERIAL_RXD_INT_EXIT(); 189 SERIAL_RXD_INT_EXIT();
190 SERIAL_SOFT_DEBUG_TGL()
139} 191}