Problem with converting arduino SPI into IDF

vishal.borle
Posts: 13
Joined: Thu May 07, 2020 1:32 pm

Problem with converting arduino SPI into IDF

Postby vishal.borle » Thu May 14, 2020 4:43 am

Hello to all,
We have started using ESP32 IDF in that SPI communication with ADE9000 chip. But problem getting able to read version.
Here is below code snippet.

Code: Untitled.c Select all

[void ade_cmd(spi_device_handle_t spi, const uint16_t cmd)
{
esp_err_t ret;
spi_transaction_t t;
memset(&t, 0, sizeof(t)); //Zero out the transaction
t.length=16; //Command is 16 bits
t.tx_buffer=&cmd; //The data is the cmd itself
t.user=(void*)0; //D/C needs to be set to 0
ret=spi_device_polling_transmit(spi, &t); //Transmit!
assert(ret==ESP_OK); //Should have had no issues.
}

//This function is called (in irq context!) just before a transmission starts. It will
//set the D/C line to the value indicated in the user field.
void lcd_spi_pre_transfer_callback(spi_transaction_t *t)
{
int dc=(int)t->user;
gpio_set_level(PIN_NUM_CS, dc);
}


uint32_t ade_get_version(spi_device_handle_t spi)
{
uint16_t Address = 0x000004FE;
uint16_t temp_address;

temp_address = (((Address << 4) & 0xFFF0)+8);
ade_cmd(spi, temp_address);

spi_transaction_t t;
memset(&t, 0, sizeof(t));
t.length=8*4;
t.flags = SPI_TRANS_USE_RXDATA;
t.user = (void*)1;

esp_err_t ret = spi_device_polling_transmit(spi, &t);
assert( ret == ESP_OK );
// gpio_set_level(PIN_NUM_CS, 1);
printf("ADE9000 VERSION 1 byte: %02X%02X%02X%02X\n", t.rx_data[0],t.rx_data[1],t.rx_data[2],t.rx_data[3]);
printf("ADE9000 VERSION before: %08X\n", *(uint32_t*)t.rx_data);
return *(uint32_t*)t.rx_data;
}
void ade9000_init(spi_device_handle_t spi)
{
gpio_set_direction(PIN_NUM_RST, GPIO_MODE_OUTPUT);
//Reset the display
gpio_set_level(PIN_NUM_RST, 0);
vTaskDelay(100 / portTICK_RATE_MS);
gpio_set_level(PIN_NUM_RST, 1);
vTaskDelay(100 / portTICK_RATE_MS);

uint32_t ade_version = ade_get_version(spi);
printf("ADE9000 VERSION: %08X\n", ade_version);

}

void app_main(void)
{
esp_err_t ret;
spi_device_handle_t spi;
spi_bus_config_t buscfg={
.miso_io_num=PIN_NUM_MISO,
.mosi_io_num=PIN_NUM_MOSI,
.sclk_io_num=PIN_NUM_CLK,
.quadwp_io_num=-1,
.quadhd_io_num=-1,
//.max_transfer_sz=PARALLEL_LINES*320*2+8
};
spi_device_interface_config_t devcfg={
#ifdef CONFIG_LCD_OVERCLOCK
.clock_speed_hz=26*1000*1000, //Clock out at 26 MHz
#else
.clock_speed_hz=10*1000*1000, //Clock out at 10 MHz
#endif
.mode=0, //SPI mode 0
.spics_io_num=PIN_NUM_CS, //CS pin
.queue_size=7, //We want to be able to queue 7 transactions at a time
//.pre_cb=lcd_spi_pre_transfer_callback, //Specify pre-transfer callback to handle D/C line
};
//Initialize the SPI bus
ret=spi_bus_initialize(HSPI_HOST, &buscfg, DMA_CHAN);
ESP_ERROR_CHECK(ret);
//Attach the LCD to the SPI bus
ret=spi_bus_add_device(HSPI_HOST, &devcfg, &spi);
ESP_ERROR_CHECK(ret);
//Initialize the LCD
//lcd_init(spi);
ade9000_init(spi);
//Initialize the effect displayed
/*ret=pretty_effect_init();
ESP_ERROR_CHECK(ret);

//Go do nice stuff.
display_pretty_colors(spi);*/
}]

Working Arduino code is
[Codebox=c file=Untitled.c][void ADE9000Class::SPI_Init(uint32_t SPI_speed , uint8_t chipSelect_Pin)
{
SPI.begin(); //Initiate SPI port
SPI.beginTransaction(SPISettings(SPI_speed,MSBFIRST,SPI_MODE0)); //Setup SPI parameters
pinMode(chipSelect_Pin, OUTPUT); //Set Chip select pin as output
digitalWrite(chipSelect_Pin, HIGH); //Set Chip select pin high

_chipSelect_Pin = chipSelect_Pin;
}
uint32_t ADE9000Class:: SPI_Read_32(uint16_t Address)
{
uint16_t temp_address;
uint16_t temp_highpacket;
uint16_t temp_lowpacket;
uint32_t returnData;
digitalWrite(_chipSelect_Pin, LOW);
temp_address = (((Address << 4) & 0xFFF0)+8);
SPI.transfer16(temp_address);
temp_highpacket = SPI.transfer16(0);
temp_lowpacket = SPI.transfer16(0);
digitalWrite(_chipSelect_Pin, HIGH);
returnData = temp_highpacket << 16;
returnData = returnData + temp_lowpacket;
return returnData;

}]
I am new in IDF please provide me sample SPI code with how write and read data.
Looking forward your response.
Thank you........

Sprite
Espressif staff
Espressif staff
Posts: 10596
Joined: Thu Nov 26, 2015 4:08 am

Re: Problem with converting arduino SPI into IDF

Postby Sprite » Thu May 14, 2020 7:55 am

Do you happen to have a LA or oscilloscope you can use to look at the signals? Makes it easier to figure out what's going wrong here.

vishal.borle
Posts: 13
Joined: Thu May 07, 2020 1:32 pm

Re: Problem with converting arduino SPI into IDF

Postby vishal.borle » Thu May 14, 2020 10:09 am

Thanks for the replay....
NO currently not having any instruments. Can you tell me Is my SPI program looks correct?
How I can do my SPI code working.
Thanks...

Sprite
Espressif staff
Espressif staff
Posts: 10596
Joined: Thu Nov 26, 2015 4:08 am

Re: Problem with converting arduino SPI into IDF

Postby Sprite » Thu May 14, 2020 2:03 pm

Nothing that I can see. lcd_spi_pre_transfer_callback in your code is a bit suspicious, but because the line that uses it is commented out, it shouldn't stop your program from working.

vishal.borle
Posts: 13
Joined: Thu May 07, 2020 1:32 pm

Re: Problem with converting arduino SPI into IDF

Postby vishal.borle » Fri May 15, 2020 4:07 am

But in my program I am not using any D/C line so that's why I have commented this line.

Sprite
Espressif staff
Espressif staff
Posts: 10596
Joined: Thu Nov 26, 2015 4:08 am

Re: Problem with converting arduino SPI into IDF

Postby Sprite » Fri May 15, 2020 7:20 am

Yes, I saw, and that is fine, it's just a bit confusing to anyone who reads it that that routine still is in there.

vishal.borle
Posts: 13
Joined: Thu May 07, 2020 1:32 pm

Re: Problem with converting arduino SPI into IDF

Postby vishal.borle » Fri May 15, 2020 7:37 am

I am getting strange for next What should I do now, We need to find solution as soon as possible. My other confusion is it neccessary to send dummy byte to read bytes from slave.
I am send 16 bit address to read interface ADE chip version.
Here is below code:

Code: Untitled.c Select all

[void ade_cmd(spi_device_handle_t spi, const uint16_t cmd)
{
esp_err_t ret;
spi_transaction_t t;
memset(&t, 0, sizeof(t)); //Zero out the transaction
t.length=16; //Command is 16 bits
t.tx_buffer=&cmd; //The data is the cmd itself
t.user=(void*)0; //D/C needs to be set to 0
ret=spi_device_polling_transmit(spi, &t); //Transmit!
assert(ret==ESP_OK); //Should have had no issues.
}


uint32_t ade_get_version(spi_device_handle_t spi)
{
//get_id cmd
uint16_t Address = 0x000004FE; //Address of read ADE version 16 bit address
uint16_t temp_address;
// gpio_set_level(PIN_NUM_CS, 0); // no necessary to handle chip select pin
temp_address = (((Address << 4) & 0xFFF0)+8); // this done in arduino library code
ade_cmd(spi, temp_address);

spi_transaction_t t;
memset(&t, 0, sizeof(t));
t.length=8*4; //length of recive buffer in bit
t.flags = SPI_TRANS_USE_RXDATA;
t.user = (void*)1;
// esp_err_t ret = spi_device_polling_transmit(spi, &t);
// assert( ret == ESP_OK );
esp_err_t ret = spi_device_transmit(spi, &t);
assert( ret == ESP_OK );

// gpio_set_level(PIN_NUM_CS, 1);
printf("ADE9000 VERSION all bytes: %02X%02X%02X%02X\n", t.rx_data[0],t.rx_data[1],t.rx_data[2],t.rx_data[3]);
printf("ADE9000 VERSION before: %08X\n", *(uint32_t*)t.rx_data);
return *(uint32_t*)t.rx_data;
}]

Sprite
Espressif staff
Espressif staff
Posts: 10596
Joined: Thu Nov 26, 2015 4:08 am

Re: Problem with converting arduino SPI into IDF

Postby Sprite » Sat May 16, 2020 5:56 am

Sorry, you are getting a strange whatnow?

vishal.borle
Posts: 13
Joined: Thu May 07, 2020 1:32 pm

Re: Problem with converting arduino SPI into IDF

Postby vishal.borle » Sat May 16, 2020 7:16 am

Can you please give me ans of few questions:
I am trying to read version of ADE9000 chip for SPI communication with below code
uint32_t ade_get_version(spi_device_handle_t spi)
{
uint16_t Address = 0x000004FE; //Address of read ADE version 16 bit address
uint16_t temp_address;
uint32_t returnData;
// gpio_set_level(PIN_NUM_CS, 0); // no necessary to handle chip select pin
temp_address = (((Address << 4) & 0xFFF0)+8); // this done in arduino library code

spi_transaction_t t;
memset(&t, 0, sizeof(t));
t.length=8*4; //length of recive buffer in bit
t.cmd = temp_address;
// t.tx_buffer=0;
t.flags = SPI_TRANS_USE_RXDATA;
esp_err_t ret = spi_device_transmit(spi, &t);
assert( ret == ESP_OK );

// gpio_set_level(PIN_NUM_CS, 1);
printf("ADE9000 VERSION all bytes: %02X%02X%02X%02X\n", t.rx_data[0],t.rx_data[1],t.rx_data[2],t.rx_data[3]);
printf("ADE9000 VERSION before: %08X\n", *(uint32_t*)t.rx_data);
return *(uint32_t*)t.rx_data;
}
This code return ADE9000 VERSION: EF097F00 but vesion is FE13DE
In datasheet given SPI waveform I have attached here.
Questions:
Is my code snippet is looks correct?
If any changes is need where I need to change?

Thanks for your support..!!
Attachments
spi.PNG
spi.PNG (27.88 KiB) Viewed 9564 times

rsimpsonbusa
Posts: 131
Joined: Tue May 17, 2016 8:12 pm

Re: Problem with converting arduino SPI into IDF

Postby rsimpsonbusa » Mon May 18, 2020 2:09 am

In

Code: Select all

spi_transaction_t t;
    memset(&t, 0, sizeof(t));
    t.length=8*4;
    t.flags = SPI_TRANS_USE_RXDATA;
    t.user = (void*)1;
try setting the t.rxlength to a specific number fo bits. If u want all 4 bytes of USE_RXDATA then set it to 32. Maybe this can help.

I looks like u are confusing the transmission data length (t.length) with the receive length (t.rxlength) buffer for receiving.

As I see it, the SPI will try to SEND 32 bits from the t.tx_buffer (not set in your code) and receive 0 bits into the internal 4 bytes buffer (USE_RX_DATA).

BTW, bzero(&t, sizeof(t)) is faster...

Hope it helps.

Who is online

Users browsing this forum: Baidu [Spider], Qwantbot, Semrush [Bot] and 2 guests