Lines Matching +full:tx +full:- +full:dummy

3  * Copyright (c) 2017, 2020-2021, NXP
5 * SPDX-License-Identifier: Apache-2.0
89 const struct spi_mcux_config *config = dev->config; in spi_mcux_transfer_next_packet()
90 struct spi_mcux_data *data = dev->data; in spi_mcux_transfer_next_packet()
91 SPI_Type *base = config->base; in spi_mcux_transfer_next_packet()
92 struct spi_context *ctx = &data->ctx; in spi_mcux_transfer_next_packet()
96 if ((ctx->tx_len == 0) && (ctx->rx_len == 0)) { in spi_mcux_transfer_next_packet()
97 /* nothing left to rx or tx, we're done! */ in spi_mcux_transfer_next_packet()
99 spi_context_cs_control(&data->ctx, false); in spi_mcux_transfer_next_packet()
100 spi_context_complete(&data->ctx, dev, 0); in spi_mcux_transfer_next_packet()
106 if (!config->is_dma_chn_shared) { in spi_mcux_transfer_next_packet()
108 if (ctx->tx_len != 0) { in spi_mcux_transfer_next_packet()
112 data->tx_dma_config.dma_channel); in spi_mcux_transfer_next_packet()
113 ret = dma_start(data->tx_dma_config.dma_dev, in spi_mcux_transfer_next_packet()
114 data->tx_dma_config.dma_channel); in spi_mcux_transfer_next_packet()
117 data->tx_dma_config.dma_channel, ret); in spi_mcux_transfer_next_packet()
122 if (ctx->rx_len != 0) { in spi_mcux_transfer_next_packet()
126 data->rx_dma_config.dma_channel); in spi_mcux_transfer_next_packet()
127 ret = dma_start(data->rx_dma_config.dma_dev, in spi_mcux_transfer_next_packet()
128 data->rx_dma_config.dma_channel); in spi_mcux_transfer_next_packet()
131 data->rx_dma_config.dma_channel, ret); in spi_mcux_transfer_next_packet()
141 if (config->is_dma_chn_shared) { in spi_mcux_transfer_next_packet()
142 /* in master mode start tx */ in spi_mcux_transfer_next_packet()
143 dma_start(data->tx_dma_config.dma_dev, data->tx_dma_config.dma_channel); in spi_mcux_transfer_next_packet()
147 LOG_DBG("trigger tx to start master"); in spi_mcux_transfer_next_packet()
154 (ctx->config->slave << DSPI_MASTER_PCS_SHIFT); in spi_mcux_transfer_next_packet()
156 if (ctx->tx_len == 0) { in spi_mcux_transfer_next_packet()
157 /* rx only, nothing to tx */ in spi_mcux_transfer_next_packet()
159 transfer.rxData = ctx->rx_buf; in spi_mcux_transfer_next_packet()
160 transfer.dataSize = ctx->rx_len; in spi_mcux_transfer_next_packet()
161 } else if (ctx->rx_len == 0) { in spi_mcux_transfer_next_packet()
162 /* tx only, nothing to rx */ in spi_mcux_transfer_next_packet()
163 transfer.txData = (uint8_t *) ctx->tx_buf; in spi_mcux_transfer_next_packet()
165 transfer.dataSize = ctx->tx_len; in spi_mcux_transfer_next_packet()
166 } else if (ctx->tx_len == ctx->rx_len) { in spi_mcux_transfer_next_packet()
167 /* rx and tx are the same length */ in spi_mcux_transfer_next_packet()
168 transfer.txData = (uint8_t *) ctx->tx_buf; in spi_mcux_transfer_next_packet()
169 transfer.rxData = ctx->rx_buf; in spi_mcux_transfer_next_packet()
170 transfer.dataSize = ctx->tx_len; in spi_mcux_transfer_next_packet()
171 } else if (ctx->tx_len > ctx->rx_len) { in spi_mcux_transfer_next_packet()
172 /* Break up the tx into multiple transfers so we don't have to in spi_mcux_transfer_next_packet()
176 transfer.txData = (uint8_t *) ctx->tx_buf; in spi_mcux_transfer_next_packet()
177 transfer.rxData = ctx->rx_buf; in spi_mcux_transfer_next_packet()
178 transfer.dataSize = ctx->rx_len; in spi_mcux_transfer_next_packet()
182 * tx from a longer intermediate buffer. Leave chip select in spi_mcux_transfer_next_packet()
185 transfer.txData = (uint8_t *) ctx->tx_buf; in spi_mcux_transfer_next_packet()
186 transfer.rxData = ctx->rx_buf; in spi_mcux_transfer_next_packet()
187 transfer.dataSize = ctx->tx_len; in spi_mcux_transfer_next_packet()
191 if (!(ctx->tx_count <= 1 && ctx->rx_count <= 1)) { in spi_mcux_transfer_next_packet()
195 data->transfer_len = transfer.dataSize; in spi_mcux_transfer_next_packet()
197 status = DSPI_MasterTransferNonBlocking(base, &data->handle, &transfer); in spi_mcux_transfer_next_packet()
199 LOG_ERR("Transfer could not start on %s: %d", dev->name, status); in spi_mcux_transfer_next_packet()
200 return status == kDSPI_Busy ? -EBUSY : -EINVAL; in spi_mcux_transfer_next_packet()
208 const struct spi_mcux_config *config = dev->config; in spi_mcux_isr()
209 struct spi_mcux_data *data = dev->data; in spi_mcux_isr()
210 SPI_Type *base = config->base; in spi_mcux_isr()
218 dma_start(data->rx_dma_config.dma_dev, data->rx_dma_config.dma_channel); in spi_mcux_isr()
221 DSPI_MasterTransferHandleIRQ(base, &data->handle); in spi_mcux_isr()
228 uint16_t dummy) in mcux_init_inner_buffer_with_cmd() argument
230 const struct spi_mcux_config *config = dev->config; in mcux_init_inner_buffer_with_cmd()
231 struct spi_mcux_data *data = dev->data; in mcux_init_inner_buffer_with_cmd()
233 uint32_t *pbuf = data->inner_tx_buffer->buf; in mcux_init_inner_buffer_with_cmd()
237 commandStruct.whichPcs = data->which_pcs; in mcux_init_inner_buffer_with_cmd()
241 commandStruct.whichCtar = config->which_ctar; in mcux_init_inner_buffer_with_cmd()
242 commandStruct.isPcsContinuous = config->enable_continuous_sck; in mcux_init_inner_buffer_with_cmd()
244 for (i = 0; i < data->inner_tx_buffer->len / 4; i++) { in mcux_init_inner_buffer_with_cmd()
245 *pbuf = command | dummy; in mcux_init_inner_buffer_with_cmd()
251 * @brief update the tx data to internal buffer with command embedded,
252 * if no tx data, use dummy value.
253 * tx data frame size shall not bigger than 16 bits
258 struct spi_mcux_data *data = dev->data; in mcux_spi_context_data_update()
259 uint32_t frame_size_bit = data->frame_size; in mcux_spi_context_data_update()
260 struct spi_context *ctx = (struct spi_context *)&data->ctx; in mcux_spi_context_data_update()
261 uint32_t *pcdata = data->inner_tx_buffer->buf; in mcux_spi_context_data_update()
266 return -EINVAL; in mcux_spi_context_data_update()
270 /* only used when use inner buffer to translate tx format */ in mcux_spi_context_data_update()
272 get_size_byte_by_frame_size(ctx->current_tx->len, frame_size_bit)) { in mcux_spi_context_data_update()
275 ctx->current_tx->len * 8 / frame_size_bit, in mcux_spi_context_data_update()
277 return -EINVAL; in mcux_spi_context_data_update()
282 uint8_t *pdata = (uint8_t *)ctx->tx_buf; in mcux_spi_context_data_update()
293 } while (i < ctx->current_tx->len && in mcux_spi_context_data_update()
294 i < data->inner_tx_buffer->len); in mcux_spi_context_data_update()
297 if (i == ctx->current_tx->len) { in mcux_spi_context_data_update()
298 --pcdata; in mcux_spi_context_data_update()
304 uint16_t *pdata = (uint16_t *)ctx->tx_buf; in mcux_spi_context_data_update()
313 } while (i < ctx->current_tx->len && in mcux_spi_context_data_update()
314 i < data->inner_tx_buffer->len); in mcux_spi_context_data_update()
316 if (i == ctx->current_tx->len) { in mcux_spi_context_data_update()
318 --pcdata; in mcux_spi_context_data_update()
325 return -EINVAL; in mcux_spi_context_data_update()
337 struct spi_mcux_data *data = dev->data; in update_tx_dma()
338 const struct spi_mcux_config *config = dev->config; in update_tx_dma()
339 SPI_Type *base = config->base; in update_tx_dma()
340 uint32_t frame_size = data->frame_size; in update_tx_dma()
344 if (data->ctx.tx_len == 0) { in update_tx_dma()
349 if (data->ctx.current_tx && data->ctx.current_tx->len > 0 && in update_tx_dma()
350 data->ctx.current_tx->buf != NULL) { in update_tx_dma()
352 tx_size = get_size_byte_by_frame_size(data->transfer_len, in update_tx_dma()
354 tx_buf = data->inner_tx_buffer->buf; in update_tx_dma()
356 /* expect the buffer is pre-set */ in update_tx_dma()
357 tx_size = get_size_byte_by_frame_size(data->ctx.current_tx->len, in update_tx_dma()
359 LOG_DBG("tx size is %d", tx_size); in update_tx_dma()
360 tx_buf = data->ctx.current_tx->buf; in update_tx_dma()
363 tx_buf = data->inner_tx_buffer->buf; in update_tx_dma()
364 tx_size = get_size_byte_by_frame_size(data->transfer_len, in update_tx_dma()
370 data->tx_dma_block.source_address = (uint32_t)tx_buf; in update_tx_dma()
371 data->tx_dma_block.dest_address = in update_tx_dma()
373 data->tx_dma_block.next_block = NULL; in update_tx_dma()
374 if (config->is_dma_chn_shared) { in update_tx_dma()
376 data->tx_dma_block.block_size = 4; in update_tx_dma()
378 data->tx_dma_block.block_size = tx_size; in update_tx_dma()
381 data->tx_dma_config.dma_cfg.user_data = (void *) dev; in update_tx_dma()
382 dma_config(data->tx_dma_config.dma_dev, data->tx_dma_config.dma_channel, in update_tx_dma()
383 (struct dma_config *)&data->tx_dma_config.dma_cfg); in update_tx_dma()
392 struct spi_mcux_data *data = dev->data; in update_rx_dma()
393 const struct spi_mcux_config *config = dev->config; in update_rx_dma()
394 SPI_Type *base = config->base; in update_rx_dma()
395 uint32_t frame_size_byte = (data->frame_size >> 3); in update_rx_dma()
399 if (data->ctx.rx_len == 0) { in update_rx_dma()
404 if (data->ctx.current_rx) { in update_rx_dma()
405 rx_size = data->transfer_len; in update_rx_dma()
406 if (data->ctx.rx_buf != NULL) { in update_rx_dma()
407 rx_buf = data->ctx.rx_buf; in update_rx_dma()
409 rx_buf = data->inner_rx_buffer->buf; in update_rx_dma()
412 /* tx only */ in update_rx_dma()
413 rx_buf = data->inner_rx_buffer->buf; in update_rx_dma()
414 rx_size = data->transfer_len; in update_rx_dma()
416 LOG_DBG("tx only 0x%x, size %d", (uint32_t)rx_buf, rx_size); in update_rx_dma()
419 if (config->is_dma_chn_shared) { in update_rx_dma()
420 if (data->ctx.rx_len == 1) { in update_rx_dma()
421 /* do not link tx on last frame*/ in update_rx_dma()
422 LOG_DBG("do not link tx/rx channel for last one"); in update_rx_dma()
423 data->rx_dma_config.dma_cfg.source_chaining_en = 0; in update_rx_dma()
424 data->rx_dma_config.dma_cfg.dest_chaining_en = 0; in update_rx_dma()
426 LOG_DBG("shared mux mode, link tx/rx channel"); in update_rx_dma()
427 data->rx_dma_config.dma_cfg.source_chaining_en = 1; in update_rx_dma()
428 data->rx_dma_config.dma_cfg.dest_chaining_en = 1; in update_rx_dma()
429 data->rx_dma_config.dma_cfg.linked_channel = in update_rx_dma()
430 data->tx_dma_config.dma_channel; in update_rx_dma()
433 data->rx_dma_block.dest_address = (uint32_t)rx_buf; in update_rx_dma()
434 data->rx_dma_block.source_address = in update_rx_dma()
437 data->rx_dma_block.block_size = frame_size_byte; in update_rx_dma()
438 data->rx_dma_config.dma_cfg.source_burst_length = in update_rx_dma()
440 data->rx_dma_config.dma_cfg.dest_burst_length = frame_size_byte; in update_rx_dma()
441 data->rx_dma_config.dma_cfg.source_data_size = frame_size_byte; in update_rx_dma()
442 data->rx_dma_config.dma_cfg.dest_data_size = frame_size_byte; in update_rx_dma()
445 data->rx_dma_block.dest_address = (uint32_t)rx_buf; in update_rx_dma()
446 data->rx_dma_block.source_address = in update_rx_dma()
448 data->rx_dma_block.block_size = rx_size; in update_rx_dma()
449 data->rx_dma_config.dma_cfg.source_burst_length = in update_rx_dma()
451 data->rx_dma_config.dma_cfg.dest_burst_length = frame_size_byte; in update_rx_dma()
452 data->rx_dma_config.dma_cfg.source_data_size = frame_size_byte; in update_rx_dma()
453 data->rx_dma_config.dma_cfg.dest_data_size = frame_size_byte; in update_rx_dma()
456 data->rx_dma_config.dma_cfg.user_data = (void *) dev; in update_rx_dma()
457 dma_config(data->rx_dma_config.dma_dev, data->rx_dma_config.dma_channel, in update_rx_dma()
458 (struct dma_config *)&data->rx_dma_config.dma_cfg); in update_rx_dma()
465 const struct spi_mcux_config *config = dev->config; in configure_dma()
467 if (config->is_dma_chn_shared) { in configure_dma()
480 const struct spi_mcux_config *config = dev->config; in dma_callback()
481 SPI_Type *base = config->base; in dma_callback()
482 struct spi_mcux_data *data = dev->data; in dma_callback()
491 if (channel == data->tx_dma_config.dma_channel) { in dma_callback()
492 LOG_DBG("ctx.tx_len is %d", data->ctx.tx_len); in dma_callback()
493 LOG_DBG("tx count %d", data->ctx.tx_count); in dma_callback()
495 spi_context_update_tx(&data->ctx, 1, data->transfer_len); in dma_callback()
496 LOG_DBG("tx count %d", data->ctx.tx_count); in dma_callback()
497 LOG_DBG("tx buf/len %p/%zu", data->ctx.tx_buf, in dma_callback()
498 data->ctx.tx_len); in dma_callback()
499 data->tx_transfer_count++; in dma_callback()
500 /* tx done */ in dma_callback()
502 LOG_DBG("ctx.rx_len is %d", data->ctx.rx_len); in dma_callback()
503 LOG_DBG("rx count %d", data->ctx.rx_count); in dma_callback()
504 spi_context_update_rx(&data->ctx, 1, data->transfer_len); in dma_callback()
505 LOG_DBG("rx count %d", data->ctx.rx_count); in dma_callback()
506 /* setup the inner tx buffer */ in dma_callback()
507 LOG_DBG("rx buf/len %p/%zu", data->ctx.rx_buf, in dma_callback()
508 data->ctx.rx_len); in dma_callback()
509 data->rx_transfer_count++; in dma_callback()
512 if (data->tx_transfer_count == data->rx_transfer_count) { in dma_callback()
521 if (config->is_dma_chn_shared) { in dma_callback()
522 data->transfer_len = data->frame_size >> 3; in dma_callback()
524 if (data->ctx.tx_len == 0) { in dma_callback()
525 data->transfer_len = data->ctx.rx_len; in dma_callback()
526 } else if (data->ctx.rx_len == 0) { in dma_callback()
527 data->transfer_len = data->ctx.tx_len; in dma_callback()
529 data->transfer_len = in dma_callback()
530 data->ctx.tx_len > data->ctx.rx_len ? in dma_callback()
531 data->ctx.rx_len : in dma_callback()
532 data->ctx.tx_len; in dma_callback()
538 } else if (data->ctx.rx_len == 0 && data->ctx.tx_len == 0) { in dma_callback()
544 data->transfer_len = 0; in dma_callback()
547 LOG_DBG("TX/RX DMA callback done"); in dma_callback()
557 spi_context_update_tx(&data->ctx, 1, data->transfer_len); in spi_mcux_master_transfer_callback()
558 spi_context_update_rx(&data->ctx, 1, data->transfer_len); in spi_mcux_master_transfer_callback()
560 spi_mcux_transfer_next_packet(data->dev); in spi_mcux_master_transfer_callback()
568 const struct spi_mcux_config *config = dev->config; in spi_mcux_configure()
569 struct spi_mcux_data *data = dev->data; in spi_mcux_configure()
570 SPI_Type *base = config->base; in spi_mcux_configure()
577 if (spi_context_configured(&data->ctx, spi_cfg)) { in spi_mcux_configure()
582 if (spi_cfg->operation & SPI_HALF_DUPLEX) { in spi_mcux_configure()
583 LOG_ERR("Half-duplex not supported"); in spi_mcux_configure()
584 return -ENOTSUP; in spi_mcux_configure()
589 master_config.whichPcs = 1U << spi_cfg->slave; in spi_mcux_configure()
590 master_config.whichCtar = config->which_ctar; in spi_mcux_configure()
592 (spi_cfg->operation & SPI_CS_ACTIVE_HIGH) ? in spi_mcux_configure()
595 master_config.samplePoint = config->samplePoint; in spi_mcux_configure()
596 master_config.enableContinuousSCK = config->enable_continuous_sck; in spi_mcux_configure()
597 master_config.enableRxFifoOverWrite = config->enable_rxfifo_overwrite; in spi_mcux_configure()
599 config->enable_modified_timing_format; in spi_mcux_configure()
601 if (spi_cfg->slave > FSL_FEATURE_DSPI_CHIP_SELECT_COUNT) { in spi_mcux_configure()
603 spi_cfg->slave, FSL_FEATURE_DSPI_CHIP_SELECT_COUNT); in spi_mcux_configure()
604 return -EINVAL; in spi_mcux_configure()
607 word_size = SPI_WORD_SIZE_GET(spi_cfg->operation); in spi_mcux_configure()
611 return -EINVAL; in spi_mcux_configure()
614 ctar_config->bitsPerFrame = word_size; in spi_mcux_configure()
616 ctar_config->cpol = in spi_mcux_configure()
617 (SPI_MODE_GET(spi_cfg->operation) & SPI_MODE_CPOL) in spi_mcux_configure()
621 ctar_config->cpha = in spi_mcux_configure()
622 (SPI_MODE_GET(spi_cfg->operation) & SPI_MODE_CPHA) in spi_mcux_configure()
626 ctar_config->direction = in spi_mcux_configure()
627 (spi_cfg->operation & SPI_TRANSFER_LSB) in spi_mcux_configure()
631 ctar_config->baudRate = spi_cfg->frequency; in spi_mcux_configure()
633 ctar_config->pcsToSckDelayInNanoSec = config->pcs_sck_delay; in spi_mcux_configure()
634 ctar_config->lastSckToPcsDelayInNanoSec = config->sck_pcs_delay; in spi_mcux_configure()
635 ctar_config->betweenTransferDelayInNanoSec = config->transfer_delay; in spi_mcux_configure()
637 if (!device_is_ready(config->clock_dev)) { in spi_mcux_configure()
639 return -ENODEV; in spi_mcux_configure()
642 if (clock_control_get_rate(config->clock_dev, config->clock_subsys, in spi_mcux_configure()
644 return -EINVAL; in spi_mcux_configure()
656 data->frame_size = word_size; in spi_mcux_configure()
658 data->which_pcs = 1U << spi_cfg->slave; in spi_mcux_configure()
663 DSPI_MasterTransferCreateHandle(base, &data->handle, in spi_mcux_configure()
670 data->ctx.config = spi_cfg; in spi_mcux_configure()
683 struct spi_mcux_data *data = dev->data; in transceive()
686 const struct spi_mcux_config *config = dev->config; in transceive()
687 SPI_Type *base = config->base; in transceive()
690 spi_context_lock(&data->ctx, asynchronous, cb, userdata, spi_cfg); in transceive()
697 spi_context_buffers_setup(&data->ctx, tx_bufs, rx_bufs, 1); in transceive()
699 spi_context_cs_control(&data->ctx, true); in transceive()
705 /* setup the tx buffer with end */ in transceive()
708 if (config->is_dma_chn_shared) { in transceive()
709 data->transfer_len = data->frame_size >> 3; in transceive()
711 data->transfer_len = data->ctx.tx_len > data->ctx.rx_len ? in transceive()
712 data->ctx.rx_len : in transceive()
713 data->ctx.tx_len; in transceive()
715 data->tx_transfer_count = 0; in transceive()
716 data->rx_transfer_count = 0; in transceive()
725 ret = spi_context_wait_for_completion(&data->ctx); in transceive()
727 spi_context_release(&data->ctx, ret); in transceive()
755 struct spi_mcux_data *data = dev->data; in spi_mcux_release()
757 spi_context_unlock_unconditionally(&data->ctx); in spi_mcux_release()
765 struct spi_mcux_data *data = dev->data; in spi_mcux_init()
766 const struct spi_mcux_config *config = dev->config; in spi_mcux_init()
772 dma_dev = data->rx_dma_config.dma_dev; in spi_mcux_init()
773 data->rx_dma_config.dma_channel = in spi_mcux_init()
775 dma_dev = data->tx_dma_config.dma_dev; in spi_mcux_init()
776 data->tx_dma_config.dma_channel = in spi_mcux_init()
779 config->irq_config_func(dev); in spi_mcux_init()
781 err = pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT); in spi_mcux_init()
786 data->dev = dev; in spi_mcux_init()
788 err = spi_context_cs_configure_all(&data->ctx); in spi_mcux_init()
793 spi_context_unlock_unconditionally(&data->ctx); in spi_mcux_init()
835 DEVICE_DT_GET(DT_INST_DMAS_CTLR_BY_NAME(id, tx)), \
848 id, tx, source), \