SPI does not send address in master mode

marekg
Posts: 10
Joined: Thu Apr 18, 2019 2:08 pm

SPI does not send address in master mode

Postby marekg » Thu Apr 18, 2019 2:41 pm

Hello,

I am struggling with SPI in master mode.
I want to send address plus buffer with help of function spi_device_queue_trans but SPI does not send address and send only data.

SPI device is configured like this:

Code: Select all

    spi_device_interface_config_t sx1276_config =  {           
                .clock_speed_hz = (SPI_SX1276_BUS_CLOCK_MHZ),   //Clock out at 10 MHz. 
                .mode=0,                                        //SPI mode 0 (CPOL=0, CPHA=0)
                .spics_io_num   = PIN_NUM_SX1276_CS,            //CS pin 
                .queue_size     = 1,                            //Transaction queue size.
                .address_bits   = 8,
                .cs_ena_pretrans = 1,                           //one clock delay prior CS line is active
                .cs_ena_posttrans= 1,                           //one clock delay after CS line is released
        };

    //Initialise the SPI bus for both devices
    spi_error_ret=spi_bus_initialize(HSPI_HOST, &spi_bus_config, NO_SPI_DMA_CHANNEL);
    ESP_ERROR_CHECK(spi_error_ret);   //SPI bus error handling

    //Attach to SPI bus
    spi_error_ret = spi_bus_add_device(HSPI_HOST, &sx1276_config, &spi_sx1276_handle);
    ESP_ERROR_CHECK(spi_error_ret);   //SPI bus error handling
SPI function to send data is as follow:

Code: Select all

static void spi1_Send_Data_To_SX1276_Device(spi_device_handle_t spi_sx1276_handle, uint8_t addr, uint8_t *buffer, uint16_t size)
{
    static spi_transaction_t spi_transaction;
    memset(&spi_transaction, 0, sizeof(spi_transaction_t));
[Codebox=c file=Untitled.c][Codebox=c file=Untitled.c][/Codebox][/Codebox]
    spi_transaction.flags = SPI_DEVICE_HALFDUPLEX;      //SPI_TRANS_USE_TXDATA,
    spi_transaction.addr = (uint8_t) addr;
    spi_transaction.length =  8 + (size * 8);           // data length is in bits
    spi_transaction.tx_buffer = buffer;
    spi_transaction.rx_buffer = NULL;

    spi_error_ret = spi_device_queue_trans(spi_sx1276_handle, &spi_transaction, SPI_SX1276_TICKS_TIMEOUT_MS);   //queue data to send
    ESP_ERROR_CHECK(spi_error_ret);       //SPI bus error handling
}
With this configuration SPI sends only data buffer and not address.
Target is to send address plus data.

Do you have any idea what could be wrong in my code, please?
Thank you

ESP_Sprite
Posts: 8921
Joined: Thu Nov 26, 2015 4:08 am

Re: SPI does not send address in master mode

Postby ESP_Sprite » Fri Apr 19, 2019 2:35 am

Hmm, at first glance I don't think you're doing wrong (apart from the fact that the length in a transaction is supposed to be just the data length; you don't need to add the address length as well.) Just for completeness sake: how did you conclude the address isn't sent?

ESP_michael
Posts: 37
Joined: Mon Aug 28, 2017 10:25 am

Re: SPI does not send address in master mode

Postby ESP_michael » Fri Apr 19, 2019 7:45 am

Hi,

The cs_ena_pretrans and address phase are not compatible in full duplex mode, please see:
https://espressif-docs.readthedocs-host ... _pretransE

The driver automatically set the address length to 0 if you enable the cs_ena_pretrans in full duplex mode. If you remove this, your transaction will goes infinitely.

We may add check for this in the future, but since the address can be variable among transactions, you should still be aware of this
marekg wrote:
Thu Apr 18, 2019 2:41 pm
Hello,

I am struggling with SPI in master mode.
I want to send address plus buffer with help of function spi_device_queue_trans but SPI does not send address and send only data.

SPI device is configured like this:

Code: Select all

    spi_device_interface_config_t sx1276_config =  {           
                .clock_speed_hz = (SPI_SX1276_BUS_CLOCK_MHZ),   //Clock out at 10 MHz. 
                .mode=0,                                        //SPI mode 0 (CPOL=0, CPHA=0)
                .spics_io_num   = PIN_NUM_SX1276_CS,            //CS pin 
                .queue_size     = 1,                            //Transaction queue size.
                .address_bits   = 8,
                .cs_ena_pretrans = 1,                           //one clock delay prior CS line is active
                .cs_ena_posttrans= 1,                           //one clock delay after CS line is released
        };

    //Initialise the SPI bus for both devices
    spi_error_ret=spi_bus_initialize(HSPI_HOST, &spi_bus_config, NO_SPI_DMA_CHANNEL);
    ESP_ERROR_CHECK(spi_error_ret);   //SPI bus error handling

    //Attach to SPI bus
    spi_error_ret = spi_bus_add_device(HSPI_HOST, &sx1276_config, &spi_sx1276_handle);
    ESP_ERROR_CHECK(spi_error_ret);   //SPI bus error handling
SPI function to send data is as follow:

Code: Select all

static void spi1_Send_Data_To_SX1276_Device(spi_device_handle_t spi_sx1276_handle, uint8_t addr, uint8_t *buffer, uint16_t size)
{
    static spi_transaction_t spi_transaction;
    memset(&spi_transaction, 0, sizeof(spi_transaction_t));
[Codebox=c file=Untitled.c][Codebox=c file=Untitled.c][/Codebox][/Codebox]
    spi_transaction.flags = SPI_DEVICE_HALFDUPLEX;      //SPI_TRANS_USE_TXDATA,
    spi_transaction.addr = (uint8_t) addr;
    spi_transaction.length =  8 + (size * 8);           // data length is in bits
    spi_transaction.tx_buffer = buffer;
    spi_transaction.rx_buffer = NULL;

    spi_error_ret = spi_device_queue_trans(spi_sx1276_handle, &spi_transaction, SPI_SX1276_TICKS_TIMEOUT_MS);   //queue data to send
    ESP_ERROR_CHECK(spi_error_ret);       //SPI bus error handling
}
With this configuration SPI sends only data buffer and not address.
Target is to send address plus data.

Do you have any idea what could be wrong in my code, please?
Thank you

marekg
Posts: 10
Joined: Thu Apr 18, 2019 2:08 pm

Re: SPI does not send address in master mode

Postby marekg » Tue Apr 23, 2019 5:22 am

Thank you all for your ideas.
In the mean time I found the root cause and it is functional now.
It was necessary to use spi_transaction_ext_t configuration.

Code snippet looks like this:

Code: Select all

void spi1_Init_Spi_Bus(void)
{
    spi_device_interface_config_t spi_expander_config = {   //declaration for expander SPI device
            .clock_speed_hz = (SPI_EXPANDER_BUS_CLOCK_MHZ),  //Clock out at 10 MHz. Max. clock is 10MHz due to LoRa SX1276 transceiver limitations
            .mode=0,                                        //SPI mode 0
            .spics_io_num   = PIN_NUM_EXPANDER_CS,          //CS pin for expander
            .queue_size     = 1,                            //Transaction queue size. This sets how many transactions can be ‘in the air’ (queued using spi_device_queue_trans but not yet finished using spi_device_get_trans_result) at the same time.
            .post_cb        = spi1_Post_Transfer_Callback,   //Specify post-transfer callback to handle I/O lines
    };

    spi_device_interface_config_t sx1276_config =  {            //declaration for LoRa SX1276 transceiver
                .clock_speed_hz = (SPI_SX1276_BUS_CLOCK_MHZ),   //Clock out at 10 MHz. Max. clock is 10MHz due to LoRa SX1276 transceiver limitations
                .mode=0,                                        //SPI mode 0 (CPOL=0, CPHA=0)
                .spics_io_num   = PIN_NUM_SX1276_CS,            //CS pin for LoRa SX1276 transceiver
                .queue_size     = 1,                            //Transaction queue size. This sets how many transactions can be ‘in the air’ (queued using spi_device_queue_trans but not yet finished using spi_device_get_trans_result) at the same time.
                .command_bits   = 0,
                .address_bits   = 8,
                //.cs_ena_pretrans = 1,                           //one clock delay prior CS line is active
                //.cs_ena_posttrans= 1,                           //one clock delay after CS line is released
                .dummy_bits     = 0,                          //added dummy bits
                //.post_cb        = spi1_Post_Transfer_Callback,   //Specify post-transfer callback to handle I/O lines
        };

    //Initialise the SPI bus for both devices
    spi_error_ret=spi_bus_initialize(HSPI_HOST, &spi_bus_config, NO_SPI_DMA_CHANNEL);
    ESP_ERROR_CHECK(spi_error_ret);   //SPI bus error handling

    //Attach the expander device to the SPI bus
    spi_error_ret = spi_bus_add_device(HSPI_HOST, &spi_expander_config, &spi_expander_handle);
    ESP_ERROR_CHECK(spi_error_ret);   //SPI bus error handling

    //Attach the SX1276 tranceiver chip to SPI bus
    spi_error_ret = spi_bus_add_device(HSPI_HOST, &sx1276_config, &spi_sx1276_handle);
    ESP_ERROR_CHECK(spi_error_ret);   //SPI bus error handling
}

Code: Select all

static void spi1_Send_Data_To_SX1276_Device(spi_device_handle_t spi_sx1276_handle, uint8_t addr, uint8_t *buffer, uint16_t size)
{
    spi_transaction_ext_t spi_transaction = (spi_transaction_ext_t) {           //extended transaction is required because of different address length
        .base = {
                .flags = ( SPI_TRANS_VARIABLE_ADDR | SPI_TRANS_VARIABLE_CMD ),  //define various address and command length
                .addr = (uint8_t) addr,                                         //set address
                .length = size * 8,                                             //data length
                .tx_buffer = buffer,                                            //pointer to TX buffer
                .rx_buffer = NULL,                                              //no RX buffer
        },
        .command_bits = 0,                                                      //zero command bits
        .address_bits = 8,                                                      //eight address bits
        .dummy_bits = 0,                                                        //zero dummy bits
    };

    spi_error_ret = spi_device_queue_trans(spi_sx1276_handle, (spi_transaction_t*)&spi_transaction, SPI_SX1276_TICKS_TIMEOUT_MS);   //queue data to send
    ESP_ERROR_CHECK(spi_error_ret);       //SPI bus error handling
}

Who is online

Users browsing this forum: No registered users and 124 guests