root / proj / src / libs / uart / src / uart.c @ 385
History | View | Annotate | Download (18 KB)
1 |
#include <lcom/lcf.h> |
---|---|
2 |
|
3 |
#include "uart.h" |
4 |
|
5 |
#include "queue.h" |
6 |
#include "errors.h" |
7 |
|
8 |
#define UART_BITRATE 115200 |
9 |
#define UART_WAIT 20 //microseconds |
10 |
|
11 |
#define UART_RBR 0 |
12 |
#define UART_THR 0 |
13 |
#define UART_IER 1 |
14 |
#define UART_IIR 2 |
15 |
#define UART_FCR 2 |
16 |
#define UART_LCR 3 |
17 |
#define UART_MCR 4 |
18 |
#define UART_LSR 5 |
19 |
#define UART_MSR 6 |
20 |
#define UART_SR 7 |
21 |
|
22 |
#define UART_DLL 0 |
23 |
#define UART_DLM 1 |
24 |
|
25 |
/// LCR
|
26 |
#define UART_BITS_PER_CHAR_POS 0 |
27 |
#define UART_STOP_BITS_POS 2 |
28 |
#define UART_PARITY_POS 3 |
29 |
#define UART_BREAK_CONTROL_POS 6 |
30 |
#define UART_DLAB_POS 7 |
31 |
|
32 |
#define UART_BITS_PER_CHAR (BIT(0) | BIT(1)) |
33 |
#define UART_STOP_BITS (BIT(2)) |
34 |
#define UART_PARITY (BIT(3) | BIT(4) | BIT(5)) |
35 |
#define UART_BREAK_CONTROL (BIT(6)) |
36 |
#define UART_DLAB (BIT(7)) |
37 |
|
38 |
#define UART_GET_BITS_PER_CHAR(n) (((n)&UART_BITS_PER_CHAR) + 5) |
39 |
#define UART_GET_STOP_BITS(n) (((n)&UART_STOP_BITS)? 2 : 1) |
40 |
#define UART_GET_PARITY(n) (((n)&UART_PARITY )>>UART_PARITY_POS )
|
41 |
#define UART_GET_BREAK_CONTROL(n) (((n)&UART_BREAK_CONTROL)>>UART_BREAK_CONTROL_POS)
|
42 |
#define UART_GET_DLAB(n) (((n)&UART_DLAB )>>UART_DLAB_POS )
|
43 |
#define UART_GET_DIV_LATCH(m,l) ((m)<<8 | (l)) |
44 |
#define UART_GET_DLL(n) ((n)&0xFF) |
45 |
#define UART_GET_DLM(n) (((n)>>8)&0xFF) |
46 |
|
47 |
/// IER
|
48 |
#define UART_INT_EN_RX_POS 0 |
49 |
#define UART_INT_EN_TX_POS 1 |
50 |
#define UART_INT_EN_RECEIVER_LINE_STAT_POS 2 |
51 |
#define UART_INT_EN_MODEM_STAT_POS 3 |
52 |
|
53 |
#define UART_INT_EN_RX (BIT(0)) |
54 |
#define UART_INT_EN_TX (BIT(1)) |
55 |
#define UART_INT_EN_RECEIVER_LINE_STAT (BIT(2)) |
56 |
#define UART_INT_EN_MODEM_STAT (BIT(3)) |
57 |
|
58 |
#define UART_GET_INT_EN_RX(n) (((n)&UART_INT_EN_RX )>>UART_INT_EN_RX_POS )
|
59 |
#define UART_GET_INT_EN_TX(n) (((n)&UART_INT_EN_TX )>>UART_INT_EN_TX_POS )
|
60 |
#define UART_GET_INT_EN_RECEIVER_LINE_STAT(n) (((n)&UART_INT_EN_RECEIVER_LINE_STAT)>>UART_INT_EN_RECEIVER_LINE_STAT_POS)
|
61 |
#define UART_GET_INT_EN_MODEM_STAT(n) (((n)&UART_INT_EN_MODEM_STAT )>>UART_INT_EN_MODEM_STAT_POS )
|
62 |
|
63 |
/// LSR
|
64 |
#define UART_RECEIVER_READY_POS 0 |
65 |
#define UART_OVERRUN_ERROR_POS 1 |
66 |
#define UART_PARITY_ERROR_POS 2 |
67 |
#define UART_FRAMING_ERROR_POS 3 |
68 |
#define UART_TRANSMITTER_EMPTY_POS 5 |
69 |
|
70 |
#define UART_RECEIVER_READY (BIT(0)) |
71 |
#define UART_OVERRUN_ERROR (BIT(1)) |
72 |
#define UART_PARITY_ERROR (BIT(2)) |
73 |
#define UART_FRAMING_ERROR (BIT(3)) |
74 |
#define UART_TRANSMITTER_EMPTY (BIT(5)) |
75 |
|
76 |
#define UART_GET_RECEIVER_READY(n) (((n)&UART_RECEIVER_READY )>>UART_RECEIVER_READY_POS )
|
77 |
#define UART_GET_OVERRUN_ERROR (((n)&UART_OVERRUN_ERROR )>>UART_OVERRUN_ERROR_POS )
|
78 |
#define UART_GET_PARITY_ERROR (((n)&UART_PARITY_ERROR )>>UART_PARITY_ERROR_POS )
|
79 |
#define UART_GET_FRAMING_ERROR (((n)&UART_FRAMING_ERROR )>>UART_FRAMING_ERROR_POS )
|
80 |
#define UART_GET_TRANSMITTER_EMPTY(n) (((n)&UART_TRANSMITTER_EMPTY )>>UART_TRANSMITTER_EMPTY_POS )
|
81 |
|
82 |
/// IIR
|
83 |
#define UART_INT_PEND_POS 1 |
84 |
#define UART_INT_PEND (BIT(3)|BIT(2)|BIT(1)) |
85 |
|
86 |
/// FCR
|
87 |
#define UART_EN_FIFOS_POS 0 |
88 |
#define UART_CLEAR_RCVR_POS 1 |
89 |
#define UART_CLEAR_XMIT_POS 2 |
90 |
#define UART_FIFO_TRIGGER_POS 6 |
91 |
|
92 |
#define UART_EN_FIFOS (BIT(0)) |
93 |
#define UART_CLEAR_RCVR (BIT(1)) |
94 |
#define UART_CLEAR_XMIT (BIT(2)) |
95 |
#define UART_FIFO_TRIGGER (BIT(6)|BIT(7)) |
96 |
|
97 |
#define UART_TRIGGER_LEVEL01 (0<<UART_FIFO_TRIGGER_POS) |
98 |
#define UART_TRIGGER_LEVEL04 (1<<UART_FIFO_TRIGGER_POS) |
99 |
#define UART_TRIGGER_LEVEL08 (2<<UART_FIFO_TRIGGER_POS) |
100 |
#define UART_TRIGGER_LEVEL14 (3<<UART_FIFO_TRIGGER_POS) |
101 |
|
102 |
#define UART_GET_IF_INT_PEND(n) (!((n)&1)) |
103 |
typedef enum { |
104 |
uart_int_receiver_line_stat = ( BIT(1) | BIT(0)), |
105 |
uart_int_rx = ( BIT(1) ),
|
106 |
uart_int_char_timeout_fifo = (BIT(2) | BIT(1) ), |
107 |
uart_int_tx = ( BIT(0)),
|
108 |
uart_int_modem_stat = (0)
|
109 |
} uart_int_code; |
110 |
#define UART_GET_INT_PEND(n) ((uart_int_code)(((n)&UART_INT_PEND)>>UART_INT_PEND_POS))
|
111 |
|
112 |
int (subscribe_uart_interrupt)(uint8_t interrupt_bit, int *interrupt_id) { |
113 |
if (interrupt_id == NULL) return 1; |
114 |
*interrupt_id = interrupt_bit; |
115 |
return (sys_irqsetpolicy(COM1_IRQ, IRQ_REENABLE | IRQ_EXCLUSIVE, interrupt_id));
|
116 |
} |
117 |
|
118 |
static void uart_parse_config(uart_config *config){ |
119 |
/// LCR
|
120 |
config->bits_per_char = UART_GET_BITS_PER_CHAR (config->lcr); |
121 |
config->stop_bits = UART_GET_STOP_BITS (config->lcr); |
122 |
config->parity = UART_GET_PARITY (config->lcr); if((config->parity & BIT(0)) == 0) config->parity = uart_parity_none; |
123 |
config->break_control = UART_GET_BREAK_CONTROL (config->lcr); |
124 |
config->dlab = UART_GET_DLAB (config->lcr); |
125 |
/// IER
|
126 |
config->received_data_int = UART_GET_INT_EN_RX (config->ier); |
127 |
config->transmitter_empty_int = UART_GET_INT_EN_TX (config->ier); |
128 |
config->receiver_line_stat_int = UART_GET_INT_EN_RECEIVER_LINE_STAT(config->ier); |
129 |
config->modem_stat_int = UART_GET_INT_EN_MODEM_STAT (config->ier); |
130 |
/// DIV LATCH
|
131 |
config->divisor_latch = (uint16_t)UART_GET_DIV_LATCH(config->dlm, config->dll); |
132 |
} |
133 |
|
134 |
static int uart_get_lcr(int base_addr, uint8_t *p){ |
135 |
return util_sys_inb(base_addr+UART_LCR, p);
|
136 |
} |
137 |
static int uart_set_lcr(int base_addr, uint8_t config){ |
138 |
if(sys_outb(base_addr+UART_LCR, config)) return WRITE_ERROR; |
139 |
return SUCCESS;
|
140 |
} |
141 |
static int uart_get_lsr(int base_addr, uint8_t *p){ |
142 |
return util_sys_inb(base_addr+UART_LSR, p);
|
143 |
} |
144 |
static int uart_get_iir(int base_addr, uint8_t *p){ |
145 |
return util_sys_inb(base_addr+UART_IIR, p);
|
146 |
} |
147 |
|
148 |
static int uart_enable_divisor_latch(int base_addr){ |
149 |
int ret = SUCCESS;
|
150 |
uint8_t conf; if((ret = uart_get_lcr(base_addr, &conf))) return ret; |
151 |
return uart_set_lcr(base_addr, conf | UART_DLAB);
|
152 |
} |
153 |
static int uart_disable_divisor_latch(int base_addr){ |
154 |
int ret = SUCCESS;
|
155 |
uint8_t conf; if((ret = uart_get_lcr(base_addr, &conf))) return ret; |
156 |
return uart_set_lcr(base_addr, conf & (~UART_DLAB));
|
157 |
} |
158 |
|
159 |
static int uart_get_ier(int base_addr, uint8_t *p){ |
160 |
int ret;
|
161 |
if((ret = uart_disable_divisor_latch(base_addr))) return ret; |
162 |
return util_sys_inb(base_addr+UART_IER, p);
|
163 |
} |
164 |
static int uart_set_ier(int base_addr, uint8_t n){ |
165 |
int ret;
|
166 |
if((ret = uart_disable_divisor_latch(base_addr))) return ret; |
167 |
if(sys_outb(base_addr+UART_IER, n)) return WRITE_ERROR; |
168 |
return SUCCESS;
|
169 |
} |
170 |
|
171 |
int uart_get_config(int base_addr, uart_config *config){ |
172 |
int ret = SUCCESS;
|
173 |
|
174 |
config->base_addr = base_addr; |
175 |
|
176 |
if((ret = uart_get_lcr(base_addr, &config->lcr))) return ret; |
177 |
|
178 |
if((ret = uart_get_ier(base_addr, &config->ier))) return ret; |
179 |
|
180 |
if((ret = uart_enable_divisor_latch (base_addr))) return ret; |
181 |
if((ret = util_sys_inb(base_addr+UART_DLL, &config->dll ))) return ret; |
182 |
if((ret = util_sys_inb(base_addr+UART_DLM, &config->dlm ))) return ret; |
183 |
if((ret = uart_disable_divisor_latch(base_addr))) return ret; |
184 |
|
185 |
uart_parse_config(config); |
186 |
return ret;
|
187 |
} |
188 |
void uart_print_config(uart_config config){
|
189 |
|
190 |
printf("%s configuration:\n", (config.base_addr == COM1_ADDR ? "COM1" : "COM2")); |
191 |
printf("\tLCR = 0x%X: %d bits per char\t %d stop bits\t", config.lcr, config.bits_per_char, config.stop_bits);
|
192 |
if((config.parity&BIT(0)) == 0) printf("NO parity\n"); |
193 |
else switch(config.parity){ |
194 |
case uart_parity_none: printf("NO parity\n" ); break; |
195 |
case uart_parity_odd : printf("ODD parity\n" ); break; |
196 |
case uart_parity_even: printf("EVEN parity\n" ); break; |
197 |
case uart_parity_par1: printf("parity bit is 1\n"); break; |
198 |
case uart_parity_par0: printf("parity bit is 0\n"); break; |
199 |
//default : printf("invalid\n" ); break;
|
200 |
} |
201 |
printf("\tDLM = 0x%02X DLL=0x%02X: bitrate = %d bps\n", config.dlm, config.dll, UART_BITRATE/config.divisor_latch);
|
202 |
printf("\tIER = 0x%02X: Rx interrupts: %s\tTx interrupts: %s\n", config.ier,
|
203 |
(config.received_data_int ? "ENABLED":"DISABLED"), |
204 |
(config.transmitter_empty_int ? "ENABLED":"DISABLED")); |
205 |
} |
206 |
|
207 |
int uart_set_bits_per_character(int base_addr, uint8_t bits_per_char){ |
208 |
if(bits_per_char < 5 || bits_per_char > 8) return INVALID_ARG; |
209 |
int ret = SUCCESS;
|
210 |
bits_per_char = (bits_per_char-5)&0x3; |
211 |
uint8_t conf; if((ret = uart_get_lcr(base_addr, &conf))) return ret; |
212 |
conf = (conf & (~UART_BITS_PER_CHAR)) | bits_per_char; |
213 |
return uart_set_lcr(base_addr, conf);
|
214 |
} |
215 |
int uart_set_stop_bits(int base_addr, uint8_t stop){ |
216 |
if(stop != 1 && stop != 2) return INVALID_ARG; |
217 |
int ret = SUCCESS;
|
218 |
stop -= 1;
|
219 |
stop = (uint8_t)((stop&1)<<2); |
220 |
uint8_t conf; if((ret = uart_get_lcr(base_addr, &conf))) return ret; |
221 |
conf = (conf & (~UART_STOP_BITS)) | stop; |
222 |
return uart_set_lcr(base_addr, conf);
|
223 |
} |
224 |
int uart_set_parity(int base_addr, uart_parity par){ |
225 |
int ret = SUCCESS;
|
226 |
uint8_t parity = (uint8_t)(par << 3);
|
227 |
uint8_t conf; if((ret = uart_get_lcr(base_addr, &conf))) return ret; |
228 |
conf = (conf & (~UART_PARITY)) | parity; |
229 |
return uart_set_lcr(base_addr, conf);
|
230 |
} |
231 |
int uart_set_bit_rate(int base_addr, uint32_t bit_rate){ |
232 |
int ret = SUCCESS;
|
233 |
uint16_t latch = (uint16_t)(UART_BITRATE/bit_rate); |
234 |
uint8_t dll = UART_GET_DLL(latch); |
235 |
uint8_t dlm = UART_GET_DLM(latch); |
236 |
if((ret = uart_enable_divisor_latch(base_addr))) return ret; |
237 |
if(sys_outb(base_addr+UART_DLL, dll)) return WRITE_ERROR; |
238 |
if(sys_outb(base_addr+UART_DLM, dlm)) return WRITE_ERROR; |
239 |
if((ret = uart_disable_divisor_latch(base_addr))) return ret; |
240 |
return SUCCESS;
|
241 |
} |
242 |
|
243 |
static int uart_get_char(int base_addr, uint8_t *p){ |
244 |
int ret;
|
245 |
if((ret = uart_disable_divisor_latch(base_addr))) return ret; |
246 |
return util_sys_inb(base_addr+UART_RBR, p);
|
247 |
} |
248 |
static int uart_send_char(int base_addr, uint8_t c){ |
249 |
int ret;
|
250 |
if((ret = uart_disable_divisor_latch(base_addr))) return ret; |
251 |
if(sys_outb(base_addr+UART_THR, c)) return WRITE_ERROR; |
252 |
return SUCCESS;
|
253 |
} |
254 |
static int uart_receiver_ready(int base_addr){ |
255 |
uint8_t lsr; |
256 |
if(uart_get_lsr(base_addr, &lsr)) return false; |
257 |
return UART_GET_RECEIVER_READY(lsr);
|
258 |
} |
259 |
static int uart_transmitter_empty(int base_addr){ |
260 |
uint8_t lsr; |
261 |
if(uart_get_lsr(base_addr, &lsr)) return false; |
262 |
return UART_GET_TRANSMITTER_EMPTY(lsr);
|
263 |
} |
264 |
|
265 |
int uart_enable_int_rx(int base_addr){ |
266 |
int ret;
|
267 |
uint8_t ier; |
268 |
if((ret = uart_get_ier(base_addr, &ier))) return ret; |
269 |
ier |= UART_INT_EN_RX; |
270 |
return uart_set_ier(base_addr, ier);
|
271 |
} |
272 |
int uart_disable_int_rx(int base_addr){ |
273 |
int ret;
|
274 |
uint8_t ier; |
275 |
if((ret = uart_get_ier(base_addr, &ier))) return ret; |
276 |
ier &= ~UART_INT_EN_RX; |
277 |
return uart_set_ier(base_addr, ier);
|
278 |
} |
279 |
int uart_enable_int_tx(int base_addr){ |
280 |
int ret;
|
281 |
uint8_t ier; |
282 |
if((ret = uart_get_ier(base_addr, &ier))) return ret; |
283 |
ier |= UART_INT_EN_TX; |
284 |
return uart_set_ier(base_addr, ier);
|
285 |
} |
286 |
int uart_disable_int_tx(int base_addr){ |
287 |
int ret;
|
288 |
uint8_t ier; |
289 |
if((ret = uart_get_ier(base_addr, &ier))) return ret; |
290 |
ier &= ~UART_INT_EN_TX; |
291 |
return uart_set_ier(base_addr, ier);
|
292 |
} |
293 |
|
294 |
static int uart_set_fcr(int base_addr, uint8_t n){ |
295 |
if(sys_outb(base_addr+UART_FCR, n)) return WRITE_ERROR; |
296 |
return SUCCESS;
|
297 |
} |
298 |
static int uart_enable_fifos(int base_addr, uint8_t trigger_lvl){ |
299 |
uint8_t fcr = UART_EN_FIFOS | UART_CLEAR_RCVR | UART_CLEAR_XMIT; |
300 |
switch(trigger_lvl){
|
301 |
case 1: fcr |= UART_TRIGGER_LEVEL01; break; |
302 |
case 4: fcr |= UART_TRIGGER_LEVEL04; break; |
303 |
case 8: fcr |= UART_TRIGGER_LEVEL08; break; |
304 |
case 14: fcr |= UART_TRIGGER_LEVEL14; break; |
305 |
default: return INVALID_ARG; |
306 |
} |
307 |
return uart_set_fcr(base_addr, fcr);
|
308 |
} |
309 |
static int uart_disable_fifos(int base_addr){ |
310 |
return uart_set_fcr(base_addr, UART_CLEAR_RCVR | UART_CLEAR_XMIT);
|
311 |
} |
312 |
|
313 |
/// NCTP
|
314 |
|
315 |
//#define NCTP_START 0x80
|
316 |
//#define NCTP_END 0xFF
|
317 |
#define NCTP_OK 0xFF |
318 |
#define NCTP_NOK 0x00 |
319 |
#define NCTP_ALIGN 4 |
320 |
#define NCTP_FILLER 0x4E |
321 |
|
322 |
static queue_t *out = NULL; |
323 |
static queue_t *in = NULL; |
324 |
static void (*process)(const uint8_t*, const size_t) = NULL; |
325 |
|
326 |
int nctp_init(void){ |
327 |
out = queue_ctor(); if(out == NULL) return NULL_PTR; |
328 |
in = queue_ctor(); if(in == NULL) return NULL_PTR; |
329 |
//return SUCCESS;
|
330 |
return uart_enable_fifos(COM1_ADDR, NCTP_ALIGN);
|
331 |
} |
332 |
int nctp_dump(void){ |
333 |
int ret;
|
334 |
if((ret = nctp_free())) return ret; |
335 |
return nctp_init();
|
336 |
} |
337 |
int nctp_set_processor(void (*proc_func)(const uint8_t*, const size_t)){ |
338 |
process = proc_func; |
339 |
return SUCCESS;
|
340 |
} |
341 |
int nctp_free(void){ |
342 |
int ret = SUCCESS; int r; |
343 |
while(!queue_empty(out)){
|
344 |
free(queue_top(out)); |
345 |
queue_pop(out); |
346 |
} queue_dtor(out); |
347 |
while(!queue_empty(in)){
|
348 |
free(queue_top(in)); |
349 |
queue_pop(in); |
350 |
} queue_dtor(in); |
351 |
if((r = uart_disable_fifos(COM1_ADDR))) ret = r;
|
352 |
return ret;
|
353 |
} |
354 |
|
355 |
int nctp_send(size_t num, const uint8_t *const *ptr, const size_t *const sz){ |
356 |
int ret;
|
357 |
uint16_t sz_total = 0;{
|
358 |
for(size_t i = 0; i < num; ++i) |
359 |
sz_total += sz[i]; |
360 |
} |
361 |
uint8_t *tmp; |
362 |
tmp = malloc(sizeof(uint8_t)); *tmp = *((uint8_t*)(&sz_total)+0); queue_push(out, tmp); |
363 |
tmp = malloc(sizeof(uint8_t)); *tmp = *((uint8_t*)(&sz_total)+1); queue_push(out, tmp); |
364 |
for(size_t i = 0; i < num; ++i){ |
365 |
const uint8_t *p = ptr[i]; const size_t s = sz[i]; |
366 |
for(size_t j = 0; j < s; ++j, ++p){ |
367 |
tmp = malloc(sizeof(uint8_t)); *tmp = *p; queue_push(out, tmp);
|
368 |
} |
369 |
} |
370 |
uint32_t total_message = sz_total+2;
|
371 |
uint32_t num_fillers = (NCTP_ALIGN - total_message%NCTP_ALIGN)%NCTP_ALIGN; |
372 |
for(size_t i = 0; i < num_fillers; ++i){ |
373 |
tmp = malloc(sizeof(uint8_t)); *tmp = NCTP_FILLER; queue_push(out, tmp);
|
374 |
} |
375 |
|
376 |
if(uart_transmitter_empty(COM1_ADDR)){
|
377 |
if((ret = uart_send_char(COM1_ADDR, *(uint8_t*)queue_top(out)))) return ret; |
378 |
queue_pop(out); |
379 |
} |
380 |
return SUCCESS;
|
381 |
} |
382 |
static int nctp_transmit(void){ |
383 |
while(!queue_empty(out) && uart_transmitter_empty(COM1_ADDR)){
|
384 |
int ret = uart_send_char(COM1_ADDR, *(uint8_t*)queue_top(out));
|
385 |
queue_pop(out); |
386 |
if(ret) return ret; |
387 |
//return ret;
|
388 |
}/*else*/ return SUCCESS; |
389 |
} |
390 |
|
391 |
static void nctp_process_received(){ |
392 |
uint16_t sz = 0;{
|
393 |
uint8_t sz0 = *(uint8_t*)queue_top(in); free(queue_top(in)); queue_pop(in); |
394 |
uint8_t sz1 = *(uint8_t*)queue_top(in); free(queue_top(in)); queue_pop(in); |
395 |
*((uint8_t*)(&sz)+0) = sz0;
|
396 |
*((uint8_t*)(&sz)+1) = sz1;
|
397 |
} |
398 |
uint8_t *p = malloc(sz*sizeof(uint8_t));
|
399 |
for(uint16_t i = 0; i < sz; ++i){ |
400 |
p[i] = *(uint8_t*)queue_top(in); |
401 |
free(queue_top(in)); queue_pop(in); |
402 |
} |
403 |
if(process != NULL) process(p, sz); |
404 |
free(p); |
405 |
} |
406 |
|
407 |
static int num_bytes_to_receive = 0; |
408 |
static uint16_t szbytes_to_receive = 0; |
409 |
static uint8_t size0 = 0; |
410 |
static uint8_t received_so_far = 0; |
411 |
static int nctp_receive(void){ |
412 |
int ret;
|
413 |
uint8_t c; |
414 |
int counter_to_process = 0; |
415 |
|
416 |
while(uart_receiver_ready(COM1_ADDR)){
|
417 |
if((ret = uart_get_char(COM1_ADDR, &c))) return ret; |
418 |
uint8_t *tmp = malloc(sizeof(uint8_t)); *tmp = c;
|
419 |
|
420 |
if (szbytes_to_receive){ // gotta receive 2nd size byte and update num_bytes |
421 |
*((uint8_t*)(&num_bytes_to_receive)+0) = size0;
|
422 |
*((uint8_t*)(&num_bytes_to_receive)+1) = c;
|
423 |
szbytes_to_receive = 0;
|
424 |
} else if(num_bytes_to_receive > 0){ |
425 |
/* Now I know there are no more size bytes to receive.
|
426 |
* If there are normal bytes to receive, do this*/
|
427 |
--num_bytes_to_receive; |
428 |
if(num_bytes_to_receive == 0) ++counter_to_process; |
429 |
} else {
|
430 |
/* Now I know I am not expecting anything.
|
431 |
* The fact I received something means it is a filler, or the 1st size byte.
|
432 |
* If received_so_far == 0, then it is not a filler, but rather the 1st size byte. */
|
433 |
if(received_so_far == 0){ |
434 |
size0 = c; |
435 |
szbytes_to_receive = 1;
|
436 |
}else{
|
437 |
received_so_far = (received_so_far+1)%NCTP_ALIGN;
|
438 |
continue;
|
439 |
} |
440 |
} |
441 |
queue_push(in, tmp); |
442 |
received_so_far = (received_so_far+1)%NCTP_ALIGN;
|
443 |
} |
444 |
while(counter_to_process-- > 0) nctp_process_received(); |
445 |
return SUCCESS;
|
446 |
} |
447 |
|
448 |
static int nctp_ih_err = SUCCESS; |
449 |
int (nctp_get_ih_error)(void){ return nctp_ih_err; } |
450 |
void nctp_ih(void){ |
451 |
uint8_t iir; |
452 |
if((nctp_ih_err = uart_get_iir(COM1_ADDR, &iir))) return; |
453 |
if(UART_GET_IF_INT_PEND(iir)){
|
454 |
switch(UART_GET_INT_PEND(iir)){
|
455 |
case uart_int_rx: nctp_receive (); break; |
456 |
case uart_int_tx: nctp_transmit(); break; |
457 |
case uart_int_receiver_line_stat: break; |
458 |
case uart_int_modem_stat: break; |
459 |
case uart_int_char_timeout_fifo: nctp_receive (); break; |
460 |
//default: break;
|
461 |
} |
462 |
} |
463 |
} |