This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Zephyr SPI MISO returns 0 for 52840dk

Hello,

Having now finished the BLE and I2C sensor my final stop is the SPI sensor before production. I can rebuild and successfully run the ncs playground example.

My issue is regarding reading the MISO line however, for the sake of simplicity I typically trial SPI on an ADXL345 or a SPI ADC by another vendor. Unfortunately, while I can send the data via MOSI, shown in the logic analyzer breakdown, MISO only responds with 0x00.

0x2D Send0xC0 Send

I understand that the approach isn’t ideal, but currently don’t have the knowledge and skills of building a driver using Zephyr (undoubtedly a difficult and time-consuming task!). Therefore, my code is as follows:

#include <zephyr.h>
#include <sys/printk.h>
#include <drivers/spi.h>

#define DT_DRV_COMPAT nordic_nrf_spim

struct spi_cs_control spi_cs = {
	.gpio_pin = DT_GPIO_PIN(DT_DRV_INST(0), cs_gpios),
	.gpio_dt_flags = GPIO_ACTIVE_LOW,
	.delay = 0,
};

static struct spi_config spi_cfg = {
	.operation = SPI_WORD_SET(8) | SPI_TRANSFER_MSB | SPI_MODE_CPOL | SPI_MODE_CPHA,
	.frequency = 5000000,
	.slave = 0,
	.cs = &spi_cs,
};

const struct device *spi_dev;

static void spi_init(void)
{
	spi_cs.gpio_dev = device_get_binding(DT_GPIO_LABEL(DT_DRV_INST(0), cs_gpios));

	if (spi_cs.gpio_dev == NULL)
	{
		printk("Could not get gpio device\n");
	}
	else
	{
		printk("GPIO device: %s\n", DT_GPIO_LABEL(DT_DRV_INST(0), cs_gpios));
	}

	spi_dev = device_get_binding(DT_LABEL(DT_DRV_INST(0)));

	if (spi_dev == NULL)
	{
		printk("Could not get %s device\n", DT_LABEL(DT_DRV_INST(0)));
		return;
	}
	else
	{
		printk("SPI Device: %s\n", DT_LABEL(DT_DRV_INST(0)));
		printk("SPI CSN %d, MISO %d, MOSI %d, CLK %d\n",
			   DT_GPIO_PIN(DT_DRV_INST(0), cs_gpios),
			   DT_PROP(DT_DRV_INST(0), miso_pin),
			   DT_PROP(DT_DRV_INST(0), mosi_pin),
			   DT_PROP(DT_DRV_INST(0), sck_pin));
	}
}

void spi_test_send(uint8_t address, uint8_t value)
{
	int err;
	uint8_t tx_buffer[2] = {address, value};
	uint8_t rx_buffer[2];

	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, %x\n", tx_buffer[0], tx_buffer[1]);
		printk("RX recv: %x, %x\n", rx_buffer[0], rx_buffer[1]);
	}
}

void write_test(uint8_t address, uint8_t value)
{
	spi_test_send(address, value);
}

void main(void)
{
	printk("SPIM Example\n");
	spi_init();
	k_sleep(K_MSEC(1000));
	write_test(0x2d, 0x00);
	while (1)
	{

		write_test(0xC0, 0x00);
		k_sleep(K_MSEC(1000));
	}
}
&spi1 {
	compatible = "nordic,nrf-spim";
	status = "okay";
	sck-pin = <28>;
	mosi-pin = <47>;
	miso-pin = <40>;
	cs-gpios = <&gpio0 29 GPIO_ACTIVE_LOW>;
	clock-frequency = <5000000>;

};

The code basically takes the simple example from here and creates a write function with an address and value argument pair. My expectation is that if I send 0xC0 and then a dummy value, 0xFF, that it should return 0xE5, the device ID built in as shown in the datasheet on page 23. 0xC0 due to the first two bits needed for read and multi-byte (datasheet page 16), although even leaving it as (0x00 | 0x80) I had no luck either.

The 0x2D value is another pair to make sure the device is reset.

Attempts at troubleshooting:

  1. I was worried perhaps I’m not giving the ADXL345 enough time from bootup, so I added some sleep delays, no changes.
  2. I started the frequency at 5mhz as per datasheet, and began progressively lowering it to 500khz, no luck.
  3. I replaced the IC with a different, newer, breakout board. Same results, just 0x00.

Apologies for the influx of questions, very new to zephyr and Nordic, with SPI out of the way I can hopefully focus more on the work than troubleshooting!

Regards

DM

  • Hi Simonr,

    Its late here but fortunately I saw your message to comment. You are indeed correct, it is the SPI device, I unluckily have two damaged adxl345s which is why it wasn’t working!!

    Thanks for confirming the code, I tested it on a different board and it worked so I guess I’ll be ordering new chips tomorrow morning.

    Regards

    DM

Related