Hello,
I am trying to send and receive data from an external slave sensor using the NRF5340. For debugging purposes, I have connected the NRF5340 to my PC via UART.
#include <zephyr/kernel.h> #include <zephyr/device.h> #include <zephyr/drivers/spi.h> #include <zephyr/drivers/uart.h> #include <zephyr/drivers/gpio.h> // Include GPIO header file #include <zephyr/sys/printk.h> #include <zephyr/sys/byteorder.h> // Include for byte order conversion functions (if necessary) #include <stdio.h> // printk can be used via stdio.h or zephyr/sys/printk.h /* Get SPI device from Devicetree */ #define SPI_DEVICE_NODE DT_ALIAS(spi4_basic) // Set to the DT alias of the actual SPI controller being used static const struct device *spi_dev = DEVICE_DT_GET(SPI_DEVICE_NODE); // It's just getting it in two steps instead of all at once. Ultimately, it gets spi_dev. /* Get UART device from Devicetree (uses the same UART as printk) */ static const struct device *uart_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_console)); /* Get Chip Select pin configuration from Devicetree */ static const struct spi_cs_control cs_ctrl = SPI_CS_GPIOS_DT_SPEC_GET(SPI_DEVICE_NODE); /* RHD2000 SPI Configuration */ // RHD2000 uses SPI Mode 0 (CPOL=0, CPHA=0) // Data is 16-bit, MSB first static struct spi_config spi_cfg = { .frequency = 560000, // SPI frequency .operation = SPI_OP_MODE_MASTER | SPI_WORD_SET(16) | SPI_TRANSFER_MSB, // Default settings: CPOL=0, CPHA=0 .slave = 0, .cs = cs_ctrl, }; /* 16-bit SPI Communication Helper Function */ static int rhd_spi_transfer(uint16_t tx_command, uint16_t *rx_data) { uint16_t mosi_word = tx_command; uint16_t miso_word = 0; struct spi_buf tx_buf = { .buf = &mosi_word, .len = sizeof(mosi_word) }; const struct spi_buf_set tx_bufs = { .buffers = &tx_buf, .count = 1 }; // count: Information on how many parts it will be divided into struct spi_buf rx_buf = { .buf = &miso_word, .len = sizeof(miso_word) }; const struct spi_buf_set rx_bufs = { .buffers = &rx_buf, .count = 1 }; int err; // spi_dev itself is an address. Others (spi_cfg, etc.) are structs. printk("Calling spi_transceive()\n"); err = spi_transceive(spi_dev, &spi_cfg, &tx_bufs, &rx_bufs); printk("spi_transceive() completed\n"); if (err) { printk("spi_transceive() failed with error %d\n", err); return err; } if (rx_data) { *rx_data = miso_word; } return 0; } /* RHD2132 Initialization Function */ int main(void) { uint16_t miso_val; int err; printk("Executing initialization function.\n"); k_msleep(1000); // Wait for 1000 milliseconds (1 second) // According to the RHD2000 datasheet, a dummy SPI transaction may be required for initialization rhd_spi_transfer(RHD_CMD_DUMMY_READ, &miso_val); // transfer printk("Dummy1.\n"); return 0; }
To get to the point, the problem I'm facing is that the spi_transceive()
function seems to be stuck in an infinite loop.
The message "Calling spi_transceive()" is printed, but there is no response after that.
I suspect there might be an issue with how the CS pin is being handled, but I'm not sure what the exact problem is.
I have also attached the .conf
and .overlay
files I am using.
CONFIG_UART_CONSOLE=y
CONFIG_SERIAL=y
CONFIG_PRINTK=y
# Kernel
CONFIG_MAIN_STACK_SIZE=2048
CONFIG_SPI=y
CONFIG_GPIO=y
CONFIG_GPIO_NRFX=y
/ {
chosen {
zephyr,console = &uart0;
zephyr,shell-uart = &uart0;
};
aliases {
spi4-basic = &spi4;
};
};
&uart0 {
status = "okay";
current-speed = <1000000>;
};
&pinctrl {
spi4_custom_pins: spi4_custom_pins {
group1 {
psels = <NRF_PSEL(SPIM_SCK, 1, 15)>,
<NRF_PSEL(SPIM_MOSI, 1, 14)>,
<NRF_PSEL(SPIM_MISO, 1, 13)>;
};
};
spi4_custom_pins_sleep: spi4_custom_pins_sleep {
group1 {
psels = <NRF_PSEL(SPIM_SCK, 1, 15)>,
<NRF_PSEL(SPIM_MOSI, 1, 14)>,
<NRF_PSEL(SPIM_MISO, 1, 13)>;
low-power-enable;
};
};
};
&spi4 {
compatible = "nordic,nrf-spim";
status = "okay";
pinctrl-0 = <&spi4_custom_pins>;
pinctrl-1 = <&spi4_custom_pins_sleep>;
pinctrl-names = "default", "sleep";
cs-gpios = <&gpio1 12 GPIO_ACTIVE_LOW>;
};
Thank you.
Best regards, Minseok Kim