diff --git a/.cproject b/.cproject
index 8918bdc..82e4fba 100644
--- a/.cproject
+++ b/.cproject
@@ -211,7 +211,7 @@
-
+
diff --git a/src/main.c b/src/main.c
index adbddd5..a79ed78 100644
--- a/src/main.c
+++ b/src/main.c
@@ -9,6 +9,7 @@
#include
#include
#include
+#include
#endif
#include
@@ -518,6 +519,10 @@ int main(int argc, char* argv[]){
main_wx_srl_ctx_ptr->te_pin = GPIO_Pin_8;
main_wx_srl_ctx_ptr->te_port = GPIOA;
#endif
+#if defined(PARAMETEO)
+ main_wx_srl_ctx_ptr->te_pin = LL_GPIO_PIN_8;
+ main_wx_srl_ctx_ptr->te_port = GPIOA;
+#endif
// initialize APRS path with zeros
memset (main_own_path, 0x00, sizeof(main_own_path));
diff --git a/system/include/aprs/cfifo.h b/system/include/aprs/cfifo.h
index 472d59d..14a3e3e 100644
--- a/system/include/aprs/cfifo.h
+++ b/system/include/aprs/cfifo.h
@@ -1,6 +1,7 @@
#ifndef FIFO_H_
#define FIFO_H_
+#include
typedef struct FIFOBuffer
{
diff --git a/system/src/drivers/i2c.c b/system/src/drivers/f1/i2c_stm32f1x.c
similarity index 100%
rename from system/src/drivers/i2c.c
rename to system/src/drivers/f1/i2c_stm32f1x.c
diff --git a/system/src/drivers/serial.c b/system/src/drivers/f1/serial_stm32f1x.c
similarity index 100%
rename from system/src/drivers/serial.c
rename to system/src/drivers/f1/serial_stm32f1x.c
diff --git a/system/src/drivers/l4/serial_stm32l4x.c b/system/src/drivers/l4/serial_stm32l4x.c
new file mode 100644
index 0000000..8cbc95e
--- /dev/null
+++ b/system/src/drivers/l4/serial_stm32l4x.c
@@ -0,0 +1,806 @@
+#include "drivers/serial.h"
+
+#include "station_config.h"
+#include "station_config_target_hw.h"
+
+#ifdef PARAMETEO
+ // those defines and an undef are only required for shitty Eclipse indexer to see anything from STM32L471xx target
+ #define STM32L471xx
+ #define USE_FULL_LL_DRIVER
+ #undef STM32F10X_MD_VL
+#endif
+
+//#include
+#include "diag/Trace.h"
+
+#include "main.h" // global_time is here
+
+#include
+
+#include
+#include
+#include
+
+#ifdef SEPARATE_TX_BUFF
+uint8_t srl_usart1_tx_buffer[TX_BUFFER_1_LN] = {'\0'};
+#endif
+
+#ifdef SEPARATE_RX_BUFF
+uint8_t srl_usart1_rx_buffer[RX_BUFFER_1_LN] = {'\0'};
+#endif
+
+#ifdef SEPARATE_TX_BUFF
+uint8_t srl_usart2_tx_buffer[TX_BUFFER_2_LN] = {'\0'};
+#endif
+
+#ifdef SEPARATE_RX_BUFF
+uint8_t srl_usart2_rx_buffer[RX_BUFFER_2_LN] = {'\0'};
+#endif
+
+
+void srl_init(
+ srl_context_t *ctx,
+ USART_TypeDef *port,
+ uint8_t *rx_buffer,
+ uint16_t rx_buffer_size,
+ uint8_t *tx_buffer,
+ uint16_t tx_buffer_size,
+ uint32_t baudrate,
+ uint8_t stop_bits
+ ) {
+
+ if (ctx->srl_rx_state == SRL_RX_IDLE)
+ return;
+
+ #ifdef SEPARATE_TX_BUFF
+ ctx->srl_tx_buf_pointer = tx_buffer;
+ ctx->srl_rx_buf_ln = tx_buffer_size;
+ #endif
+
+ #ifdef SEPARATE_RX_BUFF
+ ctx->srl_rx_buf_pointer = rx_buffer;
+ ctx->srl_tx_buf_ln = rx_buffer_size;
+ #endif
+
+ memset(ctx->srl_rx_buf_pointer, 0x00, ctx->srl_rx_buf_ln);
+ memset(ctx->srl_tx_buf_pointer, 0x00, ctx->srl_tx_buf_ln);
+
+ ctx->port = port;
+ ctx->port_baurate = baudrate;
+ ctx->port_stopbits = stop_bits;
+
+ //ctx->te_port = 0;
+ //ctx->te_pin = 0;
+
+ ctx->srl_tx_start_time = 0xFFFFFFFFu;
+
+ LL_USART_InitTypeDef USART_InitStructure;
+
+ USART_InitStructure.BaudRate = baudrate;
+ USART_InitStructure.DataWidth = LL_USART_DATAWIDTH_8B;
+ USART_InitStructure.StopBits = LL_USART_STOPBITS_1;
+ USART_InitStructure.Parity = LL_USART_PARITY_NONE;
+ USART_InitStructure.TransferDirection = LL_USART_DIRECTION_RX;
+ USART_InitStructure.HardwareFlowControl = LL_USART_HWCONTROL_NONE;
+ USART_InitStructure.OverSampling = LL_USART_OVERSAMPLING_16;
+
+
+// USART_InitStructure.USART_BaudRate = baudrate;
+// USART_InitStructure.USART_WordLength = USART_WordLength_8b;
+// USART_InitStructure.USART_Parity = USART_Parity_No;
+// USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
+// USART_InitStructure.USART_Mode = USART_Mode_Rx;
+// if (stop_bits == 1)
+// USART_InitStructure.USART_StopBits = USART_StopBits_1;
+// else if (stop_bits == 2)
+// USART_InitStructure.USART_StopBits = USART_StopBits_2;
+// else if (stop_bits == 3)
+// USART_InitStructure.USART_StopBits = USART_StopBits_0_5;
+// else if (stop_bits == 4)
+// USART_InitStructure.USART_StopBits = USART_StopBits_1_5;
+// else
+// USART_InitStructure.USART_StopBits = USART_StopBits_1;
+//
+// USART_Init(port, &USART_InitStructure);
+
+ LL_USART_Init(port, &USART_InitStructure);
+
+ if (port == USART1) {
+ NVIC_EnableIRQ( USART1_IRQn );
+ }
+ else if (port == USART2) {
+ NVIC_EnableIRQ( USART2_IRQn );
+ }
+
+ port->CR1 |= USART_CR1_UE;
+ port->ISR &= (0xFFFFFFFF ^ USART_ISR_TC);
+
+ ctx->srl_rx_state = SRL_RX_IDLE;
+ ctx->srl_tx_state = SRL_TX_IDLE;
+
+ ctx->srl_rx_error_reason = SRL_ERR_NONE;
+
+ ctx->srl_rx_timeout_calc_started = 0;
+ ctx->total_idle_counter = 0;
+
+ ctx->srl_rx_start_time = 0;
+ ctx->srl_rx_waiting_start_time = 0;
+
+ ctx->srl_rx_timeout_enable = 0;
+ ctx->srl_rx_timeout_waiting_enable = 0;
+}
+
+void srl_close(srl_context_t *ctx) {
+ LL_USART_DeInit(ctx->port);
+
+ if (ctx->te_port != NULL && ctx->te_pin != 0) {
+ LL_GPIO_ResetOutputPin(ctx->te_port, ctx->te_pin);
+ }
+
+ ctx->srl_rx_state = SRL_RX_NOT_CONFIG;
+ ctx->srl_tx_state = SRL_TX_NOT_CONFIG;
+}
+
+// this function shall be called in 10ms periods by some timer to check the timeout
+// during receive. This method works differently depends on what receive mode was initiaded
+//
+// if start & stop characters are in use the timeout will be calculted from the time when
+// start character was received and operation mode has been switched from SRL_WAITING_TO_RX
+// to SRL_RXING
+//
+// if no start & stop character is used by software timeout is calculated from the time when
+// first character was received after calling srl_receive_data
+void srl_keep_timeout(srl_context_t *ctx) {
+ if (ctx->srl_rx_state != SRL_RX_NOT_CONFIG && ctx->srl_rx_timeout_enable == 1) {
+
+ // checking if flag to check a timeout is raised
+ if (ctx->srl_rx_timeout_calc_started == 1) {
+
+ // check if timeout expired
+ if (master_time - ctx->srl_rx_start_time > ctx->srl_rx_timeout_trigger_value_in_msec) {
+ // disable the receiving part of UART, disable interrupt and switch to an error state
+ ctx->port->CR1 &= (0xFFFFFFFF ^ USART_CR1_RE);
+ ctx->port->CR1 &= (0xFFFFFFFF ^ USART_CR1_RXNEIE);
+
+ ctx->srl_rx_state = SRL_RX_ERROR;
+
+ ctx->srl_rx_error_reason = SRL_ERR_TIMEOUT_RECEIVING;
+ }
+ }
+
+ }
+ else {
+ ;
+ }
+
+ if ((ctx->srl_rx_state == SRL_WAITING_TO_RX || ctx->srl_rx_state == SRL_RXING ) && ctx->srl_rx_timeout_waiting_enable == 1) {
+ if (master_time - ctx->srl_rx_waiting_start_time > ctx->srl_rx_timeout_trigger_value_in_msec) {
+ ctx->port->CR1 &= (0xFFFFFFFF ^ USART_CR1_RE);
+ ctx->port->CR1 &= (0xFFFFFFFF ^ USART_CR1_RXNEIE);
+
+ ctx->srl_rx_state = SRL_RX_ERROR;
+
+ ctx->srl_rx_error_reason = SRL_ERR_TIMEOUT_WAITING;
+ }
+ }
+}
+
+uint8_t srl_send_data(srl_context_t *ctx, uint8_t* data, uint8_t mode, uint16_t leng, uint8_t internal_external) {
+ if (ctx->srl_tx_state == SRL_TXING)
+ return SRL_BUSY;
+
+ /* Wesja z dnia 04.09.2013
+
+ char* data - wskaznik na tablice z danymi do przeslania
+ char mode - tryb pracy ktory okresla czy ma wysylac okreslona liczbe znakow
+ czy wysylac wszystko do napotkania 0x00
+ short leng - ilosc znakow do wyslania istotna tylko gdy mode = 1
+ internal_external - ustawienie 0 spowoduje skopiowanie do wewnentrznego bufora i wysylanie z niego
+ jedynka spowoduje wysylanie bezposrednio z wewnetrznego
+ */
+ int i;
+
+ // the bytes counter needs to be set to 1 as the first byte is sent in this function
+ ctx->srl_tx_bytes_counter = 1;
+
+ // if an user want to send data using internal buffer
+ if (internal_external == 0) {
+
+ // if data at the input is too long to fit in the buffer
+ if (leng >= ctx->srl_rx_buf_ln)
+ return SRL_DATA_TOO_LONG;
+
+ // setting a pointer to transmit buffer to the internal buffer inside the driver
+ ctx->srl_tx_buf_pointer = srl_usart1_tx_buffer;
+
+ ctx->srl_tx_buf_ln = TX_BUFFER_1_LN;
+
+ // cleaning the buffer from previous content
+ memset(ctx->srl_tx_buf_pointer, 0x00, TX_BUFFER_1_LN);
+
+ // copying the data from provided pointer to internal buffer
+ if (mode == 0) {
+ // copying everything till the 0x00 is spoted or till the buffer border is reached
+ for (i = 0; (i < TX_BUFFER_1_LN && *(data+i) != '\0'); i++)
+ ctx->srl_tx_buf_pointer[i]=data[i];
+ ctx->srl_tx_bytes_req = i;
+ }
+ else if (mode == 1) {
+ // we don't need to check against buffer size because this was confirmed already
+ for (i = 0; i<=leng ; i++)
+ ctx->srl_tx_buf_pointer[i]=data[i];
+ ctx->srl_tx_bytes_req = leng;
+ }
+ }
+ else if (internal_external == 1) {
+ ctx->srl_tx_buf_pointer = data;
+ ctx->srl_tx_bytes_req = leng;
+ ctx->srl_tx_buf_ln = leng;
+ }
+ else return SRL_WRONG_BUFFER_PARAM;
+
+ // enabling transmitter
+ ctx->port->CR1 |= USART_CR1_TE;
+ ctx->port->ISR &= (0xFFFFFFFF ^ USART_ISR_TC);
+ ctx->port->TDR = ctx->srl_tx_buf_pointer[0];
+ ctx->srl_tx_state = SRL_TXING;
+ ctx->port->CR1 |= USART_CR1_TXEIE; // przerwanie zg�aszane kiedy rejsetr DR jest pusty
+ ctx->port->CR1 |= USART_CR1_TCIE; // przerwanie zg�aszane po transmisji bajtu
+ // je�eli rejestr DR jest nadal pusty
+ return SRL_OK;
+
+}
+
+/**
+ * This function assumes than
+ */
+uint8_t srl_start_tx(srl_context_t *ctx, short leng) {
+ if (ctx->srl_tx_state == SRL_TXING)
+ return SRL_BUSY;
+
+ // if data at the input is too long to fit in the buffer
+ if (leng >= ctx->srl_rx_buf_ln)
+ return SRL_DATA_TOO_LONG;
+
+ ctx->srl_tx_bytes_req = leng;
+
+ // setting a pointer to transmit buffer to the internal buffer inside the driver
+ //ctx->srl_tx_buf_pointer = srl_usart1_tx_buffer;
+
+// if (ctx->te_port != 0)
+// GPIO_SetBits(ctx->te_port, ctx->te_pin);
+
+ // check if delay should be applied to transmission
+ if (ctx->srl_tx_start_time == 0xFFFFFFFFu) {
+ // 0xFFFFFFFF is a magic number which disables the pre-tx delay
+ ctx->port->CR1 |= USART_CR1_TE;
+ ctx->port->ISR &= (0xFFFFFFFF ^ USART_ISR_TC);
+ ctx->port->TDR = ctx->srl_tx_buf_pointer[0];
+
+ // the bytes counter needs to be set to 1 as the first byte is sent in this function
+ ctx->srl_tx_bytes_counter = 1;
+
+ ctx->srl_tx_state = SRL_TXING;
+
+ ctx->port->CR1 |= USART_CR1_TXEIE;
+ ctx->port->CR1 |= USART_CR1_TCIE;
+
+ }
+ else {
+ ctx->srl_tx_state = SRL_TX_WAITING;
+ ctx->srl_tx_start_time = main_get_master_time();
+ }
+
+ return SRL_OK;
+}
+
+void srl_wait_for_tx_completion(srl_context_t *ctx) {
+ while(ctx->srl_tx_state != SRL_TX_IDLE && ctx->srl_tx_state != SRL_TX_ERROR);
+}
+
+uint8_t srl_wait_for_rx_completion_or_timeout(srl_context_t *ctx, uint8_t* output) {
+
+ *output = SRL_UNINITIALIZED;
+
+ // block the execution until the
+ while(ctx->srl_rx_state != SRL_RX_DONE && ctx->srl_rx_state != SRL_RX_ERROR);
+
+ switch (ctx->srl_rx_state) {
+ case SRL_RX_DONE: {
+ *output = SRL_OK;
+ break;
+ }
+
+ case SRL_RX_ERROR: {
+ *output = SRL_TIMEOUT;
+ break;
+ }
+
+ default: {
+ break;
+ }
+ }
+
+ return *output;
+}
+
+uint8_t srl_receive_data(srl_context_t *ctx, int num, char start, char stop, char echo, char len_addr, char len_modifier) {
+ if (ctx->srl_rx_state == SRL_RXING)
+ return SRL_BUSY;
+
+ //trace_printf("Serial:SrlReceiveData()\r\n");
+
+ if (num >= ctx->srl_rx_buf_ln)
+ return SRL_DATA_TOO_LONG;
+
+ memset(ctx->srl_rx_buf_pointer, 0x00, ctx->srl_rx_buf_ln);
+
+ ctx->srl_rx_error_reason = SRL_ERR_NONE;
+
+ // checking if user want
+ if (start != 0x00) {
+ ctx->srl_triggered_start = 1;
+ ctx->srl_start_trigger = start;
+ }
+ else {
+ ctx->srl_triggered_start = 0;
+ ctx->srl_start_trigger = 0;
+ }
+
+ if (stop != 0x00) {
+ ctx->srl_triggered_stop = 1;
+ ctx->srl_stop_trigger = stop;
+ }
+ else {
+ ctx->srl_triggered_stop = 0;
+ ctx->srl_stop_trigger = 0;
+ }
+
+ if (ctx->srl_triggered_start == 1 || ctx->srl_triggered_stop == 1) {
+ if (num < 3)
+ return SRL_WRONG_PARAMS_COMBINATION;
+
+ ctx->srl_rx_state = SRL_WAITING_TO_RX;
+ ctx->srl_rx_waiting_start_time = master_time;
+ }
+ else {
+ ctx->srl_rx_state = SRL_RXING;
+ }
+
+ ctx->srl_enable_echo = echo;
+ ctx->srl_rx_bytes_counter = 0;
+ ctx->srl_rx_bytes_req = num;
+
+ if (len_addr != 0) {
+ ctx->srl_rx_lenght_param_addres = len_addr;
+ }
+ else {
+ ctx->srl_rx_lenght_param_addres = num + 1;
+ }
+ ctx->srl_rx_lenght_param_modifier = len_modifier;
+
+ ctx->srl_rx_timeout_calc_started = 0;
+
+ ctx->port->CR1 |= USART_CR1_RE; // uruchamianie odbiornika
+ ctx->port->CR1 |= USART_CR1_RXNEIE; // przerwanie od przepe�nionego bufora odbioru
+// PORT->CR1 |= USART_CR1_IDLEIE; // przerwanie od bezczynno�ci szyny RS przy odbiorze
+ // spowodowanej zako�czeniem transmisji przez urz�dzenie
+ return SRL_OK;
+}
+
+/**
+ * This function start the transfer with
+ */
+uint8_t srl_receive_data_with_instant_timeout(srl_context_t *ctx, int num, char start, char stop, char echo, char len_addr, char len_modifier) {
+ if (ctx->srl_rx_state == SRL_RXING)
+ return SRL_BUSY;
+
+ if (num >= ctx->srl_rx_buf_ln)
+ return SRL_DATA_TOO_LONG;
+
+ memset(ctx->srl_rx_buf_pointer, 0x00, ctx->srl_rx_buf_ln);
+
+ // checking if user want
+ if (start != 0x00) {
+ ctx->srl_triggered_start = 1;
+ ctx->srl_start_trigger = start;
+ }
+ else {
+ ctx->srl_triggered_start = 0;
+ }
+
+ if (stop != 0x00) {
+ ctx->srl_triggered_stop = 1;
+ ctx->srl_stop_trigger = stop;
+ }
+ else {
+ ctx->srl_triggered_stop = 0;
+ }
+
+ if (ctx->srl_triggered_start == 1 || ctx->srl_triggered_stop == 1) {
+ if (num < 3)
+ return SRL_WRONG_PARAMS_COMBINATION;
+
+ ctx->srl_rx_state = SRL_WAITING_TO_RX;
+ ctx->srl_rx_waiting_start_time = master_time;
+ }
+ else {
+ ctx->srl_rx_state = SRL_RXING;
+ }
+
+ ctx->srl_enable_echo = echo;
+ ctx->srl_rx_bytes_counter = 0;
+ ctx->srl_rx_bytes_req = num;
+
+ if (len_addr != 0) {
+ ctx->srl_rx_lenght_param_addres = len_addr;
+ }
+ else {
+ ctx->srl_rx_lenght_param_addres = num + 1;
+ }
+ ctx->srl_rx_lenght_param_modifier = len_modifier;
+
+ // set current time as receive start time
+ ctx->srl_rx_start_time = master_time;
+
+ ctx->srl_rx_timeout_calc_started = 1;
+
+ ctx->port->CR1 |= USART_CR1_RE; // uruchamianie odbiornika
+ ctx->port->CR1 |= USART_CR1_RXNEIE; // przerwanie od przepe�nionego bufora odbioru
+// PORT->CR1 |= USART_CR1_IDLEIE; // przerwanie od bezczynno�ci szyny RS przy odbiorze
+ // spowodowanej zako�czeniem transmisji przez urz�dzenie
+ return SRL_OK;
+}
+
+uint8_t srl_receive_data_with_callback(srl_context_t *ctx, srl_rx_termination_callback_t cbk) {
+ uint8_t retval = SRL_OK;
+
+ if (ctx->srl_rx_state == SRL_RXING) {
+ retval = SRL_BUSY;
+ }
+ else {
+ // check if input pointers were set to something
+ if (cbk == NULL || ctx == NULL) {
+ retval = SRL_WRONG_PARAMS_COMBINATION;
+ }
+ else {
+ // set the callback pointer within the context
+ ctx->srl_rx_term = cbk;
+
+ // set the amount of bytes to be received as the size
+ // of the receive buffer (minus one byte for safety).
+ // it will be up to the callback function to terminate the receiving
+ ctx->srl_rx_bytes_req = ctx->srl_rx_buf_ln - 1;
+
+ // clear the rx buffer
+ memset(ctx->srl_rx_buf_pointer, 0x00, ctx->srl_rx_buf_ln);
+
+ ctx->srl_rx_bytes_counter = 0;
+
+ ctx->srl_rx_lenght_param_addres = ctx->srl_rx_buf_ln - 1;
+ ctx->srl_rx_lenght_param_modifier = 0;
+
+ ctx->srl_triggered_start = 0;
+ ctx->srl_triggered_stop = 0;
+ ctx->srl_enable_echo = 0;
+
+ ctx->srl_rx_timeout_calc_started = 0;
+
+ ctx->srl_rx_state = SRL_RXING;
+ ctx->port->CR1 |= USART_CR1_RE; // uruchamianie odbiornika
+ ctx->port->CR1 |= USART_CR1_RXNEIE;
+ ctx->port->CR1 |= USART_CR1_IDLEIE;
+
+ ctx->srl_rx_waiting_start_time = master_time;
+ ctx->srl_rx_start_time = master_time;
+
+ }
+ }
+
+ return retval;
+}
+
+void srl_irq_handler(srl_context_t *ctx) {
+
+ // local variable for recalculating a stream length (how many bytes the driver should receives)
+ uint16_t len_temp = 0;
+
+ // set to one if there are conditions to stop receiving
+ uint8_t stop_rxing = 0;
+
+ // local variable to store
+ uint8_t value = 0;
+
+ if ((ctx->port->ISR & USART_ISR_IDLE) == USART_ISR_IDLE) {
+ ctx->srl_garbage_storage = (uint8_t)ctx->port->RDR;
+
+ ctx->total_idle_counter++;
+ }
+
+ // if overrun happened, a byte hadn't been transferred from DR before the next byte is received
+ if ((ctx->port->ISR & USART_ISR_ORE) == USART_ISR_ORE) {
+ switch (ctx->srl_rx_state) {
+ case SRL_RXING:
+ ctx->srl_garbage_storage = (uint8_t)ctx->port->RDR;
+
+ break;
+ default:
+ // if the UART driver is not receiving actually but hardware controler received any data
+ // it is required to read value of DR register to clear the interrupt
+ ctx->srl_garbage_storage = (uint8_t)ctx->port->RDR;
+ break;
+ }
+ }
+
+ // if any data has been received by the UART controller
+ if ((ctx->port->ISR & USART_ISR_RXNE) == USART_ISR_RXNE) {
+
+ // incremenet the received bytes counter
+ ctx->total_rx_bytes++;
+
+ switch (ctx->srl_rx_state) {
+ case SRL_RXING: {
+
+ ctx->srl_rx_start_time = master_time;
+
+ // raise a flag to signalize that timeout shall be calulated from now.
+ ctx->srl_rx_timeout_calc_started = 1;
+
+ // disable the waiting timeout
+ ctx->srl_rx_timeout_waiting_enable = 0;
+
+ // if there is any data remaining to receive
+ if (ctx->srl_rx_bytes_counter < ctx->srl_rx_bytes_req) {
+
+ // storing received byte into buffer
+ ctx->srl_rx_buf_pointer[ctx->srl_rx_bytes_counter] = (uint8_t)ctx->port->RDR;
+
+ // check if termination callback pointer has been set
+ if (ctx->srl_rx_term != NULL) {
+ // if yes call it
+ stop_rxing = ctx->srl_rx_term( ctx->srl_rx_buf_pointer[ctx->srl_rx_bytes_counter],
+ ctx->srl_rx_buf_pointer,
+ ctx->srl_rx_bytes_counter);
+
+ // and check the return value
+ if (stop_rxing == 1) {
+ // if this was the last byte of transmission switch the state
+ // of receiving part to done
+ ctx->srl_rx_state = SRL_RX_DONE;
+
+ ctx->srl_triggered_stop = 0;
+ }
+
+ }
+
+ // checking if this byte in stream holds the protocol information about
+ // how many bytes needs to be received.
+ if (ctx->srl_rx_lenght_param_addres == ctx->srl_rx_bytes_counter) {
+ len_temp = ctx->srl_rx_buf_pointer[ctx->srl_rx_bytes_counter];
+
+ // adding (or substracting) a length modifier
+ len_temp += ctx->srl_rx_lenght_param_modifier;
+
+ // if the target length is bigger than buffer size switch to error state
+ if (len_temp >= ctx->srl_rx_buf_ln) {
+ ctx->srl_rx_error_reason = SRL_ERR_OVERFLOW;
+ ctx->srl_rx_state = SRL_RX_ERROR;
+ stop_rxing = 1;
+ }
+ else {
+ ctx->srl_rx_bytes_req = len_temp;
+ }
+ }
+
+ // moving buffer pointer forward
+ ctx->srl_rx_bytes_counter++;
+
+ }
+
+ // if the user want the driver to stop receiving after certain is received
+ if (ctx->srl_triggered_stop == 1) {
+ if (ctx->srl_rx_buf_pointer[ctx->srl_rx_bytes_counter - 1] == ctx->srl_stop_trigger) {
+ ctx->srl_rx_state = SRL_RX_DONE;
+ stop_rxing = 1;
+ }
+ }
+
+ // if after incrementing a pointer we reached the end of the buffer
+ if (ctx->srl_rx_bytes_counter >= ctx->srl_rx_bytes_req) {
+
+ // enabling a flag to disble receiver
+ stop_rxing = 1;
+
+ // setting a state to receive done
+ ctx->srl_rx_state = SRL_RX_DONE;
+ }
+
+ if (stop_rxing == 1) {
+
+ ctx->srl_rx_timeout_calc_started = 0;
+
+ // disabling UART receiver and its interrupt
+ ctx->port->CR1 &= (0xFFFFFFFF ^ USART_CR1_RE);
+ ctx->port->CR1 &= (0xFFFFFFFF ^ USART_CR1_RXNEIE);
+ ctx->port->CR1 &= (0xFFFFFFFF ^ USART_CR1_IDLEIE);
+ }
+
+ break;
+ }
+
+ // the state when a driver is waiting for start character to appear on serial link
+ case SRL_WAITING_TO_RX: {
+
+ // storing the value of DR register into local variable to protect against data races
+ // which may happened if this IT routine will be preempted by another (long) one
+ value = (uint8_t)ctx->port->RDR;
+
+ // checking if start character was received
+ if (value == ctx->srl_start_trigger) {
+
+ // storing received byte in buffer as firts one
+ ctx->srl_rx_buf_pointer[ctx->srl_rx_bytes_counter] = value;
+
+ // increasing the counter value
+ ctx->srl_rx_bytes_counter++;
+
+ // change state to receiving
+ ctx->srl_rx_state = SRL_RXING;
+
+ // as receiving is started there is no point to calculate waiting timeout
+ ctx->srl_rx_timeout_waiting_enable = 0;
+ }
+ else {
+ // if this is not start byte just store it in garbage buffer to clear interrupt condition
+ ctx->srl_garbage_storage = value;
+ }
+ break;
+ }
+ default: break;
+ }
+
+ }
+
+ // if one byte was successfully transferred from DR to shift register for transmission over USART
+ if ((ctx->port->ISR & USART_ISR_TXE) == USART_ISR_TXE) {
+
+ // increment the transmitted bytes counter
+ ctx->total_tx_bytes++;
+
+ switch (ctx->srl_tx_state) {
+ case SRL_TXING:
+ if (ctx->srl_tx_bytes_counter < ctx->srl_tx_bytes_req) {
+ if (ctx->te_port != 0) {
+ LL_GPIO_SetOutputPin(ctx->te_port, ctx->te_pin);
+ }
+
+ ctx->port->TDR = ctx->srl_tx_buf_pointer[ctx->srl_tx_bytes_counter++];
+ }
+ else {
+ while((ctx->port->ISR & USART_ISR_TC) != USART_ISR_TC);
+ ctx->port->CR1 &= (0xFFFFFFFF ^ USART_CR1_TE); //wyġṗczanie nadajnika portu szeregowego
+ ctx->port->CR1 &= (0xFFFFFFFF ^ USART_CR1_TXEIE);
+ ctx->port->CR1 &= (0xFFFFFFFF ^ USART_CR1_TCIE); // wyġṗczanie przerwañ od portu szeregowego
+ ctx->port->ISR &= (0xFFFFFFFF ^ USART_ISR_TC);
+ ctx->srl_tx_state = SRL_TX_IDLE;
+
+ if (ctx->te_port != 0) {
+ LL_GPIO_ResetOutputPin(ctx->te_port, ctx->te_pin);
+ }
+
+ }
+
+ if (ctx->srl_tx_bytes_counter >= ctx->srl_tx_buf_ln ||
+ ctx->srl_tx_bytes_req >= ctx->srl_tx_buf_ln) {
+
+ ctx->port->CR1 &= (0xFFFFFFFF ^ USART_CR1_TE); //wyġṗczanie nadajnika portu szeregowego
+ ctx->port->CR1 &= (0xFFFFFFFF ^ USART_CR1_TXEIE);
+ ctx->port->CR1 &= (0xFFFFFFFF ^ USART_CR1_TCIE); // wyġṗczanie przerwañ od portu szeregowego
+ ctx->port->ISR &= (0xFFFFFFFF ^ USART_ISR_TC);
+ ctx->srl_tx_state = SRL_TX_IDLE;
+
+ if (ctx->te_port != 0) {
+ LL_GPIO_ResetOutputPin(ctx->te_port, ctx->te_pin);
+ }
+
+ }
+
+ break;
+ default: break;
+ }
+ }
+
+}
+
+uint16_t srl_get_num_bytes_rxed(srl_context_t *ctx) {
+ return ctx->srl_rx_bytes_counter;
+}
+
+uint8_t* srl_get_rx_buffer(srl_context_t *ctx) {
+ return ctx->srl_rx_buf_pointer;
+}
+
+void srl_keep_tx_delay(srl_context_t *ctx) {
+ if (ctx != 0) {
+
+ // check if pre tx delay is enabled by an user
+ if (ctx->srl_tx_start_time != 0xFFFFFFFFu) {
+
+ // if it is enabled then check if the serial port is currently set to waiting state
+ if (ctx->srl_tx_state == SRL_TX_WAITING) {
+
+ // check if a delay has expired
+ if (main_get_master_time() - ctx->srl_tx_start_time >= SRL_TX_DELAY_IN_MS) {
+
+ // if yes start the transmission
+ ctx->port->CR1 |= USART_CR1_TE;
+ ctx->port->ISR &= (0xFFFFFFFF ^ USART_ISR_TC);
+ ctx->port->TDR = ctx->srl_tx_buf_pointer[0];
+
+ ctx->srl_tx_bytes_counter = 1;
+
+ ctx->srl_tx_state = SRL_TXING;
+
+ ctx->port->CR1 |= USART_CR1_TXEIE;
+ ctx->port->CR1 |= USART_CR1_TCIE;
+ }
+ }
+
+ }
+ }
+}
+
+void srl_switch_tx_delay(srl_context_t *ctx, uint8_t disable_enable) {
+ if (ctx != 0) {
+
+ if (disable_enable == 1) {
+ ctx->srl_tx_start_time = 0x0u;
+ }
+ else {
+ ctx->srl_tx_start_time = 0xFFFFFFFFu;
+ }
+ }
+}
+
+/**
+ * This function controls the timeout which is calculated for data reception (when the
+ * state is set to SRL_RXING). The time starts ticking after the first byte appears in
+ * data register, so this protect against stalling in the middle of data transfer
+ */
+void srl_switch_timeout(srl_context_t *ctx, uint8_t disable_enable, uint32_t value) {
+ if (disable_enable == 1)
+ ctx->srl_rx_timeout_enable = 1;
+ else if (disable_enable == 0)
+ ctx->srl_rx_timeout_enable = 0;
+ else {
+ ;
+ }
+
+ if (value != 0) {
+ ctx->srl_rx_timeout_trigger_value_in_msec = value;
+ }
+ else {
+ ctx->srl_rx_timeout_trigger_value_in_msec = SRL_DEFAULT_RX_TIMEOUT_IN_MS;
+ }
+}
+
+/**
+ * This function enables the timeout which is calculated for the waiting state for
+ * the data reception to begin (the first byte on serial port). It must be called for
+ * each RX transaction it is required as this timeout is cleared/disabled after the first
+ * byte received by the serial port (when the state changes from SRL_WAITING_TO_RX to
+ * SRL_RXING)
+ */
+void srl_switch_timeout_for_waiting(srl_context_t *ctx, uint8_t disable_enable) {
+ if (disable_enable == 1)
+ ctx->srl_rx_timeout_waiting_enable = 1;
+ else if (disable_enable == 0)
+ ctx->srl_rx_timeout_waiting_enable = 0;
+ else {
+ ;
+ }
+
+ if (ctx->srl_rx_timeout_trigger_value_in_msec == 0)
+ ctx->srl_rx_timeout_trigger_value_in_msec = SRL_DEFAULT_RX_TIMEOUT_IN_MS;
+
+}