kopia lustrzana https://github.com/espressif/esp-idf
spi_master: add support for variable dummy length in a same device
Resolves https://github.com/espressif/esp-idf/issues/2741pull/3175/head
rodzic
140b6e3893
commit
b812520b19
|
@ -109,6 +109,7 @@ typedef struct {
|
|||
#define SPI_TRANS_MODE_DIOQIO_ADDR (1<<4) ///< Also transmit address in mode selected by SPI_MODE_DIO/SPI_MODE_QIO
|
||||
#define SPI_TRANS_VARIABLE_CMD (1<<5) ///< Use the ``command_bits`` in ``spi_transaction_ext_t`` rather than default value in ``spi_device_interface_config_t``.
|
||||
#define SPI_TRANS_VARIABLE_ADDR (1<<6) ///< Use the ``address_bits`` in ``spi_transaction_ext_t`` rather than default value in ``spi_device_interface_config_t``.
|
||||
#define SPI_TRANS_VARIABLE_DUMMY (1<<7) ///< Use the ``dummy_bits`` in ``spi_transaction_ext_t`` rather than default value in ``spi_device_interface_config_t``.
|
||||
|
||||
/**
|
||||
* This structure describes one SPI transaction. The descriptor should not be modified until the transaction finishes.
|
||||
|
@ -148,6 +149,7 @@ typedef struct {
|
|||
struct spi_transaction_t base; ///< Transaction data, so that pointer to spi_transaction_t can be converted into spi_transaction_ext_t
|
||||
uint8_t command_bits; ///< The command length in this transaction, in bits.
|
||||
uint8_t address_bits; ///< The address length in this transaction, in bits.
|
||||
uint8_t dummy_bits; ///< The dummy length in this transaction, in bits.
|
||||
} spi_transaction_ext_t ;
|
||||
|
||||
|
||||
|
|
|
@ -871,8 +871,14 @@ static void SPI_MASTER_ISR_ATTR spi_new_trans(spi_device_t *dev, spi_trans_priv_
|
|||
|
||||
//SPI iface needs to be configured for a delay in some cases.
|
||||
//configure dummy bits
|
||||
host->hw->user.usr_dummy=(dev->cfg.dummy_bits+extra_dummy) ? 1 : 0;
|
||||
host->hw->user1.usr_dummy_cyclelen=dev->cfg.dummy_bits+extra_dummy-1;
|
||||
int base_dummy_bits;
|
||||
if (trans->flags & SPI_TRANS_VARIABLE_DUMMY) {
|
||||
base_dummy_bits = ((spi_transaction_ext_t *)trans)->dummy_bits;
|
||||
} else {
|
||||
base_dummy_bits = dev->cfg.dummy_bits;
|
||||
}
|
||||
host->hw->user.usr_dummy=(base_dummy_bits+extra_dummy) ? 1 : 0;
|
||||
host->hw->user1.usr_dummy_cyclelen=base_dummy_bits+extra_dummy-1;
|
||||
|
||||
int miso_long_delay = 0;
|
||||
if (dev->clk_cfg.miso_delay<0) {
|
||||
|
|
|
@ -855,6 +855,84 @@ TEST_CASE("SPI master variable cmd & addr test","[spi]")
|
|||
ESP_LOGI(MASTER_TAG, "test passed.");
|
||||
}
|
||||
|
||||
void test_dummy(spi_device_handle_t spi, int dummy_n, uint8_t* data_to_send, int len)
|
||||
{
|
||||
ESP_LOGI(TAG, "testing dummy n=%d", dummy_n);
|
||||
WORD_ALIGNED_ATTR uint8_t slave_buffer[len+(dummy_n+7)/8];
|
||||
spi_slave_transaction_t slave_t = {
|
||||
.tx_buffer = slave_buffer,
|
||||
.rx_buffer = slave_buffer,
|
||||
.length = len*8+((dummy_n+7)&(~8))+32, //receive more bytes to avoid slave discarding data
|
||||
};
|
||||
TEST_ESP_OK(spi_slave_queue_trans(TEST_SLAVE_HOST, &slave_t, portMAX_DELAY));
|
||||
|
||||
vTaskDelay(50);
|
||||
|
||||
spi_transaction_ext_t t = {
|
||||
.base = {
|
||||
.tx_buffer = data_to_send,
|
||||
.length = (len+1)*8, //send one more byte force slave receive all data
|
||||
.flags = SPI_TRANS_VARIABLE_DUMMY,
|
||||
},
|
||||
.dummy_bits = dummy_n,
|
||||
};
|
||||
TEST_ESP_OK(spi_device_transmit(spi, (spi_transaction_t*)&t));
|
||||
|
||||
spi_slave_transaction_t *ret_slave;
|
||||
TEST_ESP_OK(spi_slave_get_trans_result(TEST_SLAVE_HOST, &ret_slave, portMAX_DELAY));
|
||||
TEST_ASSERT(ret_slave == &slave_t);
|
||||
|
||||
ESP_LOG_BUFFER_HEXDUMP("rcv", slave_buffer, len+4, ESP_LOG_INFO);
|
||||
int skip_cnt = dummy_n/8;
|
||||
int dummy_remain = dummy_n % 8;
|
||||
uint8_t *slave_ptr = slave_buffer;
|
||||
if (dummy_remain > 0) {
|
||||
for (int i = 0; i < len; i++) {
|
||||
slave_ptr[0] = (slave_ptr[skip_cnt] << dummy_remain) | (slave_ptr[skip_cnt+1] >> (8-dummy_remain));
|
||||
slave_ptr++;
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < len; i++) {
|
||||
slave_ptr[0] = slave_ptr[skip_cnt];
|
||||
slave_ptr++;
|
||||
}
|
||||
}
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(data_to_send, slave_buffer, len);
|
||||
}
|
||||
|
||||
TEST_CASE("SPI master variable dummy test", "[spi]")
|
||||
{
|
||||
spi_device_handle_t spi;
|
||||
spi_bus_config_t bus_cfg = SPI_BUS_TEST_DEFAULT_CONFIG();
|
||||
spi_device_interface_config_t dev_cfg = SPI_DEVICE_TEST_DEFAULT_CONFIG();
|
||||
dev_cfg.flags = SPI_DEVICE_HALFDUPLEX;
|
||||
|
||||
TEST_ESP_OK(spi_bus_initialize(TEST_SPI_HOST, &bus_cfg, 0));
|
||||
TEST_ESP_OK(spi_bus_add_device(TEST_SPI_HOST, &dev_cfg, &spi));
|
||||
|
||||
spi_slave_interface_config_t slave_cfg =SPI_SLAVE_TEST_DEFAULT_CONFIG();
|
||||
TEST_ESP_OK(spi_slave_initialize(TEST_SLAVE_HOST, &bus_cfg, &slave_cfg, 0));
|
||||
|
||||
spitest_gpio_output_sel(bus_cfg.mosi_io_num, FUNC_GPIO, spi_periph_signal[TEST_SPI_HOST].spid_out);
|
||||
spitest_gpio_output_sel(bus_cfg.miso_io_num, FUNC_GPIO, spi_periph_signal[TEST_SLAVE_HOST].spiq_out);
|
||||
spitest_gpio_output_sel(dev_cfg.spics_io_num, FUNC_GPIO, spi_periph_signal[TEST_SPI_HOST].spics_out[0]);
|
||||
spitest_gpio_output_sel(bus_cfg.sclk_io_num, FUNC_GPIO, spi_periph_signal[TEST_SPI_HOST].spiclk_out);
|
||||
|
||||
uint8_t data_to_send[] = {0x12, 0x34, 0x56, 0x78};
|
||||
|
||||
test_dummy(spi, 0, data_to_send, sizeof(data_to_send));
|
||||
test_dummy(spi, 1, data_to_send, sizeof(data_to_send));
|
||||
test_dummy(spi, 2, data_to_send, sizeof(data_to_send));
|
||||
test_dummy(spi, 3, data_to_send, sizeof(data_to_send));
|
||||
test_dummy(spi, 4, data_to_send, sizeof(data_to_send));
|
||||
test_dummy(spi, 8, data_to_send, sizeof(data_to_send));
|
||||
test_dummy(spi, 12, data_to_send, sizeof(data_to_send));
|
||||
test_dummy(spi, 16, data_to_send, sizeof(data_to_send));
|
||||
|
||||
spi_slave_free(TEST_SLAVE_HOST);
|
||||
master_free_device_bus(spi);
|
||||
}
|
||||
|
||||
/********************************************************************************
|
||||
* Test SPI transaction interval
|
||||
********************************************************************************/
|
||||
|
|
Ładowanie…
Reference in New Issue