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