Implemented unit timed tick and uart rx timeout

sipo
Ondřej Hruška 6 years ago
parent b3d1f95e7d
commit 8272a36aee
Signed by: MightyPork
GPG Key ID: 2C5FD5035250423D
  1. 10
      framework/unit.h
  2. 18
      framework/unit_registry.c
  3. 5
      framework/unit_registry.h
  4. 2
      gex_hooks.c
  5. 1
      platform/irq_dispatcher.c
  6. 8
      units/usart/_init.c
  7. 9
      units/usart/_internal.h
  8. 19
      units/usart/unit_usart.c

@ -45,6 +45,9 @@ struct unit {
/** Bit-map of held resources */ /** Bit-map of held resources */
ResourceMap resources; ResourceMap resources;
uint16_t tick_interval;
uint16_t _tick_cnt;
}; };
/** /**
@ -111,6 +114,13 @@ struct unit_driver {
* Handle an incoming request. Return true if command was OK. * Handle an incoming request. Return true if command was OK.
*/ */
error_t (*handleRequest)(Unit *unit, TF_ID frame_id, uint8_t command, PayloadParser *pp); error_t (*handleRequest)(Unit *unit, TF_ID frame_id, uint8_t command, PayloadParser *pp);
/**
* Periodic update call.
* This is run from the SysTick interrupt handler,
* any communication should be deferred via the job queue.
*/
void (*updateTick)(Unit *unit);
}; };
/** /**

@ -583,3 +583,21 @@ void ureg_print_unit_resources(IniWriter *iw)
} }
iw_newline(iw); iw_newline(iw);
} }
void ureg_tick_units(void)
{
UlistEntry *li = ulist_head;
while (li != NULL) {
Unit *const pUnit = &li->unit;
if (pUnit->status == E_SUCCESS && pUnit->tick_interval > 0) {
if (pUnit->_tick_cnt == 0) {
if (pUnit->driver->updateTick) {
pUnit->driver->updateTick(pUnit);
}
pUnit->_tick_cnt = pUnit->tick_interval;
}
pUnit->_tick_cnt--;
}
li = li->next;
}
}

@ -142,4 +142,9 @@ Unit *ureg_get_rsc_owner(Resource resource);
*/ */
void ureg_print_unit_resources(IniWriter *iw); void ureg_print_unit_resources(IniWriter *iw);
/**
* 1ms tick for all units that want it
*/
void ureg_tick_units(void);
#endif //GEX_UNIT_REGISTRY_H #endif //GEX_UNIT_REGISTRY_H

@ -9,6 +9,7 @@
#include "platform/status_led.h" #include "platform/status_led.h"
#include "platform/debug_uart.h" #include "platform/debug_uart.h"
#include "gex_hooks.h" #include "gex_hooks.h"
#include "unit_registry.h"
/** /**
* This is a systick callback for GEX application logic * This is a systick callback for GEX application logic
@ -17,6 +18,7 @@ void GEX_MsTick(void)
{ {
TF_Tick(comm); TF_Tick(comm);
Indicator_Tick(); Indicator_Tick();
ureg_tick_units();
} }
/** /**

@ -143,6 +143,7 @@ static struct cbslot *get_slot_for_periph(void *periph)
void irqd_attach(void *periph, IrqCallback callback, void *arg) void irqd_attach(void *periph, IrqCallback callback, void *arg)
{ {
struct cbslot *slot = get_slot_for_periph(periph); struct cbslot *slot = get_slot_for_periph(periph);
assert_param(slot->callback == NULL);
slot->callback = callback; slot->callback = callback;
slot->arg = arg; slot->arg = arg;
} }

@ -1,6 +1,7 @@
// //
// Created by MightyPork on 2018/01/14. // Created by MightyPork on 2018/01/14.
// //
#include <platform/irq_dispatcher.h>
#include "platform.h" #include "platform.h"
#include "unit_base.h" #include "unit_base.h"
@ -43,9 +44,6 @@ error_t UUSART_preInit(Unit *unit)
priv->de_assert_time = 8; priv->de_assert_time = 8;
priv->de_clear_time = 8; priv->de_clear_time = 8;
priv->rx_buffer = NULL;
priv->tx_buffer = NULL;
return E_SUCCESS; return E_SUCCESS;
} }
@ -315,6 +313,10 @@ error_t UUSART_init(Unit *unit)
// modifies some usart registers that can't be modified when enabled // modifies some usart registers that can't be modified when enabled
TRY(UUSART_SetupDMAs(unit)); TRY(UUSART_SetupDMAs(unit));
// timeout based on the baudrate
unit->tick_interval = (uint16_t) ((50 * 1000) / priv->baudrate); // receive timeout (ms)
if (unit->tick_interval < 5) unit->tick_interval = 5;
return E_SUCCESS; return E_SUCCESS;
} }

@ -57,6 +57,8 @@ struct priv {
volatile uint16_t tx_buf_nw; volatile uint16_t tx_buf_nw;
volatile uint16_t tx_buf_chunk; volatile uint16_t tx_buf_chunk;
volatile bool tx_dma_busy; volatile bool tx_dma_busy;
volatile uint16_t rx_last_dmapos;
}; };
/** Allocate data structure and set defaults */ /** Allocate data structure and set defaults */
@ -95,6 +97,13 @@ void UUSART_DMA_HandleRxFromIRQ(Unit *unit, uint16_t endpos);
*/ */
uint16_t UUSART_DMA_TxQueue(struct priv *priv, const uint8_t *buffer, uint16_t len); uint16_t UUSART_DMA_TxQueue(struct priv *priv, const uint8_t *buffer, uint16_t len);
/**
* Handle rx timeout, grab what is received and send it immediately.
*
* @param unit
*/
void UUSART_DMA_HandleRxTimeout(Unit *unit);
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------

@ -2,6 +2,7 @@
// Created by MightyPork on 2018/01/02. // Created by MightyPork on 2018/01/02.
// //
#include <stm32f072xb.h>
#include "platform.h" #include "platform.h"
#include "comm/messages.h" #include "comm/messages.h"
#include "unit_base.h" #include "unit_base.h"
@ -68,6 +69,23 @@ void UUSART_DMA_HandleRxFromIRQ(Unit *unit, uint16_t endpos)
priv->rx_buf_readpos = endpos; priv->rx_buf_readpos = endpos;
} }
void UUSART_Tick(Unit *unit)
{
assert_param(unit);
struct priv *priv = unit->data;
assert_param(priv);
if (priv->rx_last_dmapos == priv->dma_rx->CNDTR) {
uint16_t endpos = (uint16_t) (UUSART_RXBUF_LEN - priv->rx_last_dmapos);
if (endpos != priv->rx_buf_readpos) {
dbg("DMA timeout");
UUSART_DMA_HandleRxFromIRQ(unit, endpos);
}
} else {
priv->rx_last_dmapos = (uint16_t) priv->dma_rx->CNDTR;
}
}
error_t UU_USART_Write(Unit *unit, const uint8_t *buffer, uint32_t len) error_t UU_USART_Write(Unit *unit, const uint8_t *buffer, uint32_t len)
{ {
@ -155,5 +173,6 @@ const UnitDriver UNIT_USART = {
.init = UUSART_init, .init = UUSART_init,
.deInit = UUSART_deInit, .deInit = UUSART_deInit,
// Function // Function
.updateTick = UUSART_Tick,
.handleRequest = UUSART_handleRequest, .handleRequest = UUSART_handleRequest,
}; };

Loading…
Cancel
Save