drivers/dose: make use of periph_uart_rx_start feature

This commit is contained in:
Benjamin Valentin 2021-05-27 22:20:53 +02:00
parent 02269ef869
commit d48f673597
4 changed files with 57 additions and 16 deletions

View File

@ -1,5 +1,6 @@
FEATURES_REQUIRED += periph_gpio_irq FEATURES_REQUIRED += periph_gpio_irq
FEATURES_REQUIRED += periph_uart FEATURES_REQUIRED += periph_uart
FEATURES_OPTIONAL += periph_uart_rxstart_irq
USEMODULE += eui_provider USEMODULE += eui_provider
USEMODULE += iolist USEMODULE += iolist

View File

@ -60,6 +60,42 @@ static uint16_t crc16_update(uint16_t crc, uint8_t octet)
return crc; return crc;
} }
static void _init_sense(dose_t *ctx, const dose_params_t *params)
{
#ifdef MODULE_PERIPH_UART_RXSTART_IRQ
(void)params;
uart_rxstart_irq_configure(ctx->uart, _isr_gpio, ctx);
#else
ctx->sense_pin = params->sense_pin;
if (gpio_is_valid(ctx->sense_pin)) {
gpio_init_int(ctx->sense_pin, GPIO_IN, GPIO_FALLING, _isr_gpio, ctx);
gpio_irq_disable(ctx->sense_pin);
}
#endif
}
static inline void _enable_sense(dose_t *ctx)
{
#ifdef MODULE_PERIPH_UART_RXSTART_IRQ
uart_rxstart_irq_enable(ctx->uart);
#else
if (gpio_is_valid(ctx->sense_pin)) {
gpio_irq_enable(ctx->sense_pin);
}
#endif
}
static inline void _disable_sense(dose_t *ctx)
{
#ifdef MODULE_PERIPH_UART_RXSTART_IRQ
uart_rxstart_irq_disable(ctx->uart);
#else
if (gpio_is_valid(ctx->sense_pin)) {
gpio_irq_disable(ctx->sense_pin);
}
#endif
}
static dose_signal_t state_transit_blocked(dose_t *ctx, dose_signal_t signal) static dose_signal_t state_transit_blocked(dose_t *ctx, dose_signal_t signal)
{ {
uint32_t backoff; uint32_t backoff;
@ -73,10 +109,8 @@ static dose_signal_t state_transit_blocked(dose_t *ctx, dose_signal_t signal)
netdev_trigger_event_isr((netdev_t *) ctx); netdev_trigger_event_isr((netdev_t *) ctx);
} }
if (gpio_is_valid(ctx->sense_pin)) { /* Enable interrupt for start bit sensing */
/* Enable GPIO interrupt for start bit sensing */ _enable_sense(ctx);
gpio_irq_enable(ctx->sense_pin);
}
/* The timeout will bring us back into IDLE state by a random time. /* The timeout will bring us back into IDLE state by a random time.
* If we entered this state from RECV state, the random time lays * If we entered this state from RECV state, the random time lays
@ -107,10 +141,10 @@ static dose_signal_t state_transit_recv(dose_t *ctx, dose_signal_t signal)
{ {
dose_signal_t rc = DOSE_SIGNAL_NONE; dose_signal_t rc = DOSE_SIGNAL_NONE;
if (ctx->state != DOSE_STATE_RECV && gpio_is_valid(ctx->sense_pin)) { if (ctx->state != DOSE_STATE_RECV) {
/* We freshly entered this state. Thus, no start bit sensing is required /* We freshly entered this state. Thus, no start bit sensing is required
* anymore. Disable GPIO IRQs during the transmission. */ * anymore. Disable RX Start IRQs during the transmission. */
gpio_irq_disable(ctx->sense_pin); _disable_sense(ctx);
} }
if (signal == DOSE_SIGNAL_UART) { if (signal == DOSE_SIGNAL_UART) {
@ -149,9 +183,9 @@ static dose_signal_t state_transit_send(dose_t *ctx, dose_signal_t signal)
{ {
(void) signal; (void) signal;
if (ctx->state != DOSE_STATE_SEND && gpio_is_valid(ctx->sense_pin)) { if (ctx->state != DOSE_STATE_SEND) {
/* Disable GPIO IRQs during the transmission. */ /* Disable RX Start IRQs during the transmission. */
gpio_irq_disable(ctx->sense_pin); _disable_sense(ctx);
} }
/* Don't trace any END octets ... the timeout or the END signal /* Don't trace any END octets ... the timeout or the END signal
@ -550,11 +584,7 @@ void dose_setup(dose_t *ctx, const dose_params_t *params, uint8_t index)
ctx->uart = params->uart; ctx->uart = params->uart;
uart_init(ctx->uart, params->baudrate, _isr_uart, (void *) ctx); uart_init(ctx->uart, params->baudrate, _isr_uart, (void *) ctx);
ctx->sense_pin = params->sense_pin; _init_sense(ctx, params);
if (gpio_is_valid(ctx->sense_pin)) {
gpio_init_int(ctx->sense_pin, GPIO_IN, GPIO_FALLING, _isr_gpio, (void *) ctx);
gpio_irq_disable(ctx->sense_pin);
}
netdev_register(&ctx->netdev, NETDEV_DOSE, index); netdev_register(&ctx->netdev, NETDEV_DOSE, index);

View File

@ -40,10 +40,15 @@ extern "C" {
#endif #endif
#ifndef DOSE_PARAMS #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, \ #define DOSE_PARAMS { .uart = DOSE_PARAM_UART, \
.baudrate = DOSE_PARAM_BAUDRATE, \ .baudrate = DOSE_PARAM_BAUDRATE, \
.sense_pin = DOSE_PARAM_SENSE_PIN } .sense_pin = DOSE_PARAM_SENSE_PIN }
#endif #endif
#endif
/**@}*/ /**@}*/
/** /**

View File

@ -31,7 +31,8 @@
* you could use an IC such as the SN65HVD233.) * you could use an IC such as the SN65HVD233.)
* *
* Basically, UART TX and RX are connected to respective pins of the * Basically, UART TX and RX are connected to respective pins of the
* transceiver. In addition, the RX pin can also be connected to the sense GPIO. * transceiver. In addition, the RX pin can also be connected to the sense GPIO
* if the UART does not implement the `periph_uart_rxstart_irq` feature.
* In this case, the bus allocation can be detected more precisely and * In this case, the bus allocation can be detected more precisely and
* collisions are less likely. * collisions are less likely.
* *
@ -157,7 +158,9 @@ typedef struct {
size_t recv_buf_ptr; /**< Index of the next empty octet of the recveive buffer */ size_t recv_buf_ptr; /**< Index of the next empty octet of the recveive buffer */
uart_t uart; /**< UART device to use */ uart_t uart; /**< UART device to use */
uint8_t uart_octet; /**< Last received octet */ uint8_t uart_octet; /**< Last received octet */
#if !defined(MODULE_PERIPH_UART_RXSTART_IRQ) || DOXYGEN
gpio_t sense_pin; /**< GPIO to sense for start bits on the UART's rx line */ gpio_t sense_pin; /**< GPIO to sense for start bits on the UART's rx line */
#endif
xtimer_t timeout; /**< Timeout timer ensuring always to get back to IDLE state */ xtimer_t timeout; /**< Timeout timer ensuring always to get back to IDLE state */
uint32_t timeout_base; /**< Base timeout in us */ uint32_t timeout_base; /**< Base timeout in us */
} dose_t; } dose_t;
@ -167,7 +170,9 @@ typedef struct {
*/ */
typedef struct { typedef struct {
uart_t uart; /**< UART device to use */ uart_t uart; /**< UART device to use */
#if !defined(MODULE_PERIPH_UART_RXSTART_IRQ) || DOXYGEN
gpio_t sense_pin; /**< GPIO to sense for start bits on the UART's rx line */ gpio_t sense_pin; /**< GPIO to sense for start bits on the UART's rx line */
#endif
uint32_t baudrate; /**< Baudrate to UART device */ uint32_t baudrate; /**< Baudrate to UART device */
} dose_params_t; } dose_params_t;