Hello, I have passed a fair amount of time doing research on how to use SPI for SDK V2.3/2.4, I manage to get somewhere using this example git project and this other example
As of now, I am doing a bare-bones code to test spi with the mpu9250 to read the who_am_i register.
Here is the register map of the mpu9250/6000
Here is my prj.conf :
CONFIG_SPI=y
here is my devicetree, to use the in i wanted for spi : &spi1_default {
group1 {
psels = <NRF_PSEL(SPIM_MISO, 1, 9)>,
<NRF_PSEL(UART_TX, 1, 8)>,
<NRF_PSEL(SPIM_MOSI, 1, 10)>,
<NRF_PSEL(SPIM_SCK, 1, 11)>;
};
};
And finally here is my main.c :
#include <zephyr/device.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/kernel.h>
#include <zephyr/drivers/spi.h>
#include <zephyr/sys/printk.h>
#define SLEEP_TIME_MS 1000
#define WHO_AM_I_REG 0x71 //Register 117 – Who Am I, you should read the value 0x68
#define USER_CTRL 0x6A //to disable the I2C need to write value 00010000 to this register
#define DISABLE_I2C_VAL 0x10
#define SPI1_NODE DT_NODELABEL(spi1)
static const struct device *spi1_dev = DEVICE_DT_GET(SPI1_NODE);
#define MY_GPIO1 DT_NODELABEL(gpio1)
static const struct device *gpio1_dev = DEVICE_DT_GET(MY_GPIO1);
#define GPIO_1_CS 8 //pin for cs (chip select) //P1.08 on dk
static struct spi_config spi_cfg ={
.frequency = 1000 * 1000,//1M for mpu9250
.operation = SPI_WORD_SET(8) | SPI_MODE_CPOL, //spi mode 3
//.operation = SPI_WORD_SET(8) | SPI_MODE_CPOL | SPI_MODE_CPHA, //to set SPI mode 4
.slave = 0,
// .cs = NULL,
};
static void readRegister (uint8_t reg, uint8_t values[], uint8_t size){
int err;
uint8_t tx_buffer[1];
tx_buffer[0]=reg;
//tx_buffer[1]=0x04; //use to disable i2c for now
struct spi_buf tx_spi_bufs[] = {
{.buf = tx_buffer, .len = sizeof(tx_buffer)},
};
struct spi_buf_set spi_tx_buffer_set = {
.buffers = tx_spi_bufs,
.count = 1
};
struct spi_buf rx_spi_bufs[] = {
{ .buf = values, .len = size }
};
struct spi_buf_set spi_rx_buffer_set = {
.buffers = rx_spi_bufs,
.count = 1
};
gpio_pin_set(gpio1_dev, GPIO_1_CS, 0);
do{
tx_buffer[0]=reg;
err = spi_write(spi1_dev, &spi_cfg, &spi_tx_buffer_set);
if (err < 0){
printk("write Registers failed: %d\n", err);
break;
}
gpio_pin_set(gpio1_dev, GPIO_1_CS, 1); //SINCE IT IS A 8 bit sensor, want to split into 2
k_usleep (2);
gpio_pin_set(gpio1_dev, GPIO_1_CS, 0);
err = spi_read(spi1_dev, &spi_cfg, &spi_rx_buffer_set);
if (err < 0)
printk("Read Registers failed: %d\n", err);
}while (false);
gpio_pin_set(gpio1_dev, GPIO_1_CS, 1);
}
static void readreg (uint8_t reg) {
uint8_t Ans;
uint8_t el;
uint8_t rx_buf_chipid[1];
readRegister(reg, rx_buf_chipid,sizeof(rx_buf_chipid));
Ans = rx_buf_chipid[0];
el = rx_buf_chipid[1];
printk("size of rx : %x\n",sizeof(rx_buf_chipid));
printk("Reg called: 0x%x Answer: 0x%x : else : %X\n", reg,Ans,el);
}
int main(void)
{
int ret;
ret = gpio_pin_configure (gpio1_dev, GPIO_1_CS, GPIO_OUTPUT_HIGH);
//gpio_pin_set(gpio1_dev, GPIO_1_CS, 1); // set up as active high
if (ret < 0) {
printk ("Failed led Config\n");
return;
}
if (!device_is_ready(spi1_dev)) {
printk ("spil_dev not ready\n"); return;
}
//readreg(USER_CTRL);
readreg(WHO_AM_I_REG);
while (1) {
}
return 0;
}
With that code i managed using a Saleae Logic analyser, on logic 2.4.1 to get those signal :
I will provide more photo if needed
but if we compare with the datasheet :
The difference are no answer from the slave + The cs goes low and after that the SPI sets in MODE 3, which I think might be a reason why it doesn't work, but only for the first time.
If you have any link and solution + example on how to implement SPI, I would be very grateful
Thank you for your time,
Mathias