Open mtmsweb opened 5 years ago
Hi @mtmsweb ,
Could you provide the timing diagram of the slave device you are communicating with? The mode should met the timing of the slave.
Maybe you can try mode 0 by setting the mode
field to 0 in the spi_device_interface_config_t
config structure. Mode 0 read and writes half a clock earlier than mode 1.
Slave device is TI's ADC- ADS1220. Datasheet link: http://www.ti.com/lit/ds/symlink/ads1220.pdf Timing about page 38. As I said (edit:or wanted to say) changing mode and even adding .input_delay_ns changes nothing. In each mode I receive same (shifted) data. I got two codes one in arduino (that works- bits are not shifted), one in esp-idf (bites shifted): Arduino:
#include <SPI.h>
#define DEFAULT_CONFIG_REG0 0b00000000
#define DEFAULT_CONFIG_REG1 0b00000000
#define DEFAULT_CONFIG_REG2 0b00000000
#define DEFAULT_CONFIG_REG3 0b00000000
#define ADS1220_CS_PIN 5
#define WREG 0x40
#define RREG 0x20
#define SPI_MASTER_DUMMY 0xFF
void writeSingleRegister(uint8_t address, const uint8_t value) {
digitalWrite(ADS1220_CS_PIN, LOW);
SPI.transfer(WREG | (address<<2));
SPI.transfer(value);
digitalWrite(ADS1220_CS_PIN,HIGH);
}
uint8_t readRegister(uint8_t address) {
uint8_t data;
digitalWrite(ADS1220_CS_PIN,LOW);
SPI.transfer(RREG|(address<<2));
data = SPI.transfer(SPI_MASTER_DUMMY);
digitalWrite(ADS1220_CS_PIN,HIGH);
return data;
}
void setup() {
Serial.begin(115200);
pinMode(ADS1220_CS_PIN, OUTPUT);
SPI.begin();
SPI.setDataMode (SPI_MODE1);
Serial.println("DEFAULT_CONFIG_REG.. : ");
writeSingleRegister( 0, DEFAULT_CONFIG_REG0 );
writeSingleRegister( 1, DEFAULT_CONFIG_REG1 );
writeSingleRegister( 2, DEFAULT_CONFIG_REG2 );
writeSingleRegister( 3, DEFAULT_CONFIG_REG3 );
delay(100);
Serial.println(readRegister(0),HEX);
Serial.println(readRegister(1),HEX);
Serial.println(readRegister(2),HEX);
Serial.println(readRegister(3),HEX);
Serial.println(" ");
}
void loop() {}
ESP-IDF:
spi_device_handle_t spi;
char * rx_buffer;
void spi_init() {
spi_bus_config_t buscfg = {
.miso_io_num=PIN_NUM_SPI_MISO,
.mosi_io_num=PIN_NUM_SPI_MOSI,
.sclk_io_num=PIN_NUM_SPI_CLK,
.quadwp_io_num=-1, .quadhd_io_num=-1,
};
spi_device_interface_config_t devcfg = {
.spics_io_num=PIN_NUM_SPI_ADC_CS,
.clock_speed_hz=5*1000*1000, // 5MHz
.mode=1, // SPI MODE 1
.command_bits=8, // 8-bit command length
.address_bits=0, // no address
.queue_size=20,
//.input_delay_ns = 25 // minimum of td(SCCS) = 25ns
};
ESP_ERROR_CHECK(spi_bus_initialize(VSPI_HOST, &buscfg, 1/*dma_chan - 0 no DMA*/));
ESP_ERROR_CHECK(spi_bus_add_device(VSPI_HOST, &devcfg, &spi));
}
void writeSingleRegister(uint8_t address, const uint8_t value) {
spi_transaction_t transaction;
memset(&transaction, 0, sizeof(transaction));
transaction.cmd = WREG | (address<<2);
transaction.length = 8;
transaction.tx_buffer = &value;
assert(spi_device_polling_transmit(spi, &transaction) == ESP_OK);
}
void readSingleRegister(uint8_t address) {
spi_transaction_t transaction;
memset(&transaction, 0, sizeof(transaction));
transaction.cmd = RREG | (address<<2);
transaction.length = 8;
transaction.rx_buffer = rx_buffer;
assert(spi_device_polling_transmit(spi, &transaction) == ESP_OK);
ESP_LOG_BUFFER_HEX("readSingleRegister:", rx_buffer, 1 );
}
void spi_task(void *pvParameters) {
rx_buffer = heap_caps_malloc(4, MALLOC_CAP_DMA);
spi_init();
while (1) {
ESP_LOGI(TAG, "DEFAULT_CONFIG_REG.. : ");
writeSingleRegister(0, DEFAULT_CONFIG_REG0);
writeSingleRegister(1, DEFAULT_CONFIG_REG1);
writeSingleRegister(2, DEFAULT_CONFIG_REG2);
writeSingleRegister(3, DEFAULT_CONFIG_REG3);
vTaskDelay(1000 / portTICK_RATE_MS);
ESP_LOGI(TAG, "Read: ");
readSingleRegister(0);
readSingleRegister(1);
readSingleRegister(2);
readSingleRegister(3);
vTaskDelay(5000 / portTICK_RATE_MS);
}
}
Above example: arduino results 0x00, esp-idf 0x80 (1st bit high)
I am able to simulate IDF behavior in arduino by setting SPI.setDataMode (SPI_MODE2) edit: I am also wondering what happends when I do not set tx_buffer. Random bytes are send or DUMMY 0xFF?
Example code provides no clues on how to receive anything from SPI device. Each my try point me to the conclusion that driver doesnt work properly or there is no enough informations to use it. I am trying to test SPI device by sending configuration and than reading configuration register. Code looks like below.
Unfortunately code doesnt work. Random bytes are printed from rx_data. Please point me right track for a solution. There are some, important for me, questions in code comments.
EDIT: Received bytes seems to be not random values but valid values shifted one bit right (0x03 is 0x81 and next byte is 0x80)