File indexing completed on 2025-05-11 08:23:54
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 #include <mpc55xx/regs.h>
0036 #include <mpc55xx/dspi.h>
0037 #include <mpc55xx/mpc55xx.h>
0038
0039 #include <bsp/irq.h>
0040
0041 #include <libcpu/powerpc-utility.h>
0042
0043 #define RTEMS_STATUS_CHECKS_USE_PRINTK
0044
0045 #include <rtems/status-checks.h>
0046
0047 #include <inttypes.h>
0048
0049 #define MPC55XX_DSPI_FIFO_SIZE 4
0050
0051 #define MPC55XX_DSPI_CTAR_NUMBER 8
0052
0053 #define MPC55XX_DSPI_CTAR_DEFAULT 0
0054
0055 #define MPC55XX_DSPI_EDMA_MAGIC_SIZE 128
0056
0057 #define MPC55XX_DSPI_BAUDRATE_SCALER_TABLE_SIZE 63
0058
0059 typedef struct {
0060 uint32_t scaler : 26;
0061 uint32_t pbr : 2;
0062 uint32_t br : 4;
0063 } mpc55xx_dspi_baudrate_scaler_entry;
0064
0065 static const mpc55xx_dspi_baudrate_scaler_entry mpc55xx_dspi_baudrate_scaler_table [MPC55XX_DSPI_BAUDRATE_SCALER_TABLE_SIZE] = {
0066 { 4, 0, 0 },
0067 { 6, 1, 0 },
0068 { 8, 0, 1 },
0069 { 10, 2, 0 },
0070 { 12, 1, 1 },
0071 { 14, 3, 0 },
0072 { 16, 0, 3 },
0073 { 18, 1, 2 },
0074 { 20, 2, 1 },
0075 { 24, 1, 3 },
0076 { 28, 3, 1 },
0077 { 30, 2, 2 },
0078 { 32, 0, 4 },
0079 { 40, 2, 3 },
0080 { 42, 3, 2 },
0081 { 48, 1, 4 },
0082 { 56, 3, 3 },
0083 { 64, 0, 5 },
0084 { 80, 2, 4 },
0085 { 96, 1, 5 },
0086 { 112, 3, 4 },
0087 { 128, 0, 6 },
0088 { 160, 2, 5 },
0089 { 192, 1, 6 },
0090 { 224, 3, 5 },
0091 { 256, 0, 7 },
0092 { 320, 2, 6 },
0093 { 384, 1, 7 },
0094 { 448, 3, 6 },
0095 { 512, 0, 8 },
0096 { 640, 2, 7 },
0097 { 768, 1, 8 },
0098 { 896, 3, 7 },
0099 { 1024, 0, 9 },
0100 { 1280, 2, 8 },
0101 { 1536, 1, 9 },
0102 { 1792, 3, 8 },
0103 { 2048, 0, 10 },
0104 { 2560, 2, 9 },
0105 { 3072, 1, 10 },
0106 { 3584, 3, 9 },
0107 { 4096, 0, 11 },
0108 { 5120, 2, 10 },
0109 { 6144, 1, 11 },
0110 { 7168, 3, 10 },
0111 { 8192, 0, 12 },
0112 { 10240, 2, 11 },
0113 { 12288, 1, 12 },
0114 { 14336, 3, 11 },
0115 { 16384, 0, 13 },
0116 { 20480, 2, 12 },
0117 { 24576, 1, 13 },
0118 { 28672, 3, 12 },
0119 { 32768, 0, 14 },
0120 { 40960, 2, 13 },
0121 { 49152, 1, 14 },
0122 { 57344, 3, 13 },
0123 { 65536, 0, 15 },
0124 { 81920, 2, 14 },
0125 { 98304, 1, 15 },
0126 { 114688, 3, 14 },
0127 { 163840, 2, 15 },
0128 { 229376, 3, 15 },
0129 };
0130
0131 static void mpc55xx_dspi_edma_done( edma_channel_context *ctx, uint32_t error_status)
0132 {
0133 const mpc55xx_dspi_edma_entry *e = (const mpc55xx_dspi_edma_entry *) ctx;
0134 rtems_semaphore_release( e->id);
0135
0136 if (error_status != 0) {
0137 RTEMS_SYSLOG_ERROR( "eDMA error: 0x%08" PRIx32 "\n", error_status);
0138 }
0139 }
0140
0141 static mpc55xx_dspi_baudrate_scaler_entry mpc55xx_dspi_search_baudrate_scaler( uint32_t scaler, int min, int mid, int max)
0142 {
0143 if (scaler <= mpc55xx_dspi_baudrate_scaler_table [mid].scaler) {
0144 max = mid;
0145 } else {
0146 min = mid;
0147 }
0148 mid = (min + max) / 2;
0149 if (mid == min) {
0150 return mpc55xx_dspi_baudrate_scaler_table [max];
0151 } else {
0152 return mpc55xx_dspi_search_baudrate_scaler( scaler, min, mid, max);
0153 }
0154 }
0155
0156 static uint32_t mpc55xx_dspi_push_data [8 * MPC55XX_DSPI_NUMBER] __attribute__ ((aligned (32)));
0157
0158 static inline void mpc55xx_dspi_store_push_data( mpc55xx_dspi_bus_entry *e)
0159 {
0160 mpc55xx_dspi_push_data [e->table_index * 8] = e->push_data.R;
0161 rtems_cache_flush_multiple_data_lines( &mpc55xx_dspi_push_data [e->table_index * 8], 4);
0162 }
0163
0164 static inline uint32_t mpc55xx_dspi_push_data_address( mpc55xx_dspi_bus_entry *e)
0165 {
0166 return (uint32_t) &mpc55xx_dspi_push_data [e->table_index * 8];
0167 }
0168
0169 static inline uint32_t mpc55xx_dspi_nirvana_address( mpc55xx_dspi_bus_entry *e)
0170 {
0171 return (uint32_t) &mpc55xx_dspi_push_data [e->table_index * 8 + 1];
0172 }
0173
0174 static rtems_status_code mpc55xx_dspi_init( rtems_libi2c_bus_t *bus)
0175 {
0176 rtems_status_code sc = RTEMS_SUCCESSFUL;
0177 mpc55xx_dspi_bus_entry *e = (mpc55xx_dspi_bus_entry *) bus;
0178 union DSPI_MCR_tag mcr = MPC55XX_ZERO_FLAGS;
0179 union DSPI_CTAR_tag ctar = MPC55XX_ZERO_FLAGS;
0180 union DSPI_RSER_tag rser = MPC55XX_ZERO_FLAGS;
0181 struct tcd_t tcd_push = EDMA_TCD_DEFAULT;
0182 int i = 0;
0183
0184
0185 sc = rtems_semaphore_create (
0186 rtems_build_name ( 'S', 'P', 'I', 'R'),
0187 0,
0188 RTEMS_SIMPLE_BINARY_SEMAPHORE,
0189 0,
0190 &e->edma_receive.id
0191 );
0192 RTEMS_CHECK_SC( sc, "create receive update semaphore");
0193
0194 sc = mpc55xx_edma_obtain_channel( &e->edma_receive.edma, MPC55XX_INTC_DEFAULT_PRIORITY);
0195 RTEMS_CHECK_SC( sc, "obtain receive eDMA channel");
0196
0197
0198 sc = rtems_semaphore_create (
0199 rtems_build_name ( 'S', 'P', 'I', 'T'),
0200 0,
0201 RTEMS_SIMPLE_BINARY_SEMAPHORE,
0202 0,
0203 &e->edma_transmit.id
0204 );
0205 RTEMS_CHECK_SC( sc, "create transmit update semaphore");
0206
0207 sc = mpc55xx_edma_obtain_channel( &e->edma_transmit.edma, MPC55XX_INTC_DEFAULT_PRIORITY);
0208 RTEMS_CHECK_SC( sc, "obtain transmit eDMA channel");
0209
0210 sc = mpc55xx_edma_obtain_channel( &e->edma_push.edma, MPC55XX_INTC_DEFAULT_PRIORITY);
0211 RTEMS_CHECK_SC( sc, "obtain push eDMA channel");
0212
0213 tcd_push.SADDR = mpc55xx_dspi_push_data_address( e);
0214 tcd_push.SDF.B.SSIZE = 2;
0215 tcd_push.SDF.B.SOFF = 0;
0216 tcd_push.DADDR = (uint32_t) &e->regs->PUSHR.R;
0217 tcd_push.SDF.B.DSIZE = 2;
0218 tcd_push.CDF.B.DOFF = 0;
0219 tcd_push.NBYTES = 4;
0220 tcd_push.CDF.B.CITER = 1;
0221 tcd_push.BMF.B.BITER = 1;
0222
0223 *e->edma_push.edma.edma_tcd = tcd_push;
0224
0225
0226 mcr.B.MSTR = e->master ? 1 : 0;
0227 mcr.B.CONT_SCKE = 0;
0228 mcr.B.DCONF = 0;
0229 mcr.B.FRZ = 0;
0230 mcr.B.MTFE = 0;
0231 mcr.B.PCSSE = 0;
0232 mcr.B.ROOE = 0;
0233 mcr.B.PCSIS0 = 1;
0234 mcr.B.PCSIS1 = 1;
0235 mcr.B.PCSIS2 = 1;
0236 mcr.B.PCSIS3 = 1;
0237 mcr.B.PCSIS5 = 1;
0238 mcr.B.MDIS = 0;
0239 mcr.B.DIS_TXF = 0;
0240 mcr.B.DIS_RXF = 0;
0241 mcr.B.CLR_TXF = 0;
0242 mcr.B.CLR_RXF = 0;
0243 mcr.B.SMPL_PT = 0;
0244 mcr.B.HALT = 0;
0245
0246 e->regs->MCR.R = mcr.R;
0247
0248
0249 ctar.B.DBR = 0;
0250 ctar.B.FMSZ = 0x7;
0251 ctar.B.CPOL = 0;
0252 ctar.B.CPHA = 0;
0253 ctar.B.LSBFE = 0;
0254 ctar.B.PCSSCK = 0;
0255 ctar.B.PASC = 0;
0256 ctar.B.PDT = 0;
0257 ctar.B.PBR = 0;
0258 ctar.B.CSSCK = 0;
0259 ctar.B.ASC = 0;
0260 ctar.B.DT = 0;
0261 ctar.B.BR = 0;
0262
0263 for (i = 0; i < MPC55XX_DSPI_CTAR_NUMBER; ++i) {
0264 e->regs->CTAR [i].R = ctar.R;
0265 }
0266
0267
0268 rser.B.TFFFRE = 1;
0269 rser.B.TFFFDIRS = 1;
0270 rser.B.RFDFRE = 1;
0271 rser.B.RFDFDIRS = 1;
0272
0273 e->regs->RSER.R = rser.R;
0274
0275 return RTEMS_SUCCESSFUL;
0276 }
0277
0278 static rtems_status_code mpc55xx_dspi_send_start( rtems_libi2c_bus_t *bus)
0279 {
0280 mpc55xx_dspi_bus_entry *e = (mpc55xx_dspi_bus_entry *) bus;
0281
0282
0283 e->push_data.B.PCS0 = 0;
0284 e->push_data.B.PCS1 = 0;
0285 e->push_data.B.PCS2 = 0;
0286 e->push_data.B.PCS3 = 0;
0287 e->push_data.B.PCS4 = 0;
0288 e->push_data.B.PCS5 = 0;
0289 mpc55xx_dspi_store_push_data( e);
0290
0291 return RTEMS_SUCCESSFUL;
0292 }
0293
0294 static rtems_status_code mpc55xx_dspi_send_stop( rtems_libi2c_bus_t *bus)
0295 {
0296 return RTEMS_SUCCESSFUL;
0297 }
0298
0299 static rtems_status_code mpc55xx_dspi_send_addr( rtems_libi2c_bus_t *bus, uint32_t addr, int rw)
0300 {
0301 mpc55xx_dspi_bus_entry *e = (mpc55xx_dspi_bus_entry *) bus;
0302 union DSPI_SR_tag sr = MPC55XX_ZERO_FLAGS;
0303
0304
0305 e->regs->MCR.B.CLR_TXF = 1;
0306 e->regs->MCR.B.CLR_RXF = 1;
0307
0308
0309 sr.B.EOQF = 1;
0310 sr.B.TFFF = 1;
0311 sr.B.RFDF = 1;
0312 e->regs->SR.R = sr.R;
0313
0314
0315 e->push_data.R = 0;
0316 e->push_data.B.CONT = 0;
0317 e->push_data.B.CTAS = MPC55XX_DSPI_CTAR_DEFAULT;
0318 e->push_data.B.EOQ = 0;
0319 e->push_data.B.CTCNT = 0;
0320 switch (addr) {
0321 case 0:
0322 e->push_data.B.PCS0 = 1;
0323 break;
0324 case 1:
0325 e->push_data.B.PCS1 = 1;
0326 break;
0327 case 2:
0328 e->push_data.B.PCS2 = 1;
0329 break;
0330 case 3:
0331 e->push_data.B.PCS3 = 1;
0332 break;
0333 case 4:
0334 e->push_data.B.PCS4 = 1;
0335 break;
0336 case 5:
0337 e->push_data.B.PCS5 = 1;
0338 break;
0339 default:
0340 return -RTEMS_INVALID_ADDRESS;
0341 }
0342 mpc55xx_dspi_store_push_data( e);
0343
0344 return RTEMS_SUCCESSFUL;
0345 }
0346
0347
0348 extern uint32_t bsp_clock_speed;
0349
0350 static int mpc55xx_dspi_set_transfer_mode( rtems_libi2c_bus_t *bus, const rtems_libi2c_tfr_mode_t *mode)
0351 {
0352 mpc55xx_dspi_bus_entry *e = (mpc55xx_dspi_bus_entry *) bus;
0353 union DSPI_CTAR_tag ctar = MPC55XX_ZERO_FLAGS;
0354
0355 if (mode->bits_per_char != 8) {
0356 return -RTEMS_INVALID_NUMBER;
0357 }
0358
0359 e->idle_char = mode->idle_char;
0360
0361 ctar.R = e->regs->CTAR [MPC55XX_DSPI_CTAR_DEFAULT].R;
0362
0363 ctar.B.PCSSCK = 0;
0364 ctar.B.CSSCK = 0;
0365 ctar.B.PASC = 0;
0366 ctar.B.ASC = 0;
0367
0368 ctar.B.LSBFE = mode->lsb_first ? 1 : 0;
0369 ctar.B.CPOL = mode->clock_inv ? 1 : 0;
0370 ctar.B.CPHA = mode->clock_phs ? 1 : 0;
0371
0372 if (mode->baudrate != e->baud) {
0373 uint32_t scaler = bsp_clock_speed / mode->baudrate;
0374 mpc55xx_dspi_baudrate_scaler_entry bse = mpc55xx_dspi_search_baudrate_scaler( scaler, 0, MPC55XX_DSPI_BAUDRATE_SCALER_TABLE_SIZE / 2, MPC55XX_DSPI_BAUDRATE_SCALER_TABLE_SIZE);
0375
0376 ctar.B.PBR = bse.pbr;
0377 ctar.B.BR = bse.br;
0378
0379 e->baud = mode->baudrate;
0380 }
0381
0382 e->regs->CTAR [MPC55XX_DSPI_CTAR_DEFAULT].R = ctar.R;
0383
0384 return 0;
0385 }
0386
0387
0388
0389
0390
0391
0392
0393
0394
0395
0396
0397
0398
0399
0400
0401
0402
0403
0404
0405
0406
0407
0408
0409
0410
0411
0412
0413
0414
0415
0416
0417
0418
0419
0420
0421
0422
0423 static int mpc55xx_dspi_read_write( rtems_libi2c_bus_t *bus, unsigned char *in, const unsigned char *out, int n)
0424 {
0425 mpc55xx_dspi_bus_entry *e = (mpc55xx_dspi_bus_entry *) bus;
0426
0427
0428 int n_nc = n;
0429
0430
0431 int n_c = 0;
0432
0433
0434 volatile void *push = &e->regs->PUSHR.R;
0435 volatile void *pop = &e->regs->POPR.R;
0436 volatile union DSPI_SR_tag *status = &e->regs->SR;
0437
0438
0439 union DSPI_PUSHR_tag push_data = e->push_data;
0440 union DSPI_POPR_tag pop_data;
0441
0442
0443 union DSPI_SR_tag sr;
0444
0445
0446 int r = 0;
0447 int w = 0;
0448
0449 if (n == 0) {
0450 return 0;
0451 } else if (in == NULL && out == NULL) {
0452 return -RTEMS_INVALID_ADDRESS;
0453 }
0454
0455 if (n > MPC55XX_DSPI_EDMA_MAGIC_SIZE) {
0456 n_nc = (int) mpc55xx_non_cache_aligned_size( in);
0457 n_c = (int) mpc55xx_cache_aligned_size( in, (size_t) n);
0458 if (n_c > EDMA_TCD_BITER_LINKED_SIZE) {
0459 RTEMS_SYSLOG_WARNING( "buffer size out of range, cannot use eDMA\n");
0460 n_nc = n;
0461 n_c = 0;
0462 } else if (n_nc + n_c != n) {
0463 RTEMS_SYSLOG_WARNING( "input buffer not proper cache aligned, cannot use eDMA\n");
0464 n_nc = n;
0465 n_c = 0;
0466 }
0467 }
0468
0469 #ifdef DEBUG
0470 if (e->regs->SR.B.TXCTR != e->regs->SR.B.RXCTR) {
0471 RTEMS_SYSLOG_WARNING( "FIFO counter not equal\n");
0472 }
0473 #endif
0474
0475
0476 if (out == NULL) {
0477 push_data.B.TXDATA = e->idle_char;
0478 while (r < n_nc || w < n_nc) {
0479
0480 do {
0481 sr.R = status->R;
0482 } while (sr.B.TXCTR == MPC55XX_DSPI_FIFO_SIZE && sr.B.RXCTR == 0);
0483
0484
0485 if (w < n_nc && (w - r) < MPC55XX_DSPI_FIFO_SIZE && sr.B.TXCTR != MPC55XX_DSPI_FIFO_SIZE) {
0486 ++w;
0487 ppc_write_word( push_data.R, push);
0488 }
0489
0490
0491 if (r < n_nc && sr.B.RXCTR != 0) {
0492 pop_data.R = ppc_read_word( pop);
0493 in [r] = (unsigned char) pop_data.B.RXDATA;
0494 ++r;
0495 }
0496 }
0497 } else if (in == NULL) {
0498 while (r < n_nc || w < n_nc) {
0499
0500 do {
0501 sr.R = status->R;
0502 } while (sr.B.TXCTR == MPC55XX_DSPI_FIFO_SIZE && sr.B.RXCTR == 0);
0503
0504
0505 if (w < n_nc && (w - r) < MPC55XX_DSPI_FIFO_SIZE && sr.B.TXCTR != MPC55XX_DSPI_FIFO_SIZE) {
0506 push_data.B.TXDATA = out [w];
0507 ++w;
0508 ppc_write_word( push_data.R, push);
0509 }
0510
0511
0512 if (r < n_nc && sr.B.RXCTR != 0) {
0513 pop_data.R = ppc_read_word( pop);
0514 ++r;
0515 }
0516 }
0517 } else {
0518 while (r < n_nc || w < n_nc) {
0519
0520 do {
0521 sr.R = status->R;
0522 } while (sr.B.TXCTR == MPC55XX_DSPI_FIFO_SIZE && sr.B.RXCTR == 0);
0523
0524
0525 if (w < n_nc && (w - r) < MPC55XX_DSPI_FIFO_SIZE && sr.B.TXCTR != MPC55XX_DSPI_FIFO_SIZE) {
0526 push_data.B.TXDATA = out [w];
0527 ++w;
0528 ppc_write_word( push_data.R, push);
0529 }
0530
0531
0532 if (r < n_nc && sr.B.RXCTR != 0) {
0533 pop_data.R = ppc_read_word( pop);
0534 in [r] = (unsigned char) pop_data.B.RXDATA;
0535 ++r;
0536 }
0537 }
0538 }
0539
0540
0541 if (n_c > 0) {
0542 rtems_status_code sc = RTEMS_SUCCESSFUL;
0543 unsigned char *in_c = in + n_nc;
0544 const unsigned char *out_c = out + n_nc;
0545 struct tcd_t tcd_transmit = EDMA_TCD_DEFAULT;
0546 struct tcd_t tcd_receive = EDMA_TCD_DEFAULT;
0547
0548
0549 rtems_cache_flush_multiple_data_lines( out_c, (size_t) n_c);
0550 rtems_cache_invalidate_multiple_data_lines( in_c, (size_t) n_c);
0551
0552
0553 if (out == NULL) {
0554 e->push_data.B.TXDATA = e->idle_char;
0555 mpc55xx_dspi_store_push_data( e);
0556 tcd_transmit.SADDR = mpc55xx_dspi_push_data_address( e);
0557 tcd_transmit.SDF.B.SSIZE = 2;
0558 tcd_transmit.SDF.B.SOFF = 0;
0559 tcd_transmit.DADDR = (uint32_t) push;
0560 tcd_transmit.SDF.B.DSIZE = 2;
0561 tcd_transmit.CDF.B.DOFF = 0;
0562 tcd_transmit.NBYTES = 4;
0563 tcd_transmit.CDF.B.CITER = n_c;
0564 tcd_transmit.BMF.B.BITER = n_c;
0565 } else {
0566 unsigned push_channel = mpc55xx_edma_channel_by_tcd( e->edma_push.edma.edma_tcd);
0567 mpc55xx_edma_clear_done( e->edma_transmit.edma.edma_tcd);
0568 tcd_transmit.SADDR = (uint32_t) out_c;
0569 tcd_transmit.SDF.B.SSIZE = 0;
0570 tcd_transmit.SDF.B.SOFF = 1;
0571 tcd_transmit.DADDR = mpc55xx_dspi_push_data_address( e) + 3;
0572 tcd_transmit.SDF.B.DSIZE = 0;
0573 tcd_transmit.CDF.B.DOFF = 0;
0574 tcd_transmit.NBYTES = 1;
0575 tcd_transmit.CDF.B.CITERE_LINK = 1;
0576 tcd_transmit.BMF.B.BITERE_LINK = 1;
0577 tcd_transmit.BMF.B.MAJORLINKCH = push_channel;
0578 tcd_transmit.CDF.B.CITER = EDMA_TCD_LINK_AND_BITER( push_channel, n_c);
0579 tcd_transmit.BMF.B.BITER = EDMA_TCD_LINK_AND_BITER( push_channel, n_c);
0580 tcd_transmit.BMF.B.MAJORE_LINK = 1;
0581 }
0582 tcd_transmit.BMF.B.D_REQ = 1;
0583 tcd_transmit.BMF.B.INT_MAJ = 1;
0584 *e->edma_transmit.edma.edma_tcd = tcd_transmit;
0585
0586
0587 if (in == NULL) {
0588 tcd_receive.CDF.B.DOFF = 0;
0589 tcd_receive.DADDR = mpc55xx_dspi_nirvana_address( e);
0590 } else {
0591 tcd_receive.CDF.B.DOFF = 1;
0592 tcd_receive.DADDR = (uint32_t) in_c;
0593 }
0594 tcd_receive.SADDR = (uint32_t) pop + 3;
0595 tcd_receive.SDF.B.SSIZE = 0;
0596 tcd_receive.SDF.B.SOFF = 0;
0597 tcd_receive.SDF.B.DSIZE = 0;
0598 tcd_receive.NBYTES = 1;
0599 tcd_receive.BMF.B.D_REQ = 1;
0600 tcd_receive.BMF.B.INT_MAJ = 1;
0601 tcd_receive.CDF.B.CITER = n_c;
0602 tcd_receive.BMF.B.BITER = n_c;
0603 *e->edma_receive.edma.edma_tcd = tcd_receive;
0604
0605
0606 sr.R = 0;
0607 sr.B.TFFF = 1;
0608 sr.B.RFDF = 1;
0609 status->R = sr.R;
0610
0611
0612 mpc55xx_edma_enable_hardware_requests( e->edma_receive.edma.edma_tcd);
0613 mpc55xx_edma_enable_hardware_requests( e->edma_transmit.edma.edma_tcd);
0614
0615
0616 sc = rtems_semaphore_obtain( e->edma_transmit.id, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0617 RTEMS_CHECK_SC_RV( sc, "transmit update");
0618
0619
0620 sc = rtems_semaphore_obtain( e->edma_receive.id, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0621 RTEMS_CHECK_SC_RV( sc, "receive update");
0622 }
0623
0624 return n;
0625 }
0626
0627
0628
0629
0630
0631
0632
0633
0634 static int mpc55xx_dspi_read( rtems_libi2c_bus_t *bus, unsigned char *in, int n)
0635 {
0636 return mpc55xx_dspi_read_write( bus, in, NULL, n);
0637 }
0638
0639
0640
0641
0642
0643
0644
0645
0646 static int mpc55xx_dspi_write( rtems_libi2c_bus_t *bus, unsigned char *out, int n)
0647 {
0648 return mpc55xx_dspi_read_write( bus, NULL, out, n);
0649 }
0650
0651 static int mpc55xx_dspi_ioctl( rtems_libi2c_bus_t *bus, int cmd, void *arg)
0652 {
0653 int rv = -1;
0654 switch (cmd) {
0655 case RTEMS_LIBI2C_IOCTL_SET_TFRMODE:
0656 rv = mpc55xx_dspi_set_transfer_mode( bus, (const rtems_libi2c_tfr_mode_t *) arg);
0657 break;
0658 case RTEMS_LIBI2C_IOCTL_READ_WRITE:
0659 rv = mpc55xx_dspi_read_write(
0660 bus,
0661 ((rtems_libi2c_read_write_t *) arg)->rd_buf,
0662 ((rtems_libi2c_read_write_t *) arg)->wr_buf,
0663 ((rtems_libi2c_read_write_t *) arg)->byte_cnt
0664 );
0665 break;
0666 default:
0667 rv = -RTEMS_NOT_DEFINED;
0668 break;
0669 }
0670 return rv;
0671 }
0672
0673 static const rtems_libi2c_bus_ops_t mpc55xx_dspi_ops = {
0674 .init = mpc55xx_dspi_init,
0675 .send_start = mpc55xx_dspi_send_start,
0676 .send_stop = mpc55xx_dspi_send_stop,
0677 .send_addr = mpc55xx_dspi_send_addr,
0678 .read_bytes = mpc55xx_dspi_read,
0679 .write_bytes = mpc55xx_dspi_write,
0680 .ioctl = mpc55xx_dspi_ioctl
0681 };
0682
0683 mpc55xx_dspi_bus_entry mpc55xx_dspi_bus_table [MPC55XX_DSPI_NUMBER] = {
0684 {
0685
0686 .bus = {
0687 .ops = &mpc55xx_dspi_ops,
0688 .size = sizeof( mpc55xx_dspi_bus_entry)
0689 },
0690 .table_index = 0,
0691 .bus_number = 0,
0692 .regs = &DSPI_A,
0693 .master = true,
0694 .push_data = MPC55XX_ZERO_FLAGS,
0695 .edma_transmit = {
0696 .edma = {
0697 .edma_tcd = EDMA_TCD_BY_CHANNEL_INDEX(EDMA_DSPI_A_SR_TFFF),
0698 .done = mpc55xx_dspi_edma_done
0699 },
0700 .id = RTEMS_ID_NONE
0701 },
0702 .edma_push = {
0703 .edma = {
0704 .edma_tcd = &EDMA.TCD [43],
0705 .done = mpc55xx_dspi_edma_done
0706 },
0707 .id = RTEMS_ID_NONE
0708 },
0709 .edma_receive = {
0710 .edma = {
0711 .edma_tcd = EDMA_TCD_BY_CHANNEL_INDEX(EDMA_DSPI_A_SR_RFDF),
0712 .done = mpc55xx_dspi_edma_done
0713 },
0714 .id = RTEMS_ID_NONE
0715 },
0716 .idle_char = 0xffffffff,
0717 .baud = 0
0718 }, {
0719
0720 .bus = {
0721 .ops = &mpc55xx_dspi_ops,
0722 .size = sizeof( mpc55xx_dspi_bus_entry)
0723 },
0724 .table_index = 1,
0725 .bus_number = 0,
0726 .regs = &DSPI_B,
0727 .master = true,
0728 .push_data = MPC55XX_ZERO_FLAGS,
0729 .edma_transmit = {
0730 .edma = {
0731 .edma_tcd = EDMA_TCD_BY_CHANNEL_INDEX(EDMA_DSPI_B_SR_TFFF),
0732 .done = mpc55xx_dspi_edma_done
0733 },
0734 .id = RTEMS_ID_NONE
0735 },
0736 .edma_push = {
0737 .edma = {
0738 .edma_tcd = &EDMA.TCD [10],
0739 .done = mpc55xx_dspi_edma_done
0740 },
0741 .id = RTEMS_ID_NONE
0742 },
0743 .edma_receive = {
0744 .edma = {
0745 .edma_tcd = EDMA_TCD_BY_CHANNEL_INDEX(EDMA_DSPI_B_SR_RFDF),
0746 .done = mpc55xx_dspi_edma_done
0747 },
0748 .id = RTEMS_ID_NONE
0749 },
0750 .idle_char = 0xffffffff,
0751 .baud = 0
0752 }, {
0753
0754 .bus = {
0755 .ops = &mpc55xx_dspi_ops,
0756 .size = sizeof( mpc55xx_dspi_bus_entry)
0757 },
0758 .table_index = 2,
0759 .bus_number = 0,
0760 .regs = &DSPI_C,
0761 .master = true,
0762 .push_data = MPC55XX_ZERO_FLAGS,
0763 .edma_transmit = {
0764 .edma = {
0765 .edma_tcd = EDMA_TCD_BY_CHANNEL_INDEX(EDMA_DSPI_C_SR_TFFF),
0766 .done = mpc55xx_dspi_edma_done
0767 },
0768 .id = RTEMS_ID_NONE
0769 },
0770 .edma_push = {
0771 .edma = {
0772 .edma_tcd = &EDMA.TCD [11],
0773 .done = mpc55xx_dspi_edma_done
0774 },
0775 .id = RTEMS_ID_NONE
0776 },
0777 .edma_receive = {
0778 .edma = {
0779 .edma_tcd = EDMA_TCD_BY_CHANNEL_INDEX(EDMA_DSPI_C_SR_RFDF),
0780 .done = mpc55xx_dspi_edma_done
0781 },
0782 .id = RTEMS_ID_NONE
0783 },
0784 .idle_char = 0xffffffff,
0785 .baud = 0
0786 #ifdef DSPI_D
0787 }, {
0788
0789 .bus = {
0790 .ops = &mpc55xx_dspi_ops,
0791 .size = sizeof( mpc55xx_dspi_bus_entry)
0792 },
0793 .table_index = 3,
0794 .bus_number = 0,
0795 .regs = &DSPI_D,
0796 .master = true,
0797 .push_data = MPC55XX_ZERO_FLAGS,
0798 .edma_transmit = {
0799 .edma = {
0800 .edma_tcd = EDMA_TCD_BY_CHANNEL_INDEX(EDMA_DSPI_D_SR_TFFF),
0801 .done = mpc55xx_dspi_edma_done
0802 },
0803 .id = RTEMS_ID_NONE
0804 },
0805 .edma_push = {
0806 .edma = {
0807 .edma_tcd = &EDMA.TCD [18],
0808 .done = mpc55xx_dspi_edma_done
0809 },
0810 .id = RTEMS_ID_NONE
0811 },
0812 .edma_receive = {
0813 .edma = {
0814 .edma_tcd = EDMA_TCD_BY_CHANNEL_INDEX(EDMA_DSPI_D_SR_RFDF),
0815 .done = mpc55xx_dspi_edma_done
0816 },
0817 .id = RTEMS_ID_NONE
0818 },
0819 .idle_char = 0xffffffff,
0820 .baud = 0
0821 #endif
0822 }
0823 };