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 #include <termios.h>
0022 #include <bsp.h>
0023 #include <rtems/libio.h>
0024 #include <rtems/console.h>
0025 #include <rtems/termiostypes.h>
0026 #include <rtems/m68k/m68360.h>
0027
0028
0029
0030
0031 int m360_clock_rate = 25000000;
0032
0033
0034
0035
0036
0037 int console_baud_rate = 9600;
0038
0039
0040
0041 #define RXBUFSIZE 16
0042
0043
0044
0045
0046 static int m360_smc1_interrupt = 1;
0047 static void *smc1ttyp;
0048
0049
0050
0051
0052 static volatile char rxBuf[RXBUFSIZE];
0053 static volatile m360BufferDescriptor_t *smcRxBd, *smcTxBd;
0054
0055
0056
0057
0058
0059
0060
0061
0062 static int
0063 smc1BRGC (int baud)
0064 {
0065 int divisor;
0066 int div16 = 0;
0067
0068 divisor = ((m360_clock_rate / 16) + (baud / 2)) / baud;
0069 if (divisor > 4096) {
0070 div16 = 1;
0071 divisor = (divisor + 8) / 16;
0072 }
0073 return M360_BRG_EN | M360_BRG_EXTC_BRGCLK | ((divisor - 1) << 1) | div16;
0074 }
0075
0076
0077
0078
0079 static int
0080 smc1SetAttributes (int minor, const struct termios *t)
0081 {
0082 int baud;
0083
0084 baud = rtems_termios_baud_to_number(t->c_ospeed);
0085 if (baud > 0)
0086 m360.brgc1 = smc1BRGC (baud);
0087 return 0;
0088 }
0089
0090
0091
0092
0093 static rtems_isr
0094 smc1InterruptHandler (rtems_vector_number v)
0095 {
0096
0097
0098
0099 if (m360.smc1.smce & 0x1) {
0100 m360.smc1.smce = 0x1;
0101 while ((smcRxBd->status & M360_BD_EMPTY) == 0) {
0102 rtems_termios_enqueue_raw_characters (smc1ttyp,
0103 (char *)smcRxBd->buffer,
0104 smcRxBd->length);
0105 smcRxBd->status = M360_BD_EMPTY | M360_BD_WRAP | M360_BD_INTERRUPT;
0106 }
0107 }
0108
0109
0110
0111
0112 if (m360.smc1.smce & 0x2) {
0113 m360.smc1.smce = 0x2;
0114 if ((smcTxBd->status & M360_BD_READY) == 0)
0115 rtems_termios_dequeue_characters (smc1ttyp, smcTxBd->length);
0116 }
0117 m360.cisr = 1UL << 4;
0118 }
0119
0120 static int
0121 smc1Initialize (int major, int minor, void *arg)
0122 {
0123
0124
0125
0126 smcRxBd = M360AllocateBufferDescriptors (1);
0127 smcTxBd = M360AllocateBufferDescriptors (1);
0128
0129
0130
0131
0132 m360.pbpar |= 0xC0;
0133 m360.pbdir &= ~0xC0;
0134 m360.pbodr &= ~0xC0;
0135
0136
0137
0138
0139 m360.brgc1 = M360_BRG_RST;
0140 m360.brgc1 = smc1BRGC (console_baud_rate);
0141
0142
0143
0144
0145 m360.simode |= M360_SI_SMC1_BRG1;
0146
0147
0148
0149
0150 m360.smc1p.rbase = (char *)smcRxBd - (char *)&m360;
0151 m360.smc1p.tbase = (char *)smcTxBd - (char *)&m360;
0152 m360.smc1p.rfcr = M360_RFCR_MOT | M360_RFCR_DMA_SPACE;
0153 m360.smc1p.tfcr = M360_TFCR_MOT | M360_TFCR_DMA_SPACE;
0154 if (m360_smc1_interrupt)
0155 m360.smc1p.mrblr = RXBUFSIZE;
0156 else
0157 m360.smc1p.mrblr = 1;
0158
0159
0160
0161
0162 m360.smc1p.un.uart.max_idl = 10;
0163 m360.smc1p.un.uart.brklen = 0;
0164 m360.smc1p.un.uart.brkec = 0;
0165 m360.smc1p.un.uart.brkcr = 0;
0166
0167
0168
0169
0170 smcRxBd->status = M360_BD_EMPTY | M360_BD_WRAP | M360_BD_INTERRUPT;
0171 smcRxBd->length = 0;
0172 smcRxBd->buffer = rxBuf;
0173
0174
0175
0176
0177 smcTxBd->status = M360_BD_WRAP;
0178
0179
0180
0181
0182 m360.smc1.smce = ~0;
0183 m360.smc1.smcm = 0;
0184 m360.smc1.smcmr = M360_SMCMR_CLEN(9) | M360_SMCMR_SM_UART;
0185
0186
0187
0188
0189 M360ExecuteRISC (M360_CR_OP_INIT_RX_TX | M360_CR_CHAN_SMC1);
0190
0191
0192
0193
0194 m360.smc1.smcmr |= M360_SMCMR_TEN | M360_SMCMR_REN;
0195
0196 if (m360_smc1_interrupt) {
0197 rtems_isr_entry old_handler;
0198
0199 (void) rtems_interrupt_catch (smc1InterruptHandler,
0200 (m360.cicr & 0xE0) | 0x04,
0201 &old_handler);
0202 m360.smc1.smcm = 3;
0203 m360.cimr |= 1UL << 4;
0204 }
0205
0206 return 0;
0207 }
0208
0209 static int
0210 smc1PollRead (int minor)
0211 {
0212 unsigned char c;
0213
0214 if (smcRxBd->status & M360_BD_EMPTY)
0215 return -1;
0216 c = rxBuf[0];
0217 smcRxBd->status = M360_BD_EMPTY | M360_BD_WRAP;
0218 return c;
0219 }
0220
0221
0222
0223
0224
0225
0226
0227
0228 static ssize_t
0229 smc1InterruptWrite (int minor, const char *buf, size_t len)
0230 {
0231 if (len > 0) {
0232 smcTxBd->buffer = (char *)buf;
0233 smcTxBd->length = len;
0234 smcTxBd->status = M360_BD_READY | M360_BD_WRAP | M360_BD_INTERRUPT;
0235 }
0236
0237 return 0;
0238 }
0239
0240 static ssize_t
0241 smc1PollWrite (int minor, const char *buf, size_t len)
0242 {
0243 size_t retval = len;
0244 while (len--) {
0245 static char txBuf;
0246 while (smcTxBd->status & M360_BD_READY)
0247 continue;
0248 txBuf = *buf++;
0249 smcTxBd->buffer = &txBuf;
0250 smcTxBd->length = 1;
0251 smcTxBd->status = M360_BD_READY | M360_BD_WRAP;
0252 }
0253 return retval;
0254 }
0255
0256
0257
0258
0259
0260
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271 rtems_device_driver console_initialize(
0272 rtems_device_major_number major,
0273 rtems_device_minor_number minor,
0274 void *arg
0275 )
0276 {
0277 rtems_status_code status;
0278
0279
0280
0281
0282 rtems_termios_initialize ();
0283
0284
0285
0286
0287 status = rtems_io_register_name ("/dev/console", major, 0);
0288 if (status != RTEMS_SUCCESSFUL)
0289 rtems_fatal_error_occurred (status);
0290 return RTEMS_SUCCESSFUL;
0291 }
0292
0293
0294
0295
0296 rtems_device_driver console_open(
0297 rtems_device_major_number major,
0298 rtems_device_minor_number minor,
0299 void * arg
0300 )
0301 {
0302 rtems_status_code sc;
0303 static const rtems_termios_callbacks intrCallbacks = {
0304 smc1Initialize,
0305 NULL,
0306 NULL,
0307 smc1InterruptWrite,
0308 smc1SetAttributes,
0309 NULL,
0310 NULL,
0311 TERMIOS_IRQ_DRIVEN
0312 };
0313 static const rtems_termios_callbacks pollCallbacks = {
0314 smc1Initialize,
0315 NULL,
0316 smc1PollRead,
0317 smc1PollWrite,
0318 smc1SetAttributes,
0319 NULL,
0320 NULL,
0321 TERMIOS_POLLED
0322 };
0323
0324
0325
0326
0327 if (m360_smc1_interrupt) {
0328 rtems_libio_open_close_args_t *args = arg;
0329
0330 sc = rtems_termios_open (major, minor, arg, &intrCallbacks);
0331 smc1ttyp = args->iop->data1;
0332 }
0333 else {
0334 sc = rtems_termios_open (major, minor, arg, &pollCallbacks);
0335 }
0336 return sc;
0337 }
0338
0339
0340
0341
0342 rtems_device_driver console_close(
0343 rtems_device_major_number major,
0344 rtems_device_minor_number minor,
0345 void * arg
0346 )
0347 {
0348 return rtems_termios_close (arg);
0349 }
0350
0351
0352
0353
0354 rtems_device_driver console_read(
0355 rtems_device_major_number major,
0356 rtems_device_minor_number minor,
0357 void * arg
0358 )
0359 {
0360 return rtems_termios_read (arg);
0361 }
0362
0363
0364
0365
0366 rtems_device_driver console_write(
0367 rtems_device_major_number major,
0368 rtems_device_minor_number minor,
0369 void * arg
0370 )
0371 {
0372 return rtems_termios_write (arg);
0373 }
0374
0375
0376
0377
0378 rtems_device_driver console_control(
0379 rtems_device_major_number major,
0380 rtems_device_minor_number minor,
0381 void * arg
0382 )
0383 {
0384 return rtems_termios_ioctl (arg);
0385 }