Resolving 'SPI Device Not Ready' Error on AVR Microcontroller with Zephyr RTOS

hey guys, I am attempting to set up SPI communication on an AVR microcontroller running Zephyr RTOS to acquire data from an SPI temperature sensor (MCP9808) and send it to an IoT cloud platform, I have configured the SPI peripheral in the prj.conf file, created a Zephyr SPI device binding in the device tree source file (dts), writing an application to read temperature data from the MCP9808 sensor. But am getting the error, what could be wrong?
SPI device not ready
SPI device not ready
I have verified the device tree source configuration to ensure proper SPI peripheral settings, checked the pin configurations to match the hardware setup, made sure the MCP9808 sensor is connected correctly to the SPI pins.
#include <zephyr.h>
#include <device.h>
#include <drivers/spi.h>
#include <logging/log.h>

LOG_MODULE_REGISTER(main);

#define MCP9808_SPI DT_NODELABEL(mcp9808)

static const struct spi_config spi_cfg = {
.frequency = 1000000U,
.operation = SPI_WORD_SET(8) | SPI_TRANSFER_MSB,
.slave = 0,
.cs = NULL,
};

void main(void) {
const struct device *spi_dev = DEVICE_DT_GET(MCP9808_SPI);

if (!device_is_ready(spi_dev)) {
LOG_ERR("SPI device not ready");
return;
}

uint8_t tx_buf[1] = {0x05}; // Register to read temperature
uint8_t rx_buf[2];
struct spi_buf tx = {.buf = tx_buf, .len = sizeof(tx_buf)};
struct spi_buf rx = {.buf = rx_buf, .len = sizeof(rx_buf)};
struct spi_buf_set tx_set = {.buffers = &tx, .count = 1};
struct spi_buf_set rx_set = {.buffers = &rx, .count = 1};

int ret = spi_transceive(spi_dev, &spi_cfg, &tx_set, &rx_set);
if (ret) {
LOG_ERR("SPI transceive failed: %d", ret);
return;
}


int temp = ((rx_buf[0] << 8) | rx_buf[1]) & 0x0FFF;
temp /= 16;

LOG_INF("Temperature: %d C", temp);
}
#include <zephyr.h>
#include <device.h>
#include <drivers/spi.h>
#include <logging/log.h>

LOG_MODULE_REGISTER(main);

#define MCP9808_SPI DT_NODELABEL(mcp9808)

static const struct spi_config spi_cfg = {
.frequency = 1000000U,
.operation = SPI_WORD_SET(8) | SPI_TRANSFER_MSB,
.slave = 0,
.cs = NULL,
};

void main(void) {
const struct device *spi_dev = DEVICE_DT_GET(MCP9808_SPI);

if (!device_is_ready(spi_dev)) {
LOG_ERR("SPI device not ready");
return;
}

uint8_t tx_buf[1] = {0x05}; // Register to read temperature
uint8_t rx_buf[2];
struct spi_buf tx = {.buf = tx_buf, .len = sizeof(tx_buf)};
struct spi_buf rx = {.buf = rx_buf, .len = sizeof(rx_buf)};
struct spi_buf_set tx_set = {.buffers = &tx, .count = 1};
struct spi_buf_set rx_set = {.buffers = &rx, .count = 1};

int ret = spi_transceive(spi_dev, &spi_cfg, &tx_set, &rx_set);
if (ret) {
LOG_ERR("SPI transceive failed: %d", ret);
return;
}


int temp = ((rx_buf[0] << 8) | rx_buf[1]) & 0x0FFF;
temp /= 16;

LOG_INF("Temperature: %d C", temp);
}
Solution:
thanks again guys after following these verifications and adjustments, the SPI communication with the MCP9808 sensor is functioning as expected! I've achieved successful temperature data readings and logging. Appreciate your assistance once more!
Jump to solution
7 Replies
Dtynin
Dtynin4mo ago
I expected to see the temperature data logged as an information message if the communication was successful. I am using Zephyr 3.6.0 version. Could anyone suggest what might be going wrong or what additional checks I should perform?
RED HAT
RED HAT4mo ago
Hey @Dtynin , it sounds like you've made good progress with your setup. The error you're encountering, "SPI device not ready," typically indicates that the SPI device isn't being initialized properly or isn't ready when your application tries to access it. you should Ensure that the device tree entry for your SPI controller (spi@... node) in your .dts file is correctly configured and verify the compatible property matches the SPI driver you're using and that the SPI pins (sck, mosi, miso, cs-gpios) are correctly assigned and configured, check your SPI configuration in the prj.conf file and Ensure the SPI bus number, frequency, and other settings (SPI_WORD_SET, SPI_TRANSFER_MSB) match the hardware requirements of your MCP9808 sensor, and verify that the Zephyr SPI driver (drivers/spi.h) supports the configuration parameters you've set (spi_cfg). Sometimes, mismatches in configuration can lead to initialization failures.
Dark AI
Dark AI4mo ago
@Dtynin also ensure that the SPI device binding (DEVICE_DT_GET(MCP9808_SPI)) correctly refers to the MCP9808 sensor node in your device tree. Double-check the DT_NODELABEL(mcp9808) matches the label used in your device tree (dts) file.
Enthernet Code
Enthernet Code4mo ago
@Dtynin in addition to the answers u ahv received also consider adding debug logs to trace the initialization process and see where exactly the error occurs. You can add logs before and after the DEVICE_DT_GET call to ensure it's fetching the SPI device correctly.
Dtynin
Dtynin4mo ago
thanks for the headsup @RED HAT I have Verified the device tree entry
(spi@...)
(spi@...)
and ensured all SPI pins
(sck, mosi, miso, cs-gpios)
(sck, mosi, miso, cs-gpios)
are correctly defined and match my hardware setup. also I Double-checked the
prj.conf
prj.conf
file to ensure the SPI bus number, frequency (1 MHz), and other settings
(SPI_WORD_SET(8), SPI_TRANSFER_MSB)
(SPI_WORD_SET(8), SPI_TRANSFER_MSB)
align with the
MCP9808
MCP9808
sensor requirements.
Dtynin
Dtynin4mo ago
@Dark AI I also confirmed the SPI device binding
DEVICE_DT_GET(MCP9808_SPI)
DEVICE_DT_GET(MCP9808_SPI)
correctly points to the MCP9808 sensor node in the device tree.
Solution
Dtynin
Dtynin4mo ago
thanks again guys after following these verifications and adjustments, the SPI communication with the MCP9808 sensor is functioning as expected! I've achieved successful temperature data readings and logging. Appreciate your assistance once more!
Want results from more Discord servers?
Add your server