File indexing completed on 2025-05-11 08:23:47
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <stdio.h>
0012 #include <fcntl.h>
0013 #include <termios.h>
0014 #include <malloc.h>
0015
0016 #include <rtems/libio.h>
0017 #include <rtems/termiostypes.h>
0018 #include <rtems/console.h>
0019 #include <rtems/bspIo.h>
0020 #include <bsp.h>
0021
0022 #define UART_INTC0_IRQ_VECTOR(x) (64+13+(x))
0023
0024 #define MCF_UART_USR_ERROR ( MCF_UART_USR_RB | \
0025 MCF_UART_USR_FE | \
0026 MCF_UART_USR_PE | \
0027 MCF_UART_USR_OE )
0028
0029 static ssize_t IntUartPollWrite(int minor, const char *buf, size_t len);
0030 static ssize_t IntUartInterruptWrite(int minor, const char *buf, size_t len);
0031
0032 #define MAX_UART_INFO 3
0033 #define RX_BUFFER_SIZE 512
0034
0035 struct IntUartInfoStruct
0036 {
0037 int iomode;
0038 volatile int uimr;
0039 int baud;
0040 int databits;
0041 int parity;
0042 int stopbits;
0043 int hwflow;
0044 int rx_in;
0045 int rx_out;
0046 char rx_buffer[RX_BUFFER_SIZE];
0047 void *ttyp;
0048 };
0049
0050 struct IntUartInfoStruct IntUartInfo[MAX_UART_INFO];
0051
0052
0053
0054
0055
0056
0057 static void
0058 IntUartSet(int minor, int baud, int databits, int parity, int stopbits,
0059 int hwflow)
0060 {
0061 int divisor;
0062 uint32_t clock_speed;
0063 uint8_t umr1 = 0;
0064 uint8_t umr2 = 0;
0065 struct IntUartInfoStruct *info = &IntUartInfo[minor];
0066 rtems_interrupt_level level=UART0_IRQ_LEVEL;
0067
0068 rtems_interrupt_disable(level);
0069
0070
0071 MCF_UART_UIMR(minor) = 0;
0072 MCF_UART_UOP0(minor) = 1;
0073 MCF_UART_UCR(minor) = (MCF_UART_UCR_TX_DISABLED | MCF_UART_UCR_RX_DISABLED);
0074
0075
0076 info->uimr = 0;
0077 info->baud = baud;
0078 info->databits = databits;
0079 info->parity = parity;
0080 info->stopbits = stopbits;
0081 info->hwflow = hwflow;
0082
0083 clock_speed = bsp_get_CPU_clock_speed();
0084
0085 divisor = ((clock_speed) / (32 * baud));
0086 if (divisor < 2)
0087 divisor = 2;
0088
0089
0090 if (hwflow) {
0091
0092 umr1 |= MCF_UART_UMR_RXRTS;
0093 umr2 |= MCF_UART_UMR_TXCTS;
0094 }
0095
0096
0097 umr1 |= (parity | databits);
0098
0099 #if 1
0100 if (minor==STATIONS_PORT)
0101 umr2 |= (stopbits) | 0x20;
0102 else
0103 umr2 |= (stopbits);
0104 #else
0105 umr2 |= (stopbits);
0106 #endif
0107
0108
0109 MCF_UART_UCR(minor) = MCF_UART_UCR_RESET_ERROR;
0110 MCF_UART_UCR(minor) = MCF_UART_UCR_RESET_RX;
0111 MCF_UART_UCR(minor) = MCF_UART_UCR_RESET_TX;
0112
0113
0114 MCF_UART_UCR(minor) = MCF_UART_UCR_RESET_MR;
0115 MCF_UART_UMR(minor) = umr1;
0116 MCF_UART_UMR(minor) = umr2;
0117
0118
0119 MCF_UART_UCSR(minor) =
0120 (MCF_UART_UCSR_RCS_SYS_CLK | MCF_UART_UCSR_TCS_SYS_CLK);
0121 MCF_UART_UBG1(minor) = (divisor & 0xff00) >> 8;
0122 MCF_UART_UBG2(minor) = (divisor & 0x00ff);
0123
0124
0125 MCF_UART_UCR(minor) = (MCF_UART_UCR_TX_ENABLED | MCF_UART_UCR_RX_ENABLED);
0126
0127
0128 if (info->iomode != TERMIOS_POLLED) {
0129
0130 info->uimr |= MCF_UART_UIMR_RXRDY_FU;
0131 MCF_UART_UIMR(minor) = info->uimr;
0132 }
0133
0134
0135 if (hwflow) {
0136
0137 MCF_UART_UOP1(minor) = 1;
0138 }
0139
0140 if (minor==STATIONS_PORT)
0141 MCF_UART_UOP0(minor) = 1;
0142
0143 rtems_interrupt_enable(level);
0144
0145 }
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156 static int IntUartSetAttributes(int minor, const struct termios *t)
0157 {
0158
0159 int baud = (int) 19200;
0160 int databits = (int) MCF_UART_UMR_BC_8;
0161 int parity = (int) MCF_UART_UMR_PM_NONE;
0162 int stopbits = (int) MCF_UART_UMR_SB_STOP_BITS_1;
0163 int hwflow = (int) 0;
0164 struct IntUartInfoStruct *info = &IntUartInfo[minor];
0165
0166
0167 if (t != (const struct termios *) 0) {
0168
0169 baud = rtems_termios_baud_to_number(t->c_ospeed);
0170
0171
0172 switch (t->c_cflag & CSIZE) {
0173 case CS5:
0174 databits = (int) MCF_UART_UMR_BC_5;
0175 break;
0176 case CS6:
0177 databits = (int) MCF_UART_UMR_BC_6;
0178 break;
0179 case CS7:
0180 databits = (int) MCF_UART_UMR_BC_7;
0181 break;
0182 case CS8:
0183 databits = (int) MCF_UART_UMR_BC_8;
0184 break;
0185 }
0186
0187
0188 if (t->c_cflag & PARENB) {
0189 if (t->c_cflag & PARODD) {
0190
0191 parity = (int) MCF_UART_UMR_PM_ODD;
0192 } else {
0193
0194 parity = (int) MCF_UART_UMR_PM_EVEN;
0195 }
0196 }
0197
0198
0199 if (t->c_cflag & CSTOPB) {
0200
0201 stopbits = (int) MCF_UART_UMR_SB_STOP_BITS_2;
0202 }
0203
0204
0205 if (t->c_cflag & CRTSCTS) {
0206 hwflow = 1;
0207 }
0208 }
0209
0210
0211 if ((baud != info->baud) ||
0212 (databits != info->databits) ||
0213 (parity != info->parity) ||
0214 (stopbits != info->stopbits) || (hwflow != info->hwflow)) {
0215
0216
0217 IntUartSet(minor, baud, databits, parity, stopbits, hwflow);
0218 }
0219
0220 return (RTEMS_SUCCESSFUL);
0221
0222 }
0223
0224
0225
0226
0227
0228
0229
0230
0231 static rtems_isr IntUartInterruptHandler(rtems_vector_number v)
0232 {
0233 unsigned int chan = v - UART_INTC0_IRQ_VECTOR(0);
0234 struct IntUartInfoStruct *info = &IntUartInfo[chan];
0235
0236
0237
0238 if (MCF_UART_UISR(chan) & MCF_UART_UISR_RXRDY_FU) {
0239
0240 #if 0
0241 if (MCF_GPIO_PORTTC&MCF_GPIO_PORTTC_PORTTC0)
0242 MCF_GPIO_PORTTC &= ~MCF_GPIO_PORTTC_PORTTC0;
0243 else
0244 MCF_GPIO_PORTTC |= MCF_GPIO_PORTTC_PORTTC0;
0245 #endif
0246
0247
0248 while (MCF_UART_USR(chan) & MCF_UART_USR_RXRDY) {
0249
0250 if (MCF_UART_USR(chan) & MCF_UART_USR_ERROR) {
0251
0252 MCF_UART_UCR(chan) = MCF_UART_UCR_RESET_ERROR;
0253 }
0254
0255 info->rx_buffer[info->rx_in] = MCF_UART_URB(chan);
0256
0257
0258 info->rx_in++;
0259
0260 if (info->rx_in >= RX_BUFFER_SIZE) {
0261 info->rx_in = 0;
0262 }
0263 }
0264
0265 if (info->ttyp) {
0266
0267
0268 if (info->iomode == TERMIOS_TASK_DRIVEN) {
0269
0270 rtems_termios_rxirq_occured(info->ttyp);
0271 } else {
0272
0273 rtems_termios_enqueue_raw_characters(info->ttyp, info->rx_buffer,
0274 info->rx_in);
0275 info->rx_in = 0;
0276 }
0277 }
0278 }
0279
0280
0281 if ((info->uimr & MCF_UART_UIMR_TXRDY) &&
0282 (MCF_UART_UISR(chan) & MCF_UART_UISR_TXRDY)) {
0283
0284
0285 info->uimr &= ~MCF_UART_UIMR_TXRDY;
0286 MCF_UART_UIMR(chan) = info->uimr;
0287
0288
0289 if (info->ttyp)
0290 rtems_termios_dequeue_characters(info->ttyp, 1);
0291 }
0292 }
0293
0294
0295
0296
0297
0298
0299
0300
0301 static void IntUartInitialize(void)
0302 {
0303 unsigned int chan;
0304 struct IntUartInfoStruct *info;
0305 rtems_isr_entry old_handler;
0306 rtems_interrupt_level level=UART0_IRQ_LEVEL;
0307
0308 for (chan = 0; chan < MAX_UART_INFO; chan++) {
0309 info = &IntUartInfo[chan];
0310
0311 info->ttyp = NULL;
0312 info->rx_in = 0;
0313 info->rx_out = 0;
0314 info->baud = -1;
0315 info->databits = -1;
0316 info->parity = -1;
0317 info->stopbits = -1;
0318 info->hwflow = -1;
0319 info->iomode = TERMIOS_IRQ_DRIVEN;
0320
0321
0322 MCF_UART_UACR(chan) = 0;
0323 MCF_UART_UIMR(chan) = 0;
0324 if (info->iomode != TERMIOS_POLLED) {
0325 rtems_interrupt_catch(IntUartInterruptHandler,
0326 UART_INTC0_IRQ_VECTOR(chan), &old_handler);
0327 }
0328
0329
0330 IntUartSetAttributes(chan, NULL);
0331
0332
0333 rtems_interrupt_disable(level);
0334 switch (chan) {
0335 case 0:
0336 MCF_INTC0_ICR13 = MCF_INTC_ICR_IL(UART0_IRQ_LEVEL) |
0337 MCF_INTC_ICR_IP(UART0_IRQ_PRIORITY);
0338 MCF_INTC0_IMRL &= ~(MCF_INTC_IMRL_MASK13 | MCF_INTC_IMRL_MASKALL);
0339 break;
0340
0341 case 1:
0342 MCF_INTC0_ICR14 = MCF_INTC_ICR_IL(UART1_IRQ_LEVEL) |
0343 MCF_INTC_ICR_IP(UART1_IRQ_PRIORITY);
0344 MCF_INTC0_IMRL &= ~(MCF_INTC_IMRL_MASK14 | MCF_INTC_IMRL_MASKALL);
0345 break;
0346
0347 case 2:
0348 MCF_INTC0_ICR15 = MCF_INTC_ICR_IL(UART2_IRQ_LEVEL) |
0349 MCF_INTC_ICR_IP(UART2_IRQ_PRIORITY);
0350 MCF_INTC0_IMRL &= ~(MCF_INTC_IMRL_MASK15 | MCF_INTC_IMRL_MASKALL);
0351 break;
0352 }
0353 rtems_interrupt_enable(level);
0354
0355 }
0356
0357 }
0358
0359
0360
0361
0362
0363
0364
0365
0366
0367 static ssize_t IntUartInterruptWrite(int minor, const char *buf, size_t len)
0368 {
0369 if (len > 0) {
0370
0371 MCF_UART_UTB(minor) = *buf;
0372
0373
0374 IntUartInfo[minor].uimr |= MCF_UART_UIMR_TXRDY;
0375 MCF_UART_UIMR(minor) = IntUartInfo[minor].uimr;
0376 }
0377
0378 return (0);
0379 }
0380
0381
0382
0383
0384
0385
0386 static int IntUartInterruptOpen(int major, int minor, void *arg)
0387 {
0388 struct IntUartInfoStruct *info = &IntUartInfo[minor];
0389
0390
0391 MCF_UART_UCR(minor) = (MCF_UART_UCR_TX_ENABLED | MCF_UART_UCR_RX_ENABLED);
0392
0393
0394 if (info->iomode != TERMIOS_POLLED) {
0395
0396 info->uimr |= MCF_UART_UIMR_RXRDY_FU;
0397 MCF_UART_UIMR(minor) = info->uimr;
0398 }
0399
0400
0401 if (info->hwflow) {
0402
0403 MCF_UART_UOP1(minor) = 1;
0404 }
0405
0406 return (0);
0407 }
0408
0409
0410
0411
0412
0413
0414 static int IntUartInterruptClose(int major, int minor, void *arg)
0415 {
0416 struct IntUartInfoStruct *info = &IntUartInfo[minor];
0417
0418
0419 MCF_UART_UIMR(minor) = 0;
0420 MCF_UART_UCR(minor) = (MCF_UART_UCR_TX_DISABLED | MCF_UART_UCR_RX_DISABLED);
0421
0422
0423 info->ttyp = NULL;
0424 info->uimr = 0;
0425 info->rx_in = 0;
0426 info->rx_out = 0;
0427
0428 return (0);
0429 }
0430
0431
0432
0433
0434
0435
0436
0437
0438 static int IntUartTaskRead(int minor)
0439 {
0440 char buffer[RX_BUFFER_SIZE];
0441 int count;
0442 int rx_in;
0443 int index = 0;
0444 struct IntUartInfoStruct *info = &IntUartInfo[minor];
0445
0446
0447 rx_in = info->rx_in;
0448 if (info->rx_out <= rx_in) {
0449 count = rx_in - info->rx_out;
0450 } else {
0451 count = (RX_BUFFER_SIZE - info->rx_out) + rx_in;
0452 }
0453
0454
0455 while ((index < count) && (index < RX_BUFFER_SIZE)) {
0456
0457 buffer[index] = info->rx_buffer[info->rx_out];
0458 index++;
0459
0460
0461 info->rx_out++;
0462 if (info->rx_out >= RX_BUFFER_SIZE) {
0463 info->rx_out = 0;
0464 }
0465 }
0466
0467
0468 if (count > 0) {
0469
0470 rtems_termios_enqueue_raw_characters(info->ttyp, buffer, count);
0471 }
0472
0473 return (EOF);
0474 }
0475
0476
0477
0478
0479
0480
0481
0482 static
0483 int IntUartPollRead(int minor)
0484 {
0485 if ((MCF_UART_USR(minor) & MCF_UART_USR_RXRDY) == 0)
0486 return (-1);
0487
0488 return (MCF_UART_URB(minor));
0489 }
0490
0491
0492
0493
0494
0495
0496
0497
0498 static ssize_t IntUartPollWrite(int minor, const char *buf, size_t len)
0499 {
0500
0501 while (len--) {
0502
0503 while ((MCF_UART_USR(minor) & MCF_UART_USR_TXRDY) == 0)
0504 continue;
0505
0506 MCF_UART_UTB(minor) = *buf++;
0507 }
0508 return (0);
0509 }
0510
0511
0512
0513
0514
0515
0516
0517 rtems_device_driver console_initialize(rtems_device_major_number major,
0518 rtems_device_minor_number minor,
0519 void *arg)
0520 {
0521 rtems_status_code status;
0522
0523
0524 rtems_termios_initialize();
0525
0526
0527 IntUartInitialize();
0528
0529
0530 status = rtems_io_register_name("/dev/console", major, CONSOLE_PORT);
0531 if (status != RTEMS_SUCCESSFUL) {
0532 rtems_fatal_error_occurred(status);
0533 }
0534
0535
0536 if ((STATIONS_PORT!=CONSOLE_PORT) && (STATIONS_PORT!=BLUETOOTH_PORT)) {
0537 status = rtems_io_register_name("/dev/tty00", major,STATIONS_PORT);
0538 if (status != RTEMS_SUCCESSFUL) {
0539 rtems_fatal_error_occurred(status);
0540 }
0541 }
0542 else {
0543 status=RTEMS_TOO_MANY;
0544 rtems_fatal_error_occurred(status);
0545 }
0546
0547
0548 if ((BLUETOOTH_PORT!=CONSOLE_PORT) && (BLUETOOTH_PORT!=STATIONS_PORT)) {
0549 status = rtems_io_register_name("/dev/tty01", major, BLUETOOTH_PORT);
0550 if (status != RTEMS_SUCCESSFUL) {
0551 rtems_fatal_error_occurred(status);
0552 }
0553 }
0554 else {
0555 status=RTEMS_TOO_MANY;
0556 rtems_fatal_error_occurred(status);
0557 }
0558
0559 return (RTEMS_SUCCESSFUL);
0560 }
0561
0562
0563
0564
0565
0566
0567
0568
0569
0570 rtems_device_driver console_open(rtems_device_major_number major,
0571 rtems_device_minor_number minor, void *arg)
0572 {
0573 rtems_status_code status = RTEMS_INVALID_NUMBER;
0574 rtems_libio_open_close_args_t *args = (rtems_libio_open_close_args_t *) arg;
0575 struct IntUartInfoStruct *info;
0576
0577 static const rtems_termios_callbacks IntUartPollCallbacks = {
0578 NULL,
0579 NULL,
0580 IntUartPollRead,
0581 IntUartPollWrite,
0582 IntUartSetAttributes,
0583 NULL,
0584 NULL,
0585 TERMIOS_POLLED
0586 };
0587 static const rtems_termios_callbacks IntUartIntrCallbacks = {
0588 IntUartInterruptOpen,
0589 IntUartInterruptClose,
0590 NULL,
0591 IntUartInterruptWrite,
0592 IntUartSetAttributes,
0593 NULL,
0594 NULL,
0595 TERMIOS_IRQ_DRIVEN
0596 };
0597
0598 static const rtems_termios_callbacks IntUartTaskCallbacks = {
0599 IntUartInterruptOpen,
0600 IntUartInterruptClose,
0601 IntUartTaskRead,
0602 IntUartInterruptWrite,
0603 IntUartSetAttributes,
0604 NULL,
0605 NULL,
0606 TERMIOS_TASK_DRIVEN
0607 };
0608
0609
0610 if ((minor >= 0) && (minor < MAX_UART_INFO)) {
0611 info = &IntUartInfo[minor];
0612 switch (info->iomode) {
0613 case TERMIOS_POLLED:
0614 status = rtems_termios_open(major, minor, arg, &IntUartPollCallbacks);
0615 break;
0616 case TERMIOS_IRQ_DRIVEN:
0617 status = rtems_termios_open(major, minor, arg, &IntUartIntrCallbacks);
0618 info->ttyp = args->iop->data1;
0619 break;
0620 case TERMIOS_TASK_DRIVEN:
0621 status = rtems_termios_open(major, minor, arg, &IntUartTaskCallbacks);
0622 info->ttyp = args->iop->data1;
0623 break;
0624 }
0625 }
0626
0627 if (status == RTEMS_SUCCESSFUL) {
0628
0629
0630
0631 struct termios term;
0632
0633 if (tcgetattr(STDIN_FILENO, &term) >= 0) {
0634 term.c_cflag &= ~(CSIZE);
0635 term.c_cflag |= CS8;
0636 term.c_ispeed = B115200;
0637 term.c_ospeed = B115200;
0638 tcsetattr(STDIN_FILENO, TCSANOW, &term);
0639 }
0640 }
0641
0642 return (status);
0643 }
0644
0645
0646
0647
0648
0649
0650 rtems_device_driver console_close(rtems_device_major_number major,
0651 rtems_device_minor_number minor, void *arg)
0652 {
0653 return (rtems_termios_close(arg));
0654 }
0655
0656
0657
0658
0659
0660
0661
0662 rtems_device_driver console_read(rtems_device_major_number major,
0663 rtems_device_minor_number minor, void *arg)
0664 {
0665 return (rtems_termios_read(arg));
0666 }
0667
0668
0669
0670
0671
0672
0673 rtems_device_driver console_write(rtems_device_major_number major,
0674 rtems_device_minor_number minor, void *arg)
0675 {
0676 return (rtems_termios_write(arg));
0677 }
0678
0679
0680
0681
0682
0683
0684 rtems_device_driver console_control(rtems_device_major_number major,
0685 rtems_device_minor_number minor,
0686 void *arg)
0687 {
0688 return (rtems_termios_ioctl(arg));
0689 }