File indexing completed on 2025-05-11 08:23:58
0001
0002
0003
0004
0005
0006
0007
0008 #include <stdint.h>
0009 #include <stdio.h>
0010 #include <bsp.h>
0011 #include <bsp/irq.h>
0012 #include <bsp/uart.h>
0013 #include <rtems/libio.h>
0014 #include <rtems/bspIo.h>
0015 #include <rtems/termiostypes.h>
0016 #include <termios.h>
0017 #include <assert.h>
0018
0019
0020
0021
0022
0023 struct uart_data
0024 {
0025 unsigned long ioBase;
0026 int irq;
0027 int hwFlow;
0028 int baud;
0029 BSP_UartBreakCbRec breakCallback;
0030 int ioMode;
0031 };
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042 #define UART_UNSUPP ((unsigned long)(-1))
0043
0044 static struct uart_data uart_data[2] = {
0045 {
0046 #ifdef BSP_UART_IOBASE_COM1
0047 BSP_UART_IOBASE_COM1,
0048 BSP_UART_COM1_IRQ,
0049 #else
0050 UART_UNSUPP,
0051 -1,
0052 #endif
0053 },
0054 {
0055 #ifdef BSP_UART_IOBASE_COM2
0056 BSP_UART_IOBASE_COM2,
0057 BSP_UART_COM2_IRQ,
0058 #else
0059 UART_UNSUPP,
0060 -1,
0061 #endif
0062 },
0063 };
0064
0065 #define MAX_UARTS (sizeof(uart_data)/sizeof(uart_data[0]))
0066 #define SANITY_CHECK(uart) \
0067 assert( MAX_UARTS > (unsigned)(uart) && uart_data[(uart)].ioBase != UART_UNSUPP )
0068
0069
0070
0071
0072
0073 static inline unsigned char
0074 uread(int uart, unsigned int reg)
0075 {
0076 return in_8((uint8_t*)(uart_data[uart].ioBase + reg));
0077 }
0078
0079 static inline void
0080 uwrite(int uart, int reg, unsigned int val)
0081 {
0082 out_8((uint8_t*)(uart_data[uart].ioBase + reg), val);
0083 }
0084
0085
0086 static void
0087 uartError(int uart, void *termiosPrivate)
0088 {
0089 unsigned char uartStatus, dummy;
0090 BSP_UartBreakCbProc h;
0091
0092 uartStatus = uread(uart, LSR);
0093 dummy = uread(uart, RBR);
0094
0095 #ifdef UARTDEBUG
0096 if (uartStatus & OE)
0097 printk("********* Over run Error **********\n");
0098 if (uartStatus & PE)
0099 printk("********* Parity Error **********\n");
0100 if (uartStatus & FE)
0101 printk("********* Framing Error **********\n");
0102 if (uartStatus & BI) {
0103 printk("********* BREAK INTERRUPT *********\n");
0104 #endif
0105 if ((h=uart_data[uart].breakCallback.handler)) {
0106 h(uart,
0107 (dummy<<8)|uartStatus,
0108 termiosPrivate,
0109 uart_data[uart].breakCallback.private);
0110 }
0111 #ifdef UARTDEBUG
0112 if (uartStatus & ERFIFO)
0113 printk("********* Error receive Fifo **********\n");
0114 #endif
0115 }
0116
0117
0118
0119
0120
0121
0122
0123 void
0124 BSP_uart_init(int uart, int baud, int hwFlow)
0125 {
0126 unsigned char tmp;
0127
0128
0129 SANITY_CHECK(uart);
0130
0131
0132
0133
0134 while ( ! (uread(uart, LSR) & TEMT) )
0135 ;
0136
0137 switch(baud)
0138 {
0139 case 50:
0140 case 75:
0141 case 110:
0142 case 134:
0143 case 300:
0144 case 600:
0145 case 1200:
0146 case 2400:
0147 case 9600:
0148 case 19200:
0149 case 38400:
0150 case 57600:
0151 case 115200:
0152 break;
0153 default:
0154 assert(0);
0155 return;
0156 }
0157
0158
0159 uwrite(uart, LCR, DLAB);
0160
0161 if ( (int)BSPBaseBaud <= 0 ) {
0162
0163 BSPBaseBaud = BSPBaseBaud ? -BSPBaseBaud : BSP_CONSOLE_BAUD;
0164 BSPBaseBaud *= ((uread(uart, DLM) << 8) | uread(uart, DLL));
0165 }
0166
0167
0168 uwrite(uart, DLL, (BSPBaseBaud/baud) & 0xff);
0169 uwrite(uart, DLM, ((BSPBaseBaud/baud) >> 8) & 0xff);
0170
0171
0172 uwrite(uart, LCR, CHR_8_BITS);
0173
0174
0175 uwrite(uart, MCR, DTR | RTS | OUT_2);
0176
0177
0178 uwrite(uart, FCR, FIFO_EN | XMIT_RESET | RCV_RESET | RECEIVE_FIFO_TRIGGER12);
0179
0180
0181 uwrite(uart, IER, 0);
0182
0183
0184 tmp = uread(uart, LSR);
0185 tmp = uread(uart, RBR);
0186 tmp = uread(uart, MSR);
0187 (void) tmp;
0188
0189
0190 uart_data[uart].hwFlow = hwFlow;
0191 uart_data[uart].baud = baud;
0192 return;
0193 }
0194
0195
0196
0197
0198 void
0199 BSP_uart_set_baud(int uart, int baud)
0200 {
0201 unsigned char mcr, ier;
0202
0203
0204 SANITY_CHECK(uart);
0205
0206
0207
0208
0209
0210
0211
0212 if(baud == uart_data[uart].baud)
0213 {
0214 return;
0215 }
0216
0217 mcr = uread(uart, MCR);
0218 ier = uread(uart, IER);
0219
0220 BSP_uart_init(uart, baud, uart_data[uart].hwFlow);
0221
0222 uwrite(uart, MCR, mcr);
0223 uwrite(uart, IER, ier);
0224
0225 return;
0226 }
0227
0228
0229
0230
0231 void
0232 BSP_uart_intr_ctrl(int uart, int cmd)
0233 {
0234
0235 SANITY_CHECK(uart);
0236
0237 switch(cmd)
0238 {
0239 case BSP_UART_INTR_CTRL_DISABLE:
0240 uwrite(uart, IER, INTERRUPT_DISABLE);
0241 break;
0242 case BSP_UART_INTR_CTRL_ENABLE:
0243 if(uart_data[uart].hwFlow)
0244 {
0245 uwrite(uart, IER,
0246 (RECEIVE_ENABLE |
0247 TRANSMIT_ENABLE |
0248 RECEIVER_LINE_ST_ENABLE |
0249 MODEM_ENABLE
0250 )
0251 );
0252 }
0253 else
0254 {
0255 uwrite(uart, IER,
0256 (RECEIVE_ENABLE |
0257 TRANSMIT_ENABLE |
0258 RECEIVER_LINE_ST_ENABLE
0259 )
0260 );
0261 }
0262 break;
0263 case BSP_UART_INTR_CTRL_TERMIOS:
0264 if(uart_data[uart].hwFlow)
0265 {
0266 uwrite(uart, IER,
0267 (RECEIVE_ENABLE |
0268 RECEIVER_LINE_ST_ENABLE |
0269 MODEM_ENABLE
0270 )
0271 );
0272 }
0273 else
0274 {
0275 uwrite(uart, IER,
0276 (RECEIVE_ENABLE |
0277 RECEIVER_LINE_ST_ENABLE
0278 )
0279 );
0280 }
0281 break;
0282 case BSP_UART_INTR_CTRL_GDB:
0283 uwrite(uart, IER, RECEIVE_ENABLE);
0284 break;
0285 default:
0286 assert(0);
0287 break;
0288 }
0289
0290 return;
0291 }
0292
0293 void
0294 BSP_uart_throttle(int uart)
0295 {
0296 unsigned int mcr;
0297
0298 SANITY_CHECK(uart);
0299
0300 if(!uart_data[uart].hwFlow)
0301 {
0302
0303 assert(0);
0304 return;
0305 }
0306 mcr = uread (uart, MCR);
0307
0308 mcr &= ~RTS;
0309 uwrite(uart, MCR, mcr);
0310
0311 return;
0312 }
0313
0314 void
0315 BSP_uart_unthrottle(int uart)
0316 {
0317 unsigned int mcr;
0318
0319 SANITY_CHECK(uart);
0320
0321 if(!uart_data[uart].hwFlow)
0322 {
0323
0324 assert(0);
0325 return;
0326 }
0327 mcr = uread (uart, MCR);
0328
0329 mcr |= RTS;
0330 uwrite(uart, MCR, mcr);
0331
0332 return;
0333 }
0334
0335
0336
0337
0338
0339
0340
0341
0342
0343
0344 int
0345 BSP_uart_polled_status(int uart)
0346 {
0347 unsigned char val;
0348
0349 SANITY_CHECK(uart);
0350
0351 val = uread(uart, LSR);
0352
0353 if(val & BI)
0354 {
0355
0356 uread(uart, RBR);
0357 return BSP_UART_STATUS_BREAK;
0358 }
0359
0360 if((val & (DR | OE | FE)) == 1)
0361 {
0362
0363 return BSP_UART_STATUS_CHAR;
0364 }
0365
0366 if((val & (DR | OE | FE)) == 0)
0367 {
0368
0369 return BSP_UART_STATUS_NOCHAR;
0370 }
0371
0372
0373
0374
0375
0376 uread(uart, RBR);
0377
0378 return BSP_UART_STATUS_ERROR;
0379 }
0380
0381
0382
0383
0384 void
0385 BSP_uart_polled_write(int uart, int val)
0386 {
0387 unsigned char val1;
0388
0389
0390 SANITY_CHECK(uart);
0391
0392 for(;;)
0393 {
0394 if((val1=uread(uart, LSR)) & THRE)
0395 {
0396 break;
0397 }
0398 }
0399
0400 if(uart_data[uart].hwFlow)
0401 {
0402 for(;;)
0403 {
0404 if(uread(uart, MSR) & CTS)
0405 {
0406 break;
0407 }
0408 }
0409 }
0410
0411 uwrite(uart, THR, val & 0xff);
0412
0413 return;
0414 }
0415
0416 void
0417 BSP_output_char_via_serial(const char val)
0418 {
0419 BSP_uart_polled_write(BSPConsolePort, val);
0420 }
0421
0422
0423
0424
0425 int
0426 BSP_uart_polled_read(int uart)
0427 {
0428 unsigned char val;
0429
0430 SANITY_CHECK(uart);
0431
0432 for(;;)
0433 {
0434 if(uread(uart, LSR) & DR)
0435 {
0436 break;
0437 }
0438 }
0439
0440 val = uread(uart, RBR);
0441
0442 return (int)(val & 0xff);
0443 }
0444
0445 unsigned
0446 BSP_poll_char_via_serial()
0447 {
0448 return BSP_uart_polled_read(BSPConsolePort);
0449 }
0450
0451 static void
0452 uart_noop(const rtems_irq_connect_data *unused)
0453 {
0454 return;
0455 }
0456
0457
0458
0459
0460
0461
0462 static int
0463 uart_isr_is_on(const rtems_irq_connect_data *irq)
0464 {
0465 int uart;
0466
0467 uart = (irq->name == BSP_UART_COM1_IRQ) ?
0468 BSP_UART_COM1 : BSP_UART_COM2;
0469
0470 return uread(uart,IER);
0471 }
0472
0473 static int
0474 doit(int uart, rtems_irq_hdl handler, int (*p)(const rtems_irq_connect_data*))
0475 {
0476 rtems_irq_connect_data d={0};
0477 d.name = uart_data[uart].irq;
0478 d.off = d.on = uart_noop;
0479 d.isOn = uart_isr_is_on;
0480 d.hdl = handler;
0481 return p(&d);
0482 }
0483
0484 int
0485 BSP_uart_install_isr(int uart, rtems_irq_hdl handler)
0486 {
0487
0488
0489
0490
0491 #ifdef BSP_UART_USE_SHARED_IRQS
0492 return doit(uart, handler, BSP_install_rtems_shared_irq_handler);
0493 #else
0494 return doit(uart, handler, BSP_install_rtems_irq_handler);
0495 #endif
0496 }
0497
0498 int
0499 BSP_uart_remove_isr(int uart, rtems_irq_hdl handler)
0500 {
0501 return doit(uart, handler, BSP_remove_rtems_irq_handler);
0502 }
0503
0504
0505
0506 static volatile int termios_stopped_com[2] = {0,0};
0507 static volatile int termios_tx_active_com[2] = {0,0};
0508 static void* termios_ttyp_com[2] = {NULL,NULL};
0509 static char termios_tx_hold_com[2] = {0,0};
0510 static volatile char termios_tx_hold_valid_com[2] = {0,0};
0511
0512
0513
0514
0515 void
0516 BSP_uart_termios_set(int uart, void *p)
0517 {
0518 struct rtems_termios_tty *ttyp = p;
0519 unsigned char val;
0520 SANITY_CHECK(uart);
0521
0522 if(uart_data[uart].hwFlow)
0523 {
0524 val = uread(uart, MSR);
0525
0526 termios_stopped_com[uart] = (val & CTS) ? 0 : 1;
0527 }
0528 else
0529 {
0530 termios_stopped_com[uart] = 0;
0531 }
0532 termios_tx_active_com[uart] = 0;
0533 termios_ttyp_com[uart] = ttyp;
0534 termios_tx_hold_com[uart] = 0;
0535 termios_tx_hold_valid_com[uart] = 0;
0536
0537 uart_data[uart].ioMode = ttyp->device.outputUsesInterrupts;
0538
0539
0540 ttyp->termios.c_ispeed = ttyp->termios.c_ospeed =
0541 rtems_termios_number_to_baud(uart_data[uart].baud);
0542
0543 return;
0544 }
0545
0546 ssize_t
0547 BSP_uart_termios_write_polled(int minor, const char *buf, size_t len)
0548 {
0549 int uart=minor;
0550 int nwrite;
0551 const char *b = buf;
0552
0553 for (nwrite=0 ; nwrite < len ; nwrite++) {
0554 BSP_uart_polled_write(uart, *b++);
0555 }
0556 return nwrite;
0557 }
0558
0559 ssize_t
0560 BSP_uart_termios_write_com(int minor, const char *buf, size_t len)
0561 {
0562 int uart=minor;
0563
0564 if(len <= 0)
0565 {
0566 return 0;
0567 }
0568
0569
0570
0571
0572 if(termios_stopped_com[uart])
0573 {
0574
0575 termios_tx_hold_com[uart] = *buf;
0576 termios_tx_hold_valid_com[uart] = 1;
0577 return 0;
0578 }
0579
0580
0581 uwrite(uart, THR, *buf & 0xff);
0582
0583
0584 if(!termios_tx_active_com[uart] && uart_data[uart].hwFlow)
0585 {
0586 termios_tx_active_com[uart] = 1;
0587 uwrite(uart, IER,
0588 (RECEIVE_ENABLE |
0589 TRANSMIT_ENABLE |
0590 RECEIVER_LINE_ST_ENABLE |
0591 MODEM_ENABLE
0592 )
0593 );
0594 }
0595 else if(!termios_tx_active_com[uart])
0596 {
0597 termios_tx_active_com[uart] = 1;
0598 uwrite(uart, IER,
0599 (RECEIVE_ENABLE |
0600 TRANSMIT_ENABLE |
0601 RECEIVER_LINE_ST_ENABLE
0602 )
0603 );
0604 }
0605
0606 return 0;
0607 }
0608
0609 int
0610 BSP_uart_termios_read_com(int uart)
0611 {
0612 int off = (int)0;
0613 char buf[40];
0614 rtems_interrupt_level l;
0615
0616
0617 while (( off < sizeof(buf) ) && ( uread(uart, LSR) & DR )) {
0618 buf[off++] = uread(uart, RBR);
0619 }
0620
0621
0622 if ( off > 0 ) {
0623 rtems_termios_enqueue_raw_characters(termios_ttyp_com[uart], buf, off);
0624 }
0625
0626
0627 rtems_interrupt_disable(l);
0628 uwrite(uart, IER, uread(uart, IER) | (RECEIVE_ENABLE | RECEIVER_LINE_ST_ENABLE));
0629 rtems_interrupt_enable(l);
0630
0631 return ( EOF );
0632 }
0633
0634 static void
0635 BSP_uart_termios_isr_com(int uart)
0636 {
0637 unsigned char buf[40];
0638 unsigned char val, ier;
0639 int off, ret, vect;
0640
0641 off = 0;
0642
0643 for(;;)
0644 {
0645 vect = uread(uart, IIR) & 0xf;
0646
0647 switch(vect)
0648 {
0649 case MODEM_STATUS :
0650 val = uread(uart, MSR);
0651 if(uart_data[uart].hwFlow)
0652 {
0653 if(val & CTS)
0654 {
0655
0656 termios_stopped_com[uart] = 0;
0657 if(termios_tx_hold_valid_com[uart])
0658 {
0659 termios_tx_hold_valid_com[uart] = 0;
0660 BSP_uart_termios_write_com(uart, &termios_tx_hold_com[uart],
0661 1);
0662 }
0663 }
0664 else
0665 {
0666
0667 termios_stopped_com[uart] = 1;
0668 }
0669 }
0670 break;
0671 case NO_MORE_INTR :
0672
0673 if(off != 0)
0674 {
0675
0676 rtems_termios_enqueue_raw_characters(termios_ttyp_com[uart],
0677 (char *)buf,
0678 off);
0679 }
0680 return;
0681 case TRANSMITTER_HODING_REGISTER_EMPTY :
0682
0683
0684
0685
0686
0687 ret = rtems_termios_dequeue_characters(termios_ttyp_com[uart], 1);
0688
0689
0690 if(ret == 0 && uart_data[uart].hwFlow)
0691 {
0692 uwrite(uart, IER,
0693 (RECEIVE_ENABLE |
0694 RECEIVER_LINE_ST_ENABLE |
0695 MODEM_ENABLE
0696 )
0697 );
0698 termios_tx_active_com[uart] = 0;
0699 }
0700 else if(ret == 0)
0701 {
0702 uwrite(uart, IER,
0703 (RECEIVE_ENABLE |
0704 RECEIVER_LINE_ST_ENABLE
0705 )
0706 );
0707 termios_tx_active_com[uart] = 0;
0708 }
0709 break;
0710 case RECEIVER_DATA_AVAIL :
0711 case CHARACTER_TIMEOUT_INDICATION:
0712 if ( uart_data[uart].ioMode == TERMIOS_TASK_DRIVEN )
0713 {
0714
0715 if ( (ier = uread(uart,IER)) & RECEIVE_ENABLE )
0716 {
0717
0718 ier &= ~(RECEIVE_ENABLE | RECEIVER_LINE_ST_ENABLE);
0719 uwrite(uart, IER, ier);
0720 rtems_termios_rxirq_occured(termios_ttyp_com[uart]);
0721 }
0722 }
0723 else
0724 {
0725
0726 assert(off < sizeof(buf));
0727 while ( off < sizeof(buf) && ( DR & uread(uart, LSR) ) )
0728 buf[off++] = uread(uart, RBR);
0729 }
0730 break;
0731 case RECEIVER_ERROR:
0732
0733 uartError(uart, termios_ttyp_com[uart]);
0734 break;
0735 default:
0736
0737 assert(0);
0738 return;
0739 }
0740 }
0741 }
0742
0743
0744
0745
0746
0747 void
0748 BSP_uart_termios_isr_com1(void *unused)
0749 {
0750 BSP_uart_termios_isr_com(BSP_UART_COM1);
0751 }
0752
0753 void
0754 BSP_uart_termios_isr_com2(void *unused)
0755 {
0756 BSP_uart_termios_isr_com(BSP_UART_COM2);
0757 }
0758
0759
0760 int
0761 BSP_uart_get_break_cb(int uart, rtems_libio_ioctl_args_t *arg)
0762 {
0763 BSP_UartBreakCb cb=arg->buffer;
0764 unsigned long flags;
0765 SANITY_CHECK(uart);
0766 rtems_interrupt_disable(flags);
0767 *cb = uart_data[uart].breakCallback;
0768 rtems_interrupt_enable(flags);
0769 arg->ioctl_return=0;
0770 return RTEMS_SUCCESSFUL;
0771 }
0772
0773
0774 int
0775 BSP_uart_set_break_cb(int uart, rtems_libio_ioctl_args_t *arg)
0776 {
0777 BSP_UartBreakCb cb=arg->buffer;
0778 unsigned long flags;
0779 SANITY_CHECK(uart);
0780 rtems_interrupt_disable(flags);
0781 uart_data[uart].breakCallback = *cb;
0782 rtems_interrupt_enable(flags);
0783 arg->ioctl_return=0;
0784 return RTEMS_SUCCESSFUL;
0785 }