File indexing completed on 2025-05-11 08:24:01
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 #include <bsp.h>
0039 #include <stdlib.h>
0040
0041 #include <libchip/serial.h>
0042 #include <libchip/sersupp.h>
0043
0044 #include <rtems/libio.h>
0045 #include <rtems/iosupp.h>
0046
0047 #include <rtems/score/sh_io.h>
0048 #include <rtems/score/ispsh7045.h>
0049 #include <rtems/score/iosh7045.h>
0050
0051 #include <sh/sh7_sci.h>
0052 #include <sh/sh7_pfc.h>
0053 #include <sh/sci_termios.h>
0054
0055
0056
0057
0058
0059 #define SH_SCI_REG_DATA(_data, _minor, _register) \
0060 (write8(_data, Console_Port_Tbl[_minor]->ulCtrlPort1 + (_register)))
0061
0062 #define SH_SCI_REG_FLAG(_flag, _minor, _register) \
0063 (write8(read8(Console_Port_Tbl[_minor]->ulCtrlPort1 + (_register)) | (_flag), \
0064 Console_Port_Tbl[_minor]->ulCtrlPort1 + (_register)))
0065
0066 #define SH_SCI_REG_MASK(_flag, _minor, _register) \
0067 (write8(read8(Console_Port_Tbl[_minor]->ulCtrlPort1 + (_register)) & ~(_flag),\
0068 Console_Port_Tbl[_minor]->ulCtrlPort1 + (_register)))
0069
0070
0071
0072
0073
0074 #define SCI_MINOR_DEVICES 2
0075
0076
0077
0078
0079
0080 extern int _sci_get_brparms(
0081 speed_t spd,
0082 unsigned char *smr,
0083 unsigned char *brr
0084 );
0085
0086
0087
0088
0089 int sh_sci_set_attributes(
0090 int minor,
0091 const struct termios *t
0092 )
0093 {
0094 uint8_t smr;
0095 uint8_t brr;
0096 int a;
0097
0098 tcflag_t c_cflag = t->c_cflag;
0099 speed_t spd = t->c_ospeed;
0100
0101 if ( spd ) {
0102 if ( _sci_get_brparms( spd, &smr, &brr ) != 0 )
0103 return -1 ;
0104 }
0105
0106 if ( c_cflag & CSIZE ) {
0107 if ( c_cflag & CS8 )
0108 smr &= ~SCI_SEVEN_BIT_DATA;
0109 else if ( c_cflag & CS7 )
0110 smr |= SCI_SEVEN_BIT_DATA;
0111 else
0112 return -1 ;
0113 }
0114
0115 if ( c_cflag & CSTOPB )
0116 smr |= SCI_STOP_BITS_2;
0117 else
0118 smr &= ~SCI_STOP_BITS_2;
0119
0120 if ( c_cflag & PARENB )
0121 smr |= SCI_PARITY_ON ;
0122 else
0123 smr &= ~SCI_PARITY_ON ;
0124
0125 if ( c_cflag & PARODD )
0126 smr |= SCI_ODD_PARITY ;
0127 else
0128 smr &= ~SCI_ODD_PARITY;
0129
0130 SH_SCI_REG_MASK((SCI_RE | SCI_TE), minor, SCI_SCR);
0131
0132 SH_SCI_REG_DATA(smr, minor, SCI_SMR);
0133 SH_SCI_REG_DATA(brr, minor, SCI_BRR);
0134
0135 for (a=0; a < 10000L; a++) {
0136 __asm__ volatile ("nop");
0137 }
0138
0139 SH_SCI_REG_FLAG((SCI_RE | SCI_TE), minor, SCI_SCR);
0140
0141 return 0;
0142 }
0143
0144
0145
0146
0147
0148
0149 static rtems_isr sh_sci_rx_isr(rtems_vector_number vector)
0150 {
0151 int minor;
0152
0153 for (minor = 0; minor < Console_Port_Count; minor++) {
0154 if (Console_Port_Tbl[minor]->ulIntVector == vector) {
0155 char temp8;
0156
0157
0158
0159
0160 temp8 = read8(Console_Port_Tbl[minor]->ulCtrlPort1 + SCI_RDR);
0161
0162 rtems_termios_enqueue_raw_characters(
0163 Console_Port_Data[minor].termios_data, &temp8, 1);
0164
0165 SH_SCI_REG_MASK(SCI_RDRF, minor, SCI_SSR);
0166 break;
0167 }
0168 }
0169 }
0170
0171
0172
0173
0174
0175
0176 static rtems_isr sh_sci_tx_isr(rtems_vector_number vector)
0177 {
0178 int minor;
0179
0180 for (minor = 0; minor < Console_Port_Count; minor++) {
0181 if (Console_Port_Tbl[minor]->ulDataPort == vector) {
0182
0183
0184
0185
0186
0187
0188
0189 SH_SCI_REG_MASK(SCI_TIE, minor, SCI_SCR);
0190
0191 if (rtems_termios_dequeue_characters(
0192 Console_Port_Data[minor].termios_data, 1)) {
0193
0194
0195
0196 SH_SCI_REG_FLAG(SCI_TIE, minor, SCI_SCR);
0197 }
0198 break;
0199 }
0200 }
0201 }
0202
0203
0204
0205
0206
0207 void sh_sci_init(int minor)
0208 {
0209 uint16_t temp16;
0210
0211
0212
0213
0214 if ((minor == 0)) {
0215 temp16 = read16(PFC_PACRL2);
0216 temp16 &= ~(PA2MD1 | PA2MD0);
0217 temp16 |= (PA_TXD0 | PA_RXD0);
0218 write16(temp16, PFC_PACRL2);
0219
0220 } else if (minor == 1) {
0221 temp16 = read16(PFC_PACRL2);
0222 temp16 &= ~(PA5MD1 | PA5MD0);
0223 temp16 |= (PA_TXD1 | PA_RXD1);
0224 write16(temp16, PFC_PACRL2);
0225 }
0226
0227
0228
0229
0230 }
0231
0232
0233
0234
0235
0236
0237
0238 void sh_sci_initialize_interrupts(int minor)
0239 {
0240 rtems_isr_entry old_isr;
0241 rtems_status_code status;
0242
0243 sh_sci_init(minor);
0244
0245
0246
0247 status = sh_set_irq_priority( Console_Port_Tbl[minor]->ulIntVector, 0);
0248
0249 if (status != RTEMS_SUCCESSFUL)
0250 rtems_fatal_error_occurred(status);
0251
0252 SH_SCI_REG_MASK(SCI_RIE, minor, SCI_SCR);
0253
0254
0255
0256
0257 status = rtems_interrupt_catch(
0258 sh_sci_rx_isr,
0259 Console_Port_Tbl[minor]->ulIntVector,
0260 &old_isr);
0261
0262 if (status != RTEMS_SUCCESSFUL)
0263 rtems_fatal_error_occurred(status);
0264
0265 status = rtems_interrupt_catch(
0266 sh_sci_tx_isr,
0267 Console_Port_Tbl[minor]->ulDataPort,
0268 &old_isr);
0269
0270 if (status != RTEMS_SUCCESSFUL)
0271 rtems_fatal_error_occurred(status);
0272
0273
0274
0275
0276 SH_SCI_REG_FLAG(SCI_RIE, minor, SCI_SCR);
0277
0278 status = sh_set_irq_priority(
0279 Console_Port_Tbl[minor]->ulIntVector,
0280 Console_Port_Tbl[minor]->ulCtrlPort2);
0281
0282 if (status != RTEMS_SUCCESSFUL)
0283 rtems_fatal_error_occurred(status);
0284 }
0285
0286
0287
0288
0289
0290
0291
0292 int sh_sci_first_open(
0293 int major,
0294 int minor,
0295 void *arg
0296 )
0297 {
0298 char temp8;
0299 unsigned int a ;
0300
0301
0302
0303
0304 if (( minor > ( SCI_MINOR_DEVICES -1 )) || ( minor < 0 )) {
0305 return RTEMS_INVALID_NUMBER;
0306 }
0307
0308
0309
0310
0311
0312 SH_SCI_REG_DATA(0x00, minor, SCI_SCR);
0313
0314
0315 sh_sci_set_attributes(minor, Console_Port_Tbl[minor]->pDeviceParams);
0316
0317 for (a=0; a < 10000L; a++) {
0318 __asm__ volatile ("nop");
0319 }
0320
0321 write8((SCI_RE | SCI_TE),
0322 Console_Port_Tbl[minor]->ulCtrlPort1 + SCI_SCR);
0323
0324
0325
0326
0327 temp8 = read8(Console_Port_Tbl[minor]->ulCtrlPort1 + SCI_SSR);
0328 while(temp8 & (SCI_RDRF | SCI_ORER | SCI_FER | SCI_PER)) {
0329
0330 temp8 = read8(Console_Port_Tbl[minor]->ulCtrlPort1 + SCI_RDR);
0331
0332
0333 SH_SCI_REG_FLAG((SCI_RDRF|SCI_ORER|SCI_FER|SCI_PER), minor, SCI_SSR);
0334
0335
0336 temp8 = read8(Console_Port_Tbl[minor]->ulCtrlPort1 + SCI_SSR);
0337 }
0338
0339
0340 SH_SCI_REG_DATA(0x00, minor, SCI_TDR);
0341
0342
0343 SH_SCI_REG_FLAG(SCI_TDRE, minor, SCI_SSR);
0344
0345
0346
0347
0348 if (Console_Port_Tbl[minor]->pDeviceFns->deviceOutputUsesInterrupts) {
0349 SH_SCI_REG_FLAG(SCI_RIE, minor, SCI_SCR);
0350 }
0351
0352 return RTEMS_SUCCESSFUL ;
0353 }
0354
0355
0356
0357
0358
0359 int sh_sci_last_close(
0360 int major,
0361 int minor,
0362 void *arg
0363 )
0364 {
0365
0366
0367
0368 if (Console_Port_Tbl[minor]->pDeviceFns->deviceOutputUsesInterrupts)
0369 {
0370 SH_SCI_REG_MASK((SCI_TIE | SCI_RIE), minor, SCI_SCR);
0371 }
0372 return RTEMS_SUCCESSFUL ;
0373 }
0374
0375
0376
0377
0378 ssize_t sh_sci_write_support_int(
0379 int minor,
0380 const char *buf,
0381 size_t len
0382 )
0383 {
0384 if (!len)
0385 return 0;
0386
0387
0388
0389 SH_SCI_REG_DATA(*buf, minor, SCI_TDR);
0390 SH_SCI_REG_MASK(SCI_TDRE, minor, SCI_SSR);
0391
0392
0393
0394 SH_SCI_REG_FLAG(SCI_TIE, minor, SCI_SCR);
0395
0396 return 1;
0397 }
0398
0399
0400
0401
0402 ssize_t sh_sci_write_support_polled(
0403 int minor,
0404 const char *buf,
0405 size_t len
0406 )
0407 {
0408 int count = 0;
0409
0410 while(count < len) {
0411 sh_sci_write_polled(minor, buf[count]);
0412 count++;
0413 }
0414
0415
0416
0417 return count;
0418 }
0419
0420
0421
0422
0423 void sh_sci_write_polled(
0424 int minor,
0425 char c
0426 )
0427 {
0428
0429
0430
0431 while(!(read8(Console_Port_Tbl[minor]->ulCtrlPort1 + SCI_SSR) & SCI_TDRE));
0432
0433
0434
0435 SH_SCI_REG_DATA(c, minor, SCI_TDR);
0436
0437
0438
0439
0440 SH_SCI_REG_MASK(SCI_TDRE, minor, SCI_SSR);
0441 }
0442
0443
0444
0445
0446 int sh_sci_inbyte_nonblocking_polled(int minor)
0447 {
0448 char inbyte;
0449
0450
0451
0452
0453 if (read8(Console_Port_Tbl[minor]->ulCtrlPort1 + SCI_SSR) & SCI_RDRF) {
0454 inbyte = read8(Console_Port_Tbl[minor]->ulCtrlPort1 + SCI_RDR);
0455 SH_SCI_REG_MASK(SCI_RDRF, minor, SCI_SSR);
0456
0457
0458
0459
0460 if (read8(Console_Port_Tbl[minor]->ulCtrlPort1 + SCI_SSR) &
0461 (SCI_ORER | SCI_FER | SCI_PER)) {
0462 SH_SCI_REG_MASK((SCI_ORER | SCI_FER | SCI_PER), minor, SCI_SSR);
0463 return -1;
0464 }
0465 return (int)inbyte;
0466 }
0467 return -1;
0468 }