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 #include <bsp.h>
0022
0023 #include <stdlib.h>
0024
0025 #include <rtems/libio.h>
0026 #include <rtems/iosupp.h>
0027 #include <rtems/score/sh_io.h>
0028 #include <rtems/score/ispsh7032.h>
0029 #include <rtems/score/iosh7032.h>
0030 #include <sh/sh7_sci.h>
0031 #include <sh/sh7_pfc.h>
0032 #include <sh/sci.h>
0033
0034
0035
0036
0037
0038 #define SCI_MINOR_DEVICES 2
0039
0040 #define SH_SCI_BASE_0 SCI0_SMR
0041 #define SH_SCI_BASE_1 SCI1_SMR
0042
0043 struct scidev_t {
0044 char * name ;
0045 uint32_t addr ;
0046 rtems_device_minor_number minor ;
0047 unsigned short opened ;
0048 tcflag_t cflags ;
0049 speed_t spd ;
0050 } sci_device[SCI_MINOR_DEVICES] =
0051 {
0052 { "/dev/sci0", SH_SCI_BASE_0, 0, 0, CS8, B9600 },
0053 { "/dev/sci1", SH_SCI_BASE_1, 1, 0, CS8, B9600 }
0054 } ;
0055
0056
0057 static int _sci_set_cflags(
0058 struct scidev_t *sci_dev,
0059 tcflag_t c_cflag,
0060 speed_t spd )
0061 {
0062 uint8_t smr ;
0063 uint8_t brr ;
0064
0065 if ( spd )
0066 {
0067 if ( _sci_get_brparms( spd, &smr, &brr ) != 0 )
0068 return -1 ;
0069 }
0070
0071 if ( c_cflag & CSIZE )
0072 {
0073 if ( c_cflag & CS8 )
0074 smr &= ~SCI_SEVEN_BIT_DATA;
0075 else if ( c_cflag & CS7 )
0076 smr |= SCI_SEVEN_BIT_DATA;
0077 else
0078 return -1 ;
0079 }
0080
0081 if ( c_cflag & CSTOPB )
0082 smr |= SCI_STOP_BITS_2;
0083 else
0084 smr &= ~SCI_STOP_BITS_2;
0085
0086 if ( c_cflag & PARENB )
0087 smr |= SCI_PARITY_ON ;
0088 else
0089 smr &= ~SCI_PARITY_ON ;
0090
0091 if ( c_cflag & PARODD )
0092 smr |= SCI_ODD_PARITY ;
0093 else
0094 smr &= ~SCI_ODD_PARITY;
0095
0096 write8( smr, sci_dev->addr + SCI_SMR );
0097 write8( brr, sci_dev->addr + SCI_BRR );
0098
0099 return 0 ;
0100 }
0101
0102 static void _sci_init(
0103 rtems_device_minor_number minor )
0104 {
0105 uint16_t temp16 ;
0106
0107
0108 if( minor == 0)
0109 {
0110 temp16 = read16( PFC_PBCR1);
0111 temp16 &= ~( PB8MD | PB9MD );
0112 temp16 |= (PB_TXD0 | PB_RXD0);
0113 write16( temp16, PFC_PBCR1);
0114 }
0115 else
0116 {
0117 temp16 = read16( PFC_PBCR1);
0118 temp16 &= ~( PB10MD | PB11MD);
0119 temp16 |= (PB_TXD1 | PB_RXD1);
0120 write16( temp16, PFC_PBCR1);
0121 }
0122
0123
0124 if( minor == 0)
0125 {
0126 temp16 = read16( PFC_PBCR1);
0127 temp16 &= ~(PB12MD);
0128 write16( temp16, PFC_PBCR1);
0129 }
0130 else
0131 {
0132 temp16 = read16( PFC_PBCR1);
0133 temp16 &= ~(PB13MD);
0134 write16( temp16, PFC_PBCR1);
0135 }
0136 }
0137
0138 static void _sci_tx_polled(
0139 int minor,
0140 const char buf )
0141 {
0142 struct scidev_t *scidev = &sci_device[minor] ;
0143 int8_t ssr ;
0144
0145 while ( !inb((scidev->addr + SCI_SSR) & SCI_TDRE ))
0146 ;
0147 write8(buf,scidev->addr+SCI_TDR);
0148
0149 ssr = inb(scidev->addr+SCI_SSR);
0150 ssr &= ~SCI_TDRE ;
0151 write8(ssr,scidev->addr+SCI_SSR);
0152 }
0153
0154 static int _sci_rx_polled (
0155 int minor)
0156 {
0157 struct scidev_t *scidev = &sci_device[minor] ;
0158
0159 unsigned char c;
0160 char ssr ;
0161 ssr = read8(scidev->addr + SCI_SSR) ;
0162
0163 if (ssr & (SCI_PER | SCI_FER | SCI_ORER))
0164 write8(ssr & ~(SCI_PER | SCI_FER | SCI_ORER), scidev->addr+SCI_SSR);
0165
0166 if ( !(ssr & SCI_RDRF) )
0167 return -1;
0168
0169 c = read8(scidev->addr + SCI_RDR) ;
0170
0171 write8(ssr & ~SCI_RDRF,scidev->addr + SCI_SSR);
0172 return c;
0173 }
0174
0175
0176
0177
0178
0179 rtems_device_driver sh_sci_initialize(
0180 rtems_device_major_number major,
0181 rtems_device_minor_number minor,
0182 void *arg )
0183 {
0184 rtems_device_driver status ;
0185 rtems_device_minor_number i;
0186
0187
0188
0189
0190
0191
0192 for ( i = 0 ; i < SCI_MINOR_DEVICES ; i++ )
0193 {
0194 status = rtems_io_register_name(
0195 sci_device[i].name,
0196 major,
0197 sci_device[i].minor );
0198 if (status != RTEMS_SUCCESSFUL)
0199 rtems_fatal_error_occurred(status);
0200 }
0201
0202
0203
0204 return RTEMS_SUCCESSFUL;
0205 }
0206
0207
0208
0209
0210
0211
0212 rtems_device_driver sh_sci_open(
0213 rtems_device_major_number major,
0214 rtems_device_minor_number minor,
0215 void * arg )
0216 {
0217 uint8_t temp8;
0218
0219
0220 if(( minor > ( SCI_MINOR_DEVICES -1 )) || ( minor < 0 ))
0221 {
0222 return RTEMS_INVALID_NUMBER;
0223 }
0224
0225
0226 if ( sci_device[minor].opened > 0 )
0227 {
0228 sci_device[minor].opened++ ;
0229 return RTEMS_SUCCESSFUL ;
0230 }
0231
0232 _sci_init( minor );
0233
0234 if (minor == 0) {
0235 temp8 = read8(sci_device[minor].addr + SCI_SCR);
0236 temp8 &= ~(SCI_TE | SCI_RE) ;
0237 write8(temp8, sci_device[minor].addr + SCI_SCR);
0238 _sci_set_cflags( &sci_device[minor], sci_device[minor].cflags, sci_device[minor].spd );
0239
0240
0241 CPU_delay(50000);
0242
0243 temp8 |= SCI_RE | SCI_TE;
0244 write8(temp8, sci_device[minor].addr + SCI_SCR);
0245 } else {
0246 temp8 = read8(sci_device[minor].addr + SCI_SCR);
0247 temp8 &= ~(SCI_TE | SCI_RE) ;
0248 write8(temp8, sci_device[minor].addr + SCI_SCR);
0249 _sci_set_cflags( &sci_device[minor], sci_device[minor].cflags, sci_device[minor].spd );
0250
0251
0252 CPU_delay(50000);
0253
0254 temp8 |= SCI_RE | SCI_TE;
0255 write8(temp8, sci_device[minor].addr + SCI_SCR);
0256 }
0257
0258 sci_device[minor].opened++ ;
0259
0260 return RTEMS_SUCCESSFUL ;
0261 }
0262
0263
0264
0265
0266
0267 rtems_device_driver sh_sci_close(
0268 rtems_device_major_number major,
0269 rtems_device_minor_number minor,
0270 void * arg
0271 )
0272 {
0273 if( sci_device[minor].opened == 0 )
0274 {
0275 return RTEMS_INVALID_NUMBER;
0276 }
0277
0278 sci_device[minor].opened-- ;
0279
0280 return RTEMS_SUCCESSFUL ;
0281 }
0282
0283
0284
0285
0286
0287 rtems_device_driver sh_sci_read(
0288 rtems_device_major_number major,
0289 rtems_device_minor_number minor,
0290 void * arg
0291 )
0292 {
0293 int count = 0;
0294
0295 rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *) arg;
0296 char * buffer = rw_args->buffer;
0297 int maximum = rw_args->count;
0298
0299 for (count = 0; count < maximum; count++) {
0300 buffer[ count ] = _sci_rx_polled(minor);
0301 if (buffer[ count ] == '\n' || buffer[ count ] == '\r') {
0302 buffer[ count++ ] = '\n';
0303 break;
0304 }
0305 }
0306
0307 rw_args->bytes_moved = count;
0308 return (count >= 0) ? RTEMS_SUCCESSFUL : RTEMS_UNSATISFIED;
0309 }
0310
0311
0312
0313
0314
0315 rtems_device_driver sh_sci_write(
0316 rtems_device_major_number major,
0317 rtems_device_minor_number minor,
0318 void * arg
0319 )
0320 {
0321 int count;
0322
0323 rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *) arg;
0324 char *buffer = rw_args->buffer;
0325 int maximum = rw_args->count;
0326
0327 for (count = 0; count < maximum; count++) {
0328 #if 0
0329 if ( buffer[ count ] == '\n') {
0330 outbyte(minor, '\r');
0331 }
0332 #endif
0333 _sci_tx_polled( minor, buffer[ count ] );
0334 }
0335
0336 rw_args->bytes_moved = maximum;
0337 return 0;
0338 }
0339
0340
0341
0342
0343
0344 rtems_device_driver sh_sci_control(
0345 rtems_device_major_number major,
0346 rtems_device_minor_number minor,
0347 void * arg
0348 )
0349 {
0350
0351 return RTEMS_SUCCESSFUL ;
0352 }