mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-01-17 05:12:57 +01:00
drivers/slipdev: implement sleep states
This commit is contained in:
parent
44a9954d32
commit
bb084612f5
@ -72,6 +72,14 @@ enum {
|
||||
* @brief Device writes received data to stdin
|
||||
*/
|
||||
SLIPDEV_STATE_STDIN,
|
||||
/**
|
||||
* @brief Device is in standby, will wake up when sending data
|
||||
*/
|
||||
SLIPDEV_STATE_STANDBY,
|
||||
/**
|
||||
* @brief Device is in sleep mode
|
||||
*/
|
||||
SLIPDEV_STATE_SLEEP,
|
||||
};
|
||||
/** @} */
|
||||
|
||||
|
@ -32,6 +32,8 @@
|
||||
#include "mutex.h"
|
||||
#include "stdio_uart.h"
|
||||
|
||||
static int _check_state(slipdev_t *dev);
|
||||
|
||||
static inline void slipdev_lock(void)
|
||||
{
|
||||
if (IS_USED(MODULE_SLIPDEV_STDIO)) {
|
||||
@ -73,6 +75,23 @@ check_end:
|
||||
}
|
||||
}
|
||||
|
||||
static void _poweron(slipdev_t *dev)
|
||||
{
|
||||
if ((dev->state != SLIPDEV_STATE_STANDBY) ||
|
||||
(dev->state != SLIPDEV_STATE_SLEEP)) {
|
||||
return;
|
||||
}
|
||||
|
||||
dev->state = 0;
|
||||
uart_init(dev->config.uart, dev->config.baudrate, _slip_rx_cb, dev);
|
||||
}
|
||||
|
||||
static inline void _poweroff(slipdev_t *dev, uint8_t state)
|
||||
{
|
||||
uart_poweroff(dev->config.uart);
|
||||
dev->state = state;
|
||||
}
|
||||
|
||||
static int _init(netdev_t *netdev)
|
||||
{
|
||||
slipdev_t *dev = (slipdev_t *)netdev;
|
||||
@ -145,10 +164,33 @@ unsigned slipdev_unstuff_readbyte(uint8_t *buf, uint8_t byte, bool *escaped)
|
||||
return res;
|
||||
}
|
||||
|
||||
static int _check_state(slipdev_t *dev)
|
||||
{
|
||||
/* power states not supported when multiplexing stdio */
|
||||
if (IS_USED(MODULE_SLIPDEV_STDIO)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* discard data when interface is in SLEEP mode */
|
||||
if (dev->state == SLIPDEV_STATE_SLEEP) {
|
||||
return -ENETDOWN;
|
||||
}
|
||||
|
||||
/* sending data wakes the interface from STANDBY */
|
||||
if (dev->state == SLIPDEV_STATE_STANDBY) {
|
||||
_poweron(dev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _send(netdev_t *netdev, const iolist_t *iolist)
|
||||
{
|
||||
slipdev_t *dev = (slipdev_t *)netdev;
|
||||
int bytes = 0;
|
||||
int bytes = _check_state(dev);
|
||||
if (bytes) {
|
||||
return bytes;
|
||||
}
|
||||
|
||||
DEBUG("slipdev: sending iolist\n");
|
||||
slipdev_lock();
|
||||
@ -220,6 +262,45 @@ static void _isr(netdev_t *netdev)
|
||||
}
|
||||
}
|
||||
|
||||
#if !IS_USED(MODULE_SLIPDEV_STDIO)
|
||||
static int _set_state(slipdev_t *dev, netopt_state_t state)
|
||||
{
|
||||
if (IS_USED(MODULE_SLIPDEV_STDIO)) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
switch (state) {
|
||||
case NETOPT_STATE_STANDBY:
|
||||
_poweroff(dev, SLIPDEV_STATE_STANDBY);
|
||||
break;
|
||||
case NETOPT_STATE_SLEEP:
|
||||
_poweroff(dev, SLIPDEV_STATE_SLEEP);
|
||||
break;
|
||||
case NETOPT_STATE_IDLE:
|
||||
_poweron(dev);
|
||||
break;
|
||||
default:
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
return sizeof(netopt_state_t);
|
||||
}
|
||||
|
||||
static int _set(netdev_t *netdev, netopt_t opt, const void *value, size_t max_len)
|
||||
{
|
||||
(void)max_len;
|
||||
|
||||
slipdev_t *dev = (slipdev_t *)netdev;
|
||||
switch (opt) {
|
||||
case NETOPT_STATE:
|
||||
assert(max_len <= sizeof(netopt_state_t));
|
||||
return _set_state(dev, *((const netopt_state_t *)value));
|
||||
default:
|
||||
return -ENOTSUP;
|
||||
}
|
||||
}
|
||||
#endif /* !MODULE_SLIPDEV_STDIO */
|
||||
|
||||
static int _get(netdev_t *netdev, netopt_t opt, void *value, size_t max_len)
|
||||
{
|
||||
(void)netdev;
|
||||
@ -249,7 +330,11 @@ static const netdev_driver_t slip_driver = {
|
||||
.init = _init,
|
||||
.isr = _isr,
|
||||
.get = _get,
|
||||
#if IS_USED(MODULE_SLIPDEV_STDIO)
|
||||
.set = netdev_set_notsup,
|
||||
#else
|
||||
.set = _set,
|
||||
#endif
|
||||
};
|
||||
|
||||
void slipdev_setup(slipdev_t *dev, const slipdev_params_t *params, uint8_t index)
|
||||
|
Loading…
Reference in New Issue
Block a user