mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-12-26 23:11:19 +01:00
Merge pull request #16752 from benpicco/drivers/dose-standby
drivers/dose: enable standby pin
This commit is contained in:
commit
12ade5a8b5
@ -48,6 +48,7 @@ static int send_octet(dose_t *ctx, uint8_t c);
|
||||
static int _send(netdev_t *dev, const iolist_t *iolist);
|
||||
static int _get(netdev_t *dev, netopt_t opt, void *value, size_t max_len);
|
||||
static int _set(netdev_t *dev, netopt_t opt, const void *value, size_t len);
|
||||
static int _set_state(dose_t *ctx, netopt_state_t state);
|
||||
static int _init(netdev_t *dev);
|
||||
|
||||
static uint16_t crc16_update(uint16_t crc, uint8_t octet)
|
||||
@ -60,6 +61,15 @@ static uint16_t crc16_update(uint16_t crc, uint8_t octet)
|
||||
return crc;
|
||||
}
|
||||
|
||||
static void _init_standby(dose_t *ctx, const dose_params_t *params)
|
||||
{
|
||||
ctx->standby_pin = params->standby_pin;
|
||||
if (gpio_is_valid(ctx->standby_pin) &&
|
||||
gpio_init(ctx->standby_pin, GPIO_OUT)) {
|
||||
gpio_clear(ctx->standby_pin);
|
||||
}
|
||||
}
|
||||
|
||||
static void _init_sense(dose_t *ctx, const dose_params_t *params)
|
||||
{
|
||||
#ifdef MODULE_PERIPH_UART_RXSTART_IRQ
|
||||
@ -389,8 +399,8 @@ static int send_octet(dose_t *ctx, uint8_t c)
|
||||
uart_write(ctx->uart, (uint8_t *) &c, sizeof(c));
|
||||
|
||||
/* Wait for a state transition */
|
||||
uint8_t state = wait_for_state(ctx, DOSE_STATE_ANY);
|
||||
if (state != DOSE_STATE_SEND) {
|
||||
uint8_t new_state = wait_for_state(ctx, DOSE_STATE_ANY);
|
||||
if (new_state != DOSE_STATE_SEND) {
|
||||
/* Timeout */
|
||||
DEBUG("dose send_octet(): timeout\n");
|
||||
return -2;
|
||||
@ -429,6 +439,16 @@ static int _send(netdev_t *dev, const iolist_t *iolist)
|
||||
size_t pktlen;
|
||||
uint16_t crc;
|
||||
|
||||
/* discard data when interface is in SLEEP mode */
|
||||
if (ctx->state == DOSE_STATE_SLEEP) {
|
||||
return -ENETDOWN;
|
||||
}
|
||||
|
||||
/* sending data wakes the interface from STANDBY */
|
||||
if (ctx->state == DOSE_STATE_STANDBY) {
|
||||
_set_state(ctx, NETOPT_STATE_IDLE);
|
||||
}
|
||||
|
||||
send:
|
||||
crc = 0xffff;
|
||||
pktlen = 0;
|
||||
@ -517,6 +537,45 @@ static int _get(netdev_t *dev, netopt_t opt, void *value, size_t max_len)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void _gpio_try_set(gpio_t pin)
|
||||
{
|
||||
if (gpio_is_valid(pin)) {
|
||||
gpio_set(pin);
|
||||
}
|
||||
}
|
||||
|
||||
static void _gpio_try_clear(gpio_t pin)
|
||||
{
|
||||
if (gpio_is_valid(pin)) {
|
||||
gpio_clear(pin);
|
||||
}
|
||||
}
|
||||
|
||||
static int _set_state(dose_t *ctx, netopt_state_t state)
|
||||
{
|
||||
switch (state) {
|
||||
case NETOPT_STATE_STANDBY:
|
||||
_gpio_try_set(ctx->standby_pin);
|
||||
uart_poweroff(ctx->uart);
|
||||
ctx->state = DOSE_STATE_STANDBY;
|
||||
return sizeof(netopt_state_t);
|
||||
case NETOPT_STATE_SLEEP:
|
||||
_gpio_try_set(ctx->standby_pin);
|
||||
uart_poweroff(ctx->uart);
|
||||
ctx->state = DOSE_STATE_SLEEP;
|
||||
return sizeof(netopt_state_t);
|
||||
case NETOPT_STATE_IDLE:
|
||||
uart_poweron(ctx->uart);
|
||||
_gpio_try_clear(ctx->standby_pin);
|
||||
ctx->state = DOSE_STATE_IDLE;
|
||||
return sizeof(netopt_state_t);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
static int _set(netdev_t *dev, netopt_t opt, const void *value, size_t len)
|
||||
{
|
||||
dose_t *ctx = container_of(dev, dose_t, netdev);
|
||||
@ -539,6 +598,9 @@ static int _set(netdev_t *dev, netopt_t opt, const void *value, size_t len)
|
||||
CLRBIT(ctx->opts, DOSE_OPT_PROMISCUOUS);
|
||||
}
|
||||
return sizeof(netopt_enable_t);
|
||||
case NETOPT_STATE:
|
||||
assert(len <= sizeof(netopt_state_t));
|
||||
return _set_state(ctx, *((const netopt_state_t *)value));
|
||||
default:
|
||||
return netdev_eth_set(dev, opt, value, len);
|
||||
}
|
||||
@ -585,6 +647,7 @@ void dose_setup(dose_t *ctx, const dose_params_t *params, uint8_t index)
|
||||
uart_init(ctx->uart, params->baudrate, _isr_uart, (void *) ctx);
|
||||
|
||||
_init_sense(ctx, params);
|
||||
_init_standby(ctx, params);
|
||||
|
||||
netdev_register(&ctx->netdev, NETDEV_DOSE, index);
|
||||
|
||||
|
||||
@ -38,16 +38,25 @@ extern "C" {
|
||||
#ifndef DOSE_PARAM_SENSE_PIN
|
||||
#define DOSE_PARAM_SENSE_PIN (GPIO_UNDEF)
|
||||
#endif
|
||||
#ifndef DOSE_PARAM_STANDBY_PIN
|
||||
#define DOSE_PARAM_STANDBY_PIN (GPIO_UNDEF) /**< Standby/Silent mode */
|
||||
#endif
|
||||
|
||||
#ifndef DOSE_PARAMS
|
||||
#ifdef MODULE_PERIPH_UART_RXSTART_IRQ
|
||||
#define DOSE_PARAMS { .uart = DOSE_PARAM_UART, \
|
||||
.baudrate = DOSE_PARAM_BAUDRATE }
|
||||
#else
|
||||
#define DOSE_PARAMS { .uart = DOSE_PARAM_UART, \
|
||||
.baudrate = DOSE_PARAM_BAUDRATE, \
|
||||
.sense_pin = DOSE_PARAM_SENSE_PIN }
|
||||
#endif
|
||||
#define DOSE_PARAMS { \
|
||||
.uart = DOSE_PARAM_UART, \
|
||||
.baudrate = DOSE_PARAM_BAUDRATE, \
|
||||
.standby_pin = DOSE_PARAM_STANDBY_PIN, \
|
||||
}
|
||||
#else /* MODULE_PERIPH_UART_RXSTART_IRQ */
|
||||
#define DOSE_PARAMS { \
|
||||
.uart = DOSE_PARAM_UART, \
|
||||
.baudrate = DOSE_PARAM_BAUDRATE, \
|
||||
.standby_pin = DOSE_PARAM_STANDBY_PIN, \
|
||||
.sense_pin = DOSE_PARAM_SENSE_PIN, \
|
||||
}
|
||||
#endif /* !MODULE_PERIPH_UART_RXSTART_IRQ */
|
||||
#endif
|
||||
/**@}*/
|
||||
|
||||
|
||||
@ -87,6 +87,8 @@ typedef enum {
|
||||
DOSE_STATE_IDLE = 0x02, /**< Frames will be received or sent */
|
||||
DOSE_STATE_RECV = 0x03, /**< Currently receiving a frame */
|
||||
DOSE_STATE_SEND = 0x04, /**< Currently sending a frame */
|
||||
DOSE_STATE_STANDBY = 0x05, /**< Receiver is turned off, but send will wake it up */
|
||||
DOSE_STATE_SLEEP = 0x06, /**< Receiver is turned off and send will be discarded */
|
||||
DOSE_STATE_ANY = 0x0F /**< Special state filter used internally to observe any state transition */
|
||||
} dose_state_t;
|
||||
|
||||
@ -158,6 +160,7 @@ typedef struct {
|
||||
#if !defined(MODULE_PERIPH_UART_RXSTART_IRQ) || DOXYGEN
|
||||
gpio_t sense_pin; /**< GPIO to sense for start bits on the UART's rx line */
|
||||
#endif
|
||||
gpio_t standby_pin; /**< GPIO to put the CAN transceiver in standby mode */
|
||||
xtimer_t timeout; /**< Timeout timer ensuring always to get back to IDLE state */
|
||||
uint32_t timeout_base; /**< Base timeout in us */
|
||||
} dose_t;
|
||||
@ -170,6 +173,7 @@ typedef struct {
|
||||
#if !defined(MODULE_PERIPH_UART_RXSTART_IRQ) || DOXYGEN
|
||||
gpio_t sense_pin; /**< GPIO to sense for start bits on the UART's rx line */
|
||||
#endif
|
||||
gpio_t standby_pin; /**< GPIO to put the CAN transceiver in standby mode */
|
||||
uint32_t baudrate; /**< Baudrate to UART device */
|
||||
} dose_params_t;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user