Skip to content

Commit

Permalink
drivers: ethernet: w5500: Add support for WIZ550io module
Browse files Browse the repository at this point in the history
WIZ550io is a W5500 breakout board with an extra PIC12F519 MCU.
The PIC12F519 MCU initialises the W5500 with a unique MAC address
after a GPIO reset. The PIC12F519 requires a 150ms delay after GPIO
reset to configure the W5500. There is an additional "ready" GPIO
signal that can be used to reduce that delay.

Add support for the "ready" GPIO signal and using the WIZ550io
preconfigured MAC address.

Signed-off-by: Grant Ramsay <gramsay@enphaseenergy.com>
  • Loading branch information
gramsay0 committed May 8, 2024
1 parent 49d6b6b commit e7537f7
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 1 deletion.
56 changes: 55 additions & 1 deletion drivers/ethernet/eth_w5500.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,16 @@ LOG_MODULE_REGISTER(eth_w5500, CONFIG_ETHERNET_LOG_LEVEL);
#define W5500_SPI_WRITE_CONTROL(addr) \
((W5500_SPI_BLOCK_SELECT(addr) << 3) | BIT(2))

/* W5500 datasheet recommends 1ms delay after hardware reset for
* internal PLL to stabilize.
*/
#define W5500_RESET_DELAY K_MSEC(1)

/* WIZ550io documentation recommends 150ms delay after HW reset
* for PIC12F519 MCU to configure the W5500.
*/
#define WIZ550IO_RESET_DELAY K_MSEC(150)

static int w5500_spi_read(const struct device *dev, uint32_t addr,
uint8_t *data, uint32_t len)
{
Expand Down Expand Up @@ -567,10 +577,51 @@ static int w5500_init(const struct device *dev)
LOG_ERR("Unable to configure GPIO pin %u", config->reset.pin);
return -EINVAL;
}
gpio_pin_set_dt(&config->reset, 0);
gpio_pin_set_dt(&config->reset, 1);
k_usleep(500);
gpio_pin_set_dt(&config->reset, 0);
}

#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(ready_gpios)
if (config->ready.port) {
if (!gpio_is_ready_dt(&config->ready)) {
LOG_ERR("GPIO port %s not ready", config->ready.port->name);
return -EINVAL;
}
if (gpio_pin_configure_dt(&config->ready, GPIO_INPUT)) {
LOG_ERR("Unable to configure GPIO pin %u", config->ready.pin);
return -EINVAL;
}

k_timepoint_t timeout = sys_timepoint_calc(WIZ550IO_RESET_DELAY);

while (!gpio_pin_get_dt(&config->ready)) {
if (sys_timepoint_expired(timeout)) {
LOG_ERR("W5500 not ready");
return -ETIMEDOUT;
}
k_msleep(1);
}
} else
#endif
{
k_sleep(W5500_RESET_DELAY);
}

#if !DT_INST_PROP(0, zephyr_random_mac_address) && !NODE_HAS_VALID_MAC_ADDR(DT_DRV_INST(0))
/* If neither a random or fixed MAC address is specified,
* default to the MAC address in the device.
* WIZ550io module has a preconfigured unique MAC address
* assigned by the PIC12F519 after hardware reset. It needs to
* be read out after a hardware reset and before software reset.
*/
err = w5500_spi_read(dev, W5500_SHAR, ctx->mac_addr, sizeof(ctx->mac_addr));
if (err) {
LOG_ERR("Unable to read MAC address");
return -EIO;
}
#endif

err = w5500_soft_reset(dev);
if (err) {
LOG_ERR("Reset failed");
Expand Down Expand Up @@ -615,6 +666,9 @@ static const struct w5500_config w5500_0_config = {
.interrupt = GPIO_DT_SPEC_INST_GET(0, int_gpios),
.reset = GPIO_DT_SPEC_INST_GET_OR(0, reset_gpios, { 0 }),
.timeout = CONFIG_ETH_W5500_TIMEOUT,
#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(ready_gpios)
.ready = GPIO_DT_SPEC_INST_GET_OR(0, ready_gpios, { 0 }),
#endif
};

ETH_NET_DEVICE_DT_INST_DEFINE(0,
Expand Down
3 changes: 3 additions & 0 deletions drivers/ethernet/eth_w5500_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ struct w5500_config {
struct gpio_dt_spec interrupt;
struct gpio_dt_spec reset;
int32_t timeout;
#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(ready_gpios)
struct gpio_dt_spec ready;
#endif
};

struct w5500_runtime {
Expand Down
6 changes: 6 additions & 0 deletions dts/bindings/ethernet/wiznet,w5500.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,9 @@ properties:
The reset pin of W5500 is active low.
If connected directly the MCU pin should be configured
as active low.
ready-gpios:
type: phandle-array
description: Ready pin (WIZ550io only).

The WIZ550io module has an extra GPIO pin that signals
when the PIC12F519 has finished configuring the W5500.

0 comments on commit e7537f7

Please sign in to comment.