Commit 1cacd933 authored by galjonsfigur's avatar galjonsfigur Committed by Marcel Stör
Browse files

Fix timing of softuart module RX (#3029)

parent d455f8bc
...@@ -13,9 +13,12 @@ ...@@ -13,9 +13,12 @@
#define SOFTUART_MAX_RX_BUFF 128 #define SOFTUART_MAX_RX_BUFF 128
#define SOFTUART_GPIO_COUNT 13 #define SOFTUART_GPIO_COUNT 13
//TODO: Overflow flag as callback function + docs
typedef struct { typedef struct {
char receive_buffer[SOFTUART_MAX_RX_BUFF]; char receive_buffer[SOFTUART_MAX_RX_BUFF];
uint8_t length; uint8_t buffer_first;
uint8_t buffer_last;
uint8_t bytes_count;
uint8_t buffer_overflow; uint8_t buffer_overflow;
} softuart_buffer_t; } softuart_buffer_t;
...@@ -108,26 +111,36 @@ uint32_t ICACHE_RAM_ATTR softuart_intr_handler(uint32_t ret_gpio_status) ...@@ -108,26 +111,36 @@ uint32_t ICACHE_RAM_ATTR softuart_intr_handler(uint32_t ret_gpio_status)
start_time += s->bit_time; start_time += s->bit_time;
} }
// Wait for stop bit
// TODO: Add config for stop bits and parity bits
while ((uint32_t)(asm_ccount() - start_time) < s->bit_time);
// Store byte in buffer // Store byte in buffer
// If buffer full, set the overflow flag and return // If buffer full, set the overflow flag and return
uint8 next = s->buffer.length + 1 % SOFTUART_MAX_RX_BUFF; if (s->buffer.bytes_count == SOFTUART_MAX_RX_BUFF) {
if (next != 0) { s->buffer.buffer_overflow = 1;
s->buffer.receive_buffer[s->buffer.length] = byte; // save new byte } else if (s->buffer.bytes_count < SOFTUART_MAX_RX_BUFF) {
s->buffer.length = next; s->buffer.receive_buffer[s->buffer.buffer_last] = byte;
// Run callback when buffer is filled with enough data or last char is the triggering one s->buffer.buffer_last++;
if (((s->need_len != 0) && (s->buffer.length >= s->need_len)) || \ s->buffer.bytes_count++;
((s->need_len == 0) && ((char)byte == s->end_char))) {
// Check for callback conditions
if (((s->need_len != 0) && (s->buffer.bytes_count >= s->need_len)) || \
((s->need_len == 0) && ((char)byte == s->end_char))) {
// Send the pointer to task handler
s->armed = 0; s->armed = 0;
task_post_low(uart_recieve_task, (task_param_t)s); // Send the pointer to task handler task_post_low(uart_recieve_task, (task_param_t)s);
} }
} else { }
//TODO: use this information somehow? // Check for overflow after appending new byte
if (s->buffer.bytes_count == SOFTUART_MAX_RX_BUFF) {
s->buffer.buffer_overflow = 1; s->buffer.buffer_overflow = 1;
} }
// Roll over buffer index if necessary
if (s->buffer.buffer_last == SOFTUART_MAX_RX_BUFF) {
s->buffer.buffer_last = 0;
}
// Wait for stop bit
// TODO: Add config for stop bits and parity bits
while ((uint32_t)(asm_ccount() - start_time) < s->bit_time);
} }
} }
// re-enable all interrupts // re-enable all interrupts
...@@ -163,8 +176,8 @@ static void softuart_init(softuart_t *s) ...@@ -163,8 +176,8 @@ static void softuart_init(softuart_t *s)
{ {
NODE_DBG("SoftUART initialize gpio\n"); NODE_DBG("SoftUART initialize gpio\n");
// Init tx pin
if (s->pin_tx != 0xFF){ if (s->pin_tx != 0xFF){
// Init tx pin
platform_gpio_mode(s->pin_tx, PLATFORM_GPIO_OUTPUT, PLATFORM_GPIO_PULLUP); platform_gpio_mode(s->pin_tx, PLATFORM_GPIO_OUTPUT, PLATFORM_GPIO_PULLUP);
platform_gpio_write(s->pin_tx, PLATFORM_GPIO_HIGH); platform_gpio_write(s->pin_tx, PLATFORM_GPIO_HIGH);
} }
...@@ -235,7 +248,14 @@ static int softuart_setup(lua_State *L) ...@@ -235,7 +248,14 @@ static int softuart_setup(lua_State *L)
suart->softuart->pin_tx = tx_gpio_id; suart->softuart->pin_tx = tx_gpio_id;
suart->softuart->need_len = RX_BUFF_SIZE; suart->softuart->need_len = RX_BUFF_SIZE;
suart->softuart->armed = 0; suart->softuart->armed = 0;
//set bit time
// Set buffer
suart->softuart->buffer.buffer_first = 0;
suart->softuart->buffer.buffer_last = 0;
suart->softuart->buffer.bytes_count = 0;
suart->softuart->buffer.buffer_overflow = 0;
// Set bit time
suart->softuart->bit_time = system_get_cpu_freq() * 1000000 / baudrate; suart->softuart->bit_time = system_get_cpu_freq() * 1000000 / baudrate;
// Set metatable // Set metatable
...@@ -251,12 +271,21 @@ static void softuart_rx_callback(task_param_t arg) ...@@ -251,12 +271,21 @@ static void softuart_rx_callback(task_param_t arg)
softuart_t *softuart = (softuart_t*)arg; //Receive pointer from ISR softuart_t *softuart = (softuart_t*)arg; //Receive pointer from ISR
lua_State *L = lua_getstate(); lua_State *L = lua_getstate();
lua_rawgeti(L, LUA_REGISTRYINDEX, softuart_rx_cb_ref[softuart->pin_rx]); lua_rawgeti(L, LUA_REGISTRYINDEX, softuart_rx_cb_ref[softuart->pin_rx]);
// Clear overflow flag if needed
if(softuart->buffer.bytes_count == SOFTUART_MAX_RX_BUFF) {
softuart->buffer.buffer_overflow = 0;
}
// Copy volatile data to static buffer // Copy volatile data to static buffer
for (int i = 0; i < softuart->buffer.length; i++) { uint8_t buffer_lenght = softuart->buffer.bytes_count;
softuart_rx_buffer[i] = softuart->buffer.receive_buffer[i]; for (int i = 0; i < buffer_lenght; i++) {
softuart_rx_buffer[i] = softuart->buffer.receive_buffer[softuart->buffer.buffer_first];
softuart->buffer.buffer_first++;
softuart->buffer.bytes_count--;
if (softuart->buffer.buffer_first == SOFTUART_MAX_RX_BUFF) {
softuart->buffer.buffer_first = 0;
}
} }
lua_pushlstring(L, softuart_rx_buffer, softuart->buffer.length); lua_pushlstring(L, softuart_rx_buffer, buffer_lenght);
softuart->buffer.length = 0;
softuart->armed = 1; softuart->armed = 1;
lua_call(L, 1, 0); lua_call(L, 1, 0);
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment