Lines Matching +full:hw +full:- +full:rx +full:- +full:buffer +full:- +full:offset

4  * SPDX-License-Identifier: Apache-2.0
9 /* Include esp-idf headers first to avoid redefining BIT() macro */
46 return spi_context_tx_on(&data->ctx) || spi_context_rx_on(&data->ctx); in spi_esp32_transfer_ongoing()
58 spi_context_cs_control(&data->ctx, false); in spi_esp32_complete()
61 spi_context_complete(&data->ctx, dev, status); in spi_esp32_complete()
68 struct spi_esp32_data *data = dev->data; in spi_esp32_transfer()
69 const struct spi_esp32_config *cfg = dev->config; in spi_esp32_transfer()
70 struct spi_context *ctx = &data->ctx; in spi_esp32_transfer()
71 spi_hal_context_t *hal = &data->hal; in spi_esp32_transfer()
72 spi_hal_dev_config_t *hal_dev = &data->dev_config; in spi_esp32_transfer()
73 spi_hal_trans_config_t *hal_trans = &data->trans_config; in spi_esp32_transfer()
74 size_t chunk_len_bytes = spi_context_max_continuous_chunk(&data->ctx) * data->dfs; in spi_esp32_transfer()
76 cfg->dma_enabled ? SPI_DMA_MAX_BUFFER_SIZE : SOC_SPI_MAXIMUM_BUFFER_SIZE; in spi_esp32_transfer()
78 size_t transfer_len_frames = transfer_len_bytes / data->dfs; in spi_esp32_transfer()
82 uint8_t dma_len_tx = MIN(ctx->tx_len * data->dfs, SPI_DMA_MAX_BUFFER_SIZE); in spi_esp32_transfer()
83 uint8_t dma_len_rx = MIN(ctx->rx_len * data->dfs, SPI_DMA_MAX_BUFFER_SIZE); in spi_esp32_transfer()
85 if (cfg->dma_enabled) { in spi_esp32_transfer()
88 if (ctx->tx_buf && !esp_ptr_dma_capable((uint32_t *)&ctx->tx_buf[0])) { in spi_esp32_transfer()
89 LOG_DBG("Tx buffer not DMA capable"); in spi_esp32_transfer()
92 LOG_ERR("Error allocating temp buffer Tx"); in spi_esp32_transfer()
93 return -ENOMEM; in spi_esp32_transfer()
95 memcpy(tx_temp, &ctx->tx_buf[0], dma_len_tx); in spi_esp32_transfer()
97 if (ctx->rx_buf && (!esp_ptr_dma_capable((uint32_t *)&ctx->rx_buf[0]) || in spi_esp32_transfer()
98 ((int)&ctx->rx_buf[0] % 4 != 0) || (dma_len_rx % 4 != 0))) { in spi_esp32_transfer()
99 /* The rx buffer need to be length of in spi_esp32_transfer()
103 LOG_DBG("Rx buffer not DMA capable"); in spi_esp32_transfer()
106 LOG_ERR("Error allocating temp buffer Rx"); in spi_esp32_transfer()
108 return -ENOMEM; in spi_esp32_transfer()
114 memset((uint32_t *)hal->hw->data_buf, 0, sizeof(hal->hw->data_buf)); in spi_esp32_transfer()
115 hal_trans->send_buffer = tx_temp ? tx_temp : (uint8_t *)ctx->tx_buf; in spi_esp32_transfer()
116 hal_trans->rcv_buffer = rx_temp ? rx_temp : ctx->rx_buf; in spi_esp32_transfer()
117 hal_trans->tx_bitlen = bit_len; in spi_esp32_transfer()
118 hal_trans->rx_bitlen = bit_len; in spi_esp32_transfer()
121 hal_trans->cs_keep_active = in spi_esp32_transfer()
122 (!ctx->num_cs_gpios && in spi_esp32_transfer()
123 (ctx->rx_count > 1 || ctx->tx_count > 1 || ctx->rx_len > transfer_len_frames || in spi_esp32_transfer()
124 ctx->tx_len > transfer_len_frames)); in spi_esp32_transfer()
132 spi_context_update_tx(&data->ctx, data->dfs, transfer_len_frames); in spi_esp32_transfer()
142 memcpy(&ctx->rx_buf[0], rx_temp, transfer_len_bytes); in spi_esp32_transfer()
145 spi_context_update_rx(&data->ctx, data->dfs, transfer_len_frames); in spi_esp32_transfer()
157 const struct spi_esp32_config *cfg = dev->config; in spi_esp32_isr()
158 struct spi_esp32_data *data = dev->data; in spi_esp32_isr()
164 spi_esp32_complete(dev, data, cfg->spi, 0); in spi_esp32_isr()
170 const struct spi_esp32_config *cfg = dev->config; in spi_esp32_init_dma()
171 struct spi_esp32_data *data = dev->data; in spi_esp32_init_dma()
174 if (clock_control_on(cfg->clock_dev, (clock_control_subsys_t)cfg->dma_clk_src)) { in spi_esp32_init_dma()
176 return -EIO; in spi_esp32_init_dma()
180 gdma_hal_init(&data->hal_gdma, 0); in spi_esp32_init_dma()
181 gdma_ll_enable_clock(data->hal_gdma.dev, true); in spi_esp32_init_dma()
182 gdma_ll_tx_reset_channel(data->hal_gdma.dev, cfg->dma_host); in spi_esp32_init_dma()
183 gdma_ll_rx_reset_channel(data->hal_gdma.dev, cfg->dma_host); in spi_esp32_init_dma()
184 gdma_ll_tx_connect_to_periph(data->hal_gdma.dev, cfg->dma_host, GDMA_TRIG_PERIPH_SPI, in spi_esp32_init_dma()
185 cfg->dma_host); in spi_esp32_init_dma()
186 gdma_ll_rx_connect_to_periph(data->hal_gdma.dev, cfg->dma_host, GDMA_TRIG_PERIPH_SPI, in spi_esp32_init_dma()
187 cfg->dma_host); in spi_esp32_init_dma()
194 DPORT_SET_PERI_REG_BITS(DPORT_SPI_DMA_CHAN_SEL_REG, 3, cfg->dma_host + 1, in spi_esp32_init_dma()
195 ((cfg->dma_host + 1) * 2)); in spi_esp32_init_dma()
198 data->hal_config.dma_in = (spi_dma_dev_t *)cfg->spi; in spi_esp32_init_dma()
199 data->hal_config.dma_out = (spi_dma_dev_t *)cfg->spi; in spi_esp32_init_dma()
200 data->hal_config.dma_enabled = true; in spi_esp32_init_dma()
201 data->hal_config.tx_dma_chan = cfg->dma_host + channel_offset; in spi_esp32_init_dma()
202 data->hal_config.rx_dma_chan = cfg->dma_host + channel_offset; in spi_esp32_init_dma()
203 data->hal_config.dmadesc_n = 1; in spi_esp32_init_dma()
204 data->hal_config.dmadesc_rx = &data->dma_desc_rx; in spi_esp32_init_dma()
205 data->hal_config.dmadesc_tx = &data->dma_desc_tx; in spi_esp32_init_dma()
207 if (data->hal_config.dmadesc_tx == NULL || data->hal_config.dmadesc_rx == NULL) { in spi_esp32_init_dma()
208 k_free(data->hal_config.dmadesc_tx); in spi_esp32_init_dma()
209 k_free(data->hal_config.dmadesc_rx); in spi_esp32_init_dma()
210 return -ENOMEM; in spi_esp32_init_dma()
213 spi_hal_init(&data->hal, cfg->dma_host + 1, &data->hal_config); in spi_esp32_init_dma()
220 const struct spi_esp32_config *cfg = dev->config; in spi_esp32_init()
221 struct spi_esp32_data *data = dev->data; in spi_esp32_init()
222 spi_hal_context_t *hal = &data->hal; in spi_esp32_init()
224 if (!cfg->clock_dev) { in spi_esp32_init()
225 return -EINVAL; in spi_esp32_init()
228 if (!device_is_ready(cfg->clock_dev)) { in spi_esp32_init()
230 return -ENODEV; in spi_esp32_init()
234 err = clock_control_on(cfg->clock_dev, cfg->clock_subsys); in spi_esp32_init()
240 spi_ll_master_init(hal->hw); in spi_esp32_init()
242 if (cfg->dma_enabled) { in spi_esp32_init()
247 spi_ll_disable_int(cfg->spi); in spi_esp32_init()
248 spi_ll_clear_int_stat(cfg->spi); in spi_esp32_init()
250 err = esp_intr_alloc(cfg->irq_source, in spi_esp32_init()
251 ESP_PRIO_TO_FLAGS(cfg->irq_priority) | in spi_esp32_init()
252 ESP_INT_FLAGS_CHECK(cfg->irq_flags) | ESP_INTR_FLAG_IRAM, in spi_esp32_init()
263 err = spi_context_cs_configure_all(&data->ctx); in spi_esp32_init()
269 cfg->clock_source, ESP_CLK_TREE_SRC_FREQ_PRECISION_APPROX, &data->clock_source_hz); in spi_esp32_init()
275 spi_context_unlock_unconditionally(&data->ctx); in spi_esp32_init()
303 const struct spi_esp32_config *cfg = dev->config; in spi_esp32_configure()
304 struct spi_esp32_data *data = dev->data; in spi_esp32_configure()
305 struct spi_context *ctx = &data->ctx; in spi_esp32_configure()
306 spi_hal_context_t *hal = &data->hal; in spi_esp32_configure()
307 spi_hal_dev_config_t *hal_dev = &data->dev_config; in spi_esp32_configure()
314 ctx->config = spi_cfg; in spi_esp32_configure()
316 if (spi_cfg->operation & SPI_HALF_DUPLEX) { in spi_esp32_configure()
317 LOG_ERR("Half-duplex not supported"); in spi_esp32_configure()
318 return -ENOTSUP; in spi_esp32_configure()
321 if (spi_cfg->operation & SPI_OP_MODE_SLAVE) { in spi_esp32_configure()
323 return -ENOTSUP; in spi_esp32_configure()
326 if (spi_cfg->operation & SPI_MODE_LOOP) { in spi_esp32_configure()
328 return -ENOTSUP; in spi_esp32_configure()
331 hal_dev->cs_pin_id = ctx->config->slave; in spi_esp32_configure()
332 int ret = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT); in spi_esp32_configure()
341 .half_duplex = hal_dev->half_duplex, in spi_esp32_configure()
342 .no_compensate = hal_dev->no_compensate, in spi_esp32_configure()
343 .expected_freq = spi_cfg->frequency, in spi_esp32_configure()
344 .duty_cycle = cfg->duty_cycle == 0 ? 128 : cfg->duty_cycle, in spi_esp32_configure()
345 .input_delay_ns = cfg->input_delay_ns, in spi_esp32_configure()
346 .use_gpio = !cfg->use_iomux, in spi_esp32_configure()
347 .clk_src_hz = data->clock_source_hz, in spi_esp32_configure()
350 spi_hal_cal_clock_conf(&timing_param, &freq, &hal_dev->timing_conf); in spi_esp32_configure()
352 data->trans_config.dummy_bits = hal_dev->timing_conf.timing_dummy; in spi_esp32_configure()
354 hal_dev->tx_lsbfirst = spi_cfg->operation & SPI_TRANSFER_LSB ? 1 : 0; in spi_esp32_configure()
355 hal_dev->rx_lsbfirst = spi_cfg->operation & SPI_TRANSFER_LSB ? 1 : 0; in spi_esp32_configure()
357 data->trans_config.line_mode.data_lines = spi_esp32_get_line_mode(spi_cfg->operation); in spi_esp32_configure()
360 data->trans_config.line_mode.addr_lines = 1; in spi_esp32_configure()
361 data->trans_config.line_mode.cmd_lines = 1; in spi_esp32_configure()
364 hal_dev->mode = 0; in spi_esp32_configure()
365 if (SPI_MODE_GET(spi_cfg->operation) & SPI_MODE_CPHA) { in spi_esp32_configure()
366 hal_dev->mode = BIT(0); in spi_esp32_configure()
368 if (SPI_MODE_GET(spi_cfg->operation) & SPI_MODE_CPOL) { in spi_esp32_configure()
369 hal_dev->mode |= BIT(1); in spi_esp32_configure()
375 hal_dev->cs_hold = cfg->cs_hold; in spi_esp32_configure()
376 hal_dev->cs_setup = cfg->cs_setup; in spi_esp32_configure()
383 spi_dev_t *hw = hal->hw; in spi_esp32_configure() local
385 if (cfg->line_idle_low) { in spi_esp32_configure()
386 hw->ctrl.d_pol = 0; in spi_esp32_configure()
387 hw->ctrl.q_pol = 0; in spi_esp32_configure()
389 hw->ctrl.d_pol = 1; in spi_esp32_configure()
390 hw->ctrl.q_pol = 1; in spi_esp32_configure()
400 if (ctx->num_cs_gpios && (hal_dev->mode & (SPI_MODE_CPOL | SPI_MODE_CPHA))) { in spi_esp32_configure()
410 uint8_t dfs = SPI_WORD_SIZE_GET(spi_cfg->operation); in spi_esp32_get_frame_size()
414 LOG_WRN("Unsupported dfs, 1-byte size will be used"); in spi_esp32_get_frame_size()
427 const struct spi_esp32_config *cfg = dev->config; in transceive()
428 struct spi_esp32_data *data = dev->data; in transceive()
437 return -ENOTSUP; in transceive()
441 spi_context_lock(&data->ctx, asynchronous, cb, userdata, spi_cfg); in transceive()
443 data->dfs = spi_esp32_get_frame_size(spi_cfg); in transceive()
450 spi_context_buffers_setup(&data->ctx, tx_bufs, rx_bufs, data->dfs); in transceive()
452 spi_context_cs_control(&data->ctx, true); in transceive()
455 spi_ll_enable_int(cfg->spi); in transceive()
456 spi_ll_set_int_stat(cfg->spi); in transceive()
463 spi_esp32_complete(dev, data, cfg->spi, 0); in transceive()
468 spi_context_release(&data->ctx, ret); in transceive()
496 struct spi_esp32_data *data = dev->data; in spi_esp32_release()
498 spi_context_unlock_unconditionally(&data->ctx); in spi_esp32_release()
529 .hw = (spi_dev_t *)DT_INST_REG_ADDR(idx), \
551 (clock_control_subsys_t)DT_INST_CLOCKS_CELL(idx, offset), \