File indexing completed on 2025-05-11 08:23:53
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 #include <rtems.h>
0035 #include <rtems/libio.h>
0036 #include <errno.h>
0037 #include <string.h>
0038 #include <stdio.h>
0039 #include <bsp.h>
0040 #include <bsp/mpc5200.h>
0041 #include <bsp/nvram.h>
0042 #include "m93cxx.h"
0043
0044
0045
0046
0047 void wait_usec(unsigned long usec)
0048 {
0049 unsigned long start_count = 0, update_count;
0050 unsigned long delay_count;
0051
0052 if(TMBASE_CLOCK < 1000000)
0053 delay_count = (TMBASE_CLOCK * usec )/1000000;
0054 else
0055 delay_count = (TMBASE_CLOCK / 1000000) * usec;
0056
0057 TBL_READ(start_count);
0058
0059 update_count = start_count;
0060
0061 while((update_count - start_count) < delay_count)
0062 TBL_READ(update_count);
0063
0064 }
0065
0066
0067
0068
0069
0070 static void m93cxx_enable_write()
0071 {
0072 uint32_t header, i;
0073
0074 ENABLE_CHIP_SELECT;
0075
0076 WAIT(1);
0077
0078 header = M93C46_EWEN;
0079
0080 for(i = 0; i < M93C46_CLOCK_CYCLES; i++)
0081 {
0082
0083 MASK_HEAD_SHIFT(header);
0084
0085 WAIT(1);
0086
0087 DO_CLOCK_CYCLE;
0088
0089 WAIT(1);
0090
0091 }
0092
0093 DISABLE_CHIP_SELECT;
0094
0095 return;
0096
0097 }
0098
0099
0100
0101
0102
0103 static void m93cxx_disable_write()
0104 {
0105 uint32_t header, i;
0106
0107 ENABLE_CHIP_SELECT;
0108
0109 WAIT(1);
0110
0111 header = M93C46_EWDS;
0112
0113 for(i = 0; i < M93C46_CLOCK_CYCLES; i++)
0114 {
0115
0116 MASK_HEAD_SHIFT(header);
0117
0118 WAIT(1);
0119
0120 DO_CLOCK_CYCLE;
0121
0122 WAIT(1);
0123
0124 }
0125
0126 DISABLE_CHIP_SELECT;
0127
0128 return;
0129
0130 }
0131
0132
0133
0134
0135
0136 static uint8_t m93cxx_read_byte(uint32_t offset)
0137 {
0138 uint8_t byte2read;
0139 uint32_t header, tmp_offset, i;
0140 #ifdef M93CXX_MODE_BYTE
0141 uint8_t byte_recv = 0;
0142 #else
0143 uint32_t word_recv = 0;
0144 #endif
0145
0146 ENABLE_CHIP_SELECT;
0147
0148 WAIT(1);
0149
0150 #ifdef M93CXX_MODE_BYTE
0151
0152 header = M93C46_READ(offset);
0153
0154 for(i = 0; i < M93C46_CLOCK_CYCLES; i++)
0155 {
0156
0157 MASK_HEAD_SHIFT(header);
0158
0159 WAIT(1);
0160
0161 DO_CLOCK_CYCLE;
0162
0163 WAIT(1);
0164
0165 }
0166
0167 for(i = 0; i < 8; i++)
0168 {
0169
0170 WAIT(1);
0171
0172 DO_CLOCK_CYCLE;
0173
0174 WAIT(1);
0175
0176 GET_DATA_BYTE_SHIFT(byte_recv);
0177
0178 }
0179
0180 byte_recv >>= 1;
0181
0182 byte2read = byte_recv;
0183
0184 #else
0185 tmp_offset = offset/2;
0186
0187 header = M93C46_READ(tmp_offset);
0188
0189 for(i = 0; i < M93C46_CLOCK_CYCLES; i++)
0190 {
0191
0192 MASK_HEAD_SHIFT(header);
0193
0194 WAIT(1);
0195
0196 DO_CLOCK_CYCLE;
0197
0198 WAIT(1);
0199
0200 }
0201
0202 for(i = 0; i < 16; i++)
0203 {
0204
0205 DO_CLOCK_CYCLE;
0206
0207 WAIT(1);
0208
0209 GET_DATA_WORD_SHIFT(word_recv);
0210
0211 WAIT(1);
0212
0213 }
0214
0215 word_recv >>= 1;
0216
0217 if(offset%2)
0218 {
0219
0220 byte2read = (uint8_t)((word_recv & 0xFF00) >> 8);
0221
0222 #ifdef NVRAM_DEBUG
0223 printf("\nbyte_read(o) = %x", byte2read);
0224 #endif
0225
0226 }
0227 else
0228 {
0229
0230 byte2read = (uint8_t)(word_recv & 0x00FF);
0231
0232 #ifdef NVRAM_DEBUG
0233 printf("\nbyte_read(e) = %x", byte2read);
0234 #endif
0235 }
0236
0237 #endif
0238
0239 WAIT(1);
0240
0241 DISABLE_CHIP_SELECT;
0242
0243 return byte2read;
0244
0245 }
0246
0247
0248
0249
0250
0251 void m93cxx_write_byte(uint32_t offset, uint8_t byte2write)
0252 {
0253 uint32_t header, tmp_offset, i;
0254 #ifdef M93CXX_MODE_BYTE
0255 uint8_t byte_send;
0256 #else
0257 uint16_t word_send;
0258 #endif
0259
0260 ENABLE_CHIP_SELECT;
0261
0262 WAIT(1);
0263
0264 #ifdef M93CXX_MODE_BYTE
0265 header = M93C46_WRITE(offset);
0266
0267 for(i = 0; i < M93C46_CLOCK_CYCLES; i++)
0268 {
0269
0270 MASK_HEAD_SHIFT(header);
0271
0272 WAIT(1);
0273
0274 DO_CLOCK_CYCLE;
0275
0276 WAIT(1);
0277
0278 }
0279
0280 byte_send = byte2write;
0281
0282 for(i = 0; i < 8; i++)
0283 {
0284
0285 SET_DATA_BYTE_SHIFT(byte_send);
0286
0287 WAIT(1);
0288
0289 DO_CLOCK_CYCLE;
0290
0291 WAIT(1);
0292
0293 }
0294
0295 }
0296 #else
0297
0298 if(offset%2)
0299 {
0300
0301 word_send = (uint16_t)m93cxx_read_byte(offset-1);
0302 word_send |= (uint16_t)(m93cxx_read_byte(offset) << 8);
0303
0304 }
0305 else
0306 {
0307
0308 word_send = (uint16_t)m93cxx_read_byte(offset);
0309 word_send |= (uint16_t)(m93cxx_read_byte(offset + 1) << 8);
0310
0311 }
0312
0313 tmp_offset = offset/2;
0314
0315 WAIT(1);
0316
0317 ENABLE_CHIP_SELECT;
0318
0319 WAIT(1);
0320
0321 header = M93C46_WRITE(tmp_offset);
0322
0323 for(i = 0; i < M93C46_CLOCK_CYCLES; i++)
0324 {
0325
0326 MASK_HEAD_SHIFT(header);
0327
0328 WAIT(1);
0329
0330 DO_CLOCK_CYCLE;
0331
0332 WAIT(1);
0333
0334 }
0335
0336 if(offset%2)
0337 {
0338
0339 word_send = (word_send & 0x00FF) | ((uint16_t)(byte2write << 8));
0340
0341 #ifdef NVRAM_DEBUG
0342 printf("\nword_send = %x", word_send);
0343 #endif
0344
0345 }
0346 else
0347 {
0348
0349 word_send = (word_send & 0xFF00) | (uint16_t)byte2write;
0350 #ifdef NVRAM_DEBUG
0351 printf("\nword_send = %x", word_send);
0352 #endif
0353
0354 }
0355
0356 for(i = 0; i < 16; i++)
0357 {
0358
0359 SET_DATA_WORD_SHIFT(word_send);
0360
0361 WAIT(1);
0362
0363 DO_CLOCK_CYCLE;
0364
0365 WAIT(1);
0366
0367 }
0368
0369 DISABLE_CHIP_SELECT;
0370
0371 WAIT(1);
0372
0373 ENABLE_CHIP_SELECT;
0374
0375 WAIT(1);
0376
0377 CHECK_WRITE_BUSY;
0378
0379 #endif
0380
0381 WAIT(1);
0382
0383 DISABLE_CHIP_SELECT;
0384
0385 return;
0386
0387 }
0388
0389
0390
0391
0392
0393 rtems_device_driver nvram_driver_initialize(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
0394 {
0395 rtems_status_code sc;
0396
0397
0398 mpc5200.gpiosen |= (GPIO_PSC3_6 | GPIO_PSC3_7);
0399
0400
0401 mpc5200.gpiosod &= ~(GPIO_PSC3_6 | GPIO_PSC3_7);
0402
0403
0404 mpc5200.gpiosdo &= ~GPIO_PSC3_6;
0405
0406
0407 mpc5200.gpiosdd |= GPIO_PSC3_6;
0408 mpc5200.gpiosdd &= ~GPIO_PSC3_7;
0409
0410
0411 mpc5200.gpiosiie &= ~GPIO_PSC3_8;
0412
0413
0414 mpc5200.gpiosie |= GPIO_PSC3_8;
0415
0416
0417 mpc5200.gpiosiod &= ~GPIO_PSC3_8;
0418
0419
0420 mpc5200.gpiosido &= ~GPIO_PSC3_8;
0421
0422
0423 mpc5200.gpiosidd |= GPIO_PSC3_8;
0424
0425
0426 mpc5200.gpiowue &= ~GPIO_PSC3_9;
0427
0428
0429 mpc5200.gpiowe |= GPIO_PSC3_9;
0430
0431
0432 mpc5200.gpiowod &= ~GPIO_PSC3_9;
0433
0434
0435 mpc5200.gpiowdo &= ~GPIO_PSC3_9;
0436
0437
0438 mpc5200.gpiowdd |= GPIO_PSC3_9;
0439
0440 sc = rtems_io_register_name("/dev/nvram", major, 0);
0441
0442 if(sc != RTEMS_SUCCESSFUL)
0443 {
0444
0445 errno = EIO;
0446
0447 return RTEMS_UNSATISFIED;
0448
0449 }
0450 else
0451 return RTEMS_SUCCESSFUL;
0452
0453 }
0454
0455
0456
0457
0458
0459 rtems_device_driver nvram_driver_open(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
0460 {
0461
0462 return RTEMS_SUCCESSFUL;
0463
0464 }
0465
0466
0467
0468
0469
0470 rtems_device_driver nvram_driver_close(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
0471 {
0472
0473 return RTEMS_SUCCESSFUL;
0474
0475 }
0476
0477
0478
0479
0480
0481 rtems_device_driver nvram_driver_read(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
0482 {
0483 rtems_libio_rw_args_t *args = arg;
0484 uint32_t count, i;
0485
0486 #ifdef NVRAM_DEBUG
0487 printf("\nread count = %2x", (int)(args->count));
0488 printf("\nread offset = %2x", (int)(args->offset));
0489 #endif
0490
0491 if((args->offset >= M93C46_NVRAM_SIZE) || (args->offset + args->count > M93C46_NVRAM_SIZE))
0492 {
0493
0494 args->bytes_moved = 0;
0495 errno = EINVAL;
0496 return RTEMS_UNSATISFIED;
0497
0498 }
0499 else
0500 count = args->count;
0501
0502 for(i = 0; i < count; i++)
0503 {
0504
0505 (args->buffer)[i] = m93cxx_read_byte((args->offset) + i);
0506 (args->bytes_moved) += 1;
0507
0508 }
0509
0510 return RTEMS_SUCCESSFUL;
0511
0512 }
0513
0514
0515
0516
0517
0518 rtems_device_driver nvram_driver_write(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
0519 {
0520 rtems_libio_rw_args_t *args = arg;
0521 uint32_t count, i;
0522
0523 #ifdef NVRAM_DEBUG
0524 printf("\nwrite count = %2x", (int)(args->count));
0525 printf("\nwrite offset = %2x", (int)(args->offset));
0526 #endif
0527
0528 if((args->offset >= M93C46_NVRAM_SIZE) || (args->offset + args->count > M93C46_NVRAM_SIZE))
0529 {
0530
0531 args->bytes_moved = 0;
0532 errno = EINVAL;
0533 return RTEMS_UNSATISFIED;
0534
0535 }
0536
0537 count = args->count;
0538
0539 m93cxx_enable_write();
0540
0541 WAIT(1);
0542
0543 for(i = 0; i < count; i++)
0544 {
0545
0546 m93cxx_write_byte((args->offset) + i, (args->buffer)[i]);
0547 (args->bytes_moved) += 1;
0548
0549 }
0550
0551 WAIT(1);
0552
0553 m93cxx_disable_write();
0554
0555 return RTEMS_SUCCESSFUL;
0556
0557 }