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_uart
FEATURES_OPTIONAL += periph_uart_rxstart_irq
USEMODULE += eui_provider
USEMODULE += iolist

View File

@ -60,6 +60,42 @@ static uint16_t crc16_update(uint16_t crc, uint8_t octet)
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)
{
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);
}
if (gpio_is_valid(ctx->sense_pin)) {
/* Enable GPIO interrupt for start bit sensing */
gpio_irq_enable(ctx->sense_pin);
}
/* Enable interrupt for start bit sensing */
_enable_sense(ctx);
/* 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
@ -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;
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
* anymore. Disable GPIO IRQs during the transmission. */
gpio_irq_disable(ctx->sense_pin);
* anymore. Disable RX Start IRQs during the transmission. */
_disable_sense(ctx);
}
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;
if (ctx->state != DOSE_STATE_SEND && gpio_is_valid(ctx->sense_pin)) {
/* Disable GPIO IRQs during the transmission. */
gpio_irq_disable(ctx->sense_pin);
if (ctx->state != DOSE_STATE_SEND) {
/* Disable RX Start IRQs during the transmission. */
_disable_sense(ctx);
}
/* 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;
uart_init(ctx->uart, params->baudrate, _isr_uart, (void *) ctx);
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, (void *) ctx);
gpio_irq_disable(ctx->sense_pin);
}
_init_sense(ctx, params);
netdev_register(&ctx->netdev, NETDEV_DOSE, index);

View File

@ -40,10 +40,15 @@ extern "C" {
#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
#endif
/**@}*/
/**

View File

@ -31,7 +31,8 @@
* you could use an IC such as the SN65HVD233.)
*
* 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
* 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 */
uart_t uart; /**< UART device to use */
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 */
#endif
xtimer_t timeout; /**< Timeout timer ensuring always to get back to IDLE state */
uint32_t timeout_base; /**< Base timeout in us */
} dose_t;
@ -167,7 +170,9 @@ typedef struct {
*/
typedef struct {
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 */
#endif
uint32_t baudrate; /**< Baudrate to UART device */
} dose_params_t;