I'm struggling with SPI and nRF9160. I've used an old sample (which didn't compile right of the bat):
github.com/.../spi
Seems the CS pin isn't passed on and I'm getting the "spi_nrfx_spim: CS control inhibited (no GPIO device)" error. It fails the check:
if (ctx->config->cs && ctx->config->cs->gpio_dev)
since
ctx->config->cs = 0
ctx->config->cs->gpio_dev = 536877096
If i "fake it" in spi_context.h and hardcode in the cs config:
const struct device *port;
port = device_get_binding(DT_LABEL(DT_NODELABEL(gpio0)));
gpio_pin_configure(port, 13, GPIO_OUTPUT_INACTIVE);
It throws the CS line low (since initial state of GPIO_OUTPUT_INACTIVE is low) and it stays low. If i set it GPIO_OUTPUT_INIT_HIGH, CS stays high. Which is not so strange, since the driver isn't able to hook into the cs pin.
What am I missing?
I read somewhere that SPI only works non-secure, but I see correct data with my Saleae Logic both when building secure and non-secure.
NCS v1.5.0.
West version: v0.10.1
Here is my main.c:
/*
* Copyright (c) 2012-2014 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr.h>
#include <sys/printk.h>
#include <drivers/spi.h>
#define DT_DRV_COMPAT bosch_bmi160 //just for experimenting with DT macros
static const struct spi_config spi_cfg = {
.operation = SPI_WORD_SET(8) | SPI_TRANSFER_MSB |
SPI_MODE_CPOL | SPI_MODE_CPHA,
.frequency = 1000000,
.slave = 0,
.cs = NULL,
};
struct device * spi_dev;
static void spi_init(void)
{
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;
}
}
void spi_test_send(void)
{
int err;
static int8_t tx_buffer[1];
static int8_t rx_buffer[1];
const struct spi_buf tx_buf = {
.buf = tx_buffer,
.len = sizeof(tx_buffer)
};
const struct spi_buf_set tx = {
.buffers = &tx_buf,
.count = 1
};
struct spi_buf rx_buf = {
.buf = rx_buffer,
.len = sizeof(rx_buffer),
};
const struct spi_buf_set rx = {
.buffers = &rx_buf,
.count = 1
};
err = spi_transceive(spi_dev, &spi_cfg, &tx, &rx);
if (err) {
printk("SPI error: %d\n", err);
} else {
/* Connect MISO to MOSI for loopback */
printk("TX sent: %x\n", tx_buffer[0]);
printk("RX recv: %x\n", rx_buffer[0]);
tx_buffer[0]++;
}
}
void main(void)
{
spi_init();
while (1) {
spi_test_send();
k_sleep(K_MSEC(1000));
}
}
nrf9160dk_nrf9160.overlay and nrf9160dk_nrf9160ns.overlay are identical:
&uart3{
status = "disabled";
};
&spi3{
compatible = "nordic,nrf-spim";
status = "okay";
sck-pin = <10>;
mosi-pin = <11>;
miso-pin = <12>;
cs-gpios = <&gpio0 13 GPIO_ACTIVE_LOW>,
<&gpio0 7 GPIO_ACTIVE_LOW>,
<&gpio0 8 GPIO_ACTIVE_LOW>,
<&gpio0 9 GPIO_ACTIVE_LOW>;
accelerometer: bmi160@0 {
compatible = "bosch,bmi160";
status = "okay";
reg = <0>;
spi-max-frequency = <1000000>;
label = "BMI160";
int-gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>;
};
pressure: lps22hb-press@1 {
compatible = "st,lps22hb-press";
spi-max-frequency = <1000000>;
status = "okay";
reg = <1>;
label = "LPS22HB";
};
flashchip: at25sf321bsshbb@2 {
compatible = "jedec,spi-nor";
label = "AT25SF321BSSHBB";
status = "okay";
reg = <2>;
spi-max-frequency = <1000000>;
size = <0x10000000>;
has-dpd;
t-enter-dpd = <1000>;
t-exit-dpd = <30000>;
jedec-id = [1F 47 01];
};
memorycard: sdhc@3 {
compatible = "zephyr,mmc-spi-slot";
reg = <3>;
status = "okay";
label = "SDHC0";
spi-max-frequency = <1000000>;
};
};
prj.conf:
CONFIG_GPIO=y CONFIG_SERIAL=y #Debug Specific CONFIG_DEBUG=y CONFIG_LOG=y CONFIG_LOG_DEFAULT_LEVEL=4 CONFIG_LOG_MAX_LEVEL=4 CONFIG_LOG_BACKEND_UART=y # SPI CONFIG_SPI=y CONFIG_SPI_NRFX=y CONFIG_SPI_3=y CONFIG_NRFX_SPIM3=y CONFIG_MAIN_STACK_SIZE=4096