mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-01-18 12:52:44 +01:00
Merge pull request #17886 from benpicco/cpu/sam0_eth-sleep
cpu/sam0_eth: implement SLEEP state
This commit is contained in:
commit
c568d273ea
@ -92,6 +92,8 @@ static uint8_t rx_buf[ETH_RX_BUFFER_COUNT][ETH_RX_BUFFER_SIZE] __attribute__((a
|
|||||||
static uint8_t tx_buf[ETH_TX_BUFFER_COUNT][ETH_TX_BUFFER_SIZE] __attribute__((aligned(GMAC_BUF_ALIGNMENT)));
|
static uint8_t tx_buf[ETH_TX_BUFFER_COUNT][ETH_TX_BUFFER_SIZE] __attribute__((aligned(GMAC_BUF_ALIGNMENT)));
|
||||||
extern sam0_eth_netdev_t _sam0_eth_dev;
|
extern sam0_eth_netdev_t _sam0_eth_dev;
|
||||||
|
|
||||||
|
static bool _is_sleeping;
|
||||||
|
|
||||||
/* Flush our reception buffers and reset reception internal mechanism,
|
/* Flush our reception buffers and reset reception internal mechanism,
|
||||||
this function may be call from ISR context */
|
this function may be call from ISR context */
|
||||||
void sam0_clear_rx_buffers(void)
|
void sam0_clear_rx_buffers(void)
|
||||||
@ -104,6 +106,33 @@ void sam0_clear_rx_buffers(void)
|
|||||||
GMAC->RBQB.reg = (uint32_t) rx_desc;
|
GMAC->RBQB.reg = (uint32_t) rx_desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void _enable_clock(void)
|
||||||
|
{
|
||||||
|
/* Enable GMAC clocks */
|
||||||
|
MCLK->AHBMASK.reg |= MCLK_AHBMASK_GMAC;
|
||||||
|
MCLK->APBCMASK.reg |= MCLK_APBCMASK_GMAC;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _disable_clock(void)
|
||||||
|
{
|
||||||
|
/* Disable GMAC clocks */
|
||||||
|
MCLK->AHBMASK.reg &= ~MCLK_AHBMASK_GMAC;
|
||||||
|
MCLK->APBCMASK.reg &= ~MCLK_APBCMASK_GMAC;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sam0_eth_poweron(void)
|
||||||
|
{
|
||||||
|
_enable_clock();
|
||||||
|
sam0_clear_rx_buffers();
|
||||||
|
_is_sleeping = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sam0_eth_poweroff(void)
|
||||||
|
{
|
||||||
|
_is_sleeping = true;
|
||||||
|
_disable_clock();
|
||||||
|
}
|
||||||
|
|
||||||
static void _init_desc_buf(void)
|
static void _init_desc_buf(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@ -175,6 +204,10 @@ int sam0_eth_send(const struct iolist *iolist)
|
|||||||
unsigned tx_len = 0;
|
unsigned tx_len = 0;
|
||||||
tx_curr = &tx_desc[tx_idx];
|
tx_curr = &tx_desc[tx_idx];
|
||||||
|
|
||||||
|
if (_is_sleeping) {
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
/* load packet data into TX buffer */
|
/* load packet data into TX buffer */
|
||||||
for (const iolist_t *iol = iolist; iol; iol = iol->iol_next) {
|
for (const iolist_t *iol = iolist; iol; iol = iol->iol_next) {
|
||||||
if (tx_len + iol->iol_len > ETHERNET_MAX_LEN) {
|
if (tx_len + iol->iol_len > ETHERNET_MAX_LEN) {
|
||||||
@ -290,13 +323,6 @@ int sam0_eth_receive_blocking(char *data, unsigned max_len)
|
|||||||
return _try_receive(data, max_len, 1);
|
return _try_receive(data, max_len, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _enable_clock(void)
|
|
||||||
{
|
|
||||||
/* Enable GMAC clocks */
|
|
||||||
MCLK->AHBMASK.reg |= MCLK_AHBMASK_GMAC;
|
|
||||||
MCLK->APBCMASK.reg |= MCLK_APBCMASK_GMAC;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sam0_eth_init(void)
|
int sam0_eth_init(void)
|
||||||
{
|
{
|
||||||
/* Enable clocks */
|
/* Enable clocks */
|
||||||
|
@ -36,6 +36,8 @@
|
|||||||
|
|
||||||
/* Internal helpers */
|
/* Internal helpers */
|
||||||
extern int sam0_eth_init(void);
|
extern int sam0_eth_init(void);
|
||||||
|
extern void sam0_eth_poweron(void);
|
||||||
|
extern void sam0_eth_poweroff(void);
|
||||||
extern int sam0_eth_send(const struct iolist *iolist);
|
extern int sam0_eth_send(const struct iolist *iolist);
|
||||||
extern int sam0_eth_receive_blocking(char *data, unsigned max_len);
|
extern int sam0_eth_receive_blocking(char *data, unsigned max_len);
|
||||||
extern void sam0_eth_set_mac(const eui48_t *mac);
|
extern void sam0_eth_set_mac(const eui48_t *mac);
|
||||||
@ -101,6 +103,22 @@ static int _sam0_eth_get(netdev_t *netdev, netopt_t opt, void *val, size_t max_l
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int _set_state(netopt_state_t state)
|
||||||
|
{
|
||||||
|
switch (state) {
|
||||||
|
case NETOPT_STATE_SLEEP:
|
||||||
|
sam0_eth_poweroff();
|
||||||
|
break;
|
||||||
|
case NETOPT_STATE_IDLE:
|
||||||
|
sam0_eth_poweron();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sizeof(netopt_state_t);
|
||||||
|
}
|
||||||
|
|
||||||
static int _sam0_eth_set(netdev_t *netdev, netopt_t opt, const void *val, size_t max_len)
|
static int _sam0_eth_set(netdev_t *netdev, netopt_t opt, const void *val, size_t max_len)
|
||||||
{
|
{
|
||||||
int res = -1;
|
int res = -1;
|
||||||
@ -111,6 +129,9 @@ static int _sam0_eth_set(netdev_t *netdev, netopt_t opt, const void *val, size_t
|
|||||||
sam0_eth_set_mac((eui48_t *)val);
|
sam0_eth_set_mac((eui48_t *)val);
|
||||||
res = ETHERNET_ADDR_LEN;
|
res = ETHERNET_ADDR_LEN;
|
||||||
break;
|
break;
|
||||||
|
case NETOPT_STATE:
|
||||||
|
assert(max_len <= sizeof(netopt_state_t));
|
||||||
|
return _set_state(*((const netopt_state_t *)val));
|
||||||
default:
|
default:
|
||||||
res = netdev_eth_set(netdev, opt, val, max_len);
|
res = netdev_eth_set(netdev, opt, val, max_len);
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user