Changeset 6878519 in rtems
- Timestamp:
- 02/06/18 15:28:28 (6 years ago)
- Branches:
- 5, master
- Children:
- bf70702
- Parents:
- 538a0a8
- git-author:
- Christian Mauderer <christian.mauderer@…> (02/06/18 15:28:28)
- git-committer:
- Christian Mauderer <christian.mauderer@…> (02/12/18 13:25:02)
- Files:
-
- 2 added
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
bsps/arm/atsam/headers.am
r538a0a8 r6878519 12 12 include_bsp_HEADERS += ../../../../../../bsps/arm/atsam/include/bsp/atsam-spi.h 13 13 include_bsp_HEADERS += ../../../../../../bsps/arm/atsam/include/bsp/i2c.h 14 include_bsp_HEADERS += ../../../../../../bsps/arm/atsam/include/bsp/iocopy.h 14 15 include_bsp_HEADERS += ../../../../../../bsps/arm/atsam/include/bsp/irq.h 15 16 include_bsp_HEADERS += ../../../../../../bsps/arm/atsam/include/bsp/pin-config.h -
c/src/lib/libbsp/arm/atsam/Makefile.am
r538a0a8 r6878519 157 157 libbsp_a_SOURCES += rtc/rtc-config.c 158 158 159 # Helper functions 160 libbsp_a_SOURCES += utils/iocopy.c 161 159 162 # Includes 160 163 libbsp_a_CPPFLAGS += -I$(srcdir)/../shared/CMSIS/Include -
c/src/lib/libbsp/arm/atsam/libraries/libchip/source/qspi.c
r538a0a8 r6878519 76 76 77 77 #include <stdint.h> 78 #include <bsp/iocopy.h> 78 79 79 80 … … 210 211 211 212 pQspi->QSPI_SMR = (EnableFlag | (Random << 1)); 212 }213 214 static void do_copy(uint8_t *dst, const uint8_t *src, size_t n, bool aligned)215 {216 if (aligned) {217 while (n > 3) {218 *(uint32_t *)dst = *(uint32_t *)src;219 dst += 4;220 src += 4;221 n -= 4;222 }223 }224 225 while (n > 0) {226 *dst = *src;227 ++dst;228 ++src;229 --n;230 }231 }232 233 static void copy_to_io(void *dst, const void *src, size_t n)234 {235 do_copy(dst, src, n, ((uintptr_t)dst) % 4 == 0);236 }237 238 static void copy_from_io(void *dst, const void *src, size_t n)239 {240 do_copy(dst, src, n, ((uintptr_t)src) % 4 == 0);241 213 } 242 214 … … 767 739 768 740 if (ReadWrite == WriteAccess) { 769 copy_to_io(pQspiMem, pBuffer.pDataTx , pBuffer.TxDataSize); 741 atsam_copy_to_io(pQspiMem, pBuffer.pDataTx , 742 pBuffer.TxDataSize); 770 743 } else { 771 copy_from_io(pBuffer.pDataRx, pQspiMem, pBuffer.RxDataSize); 744 atsam_copy_from_io(pBuffer.pDataRx, pQspiMem, 745 pBuffer.RxDataSize); 772 746 } 773 747 memory_sync(); -
c/src/lib/libbsp/arm/atsam/spi/atsam_spi_bus.c
r538a0a8 r6878519 31 31 #include <bsp/atsam-clock-config.h> 32 32 #include <bsp/atsam-spi.h> 33 #include <bsp/iocopy.h> 33 34 34 35 #include <dev/spi/spi.h> … … 37 38 38 39 #define MAX_SPI_FREQUENCY 50000000 40 41 #define DMA_NR_DESC_PER_DIR 3 42 #define DMA_DESC_ALLIGNMENT 4 43 44 #define DMA_BUF_RX 0 45 #define DMA_BUF_TX 1 46 #define DMA_BUF_DIRS 2 47 48 struct atsam_spi_xdma_buf { 49 LinkedListDescriporView0 desc[DMA_NR_DESC_PER_DIR]; 50 uint8_t leadbuf[CPU_CACHE_LINE_BYTES]; 51 uint8_t trailbuf[CPU_CACHE_LINE_BYTES]; 52 }; 39 53 40 54 typedef struct { … … 42 56 bool msg_cs_change; 43 57 const spi_ioc_transfer *msg_current; 58 const spi_ioc_transfer *msg_next; 44 59 uint32_t msg_todo; 45 60 int msg_error; … … 48 63 uint32_t dma_tx_channel; 49 64 uint32_t dma_rx_channel; 65 struct atsam_spi_xdma_buf *dma_bufs; 66 size_t leadbuf_rx_buffered_len; 67 size_t trailbuf_rx_buffered_len; 50 68 int transfer_in_progress; 51 69 bool chip_select_active; … … 128 146 } 129 147 148 static void atsam_spi_check_alignment_and_set_up_dma_descriptors( 149 atsam_spi_bus *bus, 150 struct atsam_spi_xdma_buf *buf, 151 const uint8_t *start, 152 size_t len, 153 bool tx 154 ) 155 { 156 LinkedListDescriporView0 *curdesc = buf->desc; 157 size_t misaligned_begin; 158 size_t misaligned_end; 159 size_t len_main; 160 const uint8_t *start_main; 161 const uint8_t *start_trail; 162 163 /* Check alignments. */ 164 if (len < CPU_CACHE_LINE_BYTES) { 165 misaligned_begin = len; 166 misaligned_end = 0; 167 len_main = 0; 168 } else { 169 misaligned_begin = ((uint32_t) start) % CPU_CACHE_LINE_BYTES; 170 misaligned_end = (((uint32_t) start) + len) % CPU_CACHE_LINE_BYTES; 171 len_main = len - misaligned_begin - misaligned_end; 172 } 173 start_main = start + misaligned_begin; 174 start_trail = start_main + len_main; 175 176 /* Store length for copying data back. */ 177 if (!tx) { 178 bus->leadbuf_rx_buffered_len = misaligned_begin; 179 bus->trailbuf_rx_buffered_len = misaligned_end; 180 } 181 182 /* Handle misalignment on begin. */ 183 if (misaligned_begin != 0) { 184 if (tx) { 185 atsam_copy_to_io(buf->leadbuf, start, misaligned_begin); 186 } 187 curdesc->mbr_nda = (uint32_t) (&curdesc[1]); 188 curdesc->mbr_ta = (uint32_t) buf->leadbuf; 189 curdesc->mbr_ubc = misaligned_begin; 190 } 191 192 /* Main part */ 193 if (len_main > 0) { 194 curdesc->mbr_ubc |= tx ? XDMA_UBC_NSEN_UPDATED : XDMA_UBC_NDEN_UPDATED; 195 curdesc->mbr_ubc |= XDMA_UBC_NVIEW_NDV0; 196 curdesc->mbr_ubc |= XDMA_UBC_NDE_FETCH_EN; 197 ++curdesc; 198 199 curdesc->mbr_nda = (uint32_t) (&curdesc[1]); 200 curdesc->mbr_ta = (uint32_t) start_main; 201 curdesc->mbr_ubc = len_main; 202 if (tx) { 203 rtems_cache_flush_multiple_data_lines(start_main, len_main); 204 } else { 205 rtems_cache_invalidate_multiple_data_lines(start_main, len_main); 206 } 207 } 208 209 /* Handle misalignment on end */ 210 if (misaligned_end != 0) { 211 curdesc->mbr_ubc |= tx ? XDMA_UBC_NSEN_UPDATED : XDMA_UBC_NDEN_UPDATED; 212 curdesc->mbr_ubc |= XDMA_UBC_NVIEW_NDV0; 213 curdesc->mbr_ubc |= XDMA_UBC_NDE_FETCH_EN; 214 ++curdesc; 215 216 if (tx) { 217 atsam_copy_to_io(buf->trailbuf, start_trail, misaligned_end); 218 } 219 curdesc->mbr_nda = 0; 220 curdesc->mbr_ta = (uint32_t) buf->trailbuf; 221 curdesc->mbr_ubc = misaligned_end; 222 curdesc->mbr_ubc |= XDMA_UBC_NDE_FETCH_DIS; 223 } 224 } 225 226 static void atsam_spi_copy_back_rx_after_dma_transfer( 227 atsam_spi_bus *bus 228 ) 229 { 230 if (bus->leadbuf_rx_buffered_len != 0) { 231 atsam_copy_from_io( 232 bus->msg_current->rx_buf, 233 bus->dma_bufs[DMA_BUF_RX].leadbuf, 234 bus->leadbuf_rx_buffered_len 235 ); 236 } 237 if (bus->trailbuf_rx_buffered_len != 0) { 238 atsam_copy_from_io( 239 bus->msg_current->rx_buf + bus->msg_current->len - 240 bus->trailbuf_rx_buffered_len, 241 bus->dma_bufs[DMA_BUF_RX].trailbuf, 242 bus->trailbuf_rx_buffered_len 243 ); 244 } 245 } 246 130 247 static void atsam_spi_start_dma_transfer( 131 248 atsam_spi_bus *bus, … … 134 251 { 135 252 Xdmac *pXdmac = XDMAC; 136 137 XDMAC_SetDestinationAddr(pXdmac, bus->dma_rx_channel, (uint32_t)msg->rx_buf); 138 XDMAC_SetSourceAddr(pXdmac, bus->dma_tx_channel, (uint32_t)msg->tx_buf); 139 XDMAC_SetMicroblockControl(pXdmac, bus->dma_rx_channel, msg->len); 140 XDMAC_SetMicroblockControl(pXdmac, bus->dma_tx_channel, msg->len); 253 size_t i; 254 255 atsam_spi_check_alignment_and_set_up_dma_descriptors( 256 bus, 257 &bus->dma_bufs[DMA_BUF_RX], 258 msg->rx_buf, 259 msg->len, 260 false 261 ); 262 atsam_spi_check_alignment_and_set_up_dma_descriptors( 263 bus, 264 &bus->dma_bufs[DMA_BUF_TX], 265 msg->tx_buf, 266 msg->len, 267 true 268 ); 269 270 XDMAC_SetDescriptorAddr( 271 pXdmac, 272 bus->dma_rx_channel, 273 (uint32_t) bus->dma_bufs[DMA_BUF_RX].desc, 274 0 275 ); 276 XDMAC_SetDescriptorControl( 277 pXdmac, 278 bus->dma_rx_channel, 279 XDMAC_CNDC_NDVIEW_NDV0 | 280 XDMAC_CNDC_NDDUP_DST_PARAMS_UPDATED | 281 XDMAC_CNDC_NDE_DSCR_FETCH_EN 282 ); 283 XDMAC_SetDescriptorAddr( 284 pXdmac, 285 bus->dma_tx_channel, 286 (uint32_t) bus->dma_bufs[DMA_BUF_TX].desc, 287 0 288 ); 289 XDMAC_SetDescriptorControl( 290 pXdmac, 291 bus->dma_tx_channel, 292 XDMAC_CNDC_NDVIEW_NDV0 | 293 XDMAC_CNDC_NDSUP_SRC_PARAMS_UPDATED | 294 XDMAC_CNDC_NDE_DSCR_FETCH_EN 295 ); 296 141 297 XDMAC_StartTransfer(pXdmac, bus->dma_rx_channel); 142 298 XDMAC_StartTransfer(pXdmac, bus->dma_tx_channel); … … 206 362 207 363 if (msg_todo > 0) { 208 const spi_ioc_transfer *msg = bus->msg_ current;364 const spi_ioc_transfer *msg = bus->msg_next; 209 365 int error; 210 366 211 367 bus->msg_cs_change = msg->cs_change; 212 bus->msg_current = msg + 1; 368 bus->msg_next = msg + 1; 369 bus->msg_current = msg; 213 370 bus->msg_todo = msg_todo - 1; 214 371 … … 232 389 233 390 if (bus->transfer_in_progress == 0) { 391 atsam_spi_copy_back_rx_after_dma_transfer(bus); 234 392 atsam_spi_setup_transfer(bus); 235 393 } … … 242 400 ) 243 401 { 402 rtems_status_code sc; 244 403 atsam_spi_bus *bus = (atsam_spi_bus *)base; 245 404 246 405 bus->msg_cs_change = false; 247 bus->msg_current = &msgs[0]; 406 bus->msg_next = &msgs[0]; 407 bus->msg_current = NULL; 248 408 bus->msg_todo = msg_count; 249 409 bus->msg_error = 0; 250 410 bus->msg_task = rtems_task_self(); 251 411 atsam_spi_setup_transfer(bus); 252 rtems_event_transient_receive(RTEMS_WAIT, RTEMS_NO_TIMEOUT); 412 sc = rtems_event_transient_receive(RTEMS_WAIT, RTEMS_NO_TIMEOUT); 413 assert(sc == RTEMS_SUCCESSFUL); 253 414 return bus->msg_error; 254 415 } … … 281 442 SPI_Disable(bus->spi.pSpiHw); 282 443 PMC_DisablePeripheral(bus->spi.spiId); 444 445 rtems_cache_coherent_free(bus->dma_bufs); 283 446 284 447 spi_bus_destroy_and_free(&bus->base); … … 306 469 uint8_t channel; 307 470 eXdmadRC rc; 471 uint32_t xdma_cndc; 472 473 bus->dma_bufs = rtems_cache_coherent_allocate( 474 DMA_BUF_DIRS * sizeof(*(bus->dma_bufs)), 475 DMA_DESC_ALLIGNMENT, 476 0 477 ); 478 assert(bus->dma_bufs != NULL); 308 479 309 480 bus->dma_tx_channel = XDMAD_AllocateChannel( … … 343 514 assert(rc == XDMAD_OK); 344 515 345 /* Put all interrupts on for non LLI list setup of DMA*/516 /* Put all relevant interrupts on */ 346 517 xdmaInt = ( 347 518 XDMAC_CIE_BIE | … … 367 538 XDMAC_CC_DAM_INCREMENTED_AM | 368 539 XDMAC_CC_PERID(channel); 540 xdma_cndc = XDMAC_CNDC_NDVIEW_NDV0 | 541 XDMAC_CNDC_NDE_DSCR_FETCH_EN | 542 XDMAC_CNDC_NDDUP_DST_PARAMS_UPDATED | 543 XDMAC_CNDC_NDSUP_SRC_PARAMS_UNCHANGED; 369 544 rc = XDMAD_ConfigureTransfer( 370 545 bus->spi.pXdmad, 371 546 bus->dma_rx_channel, 372 547 &cfg, 373 0,374 0,548 xdma_cndc, 549 (uint32_t) bus->dma_bufs[DMA_BUF_RX].desc, 375 550 xdmaInt 376 551 ); … … 392 567 XDMAC_CC_DAM_FIXED_AM | 393 568 XDMAC_CC_PERID(channel); 569 xdma_cndc = XDMAC_CNDC_NDVIEW_NDV0 | 570 XDMAC_CNDC_NDE_DSCR_FETCH_EN | 571 XDMAC_CNDC_NDDUP_DST_PARAMS_UNCHANGED | 572 XDMAC_CNDC_NDSUP_SRC_PARAMS_UPDATED; 394 573 rc = XDMAD_ConfigureTransfer( 395 574 bus->spi.pXdmad, 396 575 bus->dma_tx_channel, 397 576 &cfg, 398 0,399 0,577 xdma_cndc, 578 (uint32_t) bus->dma_bufs[DMA_BUF_TX].desc, 400 579 xdmaInt 401 580 );
Note: See TracChangeset
for help on using the changeset viewer.