[574fb67] | 1 | /** |
---|
| 2 | * @file |
---|
| 3 | * |
---|
| 4 | * @ingroup mpc55xx_dspi |
---|
| 5 | * |
---|
| 6 | * @brief Source file for the LibI2C bus driver for the Deserial Serial Peripheral Interface (DSPI). |
---|
| 7 | */ |
---|
| 8 | |
---|
| 9 | /* |
---|
| 10 | * Copyright (c) 2008 |
---|
| 11 | * Embedded Brains GmbH |
---|
| 12 | * Obere Lagerstr. 30 |
---|
| 13 | * D-82178 Puchheim |
---|
| 14 | * Germany |
---|
| 15 | * rtems@embedded-brains.de |
---|
| 16 | * |
---|
[0e27119] | 17 | * The license and distribution terms for this file may be |
---|
| 18 | * found in the file LICENSE in this distribution or at |
---|
[c499856] | 19 | * http://www.rtems.org/license/LICENSE. |
---|
[574fb67] | 20 | */ |
---|
| 21 | |
---|
| 22 | #include <mpc55xx/regs.h> |
---|
| 23 | #include <mpc55xx/dspi.h> |
---|
| 24 | #include <mpc55xx/mpc55xx.h> |
---|
| 25 | |
---|
[97fa2f1b] | 26 | #include <bsp/irq.h> |
---|
| 27 | |
---|
[574fb67] | 28 | #include <libcpu/powerpc-utility.h> |
---|
| 29 | |
---|
| 30 | #define RTEMS_STATUS_CHECKS_USE_PRINTK |
---|
| 31 | |
---|
| 32 | #include <rtems/status-checks.h> |
---|
| 33 | |
---|
| 34 | #define MPC55XX_DSPI_FIFO_SIZE 4 |
---|
| 35 | |
---|
| 36 | #define MPC55XX_DSPI_CTAR_NUMBER 8 |
---|
| 37 | |
---|
| 38 | #define MPC55XX_DSPI_CTAR_DEFAULT 0 |
---|
| 39 | |
---|
| 40 | #define MPC55XX_DSPI_EDMA_MAGIC_SIZE 128 |
---|
| 41 | |
---|
| 42 | #define MPC55XX_DSPI_BAUDRATE_SCALER_TABLE_SIZE 63 |
---|
| 43 | |
---|
| 44 | typedef struct { |
---|
| 45 | uint32_t scaler : 26; |
---|
| 46 | uint32_t pbr : 2; |
---|
| 47 | uint32_t br : 4; |
---|
| 48 | } mpc55xx_dspi_baudrate_scaler_entry; |
---|
| 49 | |
---|
| 50 | static const mpc55xx_dspi_baudrate_scaler_entry mpc55xx_dspi_baudrate_scaler_table [MPC55XX_DSPI_BAUDRATE_SCALER_TABLE_SIZE] = { |
---|
| 51 | { 4, 0, 0 }, |
---|
| 52 | { 6, 1, 0 }, |
---|
| 53 | { 8, 0, 1 }, |
---|
| 54 | { 10, 2, 0 }, |
---|
| 55 | { 12, 1, 1 }, |
---|
| 56 | { 14, 3, 0 }, |
---|
| 57 | { 16, 0, 3 }, |
---|
| 58 | { 18, 1, 2 }, |
---|
| 59 | { 20, 2, 1 }, |
---|
| 60 | { 24, 1, 3 }, |
---|
| 61 | { 28, 3, 1 }, |
---|
| 62 | { 30, 2, 2 }, |
---|
| 63 | { 32, 0, 4 }, |
---|
| 64 | { 40, 2, 3 }, |
---|
| 65 | { 42, 3, 2 }, |
---|
| 66 | { 48, 1, 4 }, |
---|
| 67 | { 56, 3, 3 }, |
---|
| 68 | { 64, 0, 5 }, |
---|
| 69 | { 80, 2, 4 }, |
---|
| 70 | { 96, 1, 5 }, |
---|
| 71 | { 112, 3, 4 }, |
---|
| 72 | { 128, 0, 6 }, |
---|
| 73 | { 160, 2, 5 }, |
---|
| 74 | { 192, 1, 6 }, |
---|
| 75 | { 224, 3, 5 }, |
---|
| 76 | { 256, 0, 7 }, |
---|
| 77 | { 320, 2, 6 }, |
---|
| 78 | { 384, 1, 7 }, |
---|
| 79 | { 448, 3, 6 }, |
---|
| 80 | { 512, 0, 8 }, |
---|
| 81 | { 640, 2, 7 }, |
---|
| 82 | { 768, 1, 8 }, |
---|
| 83 | { 896, 3, 7 }, |
---|
| 84 | { 1024, 0, 9 }, |
---|
| 85 | { 1280, 2, 8 }, |
---|
| 86 | { 1536, 1, 9 }, |
---|
| 87 | { 1792, 3, 8 }, |
---|
| 88 | { 2048, 0, 10 }, |
---|
| 89 | { 2560, 2, 9 }, |
---|
| 90 | { 3072, 1, 10 }, |
---|
| 91 | { 3584, 3, 9 }, |
---|
| 92 | { 4096, 0, 11 }, |
---|
| 93 | { 5120, 2, 10 }, |
---|
| 94 | { 6144, 1, 11 }, |
---|
| 95 | { 7168, 3, 10 }, |
---|
| 96 | { 8192, 0, 12 }, |
---|
| 97 | { 10240, 2, 11 }, |
---|
| 98 | { 12288, 1, 12 }, |
---|
| 99 | { 14336, 3, 11 }, |
---|
| 100 | { 16384, 0, 13 }, |
---|
| 101 | { 20480, 2, 12 }, |
---|
| 102 | { 24576, 1, 13 }, |
---|
| 103 | { 28672, 3, 12 }, |
---|
| 104 | { 32768, 0, 14 }, |
---|
| 105 | { 40960, 2, 13 }, |
---|
| 106 | { 49152, 1, 14 }, |
---|
| 107 | { 57344, 3, 13 }, |
---|
| 108 | { 65536, 0, 15 }, |
---|
| 109 | { 81920, 2, 14 }, |
---|
| 110 | { 98304, 1, 15 }, |
---|
| 111 | { 114688, 3, 14 }, |
---|
| 112 | { 163840, 2, 15 }, |
---|
| 113 | { 229376, 3, 15 }, |
---|
| 114 | }; |
---|
| 115 | |
---|
[db21e1d] | 116 | static void mpc55xx_dspi_edma_done( edma_channel_context *ctx, uint32_t error_status) |
---|
[d374492] | 117 | { |
---|
[db21e1d] | 118 | const mpc55xx_dspi_edma_entry *e = (const mpc55xx_dspi_edma_entry *) ctx; |
---|
[d374492] | 119 | rtems_semaphore_release( e->id); |
---|
| 120 | |
---|
| 121 | if (error_status != 0) { |
---|
| 122 | RTEMS_SYSLOG_ERROR( "eDMA error: 0x%08x\n", error_status); |
---|
| 123 | } |
---|
| 124 | } |
---|
| 125 | |
---|
[574fb67] | 126 | static mpc55xx_dspi_baudrate_scaler_entry mpc55xx_dspi_search_baudrate_scaler( uint32_t scaler, int min, int mid, int max) |
---|
| 127 | { |
---|
| 128 | if (scaler <= mpc55xx_dspi_baudrate_scaler_table [mid].scaler) { |
---|
| 129 | max = mid; |
---|
| 130 | } else { |
---|
| 131 | min = mid; |
---|
| 132 | } |
---|
| 133 | mid = (min + max) / 2; |
---|
| 134 | if (mid == min) { |
---|
| 135 | return mpc55xx_dspi_baudrate_scaler_table [max]; |
---|
| 136 | } else { |
---|
| 137 | return mpc55xx_dspi_search_baudrate_scaler( scaler, min, mid, max); |
---|
| 138 | } |
---|
| 139 | } |
---|
| 140 | |
---|
| 141 | static uint32_t mpc55xx_dspi_push_data [8 * MPC55XX_DSPI_NUMBER] __attribute__ ((aligned (32))); |
---|
| 142 | |
---|
| 143 | static inline void mpc55xx_dspi_store_push_data( mpc55xx_dspi_bus_entry *e) |
---|
| 144 | { |
---|
| 145 | mpc55xx_dspi_push_data [e->table_index * 8] = e->push_data.R; |
---|
| 146 | rtems_cache_flush_multiple_data_lines( &mpc55xx_dspi_push_data [e->table_index * 8], 4); |
---|
| 147 | } |
---|
| 148 | |
---|
| 149 | static inline uint32_t mpc55xx_dspi_push_data_address( mpc55xx_dspi_bus_entry *e) |
---|
| 150 | { |
---|
| 151 | return (uint32_t) &mpc55xx_dspi_push_data [e->table_index * 8]; |
---|
| 152 | } |
---|
| 153 | |
---|
| 154 | static inline uint32_t mpc55xx_dspi_nirvana_address( mpc55xx_dspi_bus_entry *e) |
---|
| 155 | { |
---|
| 156 | return (uint32_t) &mpc55xx_dspi_push_data [e->table_index * 8 + 1]; |
---|
| 157 | } |
---|
| 158 | |
---|
| 159 | static rtems_status_code mpc55xx_dspi_init( rtems_libi2c_bus_t *bus) |
---|
| 160 | { |
---|
| 161 | rtems_status_code sc = RTEMS_SUCCESSFUL; |
---|
| 162 | mpc55xx_dspi_bus_entry *e = (mpc55xx_dspi_bus_entry *) bus; |
---|
| 163 | union DSPI_MCR_tag mcr = MPC55XX_ZERO_FLAGS; |
---|
| 164 | union DSPI_CTAR_tag ctar = MPC55XX_ZERO_FLAGS; |
---|
| 165 | union DSPI_RSER_tag rser = MPC55XX_ZERO_FLAGS; |
---|
[d374492] | 166 | struct tcd_t tcd_push = EDMA_TCD_DEFAULT; |
---|
[574fb67] | 167 | int i = 0; |
---|
| 168 | |
---|
| 169 | /* eDMA receive */ |
---|
| 170 | sc = rtems_semaphore_create ( |
---|
| 171 | rtems_build_name ( 'S', 'P', 'I', 'R'), |
---|
| 172 | 0, |
---|
[d374492] | 173 | RTEMS_SIMPLE_BINARY_SEMAPHORE, |
---|
| 174 | 0, |
---|
| 175 | &e->edma_receive.id |
---|
[574fb67] | 176 | ); |
---|
[d374492] | 177 | RTEMS_CHECK_SC( sc, "create receive update semaphore"); |
---|
[574fb67] | 178 | |
---|
[db21e1d] | 179 | sc = mpc55xx_edma_obtain_channel( &e->edma_receive.edma, MPC55XX_INTC_DEFAULT_PRIORITY); |
---|
[d374492] | 180 | RTEMS_CHECK_SC( sc, "obtain receive eDMA channel"); |
---|
[574fb67] | 181 | |
---|
| 182 | /* eDMA transmit */ |
---|
| 183 | sc = rtems_semaphore_create ( |
---|
| 184 | rtems_build_name ( 'S', 'P', 'I', 'T'), |
---|
| 185 | 0, |
---|
[d374492] | 186 | RTEMS_SIMPLE_BINARY_SEMAPHORE, |
---|
| 187 | 0, |
---|
| 188 | &e->edma_transmit.id |
---|
[574fb67] | 189 | ); |
---|
[d374492] | 190 | RTEMS_CHECK_SC( sc, "create transmit update semaphore"); |
---|
[574fb67] | 191 | |
---|
[db21e1d] | 192 | sc = mpc55xx_edma_obtain_channel( &e->edma_transmit.edma, MPC55XX_INTC_DEFAULT_PRIORITY); |
---|
[d374492] | 193 | RTEMS_CHECK_SC( sc, "obtain transmit eDMA channel"); |
---|
[574fb67] | 194 | |
---|
[db21e1d] | 195 | sc = mpc55xx_edma_obtain_channel( &e->edma_push.edma, MPC55XX_INTC_DEFAULT_PRIORITY); |
---|
[d374492] | 196 | RTEMS_CHECK_SC( sc, "obtain push eDMA channel"); |
---|
[574fb67] | 197 | |
---|
| 198 | tcd_push.SADDR = mpc55xx_dspi_push_data_address( e); |
---|
[d374492] | 199 | tcd_push.SDF.B.SSIZE = 2; |
---|
| 200 | tcd_push.SDF.B.SOFF = 0; |
---|
[574fb67] | 201 | tcd_push.DADDR = (uint32_t) &e->regs->PUSHR.R; |
---|
[d374492] | 202 | tcd_push.SDF.B.DSIZE = 2; |
---|
| 203 | tcd_push.CDF.B.DOFF = 0; |
---|
[574fb67] | 204 | tcd_push.NBYTES = 4; |
---|
[d374492] | 205 | tcd_push.CDF.B.CITER = 1; |
---|
| 206 | tcd_push.BMF.B.BITER = 1; |
---|
[574fb67] | 207 | |
---|
[db21e1d] | 208 | *e->edma_push.edma.edma_tcd = tcd_push; |
---|
[574fb67] | 209 | |
---|
| 210 | /* Module Control Register */ |
---|
| 211 | mcr.B.MSTR = e->master ? 1 : 0; |
---|
| 212 | mcr.B.CONT_SCKE = 0; |
---|
| 213 | mcr.B.DCONF = 0; |
---|
| 214 | mcr.B.FRZ = 0; |
---|
| 215 | mcr.B.MTFE = 0; |
---|
| 216 | mcr.B.PCSSE = 0; |
---|
| 217 | mcr.B.ROOE = 0; |
---|
| 218 | mcr.B.PCSIS0 = 1; |
---|
| 219 | mcr.B.PCSIS1 = 1; |
---|
| 220 | mcr.B.PCSIS2 = 1; |
---|
| 221 | mcr.B.PCSIS3 = 1; |
---|
| 222 | mcr.B.PCSIS5 = 1; |
---|
| 223 | mcr.B.MDIS = 0; |
---|
| 224 | mcr.B.DIS_TXF = 0; |
---|
| 225 | mcr.B.DIS_RXF = 0; |
---|
| 226 | mcr.B.CLR_TXF = 0; |
---|
| 227 | mcr.B.CLR_RXF = 0; |
---|
| 228 | mcr.B.SMPL_PT = 0; |
---|
| 229 | mcr.B.HALT = 0; |
---|
| 230 | |
---|
| 231 | e->regs->MCR.R = mcr.R; |
---|
| 232 | |
---|
| 233 | /* Clock and Transfer Attributes Register */ |
---|
| 234 | ctar.B.DBR = 0; |
---|
| 235 | ctar.B.FMSZ = 0x7; |
---|
| 236 | ctar.B.CPOL = 0; |
---|
| 237 | ctar.B.CPHA = 0; |
---|
| 238 | ctar.B.LSBFE = 0; |
---|
| 239 | ctar.B.PCSSCK = 0; |
---|
| 240 | ctar.B.PASC = 0; |
---|
| 241 | ctar.B.PDT = 0; |
---|
| 242 | ctar.B.PBR = 0; |
---|
| 243 | ctar.B.CSSCK = 0; |
---|
| 244 | ctar.B.ASC = 0; |
---|
| 245 | ctar.B.DT = 0; |
---|
| 246 | ctar.B.BR = 0; |
---|
| 247 | |
---|
| 248 | for (i = 0; i < MPC55XX_DSPI_CTAR_NUMBER; ++i) { |
---|
| 249 | e->regs->CTAR [i].R = ctar.R; |
---|
| 250 | } |
---|
| 251 | |
---|
[db21e1d] | 252 | /* DMA/Interrupt Request Select and Enable Register */ |
---|
[574fb67] | 253 | rser.B.TFFFRE = 1; |
---|
| 254 | rser.B.TFFFDIRS = 1; |
---|
| 255 | rser.B.RFDFRE = 1; |
---|
| 256 | rser.B.RFDFDIRS = 1; |
---|
| 257 | |
---|
| 258 | e->regs->RSER.R = rser.R; |
---|
| 259 | |
---|
| 260 | return RTEMS_SUCCESSFUL; |
---|
| 261 | } |
---|
| 262 | |
---|
| 263 | static rtems_status_code mpc55xx_dspi_send_start( rtems_libi2c_bus_t *bus) |
---|
| 264 | { |
---|
| 265 | mpc55xx_dspi_bus_entry *e = (mpc55xx_dspi_bus_entry *) bus; |
---|
| 266 | |
---|
| 267 | /* Reset chip selects */ |
---|
| 268 | e->push_data.B.PCS0 = 0; |
---|
| 269 | e->push_data.B.PCS1 = 0; |
---|
| 270 | e->push_data.B.PCS2 = 0; |
---|
| 271 | e->push_data.B.PCS3 = 0; |
---|
| 272 | e->push_data.B.PCS4 = 0; |
---|
| 273 | e->push_data.B.PCS5 = 0; |
---|
| 274 | mpc55xx_dspi_store_push_data( e); |
---|
| 275 | |
---|
| 276 | return RTEMS_SUCCESSFUL; |
---|
| 277 | } |
---|
| 278 | |
---|
| 279 | static rtems_status_code mpc55xx_dspi_send_stop( rtems_libi2c_bus_t *bus) |
---|
| 280 | { |
---|
| 281 | return RTEMS_SUCCESSFUL; |
---|
| 282 | } |
---|
| 283 | |
---|
| 284 | static rtems_status_code mpc55xx_dspi_send_addr( rtems_libi2c_bus_t *bus, uint32_t addr, int rw) |
---|
| 285 | { |
---|
| 286 | mpc55xx_dspi_bus_entry *e = (mpc55xx_dspi_bus_entry *) bus; |
---|
| 287 | union DSPI_SR_tag sr = MPC55XX_ZERO_FLAGS; |
---|
| 288 | |
---|
| 289 | /* Flush transmit and receive FIFO */ |
---|
| 290 | e->regs->MCR.B.CLR_TXF = 1; |
---|
| 291 | e->regs->MCR.B.CLR_RXF = 1; |
---|
| 292 | |
---|
| 293 | /* Clear status flags */ |
---|
| 294 | sr.B.EOQF = 1; |
---|
| 295 | sr.B.TFFF = 1; |
---|
| 296 | sr.B.RFDF = 1; |
---|
| 297 | e->regs->SR.R = sr.R; |
---|
| 298 | |
---|
| 299 | /* Frame command */ |
---|
| 300 | e->push_data.R = 0; |
---|
| 301 | e->push_data.B.CONT = 0; |
---|
| 302 | e->push_data.B.CTAS = MPC55XX_DSPI_CTAR_DEFAULT; |
---|
| 303 | e->push_data.B.EOQ = 0; |
---|
| 304 | e->push_data.B.CTCNT = 0; |
---|
| 305 | switch (addr) { |
---|
| 306 | case 0: |
---|
| 307 | e->push_data.B.PCS0 = 1; |
---|
| 308 | break; |
---|
| 309 | case 1: |
---|
| 310 | e->push_data.B.PCS1 = 1; |
---|
| 311 | break; |
---|
| 312 | case 2: |
---|
| 313 | e->push_data.B.PCS2 = 1; |
---|
| 314 | break; |
---|
| 315 | case 3: |
---|
| 316 | e->push_data.B.PCS3 = 1; |
---|
| 317 | break; |
---|
| 318 | case 4: |
---|
| 319 | e->push_data.B.PCS4 = 1; |
---|
| 320 | break; |
---|
| 321 | case 5: |
---|
| 322 | e->push_data.B.PCS5 = 1; |
---|
| 323 | break; |
---|
| 324 | default: |
---|
| 325 | return -RTEMS_INVALID_ADDRESS; |
---|
| 326 | } |
---|
| 327 | mpc55xx_dspi_store_push_data( e); |
---|
| 328 | |
---|
| 329 | return RTEMS_SUCCESSFUL; |
---|
| 330 | } |
---|
| 331 | |
---|
[1dab788] | 332 | /* FIXME, TODO */ |
---|
| 333 | extern uint32_t bsp_clock_speed; |
---|
| 334 | |
---|
[574fb67] | 335 | static int mpc55xx_dspi_set_transfer_mode( rtems_libi2c_bus_t *bus, const rtems_libi2c_tfr_mode_t *mode) |
---|
| 336 | { |
---|
| 337 | mpc55xx_dspi_bus_entry *e = (mpc55xx_dspi_bus_entry *) bus; |
---|
| 338 | union DSPI_CTAR_tag ctar = MPC55XX_ZERO_FLAGS; |
---|
| 339 | |
---|
| 340 | if (mode->bits_per_char != 8) { |
---|
| 341 | return -RTEMS_INVALID_NUMBER; |
---|
| 342 | } |
---|
| 343 | |
---|
| 344 | e->idle_char = mode->idle_char; |
---|
| 345 | |
---|
| 346 | ctar.R = e->regs->CTAR [MPC55XX_DSPI_CTAR_DEFAULT].R; |
---|
| 347 | |
---|
| 348 | ctar.B.PCSSCK = 0; |
---|
| 349 | ctar.B.CSSCK = 0; |
---|
| 350 | ctar.B.PASC = 0; |
---|
| 351 | ctar.B.ASC = 0; |
---|
| 352 | |
---|
| 353 | ctar.B.LSBFE = mode->lsb_first ? 1 : 0; |
---|
| 354 | ctar.B.CPOL = mode->clock_inv ? 1 : 0; |
---|
| 355 | ctar.B.CPHA = mode->clock_phs ? 1 : 0; |
---|
| 356 | |
---|
[d374492] | 357 | if (mode->baudrate != e->baud) { |
---|
| 358 | uint32_t scaler = bsp_clock_speed / mode->baudrate; |
---|
| 359 | 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); |
---|
| 360 | |
---|
| 361 | ctar.B.PBR = bse.pbr; |
---|
| 362 | ctar.B.BR = bse.br; |
---|
| 363 | |
---|
| 364 | e->baud = mode->baudrate; |
---|
| 365 | } |
---|
| 366 | |
---|
[574fb67] | 367 | e->regs->CTAR [MPC55XX_DSPI_CTAR_DEFAULT].R = ctar.R; |
---|
| 368 | |
---|
| 369 | return 0; |
---|
| 370 | } |
---|
| 371 | |
---|
| 372 | /** |
---|
| 373 | * @brief Writes @a n characters from @a out to bus @a bus and synchronously stores the received data in @a in. |
---|
| 374 | * |
---|
| 375 | * eDMA channel usage for transmission: |
---|
| 376 | * @dot |
---|
| 377 | * digraph push { |
---|
| 378 | * push [label="Push Register"]; |
---|
| 379 | * push_data [label="Push Data"]; |
---|
| 380 | * idle_push_data [label="Idle Push Data"]; |
---|
| 381 | * out [shape=box,label="Output Buffer"]; |
---|
| 382 | * edge [color=red,fontcolor=red]; |
---|
[d374492] | 383 | * push -> idle_push_data [label="Transmit Request",URL="\ref mpc55xx_dspi_bus_entry::edma_transmit"]; |
---|
| 384 | * push -> out [label="Transmit Request",URL="\ref mpc55xx_dspi_bus_entry::edma_transmit"]; |
---|
| 385 | * out -> push_data [label="Channel Link",URL="\ref mpc55xx_dspi_bus_entry::edma_push"]; |
---|
[574fb67] | 386 | * edge [color=blue,fontcolor=blue]; |
---|
| 387 | * out -> push_data [label="Data"]; |
---|
| 388 | * push_data -> push [label="Data"]; |
---|
| 389 | * idle_push_data -> push [label="Data"]; |
---|
| 390 | * } |
---|
| 391 | * @enddot |
---|
| 392 | * |
---|
| 393 | * eDMA channel usage for receiving: |
---|
| 394 | * @dot |
---|
| 395 | * digraph pop { |
---|
| 396 | * pop [label="Pop Register"]; |
---|
| 397 | * nirvana [label="Nirvana"]; |
---|
| 398 | * in [shape=box,label="Input Buffer"]; |
---|
| 399 | * edge [color=red,fontcolor=red]; |
---|
[d374492] | 400 | * pop -> nirvana [label="Receive Request",URL="\ref mpc55xx_dspi_bus_entry::edma_receive"]; |
---|
| 401 | * pop -> in [label="Receive Request",URL="\ref mpc55xx_dspi_bus_entry::edma_receive"]; |
---|
[574fb67] | 402 | * edge [color=blue,fontcolor=blue]; |
---|
| 403 | * pop -> nirvana [label="Data"]; |
---|
| 404 | * pop -> in [label="Data"]; |
---|
| 405 | * } |
---|
| 406 | * @enddot |
---|
| 407 | */ |
---|
| 408 | static int mpc55xx_dspi_read_write( rtems_libi2c_bus_t *bus, unsigned char *in, const unsigned char *out, int n) |
---|
| 409 | { |
---|
| 410 | mpc55xx_dspi_bus_entry *e = (mpc55xx_dspi_bus_entry *) bus; |
---|
| 411 | |
---|
| 412 | /* Non cache aligned characters */ |
---|
| 413 | int n_nc = n; |
---|
| 414 | |
---|
| 415 | /* Cache aligned characters */ |
---|
| 416 | int n_c = 0; |
---|
| 417 | |
---|
| 418 | /* Register addresses */ |
---|
| 419 | volatile void *push = &e->regs->PUSHR.R; |
---|
| 420 | volatile void *pop = &e->regs->POPR.R; |
---|
| 421 | volatile union DSPI_SR_tag *status = &e->regs->SR; |
---|
| 422 | |
---|
| 423 | /* Push and pop data */ |
---|
| 424 | union DSPI_PUSHR_tag push_data = e->push_data; |
---|
| 425 | union DSPI_POPR_tag pop_data; |
---|
| 426 | |
---|
| 427 | /* Status register */ |
---|
| 428 | union DSPI_SR_tag sr; |
---|
| 429 | |
---|
| 430 | /* Read and write indices */ |
---|
| 431 | int r = 0; |
---|
| 432 | int w = 0; |
---|
| 433 | |
---|
| 434 | if (n == 0) { |
---|
| 435 | return 0; |
---|
| 436 | } else if (in == NULL && out == NULL) { |
---|
| 437 | return -RTEMS_INVALID_ADDRESS; |
---|
| 438 | } |
---|
| 439 | |
---|
| 440 | if (n > MPC55XX_DSPI_EDMA_MAGIC_SIZE) { |
---|
[1dab788] | 441 | n_nc = (int) mpc55xx_non_cache_aligned_size( in); |
---|
| 442 | n_c = (int) mpc55xx_cache_aligned_size( in, (size_t) n); |
---|
[574fb67] | 443 | if (n_c > EDMA_TCD_BITER_LINKED_SIZE) { |
---|
[d374492] | 444 | RTEMS_SYSLOG_WARNING( "buffer size out of range, cannot use eDMA\n"); |
---|
[574fb67] | 445 | n_nc = n; |
---|
| 446 | n_c = 0; |
---|
| 447 | } else if (n_nc + n_c != n) { |
---|
[d374492] | 448 | RTEMS_SYSLOG_WARNING( "input buffer not proper cache aligned, cannot use eDMA\n"); |
---|
[574fb67] | 449 | n_nc = n; |
---|
| 450 | n_c = 0; |
---|
| 451 | } |
---|
| 452 | } |
---|
| 453 | |
---|
| 454 | #ifdef DEBUG |
---|
| 455 | if (e->regs->SR.B.TXCTR != e->regs->SR.B.RXCTR) { |
---|
[602aee20] | 456 | RTEMS_SYSLOG_WARNING( "FIFO counter not equal\n"); |
---|
[574fb67] | 457 | } |
---|
| 458 | #endif /* DEBUG */ |
---|
| 459 | |
---|
| 460 | /* Direct IO */ |
---|
| 461 | if (out == NULL) { |
---|
| 462 | push_data.B.TXDATA = e->idle_char; |
---|
| 463 | while (r < n_nc || w < n_nc) { |
---|
| 464 | /* Wait for available FIFO */ |
---|
| 465 | do { |
---|
| 466 | sr.R = status->R; |
---|
| 467 | } while (sr.B.TXCTR == MPC55XX_DSPI_FIFO_SIZE && sr.B.RXCTR == 0); |
---|
| 468 | |
---|
| 469 | /* Write */ |
---|
| 470 | if (w < n_nc && (w - r) < MPC55XX_DSPI_FIFO_SIZE && sr.B.TXCTR != MPC55XX_DSPI_FIFO_SIZE) { |
---|
| 471 | ++w; |
---|
| 472 | ppc_write_word( push_data.R, push); |
---|
| 473 | } |
---|
| 474 | |
---|
| 475 | /* Read */ |
---|
| 476 | if (r < n_nc && sr.B.RXCTR != 0) { |
---|
| 477 | pop_data.R = ppc_read_word( pop); |
---|
[1dab788] | 478 | in [r] = (unsigned char) pop_data.B.RXDATA; |
---|
[574fb67] | 479 | ++r; |
---|
| 480 | } |
---|
| 481 | } |
---|
| 482 | } else if (in == NULL) { |
---|
| 483 | while (r < n_nc || w < n_nc) { |
---|
| 484 | /* Wait for available FIFO */ |
---|
| 485 | do { |
---|
| 486 | sr.R = status->R; |
---|
| 487 | } while (sr.B.TXCTR == MPC55XX_DSPI_FIFO_SIZE && sr.B.RXCTR == 0); |
---|
| 488 | |
---|
| 489 | /* Write */ |
---|
| 490 | if (w < n_nc && (w - r) < MPC55XX_DSPI_FIFO_SIZE && sr.B.TXCTR != MPC55XX_DSPI_FIFO_SIZE) { |
---|
| 491 | push_data.B.TXDATA = out [w]; |
---|
| 492 | ++w; |
---|
| 493 | ppc_write_word( push_data.R, push); |
---|
| 494 | } |
---|
| 495 | |
---|
| 496 | /* Read */ |
---|
| 497 | if (r < n_nc && sr.B.RXCTR != 0) { |
---|
| 498 | pop_data.R = ppc_read_word( pop); |
---|
| 499 | ++r; |
---|
| 500 | } |
---|
| 501 | } |
---|
| 502 | } else { |
---|
| 503 | while (r < n_nc || w < n_nc) { |
---|
| 504 | /* Wait for available FIFO */ |
---|
| 505 | do { |
---|
| 506 | sr.R = status->R; |
---|
| 507 | } while (sr.B.TXCTR == MPC55XX_DSPI_FIFO_SIZE && sr.B.RXCTR == 0); |
---|
| 508 | |
---|
| 509 | /* Write */ |
---|
| 510 | if (w < n_nc && (w - r) < MPC55XX_DSPI_FIFO_SIZE && sr.B.TXCTR != MPC55XX_DSPI_FIFO_SIZE) { |
---|
| 511 | push_data.B.TXDATA = out [w]; |
---|
| 512 | ++w; |
---|
| 513 | ppc_write_word( push_data.R, push); |
---|
| 514 | } |
---|
| 515 | |
---|
| 516 | /* Read */ |
---|
| 517 | if (r < n_nc && sr.B.RXCTR != 0) { |
---|
| 518 | pop_data.R = ppc_read_word( pop); |
---|
[1dab788] | 519 | in [r] = (unsigned char) pop_data.B.RXDATA; |
---|
[574fb67] | 520 | ++r; |
---|
| 521 | } |
---|
| 522 | } |
---|
| 523 | } |
---|
| 524 | |
---|
| 525 | /* eDMA transfers */ |
---|
| 526 | if (n_c > 0) { |
---|
| 527 | rtems_status_code sc = RTEMS_SUCCESSFUL; |
---|
| 528 | unsigned char *in_c = in + n_nc; |
---|
| 529 | const unsigned char *out_c = out + n_nc; |
---|
[d374492] | 530 | struct tcd_t tcd_transmit = EDMA_TCD_DEFAULT; |
---|
| 531 | struct tcd_t tcd_receive = EDMA_TCD_DEFAULT; |
---|
[574fb67] | 532 | |
---|
| 533 | /* Cache operations */ |
---|
[1dab788] | 534 | rtems_cache_flush_multiple_data_lines( out_c, (size_t) n_c); |
---|
| 535 | rtems_cache_invalidate_multiple_data_lines( in_c, (size_t) n_c); |
---|
[574fb67] | 536 | |
---|
| 537 | /* Set transmit TCD */ |
---|
| 538 | if (out == NULL) { |
---|
| 539 | e->push_data.B.TXDATA = e->idle_char; |
---|
| 540 | mpc55xx_dspi_store_push_data( e); |
---|
| 541 | tcd_transmit.SADDR = mpc55xx_dspi_push_data_address( e); |
---|
[d374492] | 542 | tcd_transmit.SDF.B.SSIZE = 2; |
---|
| 543 | tcd_transmit.SDF.B.SOFF = 0; |
---|
[574fb67] | 544 | tcd_transmit.DADDR = (uint32_t) push; |
---|
[d374492] | 545 | tcd_transmit.SDF.B.DSIZE = 2; |
---|
| 546 | tcd_transmit.CDF.B.DOFF = 0; |
---|
[574fb67] | 547 | tcd_transmit.NBYTES = 4; |
---|
[d374492] | 548 | tcd_transmit.CDF.B.CITER = n_c; |
---|
| 549 | tcd_transmit.BMF.B.BITER = n_c; |
---|
[574fb67] | 550 | } else { |
---|
[db21e1d] | 551 | unsigned push_channel = mpc55xx_edma_channel_by_tcd( e->edma_push.edma.edma_tcd); |
---|
| 552 | mpc55xx_edma_clear_done( e->edma_transmit.edma.edma_tcd); |
---|
[574fb67] | 553 | tcd_transmit.SADDR = (uint32_t) out_c; |
---|
[d374492] | 554 | tcd_transmit.SDF.B.SSIZE = 0; |
---|
| 555 | tcd_transmit.SDF.B.SOFF = 1; |
---|
[574fb67] | 556 | tcd_transmit.DADDR = mpc55xx_dspi_push_data_address( e) + 3; |
---|
[d374492] | 557 | tcd_transmit.SDF.B.DSIZE = 0; |
---|
| 558 | tcd_transmit.CDF.B.DOFF = 0; |
---|
[574fb67] | 559 | tcd_transmit.NBYTES = 1; |
---|
[d374492] | 560 | tcd_transmit.CDF.B.CITERE_LINK = 1; |
---|
| 561 | tcd_transmit.BMF.B.BITERE_LINK = 1; |
---|
[db21e1d] | 562 | tcd_transmit.BMF.B.MAJORLINKCH = push_channel; |
---|
| 563 | tcd_transmit.CDF.B.CITER = EDMA_TCD_LINK_AND_BITER( push_channel, n_c); |
---|
| 564 | tcd_transmit.BMF.B.BITER = EDMA_TCD_LINK_AND_BITER( push_channel, n_c); |
---|
[d374492] | 565 | tcd_transmit.BMF.B.MAJORE_LINK = 1; |
---|
[574fb67] | 566 | } |
---|
[d374492] | 567 | tcd_transmit.BMF.B.D_REQ = 1; |
---|
| 568 | tcd_transmit.BMF.B.INT_MAJ = 1; |
---|
[db21e1d] | 569 | *e->edma_transmit.edma.edma_tcd = tcd_transmit; |
---|
[574fb67] | 570 | |
---|
| 571 | /* Set receive TCD */ |
---|
| 572 | if (in == NULL) { |
---|
[d374492] | 573 | tcd_receive.CDF.B.DOFF = 0; |
---|
[574fb67] | 574 | tcd_receive.DADDR = mpc55xx_dspi_nirvana_address( e); |
---|
| 575 | } else { |
---|
[d374492] | 576 | tcd_receive.CDF.B.DOFF = 1; |
---|
[574fb67] | 577 | tcd_receive.DADDR = (uint32_t) in_c; |
---|
| 578 | } |
---|
| 579 | tcd_receive.SADDR = (uint32_t) pop + 3; |
---|
[d374492] | 580 | tcd_receive.SDF.B.SSIZE = 0; |
---|
| 581 | tcd_receive.SDF.B.SOFF = 0; |
---|
| 582 | tcd_receive.SDF.B.DSIZE = 0; |
---|
[574fb67] | 583 | tcd_receive.NBYTES = 1; |
---|
[d374492] | 584 | tcd_receive.BMF.B.D_REQ = 1; |
---|
| 585 | tcd_receive.BMF.B.INT_MAJ = 1; |
---|
| 586 | tcd_receive.CDF.B.CITER = n_c; |
---|
| 587 | tcd_receive.BMF.B.BITER = n_c; |
---|
[db21e1d] | 588 | *e->edma_receive.edma.edma_tcd = tcd_receive; |
---|
[574fb67] | 589 | |
---|
| 590 | /* Clear request flags */ |
---|
| 591 | sr.R = 0; |
---|
| 592 | sr.B.TFFF = 1; |
---|
| 593 | sr.B.RFDF = 1; |
---|
| 594 | status->R = sr.R; |
---|
| 595 | |
---|
| 596 | /* Enable hardware requests */ |
---|
[db21e1d] | 597 | mpc55xx_edma_enable_hardware_requests( e->edma_receive.edma.edma_tcd); |
---|
| 598 | mpc55xx_edma_enable_hardware_requests( e->edma_transmit.edma.edma_tcd); |
---|
[574fb67] | 599 | |
---|
| 600 | /* Wait for transmit update */ |
---|
[d374492] | 601 | sc = rtems_semaphore_obtain( e->edma_transmit.id, RTEMS_WAIT, RTEMS_NO_TIMEOUT); |
---|
| 602 | RTEMS_CHECK_SC_RV( sc, "transmit update"); |
---|
[574fb67] | 603 | |
---|
| 604 | /* Wait for receive update */ |
---|
[d374492] | 605 | sc = rtems_semaphore_obtain( e->edma_receive.id, RTEMS_WAIT, RTEMS_NO_TIMEOUT); |
---|
| 606 | RTEMS_CHECK_SC_RV( sc, "receive update"); |
---|
[574fb67] | 607 | } |
---|
| 608 | |
---|
| 609 | return n; |
---|
| 610 | } |
---|
| 611 | |
---|
| 612 | /** |
---|
| 613 | * @brief Reads @a n characters from bus @a bus and stores it in @a in. |
---|
| 614 | * |
---|
| 615 | * Writes idle characters to receive data. |
---|
| 616 | * |
---|
| 617 | * @see mpc55xx_dspi_read_write(). |
---|
| 618 | */ |
---|
| 619 | static int mpc55xx_dspi_read( rtems_libi2c_bus_t *bus, unsigned char *in, int n) |
---|
| 620 | { |
---|
| 621 | return mpc55xx_dspi_read_write( bus, in, NULL, n); |
---|
| 622 | } |
---|
| 623 | |
---|
| 624 | /** |
---|
| 625 | * @brief Writes @a n characters from @a out to bus @a bus. |
---|
| 626 | * |
---|
| 627 | * Discards the synchronously received data. |
---|
| 628 | * |
---|
| 629 | * @see mpc55xx_dspi_read_write(). |
---|
| 630 | */ |
---|
| 631 | static int mpc55xx_dspi_write( rtems_libi2c_bus_t *bus, unsigned char *out, int n) |
---|
| 632 | { |
---|
| 633 | return mpc55xx_dspi_read_write( bus, NULL, out, n); |
---|
| 634 | } |
---|
| 635 | |
---|
| 636 | static int mpc55xx_dspi_ioctl( rtems_libi2c_bus_t *bus, int cmd, void *arg) |
---|
| 637 | { |
---|
| 638 | int rv = -1; |
---|
| 639 | switch (cmd) { |
---|
| 640 | case RTEMS_LIBI2C_IOCTL_SET_TFRMODE: |
---|
| 641 | rv = mpc55xx_dspi_set_transfer_mode( bus, (const rtems_libi2c_tfr_mode_t *) arg); |
---|
| 642 | break; |
---|
| 643 | case RTEMS_LIBI2C_IOCTL_READ_WRITE: |
---|
| 644 | rv = mpc55xx_dspi_read_write( |
---|
| 645 | bus, |
---|
| 646 | ((rtems_libi2c_read_write_t *) arg)->rd_buf, |
---|
| 647 | ((rtems_libi2c_read_write_t *) arg)->wr_buf, |
---|
| 648 | ((rtems_libi2c_read_write_t *) arg)->byte_cnt |
---|
| 649 | ); |
---|
| 650 | break; |
---|
| 651 | default: |
---|
| 652 | rv = -RTEMS_NOT_DEFINED; |
---|
| 653 | break; |
---|
| 654 | } |
---|
| 655 | return rv; |
---|
| 656 | } |
---|
| 657 | |
---|
| 658 | static const rtems_libi2c_bus_ops_t mpc55xx_dspi_ops = { |
---|
| 659 | .init = mpc55xx_dspi_init, |
---|
| 660 | .send_start = mpc55xx_dspi_send_start, |
---|
| 661 | .send_stop = mpc55xx_dspi_send_stop, |
---|
| 662 | .send_addr = mpc55xx_dspi_send_addr, |
---|
| 663 | .read_bytes = mpc55xx_dspi_read, |
---|
| 664 | .write_bytes = mpc55xx_dspi_write, |
---|
| 665 | .ioctl = mpc55xx_dspi_ioctl |
---|
| 666 | }; |
---|
| 667 | |
---|
[d374492] | 668 | mpc55xx_dspi_bus_entry mpc55xx_dspi_bus_table [MPC55XX_DSPI_NUMBER] = { |
---|
| 669 | { |
---|
[574fb67] | 670 | /* DSPI A */ |
---|
| 671 | .bus = { |
---|
| 672 | .ops = &mpc55xx_dspi_ops, |
---|
| 673 | .size = sizeof( mpc55xx_dspi_bus_entry) |
---|
| 674 | }, |
---|
| 675 | .table_index = 0, |
---|
| 676 | .bus_number = 0, |
---|
| 677 | .regs = &DSPI_A, |
---|
[d374492] | 678 | .master = true, |
---|
[574fb67] | 679 | .push_data = MPC55XX_ZERO_FLAGS, |
---|
[d374492] | 680 | .edma_transmit = { |
---|
[db21e1d] | 681 | .edma = { |
---|
| 682 | .edma_tcd = EDMA_TCD_BY_CHANNEL_INDEX(EDMA_DSPI_A_SR_TFFF), |
---|
| 683 | .done = mpc55xx_dspi_edma_done |
---|
| 684 | }, |
---|
[d374492] | 685 | .id = RTEMS_ID_NONE |
---|
| 686 | }, |
---|
| 687 | .edma_push = { |
---|
[db21e1d] | 688 | .edma = { |
---|
| 689 | .edma_tcd = &EDMA.TCD [43], |
---|
| 690 | .done = mpc55xx_dspi_edma_done |
---|
| 691 | }, |
---|
[d374492] | 692 | .id = RTEMS_ID_NONE |
---|
| 693 | }, |
---|
| 694 | .edma_receive = { |
---|
[db21e1d] | 695 | .edma = { |
---|
| 696 | .edma_tcd = EDMA_TCD_BY_CHANNEL_INDEX(EDMA_DSPI_A_SR_RFDF), |
---|
| 697 | .done = mpc55xx_dspi_edma_done |
---|
| 698 | }, |
---|
[d374492] | 699 | .id = RTEMS_ID_NONE |
---|
| 700 | }, |
---|
[574fb67] | 701 | .idle_char = 0xffffffff, |
---|
[d374492] | 702 | .baud = 0 |
---|
[574fb67] | 703 | }, { |
---|
| 704 | /* DSPI B */ |
---|
| 705 | .bus = { |
---|
| 706 | .ops = &mpc55xx_dspi_ops, |
---|
| 707 | .size = sizeof( mpc55xx_dspi_bus_entry) |
---|
| 708 | }, |
---|
| 709 | .table_index = 1, |
---|
| 710 | .bus_number = 0, |
---|
| 711 | .regs = &DSPI_B, |
---|
[d374492] | 712 | .master = true, |
---|
[574fb67] | 713 | .push_data = MPC55XX_ZERO_FLAGS, |
---|
[d374492] | 714 | .edma_transmit = { |
---|
[db21e1d] | 715 | .edma = { |
---|
| 716 | .edma_tcd = EDMA_TCD_BY_CHANNEL_INDEX(EDMA_DSPI_B_SR_TFFF), |
---|
| 717 | .done = mpc55xx_dspi_edma_done |
---|
| 718 | }, |
---|
[d374492] | 719 | .id = RTEMS_ID_NONE |
---|
| 720 | }, |
---|
| 721 | .edma_push = { |
---|
[db21e1d] | 722 | .edma = { |
---|
| 723 | .edma_tcd = &EDMA.TCD [10], |
---|
| 724 | .done = mpc55xx_dspi_edma_done |
---|
| 725 | }, |
---|
[d374492] | 726 | .id = RTEMS_ID_NONE |
---|
| 727 | }, |
---|
| 728 | .edma_receive = { |
---|
[db21e1d] | 729 | .edma = { |
---|
| 730 | .edma_tcd = EDMA_TCD_BY_CHANNEL_INDEX(EDMA_DSPI_B_SR_RFDF), |
---|
| 731 | .done = mpc55xx_dspi_edma_done |
---|
| 732 | }, |
---|
[d374492] | 733 | .id = RTEMS_ID_NONE |
---|
| 734 | }, |
---|
[574fb67] | 735 | .idle_char = 0xffffffff, |
---|
[d374492] | 736 | .baud = 0 |
---|
[574fb67] | 737 | }, { |
---|
| 738 | /* DSPI C */ |
---|
| 739 | .bus = { |
---|
| 740 | .ops = &mpc55xx_dspi_ops, |
---|
| 741 | .size = sizeof( mpc55xx_dspi_bus_entry) |
---|
| 742 | }, |
---|
| 743 | .table_index = 2, |
---|
| 744 | .bus_number = 0, |
---|
| 745 | .regs = &DSPI_C, |
---|
[d374492] | 746 | .master = true, |
---|
[574fb67] | 747 | .push_data = MPC55XX_ZERO_FLAGS, |
---|
[d374492] | 748 | .edma_transmit = { |
---|
[db21e1d] | 749 | .edma = { |
---|
| 750 | .edma_tcd = EDMA_TCD_BY_CHANNEL_INDEX(EDMA_DSPI_C_SR_TFFF), |
---|
| 751 | .done = mpc55xx_dspi_edma_done |
---|
| 752 | }, |
---|
[d374492] | 753 | .id = RTEMS_ID_NONE |
---|
| 754 | }, |
---|
| 755 | .edma_push = { |
---|
[db21e1d] | 756 | .edma = { |
---|
| 757 | .edma_tcd = &EDMA.TCD [11], |
---|
| 758 | .done = mpc55xx_dspi_edma_done |
---|
| 759 | }, |
---|
[d374492] | 760 | .id = RTEMS_ID_NONE |
---|
| 761 | }, |
---|
| 762 | .edma_receive = { |
---|
[db21e1d] | 763 | .edma = { |
---|
| 764 | .edma_tcd = EDMA_TCD_BY_CHANNEL_INDEX(EDMA_DSPI_C_SR_RFDF), |
---|
| 765 | .done = mpc55xx_dspi_edma_done |
---|
| 766 | }, |
---|
[d374492] | 767 | .id = RTEMS_ID_NONE |
---|
| 768 | }, |
---|
[574fb67] | 769 | .idle_char = 0xffffffff, |
---|
[d374492] | 770 | .baud = 0 |
---|
[a762dc2] | 771 | #ifdef DSPI_D |
---|
[574fb67] | 772 | }, { |
---|
| 773 | /* DSPI D */ |
---|
| 774 | .bus = { |
---|
| 775 | .ops = &mpc55xx_dspi_ops, |
---|
| 776 | .size = sizeof( mpc55xx_dspi_bus_entry) |
---|
| 777 | }, |
---|
| 778 | .table_index = 3, |
---|
| 779 | .bus_number = 0, |
---|
| 780 | .regs = &DSPI_D, |
---|
[d374492] | 781 | .master = true, |
---|
[574fb67] | 782 | .push_data = MPC55XX_ZERO_FLAGS, |
---|
[d374492] | 783 | .edma_transmit = { |
---|
[db21e1d] | 784 | .edma = { |
---|
| 785 | .edma_tcd = EDMA_TCD_BY_CHANNEL_INDEX(EDMA_DSPI_D_SR_TFFF), |
---|
| 786 | .done = mpc55xx_dspi_edma_done |
---|
| 787 | }, |
---|
[d374492] | 788 | .id = RTEMS_ID_NONE |
---|
| 789 | }, |
---|
| 790 | .edma_push = { |
---|
[db21e1d] | 791 | .edma = { |
---|
| 792 | .edma_tcd = &EDMA.TCD [18], |
---|
| 793 | .done = mpc55xx_dspi_edma_done |
---|
| 794 | }, |
---|
[d374492] | 795 | .id = RTEMS_ID_NONE |
---|
| 796 | }, |
---|
| 797 | .edma_receive = { |
---|
[db21e1d] | 798 | .edma = { |
---|
| 799 | .edma_tcd = EDMA_TCD_BY_CHANNEL_INDEX(EDMA_DSPI_D_SR_RFDF), |
---|
| 800 | .done = mpc55xx_dspi_edma_done |
---|
| 801 | }, |
---|
[d374492] | 802 | .id = RTEMS_ID_NONE |
---|
| 803 | }, |
---|
[574fb67] | 804 | .idle_char = 0xffffffff, |
---|
[d374492] | 805 | .baud = 0 |
---|
[a762dc2] | 806 | #endif |
---|
[d374492] | 807 | } |
---|
[574fb67] | 808 | }; |
---|