Hello,
i'm trying to use SPI with nrf9160DK as master and RFM96 module as slave. At the moment, i'm developing elementary functions to write and read from my slave device. RFM9X module needs the following settings:
Word size: 8bit, CPOL=0, CPHA=0, Max SPI bus Frequency = 10MHz, CS Active Low, MSB first
The SPI timing sequence for a standard single access is the following:
The MSb of the address byte needs to be 1 if i'm writing, 0 if i'm reading the register.
The pin used in this test are placed in overlay file:
&spi3 { status = "ok"; sck-pin = <10>; mosi-pin = <11>; miso-pin = <12>; spi-max-frequency = <2000000>; };
I used VDD=3V using SW11 of the nrf9160DK. I verified that SPI is generally working using a loopback test. I verified all the connections from the slave side.
This is the code i developed:
#include <zephyr.h> #include <sys/printk.h> #include <drivers/spi.h> #include <stdlib.h> #include <device.h> #include <drivers/gpio.h> #define SPI_READ_REGISTER 0x00 //0 - most significant bit = 0 #define SPI_WRITE_REGISTER 0x80 //128 - most significant bit = 1 #define GPIO_CS 13 struct device * spi_dev; struct device *CS_dev; struct spi_config spi_cfg = { .operation = SPI_WORD_SET(8) | SPI_TRANSFER_MSB, //CPOL=0, CPHA=0 .frequency = 2000000, //Max RFM96 speed is 10MHz .slave = 1, }; struct device* spi_init(struct spi_config * spi_cfg) { struct device *spi_dev; const char* const spiName = "SPI_3"; spi_dev = device_get_binding(spiName); if (spi_dev == NULL) { printk("Could not get %s device\n", spiName); } return spi_dev; } int spi_read_test(struct device * spi_dev, const struct spi_config * spi_cfg, u8_t reg_addr, u8_t * rx_data) { int err; //create the tx buffer - i need to send on MOSI the register address i want to read u8_t tx_buf[1]={SPI_READ_REGISTER|reg_addr}; const struct spi_buf spi_tx_buf = { .buf = tx_buf, .len = sizeof(tx_buf), }; const struct spi_buf_set tx = { .buffers = &spi_tx_buf, .count = 1, }; //write data on spi bus err = spi_write(spi_dev, spi_cfg, &tx); if (err<0) { return err; } //build spi_buf_set element for read const struct spi_buf spi_rx_buf = { .buf = rx_data, .len = 1, }; const struct spi_buf_set rx = { .buffers = &spi_rx_buf, .count = 1, }; err = spi_read(spi_dev, spi_cfg, &rx); return err; } void main(void) { printk("Debug SPI test\n"); //Configure CS device and behaviour CS_dev = device_get_binding(DT_GPIO_P0_DEV_NAME); gpio_pin_configure(CS_dev, GPIO_CS, GPIO_DIR_OUT); gpio_pin_write(CS_dev, GPIO_CS, 1); //PULL CS HIGH //Init spi device (actually pin for CS is useless and it is driven manually) spi_dev = spi_init(&spi_cfg); k_sleep(3000); u8_t rx_data=0; u8_t reg_addr=0x01; gpio_pin_write(CS_dev, GPIO_CS, 0); //PULL CS LOW spi_read_test(spi_dev,&spi_cfg, reg_addr,&rx_data); //i want to read register address 1 gpio_pin_write(CS_dev, GPIO_CS, 1); //PULL CS HIGH printk("Written to reg address: %d\n", reg_addr); printk("Register value: %d\n",rx_data); }
With this code i'm unable to get any consistent answer from my slave device (i noticed that i get always 8 or 0 if the address i use is even/odd...doesn't make any sense). This is a first bunch of fast questions about SPI:
- Is the spi config structure correctly set or i missed anything? In particular i want to be sure that i understood CPOL and CPHA setting;
- What about the "slave" element of spi config structure? I have 1 slave so i suppose i had to set it to 1, but is it really necessary?
- I'm having hard time getting a full grasp about "spi_buf" and "spi_buf_set" structure. While is intuitive understanding why "spi_buf" is structured like this, i don't understand why "spi_buf_set" has a "count" element. Why should i set an array or spi_buf struct?
- Is, in general, the flow described in the above picture reproduced by my code or i am missing anything?
Thanks,
Frax