Hello Everyone,
I am using NRF52840 dk evaluation board Arduino ethernet shield which has W5500 ethernet chip and for my development purpose using SDK 2.6.1 on visual studio code.
I am trying to read W5500 version register but always getting the wrong output. Can you check my code and tell me what can be wrong.
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
#include <zephyr/device.h>
#include <zephyr/devicetree.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/drivers/spi.h>
LOG_MODULE_REGISTER(Lesson5_Exercise1, LOG_LEVEL_INF);
#define SPIOP SPI_WORD_SET(8) | SPI_TRANSFER_MSB
const struct gpio_dt_spec ledspec = GPIO_DT_SPEC_GET(DT_NODELABEL(led0), gpios);
struct spi_dt_spec spispec = SPI_DT_SPEC_GET(DT_NODELABEL(w5500), SPIOP, 0);
/* W5500 Control Byte Definitions */
#define W5500_READ 0x00 /* Read operation */
#define W5500_WRITE 0x04 /* Write operation */
#define W5500_VDM 0x00 /* Fixed data length mode */
/* W5500 Block Select Bits (BSB) */
#define W5500_COMMON_REG 0x00 /* Common registers */
#define W5500_SOCKET0_REG 0x08 /* Socket 0 registers */
#define W5500_SOCKET0_TX 0x10 /* Socket 0 TX buffer */
#define W5500_SOCKET0_RX 0x18 /* Socket 0 RX buffer */
/**
* w5500_read_reg - Read data from W5500 register or memory
* @addr: 16-bit address of the register or buffer
* @bsb: Block Select Bits (e.g., W5500_COMMON_REG, W5500_SOCKET0_REG)
* @data: Buffer to store read data
* @len: Number of bytes to read
*
* Returns: 0 on success, negative error code on failure
*/
static int w5500_read_reg(uint16_t addr, uint8_t bsb, uint8_t *data, size_t len)
{
int err;
/* SPI transmit buffer: [Addr High, Addr Low, Control Byte] */
uint8_t tx_buffer[3] = {
(uint8_t)(addr >> 8), /* Address high byte */
(uint8_t)(addr & 0xFF), /* Address low byte */
bsb | W5500_READ | W5500_VDM |0x80 /* Control byte */
};
struct spi_buf tx_spi_buf = {.buf = tx_buffer, .len = sizeof(tx_buffer)};
struct spi_buf_set tx_spi_buf_set = {.buffers = &tx_spi_buf, .count = 1};
/* SPI receive buffer */
struct spi_buf rx_spi_buf = {.buf = data, .len = len};
struct spi_buf_set rx_spi_buf_set = {.buffers = &rx_spi_buf, .count = 1};
/* Perform SPI transaction */
err = spi_transceive_dt(&spispec, &tx_spi_buf_set, &rx_spi_buf_set);
if (err < 0) {
LOG_ERR("w5500_read_reg failed, addr: 0x%04x, err: %d", addr, err);
return err;
}
return 0;
}
/**
* w5500_write_reg - Write data to W5500 register or memory
* @addr: 16-bit address of the register or buffer
* @bsb: Block Select Bits (e.g., W5500_COMMON_REG, W5500_SOCKET0_REG)
* @data: Buffer containing data to write
* @len: Number of bytes to write
*
* Returns: 0 on success, negative error code on failure
*/
static int w5500_write_reg(uint16_t addr, uint8_t bsb, const uint8_t *data, size_t len)
{
int err;
/* SPI transmit buffer: [Addr High, Addr Low, Control Byte, Data...] */
uint8_t *tx_buffer = k_malloc(3 + len);
if (!tx_buffer) {
LOG_ERR("w5500_write_reg: Memory allocation failed");
return -ENOMEM;
}
tx_buffer[0] = (uint8_t)(addr >> 8); /* Address high byte */
tx_buffer[1] = (uint8_t)(addr & 0xFF); /* Address low byte */
tx_buffer[2] = bsb | W5500_WRITE | W5500_VDM; /* Control byte */
memcpy(&tx_buffer[3], data, len); /* Copy data */
struct spi_buf tx_spi_buf = {.buf = tx_buffer, .len = 3 + len};
struct spi_buf_set tx_spi_buf_set = {.buffers = &tx_spi_buf, .count = 1};
/* Perform SPI write */
err = spi_write_dt(&spispec, &tx_spi_buf_set);
k_free(tx_buffer);
if (err < 0) {
LOG_ERR("w5500_write_reg failed, addr: 0x%04x, err: %d", addr, err);
return err;
}
return 0;
}
/* Example usage: Read W5500 Version Register (0x0039) */
int w5500_test_read_version(void)
{
uint8_t version;
int err;
err = w5500_read_reg(0x0039, W5500_COMMON_REG, &version, 1);
if (err < 0) {
LOG_ERR("Failed to read W5500 version, err: %d", err);
return err;
}
LOG_INF("W5500 Version: 0x%02x (expected: 0x04)", version);
return (version == 0x04) ? 0 : -EIO;
}
int main(void)
{
int err;
printk("Welcome\n");
err = spi_is_ready_dt(&spispec);
if (!err) {
LOG_ERR("Error: SPI device is not ready, err: %d", err);
return 0;
}
err = w5500_test_read_version();
if (err < 0) {
LOG_ERR("W5500 test failed");
return err;
}
return 0;
}
my device tree overlay file is as below.
.