Lines Matching +full:spi +full:- +full:cpha
4 * SPDX-License-Identifier: Apache-2.0
17 #include <zephyr/drivers/spi.h>
18 #include <zephyr/drivers/spi/rtio.h>
37 XMC_USIC_CH_t *spi; member
79 data->dma_status_flags |= SPI_XMC4XXX_DMA_ERROR_FLAG; in spi_xmc4xxx_dma_callback()
81 if (dev_dma == data->dma_tx.dev_dma && dma_channel == data->dma_tx.dma_channel) { in spi_xmc4xxx_dma_callback()
82 data->dma_status_flags |= SPI_XMC4XXX_DMA_TX_DONE_FLAG; in spi_xmc4xxx_dma_callback()
83 } else if (dev_dma == data->dma_rx.dev_dma && in spi_xmc4xxx_dma_callback()
84 dma_channel == data->dma_rx.dma_channel) { in spi_xmc4xxx_dma_callback()
85 data->dma_status_flags |= SPI_XMC4XXX_DMA_RX_DONE_FLAG; in spi_xmc4xxx_dma_callback()
88 data->dma_status_flags |= SPI_XMC4XXX_DMA_ERROR_FLAG; in spi_xmc4xxx_dma_callback()
91 k_sem_give(&data->status_sem); in spi_xmc4xxx_dma_callback()
96 static void spi_xmc4xxx_flush_rx(XMC_USIC_CH_t *spi) in spi_xmc4xxx_flush_rx() argument
100 recv_status = XMC_USIC_CH_GetReceiveBufferStatus(spi); in spi_xmc4xxx_flush_rx()
102 XMC_SPI_CH_GetReceivedData(spi); in spi_xmc4xxx_flush_rx()
105 XMC_SPI_CH_GetReceivedData(spi); in spi_xmc4xxx_flush_rx()
111 struct spi_xmc4xxx_data *data = dev->data; in spi_xmc4xxx_shift_frames()
112 const struct spi_xmc4xxx_config *config = dev->config; in spi_xmc4xxx_shift_frames()
113 struct spi_context *ctx = &data->ctx; in spi_xmc4xxx_shift_frames()
119 tx_data = ctx->tx_buf[0]; in spi_xmc4xxx_shift_frames()
122 XMC_SPI_CH_ClearStatusFlag(config->spi, in spi_xmc4xxx_shift_frames()
129 XMC_SPI_CH_Transmit(config->spi, tx_data, XMC_SPI_CH_MODE_STANDARD); in spi_xmc4xxx_shift_frames()
137 status = XMC_SPI_CH_GetStatusFlag(config->spi); in spi_xmc4xxx_shift_frames()
145 status = XMC_SPI_CH_GetStatusFlag(config->spi); in spi_xmc4xxx_shift_frames()
152 rx_data = XMC_SPI_CH_GetReceivedData(config->spi); in spi_xmc4xxx_shift_frames()
155 *ctx->rx_buf = rx_data; in spi_xmc4xxx_shift_frames()
163 struct spi_xmc4xxx_data *data = dev->data; in spi_xmc4xxx_isr()
164 const struct spi_xmc4xxx_config *config = dev->config; in spi_xmc4xxx_isr()
165 struct spi_context *ctx = &data->ctx; in spi_xmc4xxx_isr()
168 rx_data = XMC_SPI_CH_GetReceivedData(config->spi); in spi_xmc4xxx_isr()
171 *ctx->rx_buf = rx_data; in spi_xmc4xxx_isr()
180 if (!(ctx->config->operation & SPI_HOLD_ON_CS)) { in spi_xmc4xxx_isr()
192 struct spi_xmc4xxx_data *data = dev->data; in spi_xmc4xxx_configure()
193 const struct spi_xmc4xxx_config *config = dev->config; in spi_xmc4xxx_configure()
194 struct spi_context *ctx = &data->ctx; in spi_xmc4xxx_configure()
195 uint16_t settings = spi_cfg->operation; in spi_xmc4xxx_configure()
197 bool CPHA = SPI_MODE_GET(settings) & SPI_MODE_CPHA; in spi_xmc4xxx_configure() local
198 XMC_SPI_CH_CONFIG_t usic_cfg = {.baudrate = spi_cfg->frequency}; in spi_xmc4xxx_configure()
206 ctx->config = spi_cfg; in spi_xmc4xxx_configure()
208 if (spi_cfg->operation & SPI_HALF_DUPLEX) { in spi_xmc4xxx_configure()
209 LOG_ERR("Half-duplex not supported"); in spi_xmc4xxx_configure()
210 return -ENOTSUP; in spi_xmc4xxx_configure()
213 if (spi_cfg->operation & SPI_OP_MODE_SLAVE) { in spi_xmc4xxx_configure()
215 return -ENOTSUP; in spi_xmc4xxx_configure()
218 if (SPI_WORD_SIZE_GET(spi_cfg->operation) != 8) { in spi_xmc4xxx_configure()
220 return -ENOTSUP; in spi_xmc4xxx_configure()
223 ret = XMC_SPI_CH_Stop(config->spi); in spi_xmc4xxx_configure()
225 return -EBUSY; in spi_xmc4xxx_configure()
227 XMC_SPI_CH_Init(config->spi, &usic_cfg); in spi_xmc4xxx_configure()
228 XMC_SPI_CH_Start(config->spi); in spi_xmc4xxx_configure()
231 XMC_SPI_CH_SetInputSource(config->spi, XMC_SPI_CH_INPUT_DIN0, LOOPBACK_SRC); in spi_xmc4xxx_configure()
233 XMC_SPI_CH_SetInputSource(config->spi, XMC_SPI_CH_INPUT_DIN0, config->miso_src); in spi_xmc4xxx_configure()
236 if (!CPOL && !CPHA) { in spi_xmc4xxx_configure()
238 } else if (!CPOL && CPHA) { in spi_xmc4xxx_configure()
240 } else if (CPOL && !CPHA) { in spi_xmc4xxx_configure()
242 } else if (CPOL && CPHA) { in spi_xmc4xxx_configure()
245 XMC_SPI_CH_ConfigureShiftClockOutput(config->spi, clock_settings, in spi_xmc4xxx_configure()
249 XMC_SPI_CH_SetBitOrderLsbFirst(config->spi); in spi_xmc4xxx_configure()
251 XMC_SPI_CH_SetBitOrderMsbFirst(config->spi); in spi_xmc4xxx_configure()
254 XMC_SPI_CH_SetWordLength(config->spi, 8); in spi_xmc4xxx_configure()
264 struct spi_xmc4xxx_data *data = dev->data; in spi_xmc4xxx_transceive()
265 const struct spi_xmc4xxx_config *config = dev->config; in spi_xmc4xxx_transceive()
266 struct spi_context *ctx = &data->ctx; in spi_xmc4xxx_transceive()
275 return -ENOTSUP; in spi_xmc4xxx_transceive()
283 LOG_DBG("SPI config on device %s failed", dev->name); in spi_xmc4xxx_transceive()
288 spi_xmc4xxx_flush_rx(config->spi); in spi_xmc4xxx_transceive()
295 XMC_SPI_CH_EnableEvent(config->spi, XMC_SPI_CH_EVENT_STANDARD_RECEIVE | in spi_xmc4xxx_transceive()
305 if (!(spi_cfg->operation & SPI_HOLD_ON_CS)) { in spi_xmc4xxx_transceive()
332 ret = k_sem_take(&data->status_sem, K_MSEC(CONFIG_SPI_XMC4XXX_DMA_TIMEOUT_MSEC)); in spi_xmc4xxx_dma_rx_tx_done()
337 if (data->dma_status_flags & SPI_XMC4XXX_DMA_ERROR_FLAG) { in spi_xmc4xxx_dma_rx_tx_done()
338 return -EIO; in spi_xmc4xxx_dma_rx_tx_done()
340 if (data->dma_status_flags == data->dma_completion_flags) { in spi_xmc4xxx_dma_rx_tx_done()
352 struct spi_xmc4xxx_data *data = dev->data; in spi_xmc4xxx_transceive_dma()
353 const struct spi_xmc4xxx_config *config = dev->config; in spi_xmc4xxx_transceive_dma()
354 struct spi_context *ctx = &data->ctx; in spi_xmc4xxx_transceive_dma()
355 struct spi_xmc4xxx_dma_stream *dma_tx = &data->dma_tx; in spi_xmc4xxx_transceive_dma()
356 struct spi_xmc4xxx_dma_stream *dma_rx = &data->dma_rx; in spi_xmc4xxx_transceive_dma()
364 return -ENOTSUP; in spi_xmc4xxx_transceive_dma()
369 k_sem_reset(&data->status_sem); in spi_xmc4xxx_transceive_dma()
373 LOG_ERR("SPI config on device %s failed", dev->name); in spi_xmc4xxx_transceive_dma()
379 irq_disable(config->irq_num_rx); in spi_xmc4xxx_transceive_dma()
388 while (XMC_USIC_CH_GetTransmitBufferStatus(config->spi) == in spi_xmc4xxx_transceive_dma()
392 if (data->ctx.rx_len == 0) { in spi_xmc4xxx_transceive_dma()
393 dma_len = data->ctx.tx_len; in spi_xmc4xxx_transceive_dma()
394 } else if (data->ctx.tx_len == 0) { in spi_xmc4xxx_transceive_dma()
395 dma_len = data->ctx.rx_len; in spi_xmc4xxx_transceive_dma()
397 dma_len = MIN(data->ctx.tx_len, data->ctx.rx_len); in spi_xmc4xxx_transceive_dma()
400 if (ctx->rx_buf) { in spi_xmc4xxx_transceive_dma()
402 spi_xmc4xxx_flush_rx(config->spi); in spi_xmc4xxx_transceive_dma()
404 dma_rx->blk_cfg.dest_address = (uint32_t)ctx->rx_buf; in spi_xmc4xxx_transceive_dma()
405 dma_rx->blk_cfg.dest_addr_adj = DMA_ADDR_ADJ_INCREMENT; in spi_xmc4xxx_transceive_dma()
406 dma_rx->blk_cfg.block_size = dma_len; in spi_xmc4xxx_transceive_dma()
407 dma_rx->blk_cfg.source_addr_adj = DMA_ADDR_ADJ_NO_CHANGE; in spi_xmc4xxx_transceive_dma()
409 ret = dma_config(dma_rx->dev_dma, dma_rx->dma_channel, &dma_rx->dma_cfg); in spi_xmc4xxx_transceive_dma()
414 XMC_SPI_CH_EnableEvent(config->spi, XMC_SPI_CH_EVENT_STANDARD_RECEIVE | in spi_xmc4xxx_transceive_dma()
418 ret = dma_start(dma_rx->dev_dma, dma_rx->dma_channel); in spi_xmc4xxx_transceive_dma()
424 XMC_SPI_CH_DisableEvent(config->spi, in spi_xmc4xxx_transceive_dma()
429 if (ctx->tx_buf) { in spi_xmc4xxx_transceive_dma()
430 dma_tx->blk_cfg.source_address = (uint32_t)ctx->tx_buf; in spi_xmc4xxx_transceive_dma()
431 dma_tx->blk_cfg.source_addr_adj = DMA_ADDR_ADJ_INCREMENT; in spi_xmc4xxx_transceive_dma()
433 dma_tx->blk_cfg.source_address = (uint32_t)&tx_dummy_data; in spi_xmc4xxx_transceive_dma()
434 dma_tx->blk_cfg.source_addr_adj = DMA_ADDR_ADJ_NO_CHANGE; in spi_xmc4xxx_transceive_dma()
437 dma_tx->blk_cfg.block_size = dma_len; in spi_xmc4xxx_transceive_dma()
439 ret = dma_config(dma_tx->dev_dma, dma_tx->dma_channel, &dma_tx->dma_cfg); in spi_xmc4xxx_transceive_dma()
444 data->dma_status_flags = 0; in spi_xmc4xxx_transceive_dma()
445 data->dma_completion_flags = dma_completion_flags; in spi_xmc4xxx_transceive_dma()
447 XMC_SPI_CH_EnableEvent(config->spi, XMC_SPI_CH_EVENT_RECEIVE_START); in spi_xmc4xxx_transceive_dma()
448 XMC_USIC_CH_TriggerServiceRequest(config->spi, data->service_request_tx); in spi_xmc4xxx_transceive_dma()
450 ret = dma_start(dma_tx->dev_dma, dma_tx->dma_channel); in spi_xmc4xxx_transceive_dma()
465 dma_stop(dma_tx->dev_dma, dma_tx->dma_channel); in spi_xmc4xxx_transceive_dma()
466 dma_stop(dma_rx->dev_dma, dma_rx->dma_channel); in spi_xmc4xxx_transceive_dma()
469 if (!(spi_cfg->operation & SPI_HOLD_ON_CS)) { in spi_xmc4xxx_transceive_dma()
474 irq_enable(config->irq_num_rx); in spi_xmc4xxx_transceive_dma()
487 struct spi_xmc4xxx_data *data = dev->data; in spi_xmc4xxx_transceive_sync()
489 if (data->dma_tx.dev_dma != NULL && data->dma_rx.dev_dma != NULL) { in spi_xmc4xxx_transceive_sync()
499 struct spi_xmc4xxx_data *data = dev->data; in spi_xmc4xxx_release()
501 if (!spi_context_configured(&data->ctx, config)) { in spi_xmc4xxx_release()
502 return -EINVAL; in spi_xmc4xxx_release()
505 spi_context_unlock_unconditionally(&data->ctx); in spi_xmc4xxx_release()
512 const struct spi_xmc4xxx_config *config = dev->config; in spi_xmc4xxx_configure_rx_service_requests()
513 struct spi_xmc4xxx_data *data = dev->data; in spi_xmc4xxx_configure_rx_service_requests()
515 __ASSERT(config->irq_num_rx >= USIC_IRQ_MIN && config->irq_num_rx <= USIC_IRQ_MAX, in spi_xmc4xxx_configure_rx_service_requests()
518 data->service_request_rx = (config->irq_num_rx - USIC_IRQ_MIN) % IRQS_PER_USIC; in spi_xmc4xxx_configure_rx_service_requests()
520 XMC_SPI_CH_SelectInterruptNodePointer(config->spi, in spi_xmc4xxx_configure_rx_service_requests()
522 data->service_request_rx); in spi_xmc4xxx_configure_rx_service_requests()
523 XMC_SPI_CH_SelectInterruptNodePointer(config->spi, in spi_xmc4xxx_configure_rx_service_requests()
525 data->service_request_rx); in spi_xmc4xxx_configure_rx_service_requests()
530 const struct spi_xmc4xxx_config *config = dev->config; in spi_xmc4xxx_configure_tx_service_requests()
531 struct spi_xmc4xxx_data *data = dev->data; in spi_xmc4xxx_configure_tx_service_requests()
533 __ASSERT(config->irq_num_tx >= USIC_IRQ_MIN && config->irq_num_tx <= USIC_IRQ_MAX, in spi_xmc4xxx_configure_tx_service_requests()
536 data->service_request_tx = (config->irq_num_tx - USIC_IRQ_MIN) % IRQS_PER_USIC; in spi_xmc4xxx_configure_tx_service_requests()
538 XMC_USIC_CH_SetInterruptNodePointer(config->spi, in spi_xmc4xxx_configure_tx_service_requests()
540 data->service_request_tx); in spi_xmc4xxx_configure_tx_service_requests()
546 struct spi_xmc4xxx_data *data = dev->data; in spi_xmc4xxx_init()
547 const struct spi_xmc4xxx_config *config = dev->config; in spi_xmc4xxx_init()
550 XMC_USIC_CH_Enable(config->spi); in spi_xmc4xxx_init()
552 spi_context_unlock_unconditionally(&data->ctx); in spi_xmc4xxx_init()
555 config->irq_config_func(dev); in spi_xmc4xxx_init()
562 if (data->dma_rx.dev_dma != NULL) { in spi_xmc4xxx_init()
563 if (!device_is_ready(data->dma_rx.dev_dma)) { in spi_xmc4xxx_init()
564 return -ENODEV; in spi_xmc4xxx_init()
566 data->dma_rx.blk_cfg.source_address = (uint32_t)&config->spi->RBUF; in spi_xmc4xxx_init()
567 data->dma_rx.dma_cfg.head_block = &data->dma_rx.blk_cfg; in spi_xmc4xxx_init()
568 data->dma_rx.dma_cfg.user_data = (void *)data; in spi_xmc4xxx_init()
571 if (data->dma_tx.dev_dma != NULL) { in spi_xmc4xxx_init()
572 if (!device_is_ready(data->dma_tx.dev_dma)) { in spi_xmc4xxx_init()
573 return -ENODEV; in spi_xmc4xxx_init()
575 data->dma_tx.blk_cfg.dest_address = in spi_xmc4xxx_init()
576 (uint32_t)&config->spi->TBUF[XMC_SPI_CH_MODE_STANDARD]; in spi_xmc4xxx_init()
577 data->dma_tx.blk_cfg.dest_addr_adj = DMA_ADDR_ADJ_NO_CHANGE; in spi_xmc4xxx_init()
578 data->dma_tx.dma_cfg.head_block = &data->dma_tx.blk_cfg; in spi_xmc4xxx_init()
579 data->dma_tx.dma_cfg.user_data = (void *)data; in spi_xmc4xxx_init()
581 k_sem_init(&data->status_sem, 0, 2); in spi_xmc4xxx_init()
584 ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT); in spi_xmc4xxx_init()
589 XMC_SPI_CH_SetInputSource(config->spi, XMC_SPI_CH_INPUT_DIN0, config->miso_src); in spi_xmc4xxx_init()
590 spi_context_cs_configure_all(&data->ctx); in spi_xmc4xxx_init()
595 static DEVICE_API(spi, spi_xmc4xxx_driver_api) = {
636 const struct spi_xmc4xxx_config *config = dev->config; \
641 service_request = (irq_num - USIC_IRQ_MIN) % IRQS_PER_USIC; \
644 config->spi, XMC_SPI_CH_INTERRUPT_NODE_POINTER_RECEIVE, service_request); \
646 config->spi, XMC_SPI_CH_INTERRUPT_NODE_POINTER_ALTERNATE_RECEIVE, \
649 XMC_SPI_CH_EnableEvent(config->spi, XMC_SPI_CH_EVENT_STANDARD_RECEIVE | \
685 .spi = (XMC_USIC_CH_t *)DT_INST_REG_ADDR(index), \