drivers: ethernet: enc28j60: Prevent infinate loop on driver init
In the case that there is a situation where the controller oscillator start-up timer doesn't expire, or the SPI can't read the CLKRDY bit the driver would hang during init. The config option ETH_ENC28J60_CLKRDY_INIT_WAIT_MS sets the time that the driver will wait for OST before returning an ETIMEDOUT error. Signed-off-by: Dean Sellers <dsellers@evos.com.au>
This commit is contained in:
parent
942b99a322
commit
ca7a66d787
2 changed files with 23 additions and 2 deletions
|
@ -30,6 +30,16 @@ config ETH_ENC28J60_RX_THREAD_PRIO
|
|||
Priority level for internal thread which is ran for incoming
|
||||
packet processing.
|
||||
|
||||
config ETH_ENC28J60_CLKRDY_INIT_WAIT_MS
|
||||
int "Time to wait for the CLKRDY bit on driver init"
|
||||
depends on ETH_ENC28J60
|
||||
default 2
|
||||
help
|
||||
Timeout in milliseconds. Maximum time the initialisation
|
||||
of the driver will wait for the OST to expire, indicated
|
||||
by the CLKRDY bit set. If timeout driver init will fail
|
||||
with -ETIMEDOUT.
|
||||
|
||||
config ETH_ENC28J60_TIMEOUT
|
||||
int "IP buffer timeout"
|
||||
depends on ETH_ENC28J60
|
||||
|
|
|
@ -335,7 +335,7 @@ static void eth_enc28j60_gpio_callback(const struct device *dev,
|
|||
k_sem_give(&context->int_sem);
|
||||
}
|
||||
|
||||
static void eth_enc28j60_init_buffers(const struct device *dev)
|
||||
static int eth_enc28j60_init_buffers(const struct device *dev)
|
||||
{
|
||||
uint8_t data_estat;
|
||||
|
||||
|
@ -375,11 +375,20 @@ static void eth_enc28j60_init_buffers(const struct device *dev)
|
|||
ENC28J60_RECEIVE_FILTERS);
|
||||
|
||||
/* Waiting for OST */
|
||||
/* 32 bits for this timer should be fine, rollover not an issue with initialisation */
|
||||
uint32_t start_wait = (uint32_t) k_uptime_get();
|
||||
do {
|
||||
/* If the CLK isn't ready don't wait forever */
|
||||
if ((k_uptime_get_32() - start_wait) > CONFIG_ETH_ENC28J60_CLKRDY_INIT_WAIT_MS) {
|
||||
LOG_ERR("OST wait timed out");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
/* wait 10.24 useconds */
|
||||
k_busy_wait(D10D24S);
|
||||
eth_enc28j60_read_reg(dev, ENC28J60_REG_ESTAT, &data_estat);
|
||||
} while (!(data_estat & ENC28J60_BIT_ESTAT_CLKRDY));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void eth_enc28j60_init_mac(const struct device *dev)
|
||||
|
@ -821,7 +830,9 @@ static int eth_enc28j60_init(const struct device *dev)
|
|||
context->mac_address[1] = MICROCHIP_OUI_B1;
|
||||
context->mac_address[2] = MICROCHIP_OUI_B2;
|
||||
|
||||
eth_enc28j60_init_buffers(dev);
|
||||
if (eth_enc28j60_init_buffers(dev)) {
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
eth_enc28j60_init_mac(dev);
|
||||
eth_enc28j60_init_phy(dev);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue