|
9 | 9 | #include "driver/gpio.h" |
10 | 10 | #include "esp_private/gpio.h" |
11 | 11 | #include "hal/gpio_hal.h" |
| 12 | +#include "hal/spi_ll.h" |
12 | 13 | #include "esp_rom_gpio.h" |
13 | 14 |
|
14 | 15 | int test_freq_default[] = TEST_FREQ_DEFAULT(); |
@@ -232,49 +233,81 @@ void spitest_gpio_input_sel(uint32_t gpio_num, int func, uint32_t signal_idx) |
232 | 233 | esp_rom_gpio_connect_in_signal(gpio_num, signal_idx, 0); |
233 | 234 | } |
234 | 235 |
|
235 | | -//Note this cs_dev_id is the ID of the connected devices' ID, e.g. if 2 devices are connected to the bus, |
236 | | -//then the cs_dev_id of the 1st and 2nd devices are 0 and 1 respectively. |
237 | | -void same_pin_func_sel(spi_bus_config_t bus, spi_device_interface_config_t dev, uint8_t cs_dev_id) |
| 236 | +void same_pin_func_sel(spi_bus_config_t bus, uint8_t cs_pin, uint8_t cs_dev_id, bool soft_master) |
238 | 237 | { |
239 | | - spitest_gpio_output_sel(bus.mosi_io_num, FUNC_GPIO, spi_periph_signal[TEST_SPI_HOST].spid_out); |
| 238 | + spitest_gpio_output_sel(bus.mosi_io_num, FUNC_GPIO, soft_master ? SIG_GPIO_OUT_IDX : spi_periph_signal[TEST_SPI_HOST].spid_out); |
240 | 239 | spitest_gpio_input_sel(bus.mosi_io_num, FUNC_GPIO, spi_periph_signal[TEST_SLAVE_HOST].spid_in); |
241 | 240 |
|
242 | 241 | spitest_gpio_output_sel(bus.miso_io_num, FUNC_GPIO, spi_periph_signal[TEST_SLAVE_HOST].spiq_out); |
243 | | - spitest_gpio_input_sel(bus.miso_io_num, FUNC_GPIO, spi_periph_signal[TEST_SPI_HOST].spiq_in); |
| 242 | + spitest_gpio_input_sel(bus.miso_io_num, FUNC_GPIO, soft_master ? SIG_GPIO_OUT_IDX : spi_periph_signal[TEST_SPI_HOST].spiq_in); |
244 | 243 |
|
245 | | - spitest_gpio_output_sel(dev.spics_io_num, FUNC_GPIO, spi_periph_signal[TEST_SPI_HOST].spics_out[cs_dev_id]); |
246 | | - spitest_gpio_input_sel(dev.spics_io_num, FUNC_GPIO, spi_periph_signal[TEST_SLAVE_HOST].spics_in); |
| 244 | + gpio_set_level(cs_pin, 1); //ensure CS is inactive when select to soft_master and before transaction start |
| 245 | + spitest_gpio_output_sel(cs_pin, FUNC_GPIO, soft_master ? SIG_GPIO_OUT_IDX : spi_periph_signal[TEST_SPI_HOST].spics_out[cs_dev_id]); |
| 246 | + spitest_gpio_input_sel(cs_pin, FUNC_GPIO, spi_periph_signal[TEST_SLAVE_HOST].spics_in); |
247 | 247 |
|
248 | | - spitest_gpio_output_sel(bus.sclk_io_num, FUNC_GPIO, spi_periph_signal[TEST_SPI_HOST].spiclk_out); |
| 248 | + spitest_gpio_output_sel(bus.sclk_io_num, FUNC_GPIO, soft_master ? SIG_GPIO_OUT_IDX : spi_periph_signal[TEST_SPI_HOST].spiclk_out); |
249 | 249 | spitest_gpio_input_sel(bus.sclk_io_num, FUNC_GPIO, spi_periph_signal[TEST_SLAVE_HOST].spiclk_in); |
250 | 250 | } |
251 | 251 |
|
252 | | -void spi_master_trans_impl_gpio(spi_bus_config_t bus, uint8_t cs_pin, uint8_t speed_hz, void *tx, void *rx, uint32_t len) |
| 252 | +#define GPIO_MAX_FREQ 500*1000 //max of soft spi clock at delay(0) |
| 253 | +void spi_master_trans_impl_gpio(spi_bus_config_t bus, uint8_t cs_pin, uint32_t speed_hz, uint8_t *tx, uint8_t *rx, uint32_t len, bool hold_cs) |
253 | 254 | { |
254 | | - uint8_t *u8_tx = tx, *u8_rx = rx; |
255 | | - gpio_set_level(cs_pin, 1); //ensure CS is inactive before transaction start |
256 | | - esp_rom_gpio_connect_out_signal(cs_pin, SIG_GPIO_OUT_IDX, 0, 0); |
257 | | - esp_rom_gpio_connect_out_signal(bus.sclk_io_num, SIG_GPIO_OUT_IDX, 0, 0); |
258 | | - esp_rom_gpio_connect_out_signal(bus.mosi_io_num, SIG_GPIO_OUT_IDX, 0, 0); |
259 | | - esp_rom_gpio_connect_in_signal(bus.miso_io_num, SIG_GPIO_OUT_IDX, 0); |
260 | | - |
261 | | - gpio_set_level(cs_pin, 0); |
262 | | - vTaskDelay(1); // cs_ena_pre_trans |
| 255 | + gpio_dev_t *hw = GPIO_LL_GET_HW(0); |
| 256 | + uint32_t half_duty_us = speed_hz ? ((GPIO_MAX_FREQ + speed_hz / 2) / speed_hz / 2) : 0; |
| 257 | + |
| 258 | + gpio_ll_set_level(hw, cs_pin, 0); |
263 | 259 | for (uint32_t index = 0; index < len; index ++) { |
264 | 260 | uint8_t rx_data = 0; |
265 | 261 | for (uint8_t bit = 0x80; bit > 0; bit >>= 1) { |
266 | 262 | // mode 0, output data first |
267 | | - gpio_set_level(bus.mosi_io_num, (u8_tx) ? (u8_tx[index] & bit) : 0); |
268 | | - vTaskDelay(1); |
269 | | - gpio_set_level(bus.sclk_io_num, 1); |
| 263 | + gpio_ll_set_level(hw, bus.mosi_io_num, (tx) ? (tx[index] & bit) : 0); |
| 264 | + esp_rom_delay_us(half_duty_us); |
270 | 265 | rx_data <<= 1; |
271 | 266 | rx_data |= gpio_get_level(bus.miso_io_num); |
272 | | - vTaskDelay(1); |
273 | | - gpio_set_level(bus.sclk_io_num, 0); |
| 267 | + gpio_ll_set_level(hw, bus.sclk_io_num, 1); |
| 268 | + esp_rom_delay_us(half_duty_us); |
| 269 | + gpio_ll_set_level(hw, bus.sclk_io_num, 0); |
274 | 270 | } |
275 | | - if (u8_rx) { |
276 | | - u8_rx[index] = rx_data; |
| 271 | + if (rx) { |
| 272 | + rx[index] = rx_data; |
277 | 273 | } |
278 | 274 | } |
279 | | - gpio_set_level(cs_pin, 1); |
| 275 | + if (!hold_cs) { |
| 276 | + gpio_ll_set_level(hw, cs_pin, 1); |
| 277 | + } |
| 278 | +} |
| 279 | + |
| 280 | +#if SOC_SPI_SUPPORT_SLAVE_HD_VER2 |
| 281 | +void essl_sspi_hd_dma_trans_seg(spi_bus_config_t bus, uint8_t cs_pin, uint32_t speed_hz, bool is_rx, void *buffer, int len, int seg_len) |
| 282 | +{ |
| 283 | + uint8_t cmd_addr_dummy[3] = {0, 0, 0}; |
| 284 | + uint8_t *tx = is_rx ? NULL : buffer; |
| 285 | + uint8_t *rx = is_rx ? buffer : NULL; |
| 286 | + |
| 287 | + seg_len = (seg_len > 0) ? seg_len : len; |
| 288 | + cmd_addr_dummy[0] = spi_ll_get_slave_hd_base_command(is_rx ? SPI_CMD_HD_RDDMA : SPI_CMD_HD_WRDMA); |
| 289 | + while (len > 0) { |
| 290 | + spi_master_trans_impl_gpio(bus, cs_pin, speed_hz, cmd_addr_dummy, NULL, sizeof(cmd_addr_dummy), true); |
| 291 | + |
| 292 | + int send_len = (seg_len <= len) ? seg_len : len; |
| 293 | + spi_master_trans_impl_gpio(bus, cs_pin, speed_hz, tx, rx, send_len, false); |
| 294 | + len -= send_len; |
| 295 | + tx += tx ? send_len : 0; |
| 296 | + rx += rx ? send_len : 0; |
| 297 | + } |
| 298 | + |
| 299 | + cmd_addr_dummy[0] = spi_ll_get_slave_hd_base_command(is_rx ? SPI_CMD_HD_INT0 : SPI_CMD_HD_WR_END); |
| 300 | + spi_master_trans_impl_gpio(bus, cs_pin, speed_hz, cmd_addr_dummy, NULL, sizeof(cmd_addr_dummy), false); |
| 301 | +} |
| 302 | + |
| 303 | +void essl_sspi_hd_buffer_trans(spi_bus_config_t bus, uint8_t cs_pin, uint32_t speed_hz, spi_command_t cmd, uint8_t addr, void *buffer, uint32_t len) |
| 304 | +{ |
| 305 | + uint8_t cmd_addr_dummy[3] = {0, addr, 0}; |
| 306 | + cmd_addr_dummy[0] = spi_ll_get_slave_hd_base_command(cmd); |
| 307 | + uint8_t *tx = (cmd == SPI_CMD_HD_RDBUF) ? NULL : buffer; |
| 308 | + uint8_t *rx = (cmd == SPI_CMD_HD_RDBUF) ? buffer : NULL; |
| 309 | + |
| 310 | + spi_master_trans_impl_gpio(bus, cs_pin, speed_hz, cmd_addr_dummy, NULL, sizeof(cmd_addr_dummy), true); |
| 311 | + spi_master_trans_impl_gpio(bus, cs_pin, speed_hz, tx, rx, len, false); |
280 | 312 | } |
| 313 | +#endif //SOC_SPI_SUPPORT_SLAVE_HD_VER2 |
0 commit comments