File indexing completed on 2025-05-11 08:23:45
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042 #include <termios.h>
0043
0044 #include <stdarg.h>
0045 #include <stdio.h>
0046 #include <stdlib.h>
0047
0048 #include <bsp.h>
0049 #include <rtems/libio.h>
0050 #include <rtems/termiostypes.h>
0051 #include <rtems/console.h>
0052 #include <m68340.h>
0053 #include <m340uart.h>
0054 #include <m340timer.h>
0055
0056 #define CONSOLE_VECTOR 121
0057 #define CONSOLE_IRQ_LEVEL 3
0058 #define CONSOLE_INTERRUPT_ARBITRATION 2
0059
0060 static void *ttypA;
0061
0062
0063 static void *ttypB;
0064
0065
0066 unsigned char DUIER_mirror = 0 ;
0067 unsigned char Error_Status_A = 0;
0068 unsigned char Error_Status_B = 0;
0069
0070
0071
0072
0073
0074 #define USE_INTERRUPTS_A (m340_uart_config[UART_CHANNEL_A].mode==UART_INTERRUPTS)
0075 #define USE_INTERRUPTS_B (m340_uart_config[UART_CHANNEL_B].mode==UART_INTERRUPTS)
0076 #define CHANNEL_ENABLED_A m340_uart_config[UART_CHANNEL_A].enable
0077 #define CHANNEL_ENABLED_B m340_uart_config[UART_CHANNEL_B].enable
0078
0079 #define set_DUIER(a) DUIER_mirror |= (a); DUIER = DUIER_mirror
0080 #define unset_DUIER(a) DUIER_mirror &= ~(a); DUIER = DUIER_mirror
0081
0082 #define Enable_Interrupts_Tx_A if (USE_INTERRUPTS_A) set_DUIER(m340_TxRDYA)
0083 #define Disable_Interrupts_Tx_A if (USE_INTERRUPTS_A) unset_DUIER(m340_TxRDYA)
0084
0085 #define Enable_Interrupts_Tx_B if (USE_INTERRUPTS_B) set_DUIER(m340_TxRDYB)
0086 #define Disable_Interrupts_Tx_B if (USE_INTERRUPTS_B) unset_DUIER(m340_TxRDYB)
0087
0088
0089
0090
0091
0092
0093
0094 rtems_isr
0095 InterruptHandler (rtems_vector_number v)
0096 {
0097 char ch;
0098
0099
0100
0101
0102
0103
0104 if (DUSRA & m340_RB) {
0105 Error_Status_A |= m340_RB;
0106
0107 DUCRA = m340_Reset_Error_Status;
0108 }
0109
0110
0111 if (DUSRA & m340_Rx_RDY) {
0112 do {
0113
0114 if (DUSRA & (m340_OE | m340_PE | m340_FE | m340_RB)) {
0115 Error_Status_A |= DUSRA;
0116
0117 DUCRA = m340_Reset_Error_Status;
0118
0119 while (DUSRA & m340_Rx_RDY)
0120
0121 ch = DURBA;
0122 }
0123 else {
0124
0125 ch = DURBA;
0126 rtems_termios_enqueue_raw_characters(ttypA,&ch,1);
0127 }
0128 } while (DUSRA & m340_Rx_RDY);
0129 Restart_Fifo_Full_A_Timer();
0130
0131 }
0132
0133 else
0134 Restart_Check_A_Timer();
0135
0136
0137 if (DUISR & DUIER_mirror & m340_TxRDYA) {
0138 Disable_Interrupts_Tx_A;
0139
0140 rtems_termios_dequeue_characters(ttypA,1);
0141 }
0142
0143
0144
0145
0146
0147
0148 if (DUSRB & m340_RB) {
0149 Error_Status_B |= m340_RB;
0150
0151 DUCRB = m340_Reset_Error_Status;
0152 }
0153
0154
0155 if (DUSRB & m340_Rx_RDY) {
0156 do {
0157 if (DUSRB & (m340_OE | m340_PE | m340_FE | m340_RB)) {
0158 Error_Status_B |= DUSRB;
0159
0160 DUCRB = m340_Reset_Error_Status;
0161
0162 while (DUSRB & m340_Rx_RDY)
0163
0164 ch = DURBB;
0165 }
0166 else {
0167 ch = DURBB;
0168 rtems_termios_enqueue_raw_characters(ttypB,&ch,1);
0169 }
0170
0171 } while (DUSRB & m340_Rx_RDY);
0172 Restart_Fifo_Full_B_Timer();
0173 }
0174 else
0175 Restart_Check_B_Timer();
0176
0177
0178 if (DUISR & DUIER_mirror & m340_TxRDYB) {
0179 Disable_Interrupts_Tx_B;
0180
0181 rtems_termios_dequeue_characters(ttypB,1);
0182 }
0183 }
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194 static ssize_t
0195 InterruptWrite (int minor, const char *buf, size_t len)
0196 {
0197 if (minor==UART_CHANNEL_A) {
0198 if (len>0) {
0199 DUTBA=*buf;
0200 Enable_Interrupts_Tx_A;
0201 }
0202 }
0203 else if (minor==UART_CHANNEL_B) {
0204 if (len>0) {
0205 DUTBB=*buf;
0206 Enable_Interrupts_Tx_B;
0207 }
0208 }
0209 return 0;
0210 }
0211
0212
0213
0214
0215
0216
0217
0218
0219 void dbug_out_char( int minor, int ch )
0220 {
0221 if (minor==UART_CHANNEL_A) {
0222 while (!(DUSRA & m340_Tx_RDY)) continue;
0223 DUTBA=ch;
0224 }
0225 else if (minor==UART_CHANNEL_B) {
0226 while (!(DUSRB & m340_Tx_RDY)) continue;
0227 DUTBB=ch;
0228 }
0229 }
0230
0231
0232
0233
0234
0235
0236
0237 int dbug_in_char( int minor )
0238 {
0239 if (minor==UART_CHANNEL_A) {
0240 return DURBA;
0241 }
0242 else if (minor==UART_CHANNEL_B) {
0243 return DURBB;
0244 }
0245 return 0;
0246 }
0247
0248
0249
0250
0251
0252
0253
0254
0255 int dbug_char_present( int minor )
0256 {
0257 if (minor==UART_CHANNEL_A) {
0258 return (DUSRA & m340_Rx_RDY);
0259 }
0260 else if (minor==UART_CHANNEL_B) {
0261 return (DUSRB & m340_Rx_RDY);
0262 }
0263 return 0;
0264 }
0265
0266
0267
0268
0269
0270
0271
0272 static void
0273 dbugInitialise (void)
0274 {
0275 t_baud_speed_table uart_config;
0276
0277
0278
0279
0280 DUCRA = m340_Reset_Receiver;
0281 DUCRB = m340_Reset_Receiver;
0282
0283
0284
0285
0286 DUCRA = m340_Reset_Transmitter;
0287 DUCRB = m340_Reset_Transmitter;
0288
0289
0290
0291
0292
0293
0294
0295 DUMCRH = 0x00;
0296 DUMCRL = CONSOLE_INTERRUPT_ARBITRATION;
0297
0298
0299
0300
0301 DUILR = CONSOLE_IRQ_LEVEL;
0302
0303
0304 DUIVR = CONSOLE_VECTOR;
0305
0306
0307 uart_config = Find_Right_m340_UART_Config(m340_uart_config[UART_CHANNEL_A].rx_baudrate,
0308 m340_uart_config[UART_CHANNEL_A].tx_baudrate,
0309 CHANNEL_ENABLED_A,
0310 m340_uart_config[UART_CHANNEL_B].rx_baudrate,
0311 m340_uart_config[UART_CHANNEL_B].tx_baudrate,
0312 CHANNEL_ENABLED_B);
0313
0314
0315
0316
0317 if (CHANNEL_ENABLED_A) {
0318
0319 if (USE_INTERRUPTS_A) {
0320 rtems_isr_entry old_handler;
0321
0322 (void) rtems_interrupt_catch (InterruptHandler,
0323 CONSOLE_VECTOR,
0324 &old_handler);
0325
0326
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337
0338
0339 set_DUIER(m340_RxRDYA);
0340 }
0341 else {
0342
0343
0344
0345 unset_DUIER(m340_RxRDYA&m340_TxRDYA);
0346 }
0347
0348
0349
0350
0351
0352
0353 if (uart_config.nb<1) rtems_fatal_error_occurred (-1);
0354
0355 if (uart_config.baud_speed_table[UART_CHANNEL_A].set==1)
0356 DUACR = m340_BRG_Set1;
0357 else
0358 DUACR = m340_BRG_Set2;
0359
0360
0361
0362
0363 DUOPCR = m340_OPCR_Aux;
0364
0365
0366
0367 while (DUISR & m340_XTAL_RDY) continue;
0368
0369
0370
0371
0372 DUCSRA = (uart_config.baud_speed_table[UART_CHANNEL_A].rcs << 4)
0373 | (uart_config.baud_speed_table[UART_CHANNEL_A].tcs);
0374
0375
0376
0377
0378 DUMR1A = m340_uart_config[UART_CHANNEL_A].parity_mode
0379 | m340_uart_config[UART_CHANNEL_A].bits_per_char
0380 | m340_RxRTS;
0381
0382 if (m340_uart_config[UART_CHANNEL_A].rx_mode==UART_FIFO_FULL) DUMR1A |= m340_R_F | m340_ERR;
0383
0384
0385
0386
0387 DUMR2A |= m340_normal;
0388
0389
0390
0391
0392 DUCRA = m340_Transmitter_Enable | m340_Receiver_Enable;
0393 }
0394
0395
0396
0397
0398 if (CHANNEL_ENABLED_B) {
0399
0400
0401 if ((USE_INTERRUPTS_B && !(CHANNEL_ENABLED_A))
0402 || (USE_INTERRUPTS_B && CHANNEL_ENABLED_A && !USE_INTERRUPTS_A)) {
0403 rtems_isr_entry old_handler;
0404
0405 (void) rtems_interrupt_catch (InterruptHandler,
0406 CONSOLE_VECTOR,
0407 &old_handler);
0408
0409
0410
0411
0412
0413
0414
0415
0416
0417
0418
0419
0420
0421
0422 set_DUIER(m340_RxRDYB);
0423 }
0424 else {
0425
0426
0427
0428 unset_DUIER(m340_RxRDYB&m340_TxRDYB);
0429 }
0430
0431
0432
0433
0434
0435
0436
0437 if (uart_config.nb<2) rtems_fatal_error_occurred (-1);
0438
0439
0440 if (!CHANNEL_ENABLED_A) {
0441 if (uart_config.baud_speed_table[UART_CHANNEL_B].set==1)
0442 DUACR = m340_BRG_Set1;
0443 else
0444 DUACR = m340_BRG_Set2;
0445 }
0446
0447
0448
0449
0450 if (!CHANNEL_ENABLED_A) DUOPCR = m340_OPCR_Aux;
0451
0452
0453
0454 while (DUISR & m340_XTAL_RDY) continue;
0455
0456
0457
0458
0459 DUCSRB = (uart_config.baud_speed_table[UART_CHANNEL_B].rcs << 4)
0460 | (uart_config.baud_speed_table[UART_CHANNEL_B].tcs);
0461
0462
0463
0464
0465 DUMR1B = m340_uart_config[UART_CHANNEL_B].parity_mode
0466 | m340_uart_config[UART_CHANNEL_B].bits_per_char
0467 | m340_RxRTS;
0468
0469 if (m340_uart_config[UART_CHANNEL_B].rx_mode==UART_FIFO_FULL) DUMR1B |= m340_R_F | m340_ERR;
0470
0471
0472
0473
0474 DUMR2B |= m340_normal;
0475
0476
0477
0478
0479 DUCRB = m340_Transmitter_Enable | m340_Receiver_Enable;
0480 }
0481 }
0482
0483
0484
0485
0486
0487
0488
0489
0490
0491 static int
0492 SetAttributes (int minor, const struct termios *t)
0493 {
0494 rtems_interrupt_level level;
0495 float ispeed, ospeed;
0496
0497
0498 ispeed = rtems_termios_baud_to_number(t->c_ispeed);
0499 ospeed = rtems_termios_baud_to_number(t->c_ospeed);
0500
0501 if (ispeed || ospeed) {
0502
0503 m340_uart_config[UART_CHANNEL_A].rx_baudrate = ((minor==UART_CHANNEL_A)&&(ispeed!=0)) ? ispeed : m340_uart_config[UART_CHANNEL_A].rx_baudrate;
0504 m340_uart_config[UART_CHANNEL_A].tx_baudrate = ((minor==UART_CHANNEL_A)&&(ospeed!=0)) ? ospeed : m340_uart_config[UART_CHANNEL_A].tx_baudrate;
0505 m340_uart_config[UART_CHANNEL_B].rx_baudrate = ((minor==UART_CHANNEL_B)&&(ispeed!=0)) ? ispeed : m340_uart_config[UART_CHANNEL_B].rx_baudrate;
0506 m340_uart_config[UART_CHANNEL_B].tx_baudrate = ((minor==UART_CHANNEL_B)&&(ospeed!=0)) ? ospeed : m340_uart_config[UART_CHANNEL_B].tx_baudrate;
0507 }
0508
0509
0510 if (t->c_cflag & PARENB) {
0511 if (t->c_cflag & PARODD) m340_uart_config[minor].parity_mode = m340_Odd_Parity;
0512 else m340_uart_config[minor].parity_mode = m340_Even_Parity;
0513 }
0514
0515
0516 if (t->c_cflag & CSIZE) {
0517 switch (t->c_cflag & CSIZE) {
0518 default: break;
0519 case CS5: m340_uart_config[minor].bits_per_char = m340_5bpc; break;
0520 case CS6: m340_uart_config[minor].bits_per_char = m340_6bpc; break;
0521 case CS7: m340_uart_config[minor].bits_per_char = m340_7bpc; break;
0522 case CS8: m340_uart_config[minor].bits_per_char = m340_8bpc; break;
0523 }
0524 }
0525
0526
0527 if (t->c_cflag & (CSIZE | PARENB)) {
0528 rtems_interrupt_disable(level);
0529
0530 dbugInitialise();
0531 rtems_interrupt_enable (level);
0532 }
0533
0534 return 0;
0535 }
0536
0537
0538
0539
0540
0541
0542
0543
0544
0545
0546 rtems_device_driver console_initialize(
0547 rtems_device_major_number major,
0548 rtems_device_minor_number minor,
0549 void *arg
0550 )
0551 {
0552 rtems_status_code status;
0553 int i;
0554
0555
0556
0557
0558 rtems_termios_initialize ();
0559
0560
0561
0562
0563 Init_UART_Table();
0564 dbugInitialise ();
0565 Fifo_Full_benchmark_timer_initialize();
0566
0567
0568
0569
0570 for (i=0; i<UART_NUMBER_OF_CHANNELS; i++) {
0571 if (m340_uart_config[i].enable) {
0572 status = rtems_io_register_name (m340_uart_config[i].name, major, i);
0573 if (status != RTEMS_SUCCESSFUL)
0574 rtems_fatal_error_occurred (status);
0575 }
0576 }
0577
0578 return RTEMS_SUCCESSFUL;
0579 }
0580
0581
0582
0583
0584
0585
0586
0587 rtems_device_driver console_open(
0588 rtems_device_major_number major,
0589 rtems_device_minor_number minor,
0590 void * arg
0591 )
0592 {
0593 rtems_status_code sc = 0;
0594
0595 static const rtems_termios_callbacks intrCallbacks = {
0596 NULL,
0597 NULL,
0598 NULL,
0599 InterruptWrite,
0600 SetAttributes,
0601 NULL,
0602 NULL,
0603 TERMIOS_IRQ_DRIVEN
0604 };
0605
0606 static const rtems_termios_callbacks pollCallbacks = {
0607 NULL,
0608 NULL,
0609 dbugRead,
0610 dbugWrite,
0611 SetAttributes,
0612 NULL,
0613 NULL,
0614 TERMIOS_POLLED
0615 };
0616
0617 if (minor==UART_CHANNEL_A) {
0618 if (USE_INTERRUPTS_A) {
0619 rtems_libio_open_close_args_t *args = arg;
0620
0621 sc |= rtems_termios_open (major, minor, arg, &intrCallbacks);
0622 ttypA = args->iop->data1;
0623 }
0624 else {
0625 sc |= rtems_termios_open (major, minor, arg, &pollCallbacks);
0626 }
0627 }
0628
0629 else if (minor==UART_CHANNEL_B) {
0630 if (USE_INTERRUPTS_B) {
0631 rtems_libio_open_close_args_t *args = arg;
0632
0633 sc |= rtems_termios_open (major, minor, arg, &intrCallbacks);
0634 ttypB = args->iop->data1;
0635 }
0636 else {
0637 sc |= rtems_termios_open (major, minor, arg, &pollCallbacks);
0638 }
0639 }
0640
0641 else return RTEMS_INVALID_NUMBER;
0642
0643 return sc;
0644 }
0645
0646
0647
0648
0649
0650
0651
0652 rtems_device_driver console_close(
0653 rtems_device_major_number major,
0654 rtems_device_minor_number minor,
0655 void * arg
0656 )
0657 {
0658 return rtems_termios_close (arg);
0659 }
0660
0661
0662
0663
0664
0665
0666
0667 rtems_device_driver console_read(
0668 rtems_device_major_number major,
0669 rtems_device_minor_number minor,
0670 void * arg
0671 )
0672 {
0673 return rtems_termios_read (arg);
0674 }
0675
0676
0677
0678
0679
0680
0681
0682 rtems_device_driver console_write(
0683 rtems_device_major_number major,
0684 rtems_device_minor_number minor,
0685 void * arg
0686 )
0687 {
0688 return rtems_termios_write (arg);
0689 }
0690
0691
0692
0693
0694
0695
0696
0697 rtems_device_driver console_control(
0698 rtems_device_major_number major,
0699 rtems_device_minor_number minor,
0700 void * arg
0701 )
0702 {
0703 rtems_libio_ioctl_args_t *args = arg;
0704
0705 if (args->command == TIOCSETA)
0706 SetAttributes (minor, (struct termios *)args->buffer);
0707
0708 return rtems_termios_ioctl (arg);
0709 }