drivers/stm32_eth: add 'NETDEV_EVENT_LINK_UP' event
This commit is contained in:
parent
5c3f7bde0c
commit
f3e934988c
@ -21,6 +21,7 @@ ifneq (,$(filter stm32_eth,$(USEMODULE)))
|
|||||||
USEMODULE += netdev_eth
|
USEMODULE += netdev_eth
|
||||||
USEMODULE += iolist
|
USEMODULE += iolist
|
||||||
USEMODULE += luid
|
USEMODULE += luid
|
||||||
|
USEMODULE += xtimer
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq (STM32F030x4, $(CPU_LINE))
|
ifneq (STM32F030x4, $(CPU_LINE))
|
||||||
|
|||||||
@ -33,6 +33,14 @@
|
|||||||
#define ENABLE_DEBUG (0)
|
#define ENABLE_DEBUG (0)
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
|
#if IS_USED(MODULE_STM32_ETH_LINK_UP)
|
||||||
|
#include "xtimer.h"
|
||||||
|
|
||||||
|
#define STM32_ETH_LINK_UP_TIMEOUT_US (1UL * US_PER_SEC)
|
||||||
|
|
||||||
|
static xtimer_t _link_status_timer;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Set the value of the divider with the clock configured */
|
/* Set the value of the divider with the clock configured */
|
||||||
#if !defined(CLOCK_CORECLOCK) || CLOCK_CORECLOCK < (20000000U)
|
#if !defined(CLOCK_CORECLOCK) || CLOCK_CORECLOCK < (20000000U)
|
||||||
#error This peripheral requires a CORECLOCK of at least 20MHz
|
#error This peripheral requires a CORECLOCK of at least 20MHz
|
||||||
@ -59,6 +67,10 @@
|
|||||||
#define ETH_RX_BUFFER_SIZE (256U)
|
#define ETH_RX_BUFFER_SIZE (256U)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define LINK_STATE_DOWN (0x00)
|
||||||
|
#define LINK_STATE_UP (0x01)
|
||||||
|
#define LINK_STATE_NOTIFIED_UP (0x02)
|
||||||
|
|
||||||
#if (ETH_RX_BUFFER_SIZE % 16) != 0
|
#if (ETH_RX_BUFFER_SIZE % 16) != 0
|
||||||
/* For compatibility with 128bit memory interfaces, the buffer size needs to
|
/* For compatibility with 128bit memory interfaces, the buffer size needs to
|
||||||
* be a multiple of 16 Byte. For 64 bit memory interfaces need the size to be
|
* be a multiple of 16 Byte. For 64 bit memory interfaces need the size to be
|
||||||
@ -86,6 +98,11 @@ static char rx_buffer[ETH_RX_DESCRIPTOR_COUNT][ETH_RX_BUFFER_SIZE];
|
|||||||
/* Netdev used in RIOT's API to upper layer */
|
/* Netdev used in RIOT's API to upper layer */
|
||||||
netdev_t *_netdev;
|
netdev_t *_netdev;
|
||||||
|
|
||||||
|
#if IS_USED(MODULE_STM32_ETH_LINK_UP)
|
||||||
|
/* Used for checking the link status */
|
||||||
|
static uint8_t _link_state = LINK_STATE_DOWN;
|
||||||
|
#endif
|
||||||
|
|
||||||
/** Read or write a phy register, to write the register ETH_MACMIIAR_MW is to
|
/** Read or write a phy register, to write the register ETH_MACMIIAR_MW is to
|
||||||
* be passed as the higher nibble of the value */
|
* be passed as the higher nibble of the value */
|
||||||
static unsigned _rw_phy(unsigned addr, unsigned reg, unsigned value)
|
static unsigned _rw_phy(unsigned addr, unsigned reg, unsigned value)
|
||||||
@ -166,9 +183,71 @@ static void _init_buffer(void)
|
|||||||
ETH->DMATDLAR = (uintptr_t)&tx_desc[0];
|
ETH->DMATDLAR = (uintptr_t)&tx_desc[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int stm32_eth_set(netdev_t *dev, netopt_t opt,
|
||||||
|
const void *value, size_t max_len)
|
||||||
|
{
|
||||||
|
int res = -1;
|
||||||
|
|
||||||
|
switch (opt) {
|
||||||
|
case NETOPT_ADDRESS:
|
||||||
|
assert(max_len >= ETHERNET_ADDR_LEN);
|
||||||
|
stm32_eth_set_mac((char *)value);
|
||||||
|
res = ETHERNET_ADDR_LEN;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
res = netdev_eth_set(dev, opt, value, max_len);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int stm32_eth_get(netdev_t *dev, netopt_t opt,
|
||||||
|
void *value, size_t max_len)
|
||||||
|
{
|
||||||
|
int res = -1;
|
||||||
|
|
||||||
|
switch (opt) {
|
||||||
|
case NETOPT_ADDRESS:
|
||||||
|
assert(max_len >= ETHERNET_ADDR_LEN);
|
||||||
|
stm32_eth_get_mac((char *)value);
|
||||||
|
res = ETHERNET_ADDR_LEN;
|
||||||
|
break;
|
||||||
|
case NETOPT_LINK:
|
||||||
|
res = (_phy_read(0, PHY_BSMR) & BSMR_LINK_STATUS);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
res = netdev_eth_get(dev, opt, value, max_len);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if IS_USED(MODULE_STM32_ETH_LINK_UP)
|
||||||
|
static void _timer_cb(void *arg)
|
||||||
|
{
|
||||||
|
netdev_t *dev = (netdev_t *)arg;
|
||||||
|
if (stm32_eth_get(dev, NETOPT_LINK, NULL, 0)) {
|
||||||
|
_link_state = LINK_STATE_UP;
|
||||||
|
dev->event_callback(dev, NETDEV_EVENT_ISR);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_link_state = LINK_STATE_DOWN;
|
||||||
|
xtimer_set(&_link_status_timer, STM32_ETH_LINK_UP_TIMEOUT_US);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static int stm32_eth_init(netdev_t *netdev)
|
static int stm32_eth_init(netdev_t *netdev)
|
||||||
{
|
{
|
||||||
|
#if IS_USED(MODULE_STM32_ETH_LINK_UP)
|
||||||
|
_link_status_timer.callback = _timer_cb;
|
||||||
|
_link_status_timer.arg = netdev;
|
||||||
|
xtimer_set(&_link_status_timer, STM32_ETH_LINK_UP_TIMEOUT_US);
|
||||||
|
#else
|
||||||
(void)netdev;
|
(void)netdev;
|
||||||
|
#endif
|
||||||
/* enable APB2 clock */
|
/* enable APB2 clock */
|
||||||
RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;
|
RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;
|
||||||
|
|
||||||
@ -435,7 +514,19 @@ void stm32_eth_isr_eth_wkup(void)
|
|||||||
cortexm_isr_end();
|
cortexm_isr_end();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void stm32_eth_isr(netdev_t *netdev) {
|
static void stm32_eth_isr(netdev_t *netdev)
|
||||||
|
{
|
||||||
|
#if IS_USED(MODULE_STM32_ETH_LINK_UP)
|
||||||
|
switch (_link_state) {
|
||||||
|
case LINK_STATE_UP:
|
||||||
|
netdev->event_callback(netdev, NETDEV_EVENT_LINK_UP);
|
||||||
|
_link_state = LINK_STATE_NOTIFIED_UP;
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
netdev->event_callback(netdev, NETDEV_EVENT_RX_COMPLETE);
|
netdev->event_callback(netdev, NETDEV_EVENT_RX_COMPLETE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -460,44 +551,6 @@ void isr_eth(void)
|
|||||||
cortexm_isr_end();
|
cortexm_isr_end();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int stm32_eth_set(netdev_t *dev, netopt_t opt,
|
|
||||||
const void *value, size_t max_len)
|
|
||||||
{
|
|
||||||
int res = -1;
|
|
||||||
|
|
||||||
switch (opt) {
|
|
||||||
case NETOPT_ADDRESS:
|
|
||||||
assert(max_len >= ETHERNET_ADDR_LEN);
|
|
||||||
stm32_eth_set_mac((char *)value);
|
|
||||||
res = ETHERNET_ADDR_LEN;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
res = netdev_eth_set(dev, opt, value, max_len);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int stm32_eth_get(netdev_t *dev, netopt_t opt,
|
|
||||||
void *value, size_t max_len)
|
|
||||||
{
|
|
||||||
int res = -1;
|
|
||||||
|
|
||||||
switch (opt) {
|
|
||||||
case NETOPT_ADDRESS:
|
|
||||||
assert(max_len >= ETHERNET_ADDR_LEN);
|
|
||||||
stm32_eth_get_mac((char *)value);
|
|
||||||
res = ETHERNET_ADDR_LEN;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
res = netdev_eth_get(dev, opt, value, max_len);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const netdev_driver_t netdev_driver_stm32f4eth = {
|
static const netdev_driver_t netdev_driver_stm32f4eth = {
|
||||||
.send = stm32_eth_send,
|
.send = stm32_eth_send,
|
||||||
.recv = stm32_eth_recv,
|
.recv = stm32_eth_recv,
|
||||||
|
|||||||
@ -115,6 +115,7 @@ PSEUDOMODULES += stdio_cdc_acm
|
|||||||
PSEUDOMODULES += stdio_ethos
|
PSEUDOMODULES += stdio_ethos
|
||||||
PSEUDOMODULES += stdio_uart_rx
|
PSEUDOMODULES += stdio_uart_rx
|
||||||
PSEUDOMODULES += stm32_eth
|
PSEUDOMODULES += stm32_eth
|
||||||
|
PSEUDOMODULES += stm32_eth_link_up
|
||||||
PSEUDOMODULES += suit_transport_%
|
PSEUDOMODULES += suit_transport_%
|
||||||
PSEUDOMODULES += wakaama_objects_%
|
PSEUDOMODULES += wakaama_objects_%
|
||||||
PSEUDOMODULES += wifi_enterprise
|
PSEUDOMODULES += wifi_enterprise
|
||||||
|
|||||||
@ -7,3 +7,9 @@ DEFAULT_MODULE += auto_init_lwip
|
|||||||
ifneq (,$(filter lwip_sock_async,$(USEMODULE)))
|
ifneq (,$(filter lwip_sock_async,$(USEMODULE)))
|
||||||
USEMODULE += sock_async
|
USEMODULE += sock_async
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifneq (,$(filter stm32_eth,$(USEMODULE)))
|
||||||
|
ifneq (,$(filter lwip_dhcp_auto,$(USEMODULE)))
|
||||||
|
USEMODULE += stm32_eth_link_up
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user