File indexing completed on 2025-05-11 08:24:08
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include <unistd.h>
0016 #include <termios.h>
0017 #include <stdlib.h>
0018
0019 #include <rtems.h>
0020 #include <rtems/libio.h>
0021 #include <rtems/console.h>
0022 #include <rtems/termiostypes.h>
0023
0024 #include <libchip/serial.h>
0025 #include <libchip/sersupp.h>
0026
0027 #include <bsp.h>
0028 #include <bspopts.h>
0029
0030 #define CONSOLE_BUF_SIZE (16)
0031
0032 #define CONSOLE_UART_A_TRAP ERC32_TRAP_TYPE(ERC32_INTERRUPT_UART_A_RX_TX)
0033 #define CONSOLE_UART_B_TRAP ERC32_TRAP_TYPE(ERC32_INTERRUPT_UART_B_RX_TX)
0034
0035 static uint8_t erc32_console_get_register(uintptr_t addr, uint8_t i)
0036 {
0037 volatile uint32_t *reg = (volatile uint32_t *)addr;
0038 return (uint8_t) reg [i];
0039 }
0040
0041 static void erc32_console_set_register(uintptr_t addr, uint8_t i, uint8_t val)
0042 {
0043 volatile uint32_t *reg = (volatile uint32_t *)addr;
0044 reg [i] = val;
0045 }
0046
0047 static int erc32_console_first_open(int major, int minor, void *arg);
0048
0049 #if (CONSOLE_USE_INTERRUPTS)
0050 static ssize_t erc32_console_write_support_int(
0051 int minor, const char *buf, size_t len);
0052 #else
0053 int console_inbyte_nonblocking( int port );
0054 static ssize_t erc32_console_write_support_polled(
0055 int minor, const char *buf, size_t len);
0056 #endif
0057 static void erc32_console_initialize(int minor);
0058
0059 #if (CONSOLE_USE_INTERRUPTS)
0060 const console_fns erc32_fns = {
0061 libchip_serial_default_probe,
0062 erc32_console_first_open,
0063 NULL,
0064 NULL,
0065 erc32_console_write_support_int,
0066 erc32_console_initialize,
0067 NULL,
0068 NULL,
0069 true
0070 };
0071 #else
0072 const console_fns erc32_fns = {
0073 libchip_serial_default_probe,
0074 erc32_console_first_open,
0075 NULL,
0076 console_inbyte_nonblocking,
0077 erc32_console_write_support_polled,
0078 erc32_console_initialize,
0079 NULL,
0080 NULL,
0081 false
0082 };
0083 #endif
0084
0085 console_tbl Console_Configuration_Ports [] = {
0086 {
0087 .sDeviceName = "/dev/console_a",
0088 .deviceType = SERIAL_CUSTOM,
0089 .pDeviceFns = &erc32_fns,
0090 .deviceProbe = NULL,
0091 .pDeviceFlow = NULL,
0092 .ulMargin = 16,
0093 .ulHysteresis = 8,
0094 .pDeviceParams = (void *) -1,
0095 .ulCtrlPort1 = 0,
0096 .ulCtrlPort2 = 0,
0097 .ulDataPort = 0,
0098 .getRegister = erc32_console_get_register,
0099 .setRegister = erc32_console_set_register,
0100 .getData = NULL,
0101 .setData = NULL,
0102 .ulClock = 16,
0103 .ulIntVector = ERC32_INTERRUPT_UART_A_RX_TX
0104 },
0105 {
0106 .sDeviceName = "/dev/console_b",
0107 .deviceType = SERIAL_CUSTOM,
0108 .pDeviceFns = &erc32_fns,
0109 .deviceProbe = NULL,
0110 .pDeviceFlow = NULL,
0111 .ulMargin = 16,
0112 .ulHysteresis = 8,
0113 .pDeviceParams = (void *) -1,
0114 .ulCtrlPort1 = 0,
0115 .ulCtrlPort2 = 0,
0116 .ulDataPort = 0,
0117 .getRegister = erc32_console_get_register,
0118 .setRegister = erc32_console_set_register,
0119 .getData = NULL,
0120 .setData = NULL,
0121 .ulClock = 16,
0122 .ulIntVector = ERC32_INTERRUPT_UART_B_RX_TX
0123 },
0124 };
0125
0126
0127 #define ERC32_UART_COUNT (2)
0128
0129 unsigned long Console_Configuration_Count = ERC32_UART_COUNT;
0130
0131 static int erc32_console_first_open(int major, int minor, void *arg)
0132 {
0133
0134 if (minor < 0 || minor > 1) {
0135 return -1;
0136 }
0137
0138 rtems_libio_open_close_args_t *oca = arg;
0139 struct rtems_termios_tty *tty = oca->iop->data1;
0140 console_tbl *ct = Console_Port_Tbl [minor];
0141 console_data *cd = &Console_Port_Data [minor];
0142
0143 cd->termios_data = tty;
0144 rtems_termios_set_initial_baud(tty, (int32_t)ct->pDeviceParams);
0145
0146 return 0;
0147 }
0148
0149 #if (CONSOLE_USE_INTERRUPTS)
0150 static ssize_t erc32_console_write_support_int(
0151 int minor, const char *buf, size_t len)
0152 {
0153 if (len > 0) {
0154 console_data *cd = &Console_Port_Data[minor];
0155 int k = 0;
0156
0157 if (minor == 0) {
0158 for (k = 0;
0159 k < len && (ERC32_MEC.UART_Status & ERC32_MEC_UART_STATUS_THEA);
0160 k ++) {
0161 ERC32_MEC.UART_Channel_A = (unsigned char)buf[k];
0162 }
0163 ERC32_Force_interrupt(ERC32_INTERRUPT_UART_A_RX_TX);
0164 } else {
0165 for (k = 0;
0166 k < len && (ERC32_MEC.UART_Status & ERC32_MEC_UART_STATUS_THEB);
0167 k ++) {
0168 ERC32_MEC.UART_Channel_B = (unsigned char)buf[k];
0169 }
0170 ERC32_Force_interrupt(ERC32_INTERRUPT_UART_B_RX_TX);
0171 }
0172
0173 cd->pDeviceContext = (void *)k;
0174 cd->bActive = true;
0175 }
0176
0177 return 0;
0178 }
0179
0180 static void erc32_console_isr_error(
0181 rtems_vector_number vector
0182 )
0183 {
0184 int UStat;
0185
0186 UStat = ERC32_MEC.UART_Status;
0187
0188 if (UStat & ERC32_MEC_UART_STATUS_ERRA) {
0189 ERC32_MEC.UART_Status = ERC32_MEC_UART_STATUS_CLRA;
0190 ERC32_MEC.Control = ERC32_MEC.Control;
0191 }
0192
0193 if (UStat & ERC32_MEC_UART_STATUS_ERRB) {
0194 ERC32_MEC.UART_Status = ERC32_MEC_UART_STATUS_CLRB;
0195 ERC32_MEC.Control = ERC32_MEC.Control;
0196 }
0197
0198 ERC32_Clear_interrupt( ERC32_INTERRUPT_UART_ERROR );
0199 }
0200
0201 static void erc32_console_isr_a(
0202 rtems_vector_number vector
0203 )
0204 {
0205 console_data *cd = &Console_Port_Data[0];
0206
0207
0208 if (ERC32_MEC.UART_Status & ERC32_MEC_UART_STATUS_ERRA) {
0209 ERC32_MEC.UART_Status = ERC32_MEC_UART_STATUS_CLRA;
0210 ERC32_MEC.Control = ERC32_MEC.Control;
0211 }
0212
0213 do {
0214 int chars_to_dequeue = (int)cd->pDeviceContext;
0215 int rv = 0;
0216 int i = 0;
0217 char buf[CONSOLE_BUF_SIZE];
0218
0219
0220 while (i < CONSOLE_BUF_SIZE) {
0221 if (!(ERC32_MEC.UART_Status & ERC32_MEC_UART_STATUS_DRA))
0222 break;
0223 buf[i] = ERC32_MEC.UART_Channel_A;
0224 ++i;
0225 }
0226 if ( i )
0227 rtems_termios_enqueue_raw_characters(cd->termios_data, buf, i);
0228
0229
0230 if (ERC32_MEC.UART_Status & ERC32_MEC_UART_STATUS_THEA) {
0231 rv = rtems_termios_dequeue_characters(
0232 cd->termios_data, chars_to_dequeue);
0233 if ( !rv ) {
0234 cd->pDeviceContext = 0;
0235 cd->bActive = false;
0236 }
0237 ERC32_Clear_interrupt (ERC32_INTERRUPT_UART_A_RX_TX);
0238 }
0239 } while (ERC32_Is_interrupt_pending (ERC32_INTERRUPT_UART_A_RX_TX));
0240 }
0241
0242 static void erc32_console_isr_b(
0243 rtems_vector_number vector
0244 )
0245 {
0246 console_data *cd = &Console_Port_Data[1];
0247
0248
0249 if (ERC32_MEC.UART_Status & ERC32_MEC_UART_STATUS_ERRB) {
0250 ERC32_MEC.UART_Status = ERC32_MEC_UART_STATUS_CLRB;
0251 ERC32_MEC.Control = ERC32_MEC.Control;
0252 }
0253
0254 do {
0255 int chars_to_dequeue = (int)cd->pDeviceContext;
0256 int rv = 0;
0257 int i = 0;
0258 char buf[CONSOLE_BUF_SIZE];
0259
0260
0261 while (i < CONSOLE_BUF_SIZE) {
0262 if (!(ERC32_MEC.UART_Status & ERC32_MEC_UART_STATUS_DRB))
0263 break;
0264 buf[i] = ERC32_MEC.UART_Channel_B;
0265 ++i;
0266 }
0267 if ( i )
0268 rtems_termios_enqueue_raw_characters(cd->termios_data, buf, i);
0269
0270
0271 if (ERC32_MEC.UART_Status & ERC32_MEC_UART_STATUS_THEB) {
0272 rv = rtems_termios_dequeue_characters(
0273 cd->termios_data, chars_to_dequeue);
0274 if ( !rv ) {
0275 cd->pDeviceContext = 0;
0276 cd->bActive = false;
0277 }
0278 ERC32_Clear_interrupt (ERC32_INTERRUPT_UART_B_RX_TX);
0279 }
0280 } while (ERC32_Is_interrupt_pending (ERC32_INTERRUPT_UART_B_RX_TX));
0281 }
0282 #else
0283
0284 extern void console_outbyte_polled( int port, unsigned char ch );
0285
0286 static ssize_t erc32_console_write_support_polled(
0287 int minor,
0288 const char *buf,
0289 size_t len
0290 )
0291 {
0292 int nwrite = 0;
0293
0294 while (nwrite < len) {
0295 console_outbyte_polled( minor, *buf++ );
0296 nwrite++;
0297 }
0298 return nwrite;
0299 }
0300
0301 #endif
0302
0303
0304
0305
0306
0307
0308
0309 static void erc32_console_initialize(
0310 int minor
0311 )
0312 {
0313 console_data *cd = &Console_Port_Data [minor];
0314
0315 cd->bActive = false;
0316 cd->pDeviceContext = 0;
0317
0318
0319
0320
0321
0322
0323 rtems_termios_initialize();
0324
0325
0326
0327
0328 #if (CONSOLE_USE_INTERRUPTS)
0329 set_vector(erc32_console_isr_a, CONSOLE_UART_A_TRAP, 1);
0330 set_vector(erc32_console_isr_b, CONSOLE_UART_B_TRAP, 1);
0331 set_vector(erc32_console_isr_error, CONSOLE_UART_ERROR_TRAP, 1);
0332 #endif
0333
0334
0335 ERC32_MEC.UART_Status = ERC32_MEC_UART_STATUS_CLRA;
0336 ERC32_MEC.UART_Status = ERC32_MEC_UART_STATUS_CLRB;
0337 }