00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00017 #include "sceptre.h"
00018 #include "uart.h"
00019 #include <string.h>
00020
00021
00022 #define UART_BUFFER_SIZE 0x200
00023 #define UART_BUFFER_MASK (UART_BUFFER_SIZE-1)
00024
00025 #define UART0_RX_FIFO_SIZE 16
00026 #define UART0_TX_FIFO_SIZE 16
00027 #define UART1_RX_FIFO_SIZE 16
00028 #define UART1_TX_FIFO_SIZE 16
00029
00033 typedef struct
00034 {
00035 volatile uint16_t write_ptr;
00036 volatile uint16_t read_ptr;
00037 uint8_t data[UART_BUFFER_SIZE];
00038 }
00039 uart_buffer_t;
00040
00044 typedef struct
00045 {
00046 uart_buffer_t rx;
00047 uart_buffer_t tx;
00048 volatile bool_t tx_fifo_empty;
00049 }
00050 uart_rx_tx_buffer_t;
00051
00052
00053
00054 void uart0_handler(void) __irq;
00055 uart_rx_tx_buffer_t uart0_buffer;
00056 uart_rx_hook_t uart0_rx_hook = NULL;
00057
00058
00059
00060 void uart1_handler(void) __irq;
00061 uart_rx_tx_buffer_t uart1_buffer;
00062 uart_rx_hook_t uart1_rx_hook = NULL;
00063
00064
00065
00066 inline void uart_buffer_flush(uart_buffer_t *p_buffer);
00067 inline uint32_t uart_buffer_has_data(uart_buffer_t *p_buffer);
00068 inline bool_t uart_buffer_is_full(uart_buffer_t *p_buffer);
00069 inline bool_t uart_buffer_getc(uint32_t *p_ch, uart_buffer_t *p_buffer);
00070 inline bool_t uart_buffer_putc(uint32_t ch, uart_buffer_t *p_buffer);
00071
00077 inline void uart_buffer_flush(uart_buffer_t *p_buffer)
00078 {
00079 p_buffer->write_ptr = p_buffer->read_ptr = 0;
00080 }
00081
00082
00089 inline uint32_t uart_buffer_has_data(uart_buffer_t *p_buffer)
00090 {
00091 return (p_buffer->write_ptr-p_buffer->read_ptr)&UART_BUFFER_MASK;
00092 }
00093
00094
00101 inline bool_t uart_buffer_is_full(uart_buffer_t *p_buffer)
00102 {
00103 return uart_buffer_has_data(p_buffer)==UART_BUFFER_SIZE;
00104 }
00105
00106
00114 inline bool_t uart_buffer_getc(uint32_t *p_ch, uart_buffer_t *p_buffer)
00115 {
00116 if (p_buffer->write_ptr!=p_buffer->read_ptr)
00117 {
00118 *p_ch = p_buffer->data[p_buffer->read_ptr];
00119 p_buffer->read_ptr = (p_buffer->read_ptr+1)&UART_BUFFER_MASK;
00120 return true;
00121 }
00122 return false;
00123 }
00124
00125
00133 inline bool_t uart_buffer_putc(uint32_t ch, uart_buffer_t *p_buffer)
00134 {
00135 if (p_buffer->write_ptr!=((p_buffer->read_ptr-1)&UART_BUFFER_MASK))
00136 {
00137 p_buffer->data[p_buffer->write_ptr] = (uint8_t) ch;
00138 p_buffer->write_ptr = (p_buffer->write_ptr+1)&UART_BUFFER_MASK;
00139 return true;
00140 }
00141 return false;
00142 }
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00156 void uart0_handler(void) __irq
00157 {
00158 uint8_t iir;
00159 uint8_t lsr;
00160
00161 IENABLE;
00162
00163
00164 iir = U0IIR;
00165 iir >>= 1;
00166 iir &= 0x07;
00167
00168 switch (iir)
00169 {
00170
00171 case IIR_RLS:
00172
00173 lsr = U0LSR;
00174 break;
00175
00176
00177 case IIR_RDA:
00178
00179 if (uart0_rx_hook!=NULL)
00180 {
00181
00182 while ((U0LSR&LSR_RDR)!=0)
00183 {
00184 uint32_t ch = U0RBR;
00185
00186 if (uart0_rx_hook(ch)==false) uart_buffer_putc(ch,&uart0_buffer.rx);
00187 }
00188 }
00189 else
00190 {
00191
00192 while ((U0LSR&LSR_RDR)!=0)
00193 {
00194 uart_buffer_putc(U0RBR,&uart0_buffer.rx);
00195 }
00196 }
00197 break;
00198
00199
00200 case IIR_CTI:
00201
00202 uart_buffer_putc(U0RBR,&uart0_buffer.rx);
00203 break;
00204
00205
00206 case IIR_THRE:
00207 {
00208 uart0_buffer.tx_fifo_empty = true;
00209
00210 uint8_t count = UART0_TX_FIFO_SIZE;
00211 while (count>0)
00212 {
00213 uint32_t ch;
00214 if (uart_buffer_getc(&ch,&uart0_buffer.tx)==false) break;
00215 U0THR = ch;
00216 uart0_buffer.tx_fifo_empty = false;
00217 count -= 1;
00218 }
00219 break;
00220 }
00221 }
00222
00223 IDISABLE;
00224 VICVectAddr = 0;
00225 }
00226
00227
00239 bool_t uart0_init(uint32_t baudrate, uint8_t data_bits, char parity, uint8_t stop_bits)
00240 {
00241 uint32_t dummy;
00242
00243
00244 memset(&uart0_buffer,0,sizeof(uart0_buffer));
00245 uart0_buffer.tx_fifo_empty = true;
00246
00247 PINSEL0 = (PINSEL0&0xfffffff0)|0x00000005;
00248
00249
00250 U0IER = 0;
00251
00252 dummy = U0IIR;
00253 dummy = U0RBR;
00254 dummy = U0LSR;
00255
00256
00257 uint32_t p = 0;
00258 if (parity=='o' || parity=='O') p = 0x08;
00259 else if (parity=='e' || parity=='E') p = 0x18;
00260 else if (parity=='1') p = 0x28;
00261 else if (parity=='0') p = 0x38;
00262
00263 U0LCR = 0x80 + ((data_bits-5)&0x3) + (((stop_bits-1)&0x1)<<1) + p;
00264
00265
00266 uint32_t Fdiv = (Fpclk/16)/baudrate;
00267 U0DLM = Fdiv / 256;
00268 U0DLL = Fdiv % 256;
00269
00270
00271
00272
00273
00274
00275 U0LCR &= 0x7f;
00276
00277
00278 U0FCR = 0x07;
00279
00280 if (irq_install(UART0_INT,(void*)uart0_handler)==false)
00281 {
00282 return false;
00283 }
00284
00285
00286 U0IER = IER_RBR | IER_THRE | IER_RLS;
00287 return true;
00288 }
00289
00290
00301 uint32_t uart0_send(const uint8_t *p_data, uint32_t data_size, bool_t cr_to_crlf)
00302 {
00303 uint32_t i = 0;
00304 while (i<data_size)
00305 {
00306 if (p_data[i]=='\n' && cr_to_crlf==true)
00307 {
00308
00309 if (uart0_putc('\r')==false) break;
00310 }
00311 if (uart0_putc(p_data[i])==false) break;
00312 i += 1;
00313 }
00314 return i;
00315 }
00316
00317
00325 bool_t uart0_putc(uint32_t ch)
00326 {
00327 if (uart0_buffer.tx_fifo_empty==true)
00328 {
00329 U0THR = ch;
00330 uart0_buffer.tx_fifo_empty = false;
00331 return true;
00332 }
00333 else return uart_buffer_putc(ch,&uart0_buffer.tx);
00334 }
00335
00336
00345 bool_t uart0_getc(uint32_t *p_ch, uint32_t timeout_in_ms)
00346 {
00347
00348 uint32_t last_count = timer_get_system_count();
00349 while (uart_buffer_has_data(&uart0_buffer.rx)==0 &&
00350 timer_get_system_count()-last_count<timeout_in_ms);
00351 return uart_buffer_getc(p_ch,&uart0_buffer.rx);
00352 }
00353
00354
00358 void uart0_flush_buffers(void)
00359 {
00360 uart_buffer_flush(&uart0_buffer.rx);
00361 uart_buffer_flush(&uart0_buffer.tx);
00362 }
00363
00364
00370 void uart0_set_rx_hook(uart_rx_hook_t f)
00371 {
00372 uart0_rx_hook = f;
00373 }
00374
00375
00379
00380
00384 void uart1_handler(void) __irq
00385 {
00386 uint8_t iir;
00387 uint8_t lsr;
00388
00389 IENABLE;
00390
00391
00392 iir = U1IIR;
00393 iir >>= 1;
00394 iir &= 0x07;
00395
00396 switch (iir)
00397 {
00398
00399 case IIR_RLS:
00400
00401 lsr = U1LSR;
00402 break;
00403
00404
00405 case IIR_RDA:
00406
00407 if (uart1_rx_hook!=NULL)
00408 {
00409
00410 while ((U1LSR&LSR_RDR)!=0)
00411 {
00412 uint32_t ch = U1RBR;
00413
00414 if (uart1_rx_hook(ch)==false) uart_buffer_putc(ch,&uart1_buffer.rx);
00415 }
00416 }
00417 else
00418 {
00419
00420 while ((U1LSR&LSR_RDR)!=0)
00421 {
00422 uart_buffer_putc(U1RBR,&uart1_buffer.rx);
00423 }
00424 }
00425 break;
00426
00427
00428 case IIR_CTI:
00429
00430 uart_buffer_putc(U1RBR,&uart1_buffer.rx);
00431 break;
00432
00433
00434 case IIR_THRE:
00435 {
00436 uart1_buffer.tx_fifo_empty = true;
00437
00438 uint8_t count = UART1_TX_FIFO_SIZE;
00439 while (count>0)
00440 {
00441 uint32_t ch;
00442 if (uart_buffer_getc(&ch,&uart1_buffer.tx)==false) break;
00443 U1THR = ch;
00444 uart1_buffer.tx_fifo_empty = false;
00445 count -= 1;
00446 }
00447 break;
00448 }
00449 }
00450
00451 IDISABLE;
00452 VICVectAddr = 0;
00453 }
00454
00455
00467 bool_t uart1_init(uint32_t baudrate, uint8_t data_bits, char parity, uint8_t stop_bits)
00468 {
00469 uint32_t dummy;
00470
00471
00472 memset(&uart1_buffer,0,sizeof(uart1_buffer));
00473 uart1_buffer.tx_fifo_empty = true;
00474
00475 PINSEL0 = (PINSEL0&0xfff0ffff)|0x00050000;
00476
00477
00478 U1IER = 0;
00479
00480 dummy = U1IIR;
00481 dummy = U1RBR;
00482 dummy = U1LSR;
00483
00484
00485 uint32_t p = 0;
00486 if (parity=='o' || parity=='O') p = 0x08;
00487 else if (parity=='e' || parity=='E') p = 0x18;
00488 else if (parity=='1') p = 0x28;
00489 else if (parity=='0') p = 0x38;
00490
00491 U1LCR = 0x80 + ((data_bits-5)&0x3) + (((stop_bits-1)&0x1)<<1) + p;
00492
00493 uint32_t Fdiv = (Fpclk/16)/baudrate;
00494 U1DLM = Fdiv / 256;
00495 U1DLL = Fdiv % 256;
00496 U1LCR &= 0x7f;
00497
00498
00499 U1FCR = 0x07;
00500
00501 if (irq_install(UART1_INT,(void*)uart1_handler)==false)
00502 {
00503 return false;
00504 }
00505
00506
00507 U1IER = IER_RBR | IER_THRE | IER_RLS;
00508 return true;
00509 }
00510
00511
00521 uint32_t uart1_send(const uint8_t *p_data, uint32_t data_size, bool_t cr_to_crlf)
00522 {
00523 uint32_t i = 0;
00524 while (i<data_size)
00525 {
00526 if (p_data[i]=='\n' && cr_to_crlf==true)
00527 {
00528
00529 if (uart1_putc('\r',false)==false) break;
00530 }
00531 if (uart1_putc(p_data[i],false)==false) break;
00532 i += 1;
00533 }
00534 return i;
00535 }
00536
00537
00546 bool_t uart1_putc(uint32_t ch, bool_t right_now)
00547 {
00548 if (right_now==true)
00549 {
00550 U1THR = ch;
00551 }
00552 else
00553 {
00554 if (uart1_buffer.tx_fifo_empty==true)
00555 {
00556 U1THR = ch;
00557 uart1_buffer.tx_fifo_empty = false;
00558 }
00559 else return uart_buffer_putc(ch,&uart1_buffer.tx);
00560 }
00561 return true;
00562 }
00563
00564
00573 bool_t uart1_getc(uint32_t *p_ch, uint32_t timeout_in_ms)
00574 {
00575
00576 uint32_t last_count = timer_get_system_count();
00577 while (uart_buffer_has_data(&uart1_buffer.rx)==0 &&
00578 timer_get_system_count()-last_count<timeout_in_ms);
00579 return uart_buffer_getc(p_ch,&uart1_buffer.rx);
00580 }
00581
00582
00586 void uart1_flush_buffers(void)
00587 {
00588 uart_buffer_flush(&uart1_buffer.rx);
00589 uart_buffer_flush(&uart1_buffer.tx);
00590 }
00591
00592
00598 void uart1_set_rx_hook(uart_rx_hook_t f)
00599 {
00600 uart1_rx_hook = f;
00601 }