2021-09-23 08:07:10 +00:00
|
|
|
|
#include <drivers/f1/gpio_conf_stm32f1x.h>
|
2017-08-20 12:41:17 +00:00
|
|
|
|
#include "drivers/serial.h"
|
2017-09-05 20:31:27 +00:00
|
|
|
|
#include "station_config.h"
|
2017-08-20 12:41:17 +00:00
|
|
|
|
#include "diag/Trace.h"
|
|
|
|
|
|
2019-01-13 20:55:09 +00:00
|
|
|
|
#include "main.h" // global_time is here
|
|
|
|
|
|
2019-01-02 22:05:26 +00:00
|
|
|
|
#include <string.h>
|
2017-08-20 12:41:17 +00:00
|
|
|
|
|
|
|
|
|
|
2019-01-02 07:20:19 +00:00
|
|
|
|
#ifdef SEPARATE_TX_BUFF
|
2020-09-26 19:03:28 +00:00
|
|
|
|
uint8_t srl_usart1_tx_buffer[TX_BUFFER_1_LN] = {'\0'};
|
2019-01-02 07:20:19 +00:00
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef SEPARATE_RX_BUFF
|
2020-09-26 19:03:28 +00:00
|
|
|
|
uint8_t srl_usart1_rx_buffer[RX_BUFFER_1_LN] = {'\0'};
|
2019-01-02 07:20:19 +00:00
|
|
|
|
#endif
|
|
|
|
|
|
2020-04-12 17:05:41 +00:00
|
|
|
|
#ifdef SEPARATE_TX_BUFF
|
2020-09-26 19:03:28 +00:00
|
|
|
|
uint8_t srl_usart2_tx_buffer[TX_BUFFER_2_LN] = {'\0'};
|
2020-04-12 17:05:41 +00:00
|
|
|
|
#endif
|
2019-01-13 20:55:09 +00:00
|
|
|
|
|
2020-04-12 17:05:41 +00:00
|
|
|
|
#ifdef SEPARATE_RX_BUFF
|
2020-09-26 19:03:28 +00:00
|
|
|
|
uint8_t srl_usart2_rx_buffer[RX_BUFFER_2_LN] = {'\0'};
|
2020-04-12 17:05:41 +00:00
|
|
|
|
#endif
|
2019-01-02 07:20:19 +00:00
|
|
|
|
|
2019-01-05 18:16:39 +00:00
|
|
|
|
|
2020-04-13 12:01:07 +00:00
|
|
|
|
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,
|
2020-09-20 12:13:24 +00:00
|
|
|
|
uint32_t baudrate,
|
|
|
|
|
uint8_t stop_bits
|
2020-04-13 12:01:07 +00:00
|
|
|
|
) {
|
2020-09-20 12:13:24 +00:00
|
|
|
|
|
2020-04-12 17:05:41 +00:00
|
|
|
|
if (ctx->srl_rx_state == SRL_RX_IDLE)
|
|
|
|
|
return;
|
2017-08-20 12:41:17 +00:00
|
|
|
|
|
2019-01-02 07:20:19 +00:00
|
|
|
|
#ifdef SEPARATE_TX_BUFF
|
2020-04-12 17:05:41 +00:00
|
|
|
|
ctx->srl_tx_buf_pointer = tx_buffer;
|
|
|
|
|
ctx->srl_rx_buf_ln = tx_buffer_size;
|
2019-01-02 07:20:19 +00:00
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef SEPARATE_RX_BUFF
|
2020-04-12 17:05:41 +00:00
|
|
|
|
ctx->srl_rx_buf_pointer = rx_buffer;
|
|
|
|
|
ctx->srl_tx_buf_ln = rx_buffer_size;
|
2019-01-02 07:20:19 +00:00
|
|
|
|
#endif
|
|
|
|
|
|
2022-04-07 18:56:35 +00:00
|
|
|
|
ctx->srl_tx_internal_buf_pointer = tx_buffer;
|
|
|
|
|
ctx->srl_tx_internal_buf_ln = tx_buffer_size;
|
|
|
|
|
|
2020-10-18 11:03:43 +00:00
|
|
|
|
memset(ctx->srl_rx_buf_pointer, 0x00, ctx->srl_rx_buf_ln);
|
|
|
|
|
memset(ctx->srl_tx_buf_pointer, 0x00, ctx->srl_tx_buf_ln);
|
|
|
|
|
|
2020-04-12 17:05:41 +00:00
|
|
|
|
ctx->port = port;
|
2020-10-18 11:03:43 +00:00
|
|
|
|
ctx->port_baurate = baudrate;
|
|
|
|
|
ctx->port_stopbits = stop_bits;
|
|
|
|
|
|
|
|
|
|
//ctx->te_port = 0;
|
|
|
|
|
//ctx->te_pin = 0;
|
2017-08-30 17:38:31 +00:00
|
|
|
|
|
2020-09-26 19:03:28 +00:00
|
|
|
|
ctx->srl_tx_start_time = 0xFFFFFFFFu;
|
|
|
|
|
|
2017-08-30 17:38:31 +00:00
|
|
|
|
USART_InitTypeDef USART_InitStructure;
|
|
|
|
|
|
2020-04-13 12:01:07 +00:00
|
|
|
|
USART_InitStructure.USART_BaudRate = baudrate;
|
2017-08-30 17:38:31 +00:00
|
|
|
|
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;
|
2020-09-20 12:13:24 +00:00
|
|
|
|
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;
|
|
|
|
|
|
2020-04-12 17:05:41 +00:00
|
|
|
|
USART_Init(port, &USART_InitStructure);
|
2017-08-30 17:38:31 +00:00
|
|
|
|
|
2020-04-18 12:00:40 +00:00
|
|
|
|
if (port == USART1) {
|
|
|
|
|
NVIC_EnableIRQ( USART1_IRQn );
|
|
|
|
|
}
|
|
|
|
|
else if (port == USART2) {
|
|
|
|
|
NVIC_EnableIRQ( USART2_IRQn );
|
|
|
|
|
}
|
2017-08-30 17:38:31 +00:00
|
|
|
|
|
2022-01-24 20:51:45 +00:00
|
|
|
|
port->CR1 |= USART_CR1_UE;
|
2020-04-12 17:05:41 +00:00
|
|
|
|
port->SR &= (0xFFFFFFFF ^ USART_SR_TC);
|
|
|
|
|
|
|
|
|
|
ctx->srl_rx_state = SRL_RX_IDLE;
|
|
|
|
|
ctx->srl_tx_state = SRL_TX_IDLE;
|
2019-04-03 09:41:37 +00:00
|
|
|
|
|
2020-10-18 06:42:37 +00:00
|
|
|
|
ctx->srl_rx_error_reason = SRL_ERR_NONE;
|
|
|
|
|
|
2020-04-12 17:05:41 +00:00
|
|
|
|
ctx->srl_rx_timeout_calc_started = 0;
|
2020-11-01 20:39:18 +00:00
|
|
|
|
ctx->total_idle_counter = 0;
|
2020-10-18 11:03:43 +00:00
|
|
|
|
|
|
|
|
|
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) {
|
|
|
|
|
USART_DeInit(ctx->port);
|
|
|
|
|
|
|
|
|
|
if (ctx->te_port != NULL && ctx->te_pin != 0) {
|
|
|
|
|
GPIO_ResetBits(ctx->te_port, ctx->te_pin);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ctx->srl_rx_state = SRL_RX_NOT_CONFIG;
|
|
|
|
|
ctx->srl_tx_state = SRL_TX_NOT_CONFIG;
|
2017-08-20 12:41:17 +00:00
|
|
|
|
}
|
|
|
|
|
|
2019-01-13 20:55:09 +00:00
|
|
|
|
// 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
|
2020-04-12 17:05:41 +00:00
|
|
|
|
void srl_keep_timeout(srl_context_t *ctx) {
|
|
|
|
|
if (ctx->srl_rx_state != SRL_RX_NOT_CONFIG && ctx->srl_rx_timeout_enable == 1) {
|
2019-01-13 20:55:09 +00:00
|
|
|
|
|
|
|
|
|
// checking if flag to check a timeout is raised
|
2020-04-12 17:05:41 +00:00
|
|
|
|
if (ctx->srl_rx_timeout_calc_started == 1) {
|
2019-01-13 20:55:09 +00:00
|
|
|
|
|
|
|
|
|
// check if timeout expired
|
2020-04-12 17:05:41 +00:00
|
|
|
|
if (master_time - ctx->srl_rx_start_time > ctx->srl_rx_timeout_trigger_value_in_msec) {
|
2019-01-13 20:55:09 +00:00
|
|
|
|
// disable the receiving part of UART, disable interrupt and switch to an error state
|
2020-04-12 17:05:41 +00:00
|
|
|
|
ctx->port->CR1 &= (0xFFFFFFFF ^ USART_CR1_RE);
|
|
|
|
|
ctx->port->CR1 &= (0xFFFFFFFF ^ USART_CR1_RXNEIE);
|
2019-01-13 20:55:09 +00:00
|
|
|
|
|
2020-04-12 17:05:41 +00:00
|
|
|
|
ctx->srl_rx_state = SRL_RX_ERROR;
|
2019-01-13 20:55:09 +00:00
|
|
|
|
|
2020-10-18 06:42:37 +00:00
|
|
|
|
ctx->srl_rx_error_reason = SRL_ERR_TIMEOUT_RECEIVING;
|
2019-01-13 20:55:09 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
;
|
|
|
|
|
}
|
2020-03-29 07:12:23 +00:00
|
|
|
|
|
2020-09-26 20:33:43 +00:00
|
|
|
|
if ((ctx->srl_rx_state == SRL_WAITING_TO_RX || ctx->srl_rx_state == SRL_RXING ) && ctx->srl_rx_timeout_waiting_enable == 1) {
|
2020-04-12 17:05:41 +00:00
|
|
|
|
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);
|
2020-03-29 07:12:23 +00:00
|
|
|
|
|
2020-04-12 17:05:41 +00:00
|
|
|
|
ctx->srl_rx_state = SRL_RX_ERROR;
|
2020-10-18 06:42:37 +00:00
|
|
|
|
|
|
|
|
|
ctx->srl_rx_error_reason = SRL_ERR_TIMEOUT_WAITING;
|
2020-03-29 07:12:23 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2019-01-13 20:55:09 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-01-11 15:35:44 +00:00
|
|
|
|
uint8_t srl_send_data(srl_context_t *ctx, const uint8_t* data, uint8_t mode, uint16_t leng, uint8_t internal_external) {
|
2020-04-12 17:05:41 +00:00
|
|
|
|
if (ctx->srl_tx_state == SRL_TXING)
|
2019-01-02 22:05:26 +00:00
|
|
|
|
return SRL_BUSY;
|
2019-01-02 07:20:19 +00:00
|
|
|
|
|
2017-08-20 12:41:17 +00:00
|
|
|
|
/* 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
|
2019-01-02 22:05:26 +00:00
|
|
|
|
internal_external - ustawienie 0 spowoduje skopiowanie do wewnentrznego bufora i wysylanie z niego
|
|
|
|
|
jedynka spowoduje wysylanie bezposrednio z wewnetrznego
|
2017-08-20 12:41:17 +00:00
|
|
|
|
*/
|
|
|
|
|
int i;
|
2019-01-02 07:20:19 +00:00
|
|
|
|
|
2019-10-27 19:50:01 +00:00
|
|
|
|
// the bytes counter needs to be set to 1 as the first byte is sent in this function
|
2020-04-12 17:05:41 +00:00
|
|
|
|
ctx->srl_tx_bytes_counter = 1;
|
2019-01-02 22:05:26 +00:00
|
|
|
|
|
|
|
|
|
// if an user want to send data using internal buffer
|
2019-01-02 07:20:19 +00:00
|
|
|
|
if (internal_external == 0) {
|
|
|
|
|
|
2019-01-02 22:05:26 +00:00
|
|
|
|
// if data at the input is too long to fit in the buffer
|
2020-08-27 21:53:07 +00:00
|
|
|
|
if (leng >= ctx->srl_rx_buf_ln)
|
2019-01-02 22:05:26 +00:00
|
|
|
|
return SRL_DATA_TOO_LONG;
|
|
|
|
|
|
2019-01-02 07:20:19 +00:00
|
|
|
|
// setting a pointer to transmit buffer to the internal buffer inside the driver
|
2022-04-07 18:56:35 +00:00
|
|
|
|
ctx->srl_tx_buf_pointer = ctx->srl_tx_internal_buf_pointer;
|
2019-01-02 07:20:19 +00:00
|
|
|
|
|
2022-04-07 18:56:35 +00:00
|
|
|
|
ctx->srl_tx_buf_ln = ctx->srl_tx_internal_buf_ln;
|
2019-01-05 18:16:39 +00:00
|
|
|
|
|
2019-01-02 22:05:26 +00:00
|
|
|
|
// cleaning the buffer from previous content
|
2022-04-07 18:56:35 +00:00
|
|
|
|
memset(ctx->srl_tx_buf_pointer, 0x00, ctx->srl_tx_buf_ln);
|
2019-01-02 22:05:26 +00:00
|
|
|
|
|
2019-01-02 07:20:19 +00:00
|
|
|
|
// copying the data from provided pointer to internal buffer
|
|
|
|
|
if (mode == 0) {
|
2019-01-02 22:05:26 +00:00
|
|
|
|
// copying everything till the 0x00 is spoted or till the buffer border is reached
|
2020-04-12 17:05:41 +00:00
|
|
|
|
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;
|
2017-08-20 12:41:17 +00:00
|
|
|
|
}
|
|
|
|
|
else if (mode == 1) {
|
2019-01-02 22:05:26 +00:00
|
|
|
|
// we don't need to check against buffer size because this was confirmed already
|
2017-08-20 12:41:17 +00:00
|
|
|
|
for (i = 0; i<=leng ; i++)
|
2020-04-12 17:05:41 +00:00
|
|
|
|
ctx->srl_tx_buf_pointer[i]=data[i];
|
|
|
|
|
ctx->srl_tx_bytes_req = leng;
|
2017-08-20 12:41:17 +00:00
|
|
|
|
}
|
2019-01-02 07:20:19 +00:00
|
|
|
|
}
|
|
|
|
|
else if (internal_external == 1) {
|
2020-04-12 17:05:41 +00:00
|
|
|
|
ctx->srl_tx_buf_pointer = data;
|
|
|
|
|
ctx->srl_tx_bytes_req = leng;
|
|
|
|
|
ctx->srl_tx_buf_ln = leng;
|
2019-01-02 07:20:19 +00:00
|
|
|
|
}
|
2019-01-02 22:05:26 +00:00
|
|
|
|
else return SRL_WRONG_BUFFER_PARAM;
|
|
|
|
|
|
2020-10-30 15:48:22 +00:00
|
|
|
|
// if (ctx->te_port != 0)
|
|
|
|
|
// GPIO_SetBits(ctx->te_port, ctx->te_pin);
|
2019-10-27 19:50:01 +00:00
|
|
|
|
|
2019-01-02 22:05:26 +00:00
|
|
|
|
// enabling transmitter
|
2020-04-13 12:01:07 +00:00
|
|
|
|
ctx->port->CR1 |= USART_CR1_TE;
|
|
|
|
|
ctx->port->SR &= (0xFFFFFFFF ^ USART_SR_TC);
|
|
|
|
|
ctx->port->DR = ctx->srl_tx_buf_pointer[0];
|
2020-04-12 17:05:41 +00:00
|
|
|
|
ctx->srl_tx_state = SRL_TXING;
|
2020-04-13 12:01:07 +00:00
|
|
|
|
ctx->port->CR1 |= USART_CR1_TXEIE; // przerwanie zg<7A>aszane kiedy rejsetr DR jest pusty
|
|
|
|
|
ctx->port->CR1 |= USART_CR1_TCIE; // przerwanie zg<7A>aszane po transmisji bajtu
|
2017-08-20 12:41:17 +00:00
|
|
|
|
// je<6A>eli rejestr DR jest nadal pusty
|
2019-01-02 22:05:26 +00:00
|
|
|
|
return SRL_OK;
|
2017-08-20 12:41:17 +00:00
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-02 22:05:26 +00:00
|
|
|
|
/**
|
|
|
|
|
* This function assumes than
|
|
|
|
|
*/
|
2020-04-12 17:05:41 +00:00
|
|
|
|
uint8_t srl_start_tx(srl_context_t *ctx, short leng) {
|
|
|
|
|
if (ctx->srl_tx_state == SRL_TXING)
|
2019-01-02 22:05:26 +00:00
|
|
|
|
return SRL_BUSY;
|
|
|
|
|
|
|
|
|
|
// if data at the input is too long to fit in the buffer
|
2020-08-27 21:53:07 +00:00
|
|
|
|
if (leng >= ctx->srl_rx_buf_ln)
|
2019-01-02 22:05:26 +00:00
|
|
|
|
return SRL_DATA_TOO_LONG;
|
|
|
|
|
|
2022-08-18 20:15:25 +00:00
|
|
|
|
if (leng == 0)
|
|
|
|
|
return SRL_WRONG_PARAMS_COMBINATION;
|
|
|
|
|
|
2020-04-12 17:05:41 +00:00
|
|
|
|
ctx->srl_tx_bytes_req = leng;
|
2019-10-27 19:50:01 +00:00
|
|
|
|
|
2019-01-02 22:05:26 +00:00
|
|
|
|
// setting a pointer to transmit buffer to the internal buffer inside the driver
|
2020-09-26 19:03:28 +00:00
|
|
|
|
//ctx->srl_tx_buf_pointer = srl_usart1_tx_buffer;
|
2019-01-02 22:05:26 +00:00
|
|
|
|
|
2020-10-30 15:48:22 +00:00
|
|
|
|
// if (ctx->te_port != 0)
|
|
|
|
|
// GPIO_SetBits(ctx->te_port, ctx->te_pin);
|
2019-10-27 19:50:01 +00:00
|
|
|
|
|
2020-09-26 19:03:28 +00:00
|
|
|
|
// check if delay should be applied to transmission
|
|
|
|
|
if (ctx->srl_tx_start_time == 0xFFFFFFFFu) {
|
2020-10-18 06:42:37 +00:00
|
|
|
|
// 0xFFFFFFFF is a magic number which disables the pre-tx delay
|
2020-09-26 19:03:28 +00:00
|
|
|
|
ctx->port->CR1 |= USART_CR1_TE;
|
|
|
|
|
ctx->port->SR &= (0xFFFFFFFF ^ USART_SR_TC);
|
|
|
|
|
ctx->port->DR = ctx->srl_tx_buf_pointer[0];
|
2019-01-02 22:05:26 +00:00
|
|
|
|
|
2020-10-18 06:42:37 +00:00
|
|
|
|
// the bytes counter needs to be set to 1 as the first byte is sent in this function
|
|
|
|
|
ctx->srl_tx_bytes_counter = 1;
|
|
|
|
|
|
2020-09-26 19:03:28 +00:00
|
|
|
|
ctx->srl_tx_state = SRL_TXING;
|
2019-01-02 22:05:26 +00:00
|
|
|
|
|
2020-09-26 19:03:28 +00:00
|
|
|
|
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();
|
|
|
|
|
}
|
2019-01-02 22:05:26 +00:00
|
|
|
|
|
|
|
|
|
return SRL_OK;
|
2017-08-20 12:41:17 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-04-12 17:05:41 +00:00
|
|
|
|
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);
|
2019-05-05 12:25:48 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-08-09 19:43:38 +00:00
|
|
|
|
uint8_t srl_wait_for_rx_completion_or_timeout(srl_context_t *ctx, uint8_t* output) {
|
|
|
|
|
|
2020-08-10 21:54:18 +00:00
|
|
|
|
*output = SRL_UNINITIALIZED;
|
2020-08-09 19:43:38 +00:00
|
|
|
|
|
|
|
|
|
// block the execution until the
|
2020-09-02 20:19:01 +00:00
|
|
|
|
while(ctx->srl_rx_state != SRL_RX_DONE && ctx->srl_rx_state != SRL_RX_ERROR);
|
2020-08-09 19:43:38 +00:00
|
|
|
|
|
|
|
|
|
switch (ctx->srl_rx_state) {
|
|
|
|
|
case SRL_RX_DONE: {
|
2020-08-10 21:54:18 +00:00
|
|
|
|
*output = SRL_OK;
|
2020-08-09 19:43:38 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case SRL_RX_ERROR: {
|
2020-08-10 21:54:18 +00:00
|
|
|
|
*output = SRL_TIMEOUT;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
default: {
|
2020-08-09 19:43:38 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-08-10 21:54:18 +00:00
|
|
|
|
return *output;
|
2020-08-09 19:43:38 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-04-12 17:05:41 +00:00
|
|
|
|
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)
|
2019-01-02 22:05:26 +00:00
|
|
|
|
return SRL_BUSY;
|
|
|
|
|
|
|
|
|
|
//trace_printf("Serial:SrlReceiveData()\r\n");
|
|
|
|
|
|
2020-08-27 21:53:07 +00:00
|
|
|
|
if (num >= ctx->srl_rx_buf_ln)
|
2019-01-02 22:05:26 +00:00
|
|
|
|
return SRL_DATA_TOO_LONG;
|
|
|
|
|
|
2020-04-13 12:01:07 +00:00
|
|
|
|
memset(ctx->srl_rx_buf_pointer, 0x00, ctx->srl_rx_buf_ln);
|
2019-01-02 22:05:26 +00:00
|
|
|
|
|
2020-10-18 06:42:37 +00:00
|
|
|
|
ctx->srl_rx_error_reason = SRL_ERR_NONE;
|
|
|
|
|
|
2019-01-02 22:05:26 +00:00
|
|
|
|
// checking if user want
|
|
|
|
|
if (start != 0x00) {
|
2020-04-12 17:05:41 +00:00
|
|
|
|
ctx->srl_triggered_start = 1;
|
|
|
|
|
ctx->srl_start_trigger = start;
|
2019-01-02 22:05:26 +00:00
|
|
|
|
}
|
|
|
|
|
else {
|
2020-04-12 17:05:41 +00:00
|
|
|
|
ctx->srl_triggered_start = 0;
|
2020-09-07 21:25:58 +00:00
|
|
|
|
ctx->srl_start_trigger = 0;
|
2019-01-02 22:05:26 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (stop != 0x00) {
|
2020-04-12 17:05:41 +00:00
|
|
|
|
ctx->srl_triggered_stop = 1;
|
|
|
|
|
ctx->srl_stop_trigger = stop;
|
2019-01-02 22:05:26 +00:00
|
|
|
|
}
|
|
|
|
|
else {
|
2020-04-12 17:05:41 +00:00
|
|
|
|
ctx->srl_triggered_stop = 0;
|
2020-09-07 21:25:58 +00:00
|
|
|
|
ctx->srl_stop_trigger = 0;
|
2019-01-02 22:05:26 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-04-12 17:05:41 +00:00
|
|
|
|
if (ctx->srl_triggered_start == 1 || ctx->srl_triggered_stop == 1) {
|
2019-01-05 18:16:39 +00:00
|
|
|
|
if (num < 3)
|
|
|
|
|
return SRL_WRONG_PARAMS_COMBINATION;
|
2019-01-13 14:57:59 +00:00
|
|
|
|
|
2020-04-12 17:05:41 +00:00
|
|
|
|
ctx->srl_rx_state = SRL_WAITING_TO_RX;
|
|
|
|
|
ctx->srl_rx_waiting_start_time = master_time;
|
2019-01-05 18:16:39 +00:00
|
|
|
|
}
|
2020-09-02 20:19:01 +00:00
|
|
|
|
else {
|
|
|
|
|
ctx->srl_rx_state = SRL_RXING;
|
|
|
|
|
}
|
2019-01-05 18:16:39 +00:00
|
|
|
|
|
2020-04-12 17:05:41 +00:00
|
|
|
|
ctx->srl_enable_echo = echo;
|
|
|
|
|
ctx->srl_rx_bytes_counter = 0;
|
|
|
|
|
ctx->srl_rx_bytes_req = num;
|
2017-08-20 12:41:17 +00:00
|
|
|
|
|
2020-09-02 20:19:01 +00:00
|
|
|
|
if (len_addr != 0) {
|
|
|
|
|
ctx->srl_rx_lenght_param_addres = len_addr;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
ctx->srl_rx_lenght_param_addres = num + 1;
|
|
|
|
|
}
|
2020-04-12 17:05:41 +00:00
|
|
|
|
ctx->srl_rx_lenght_param_modifier = len_modifier;
|
2019-01-02 22:05:26 +00:00
|
|
|
|
|
2020-04-12 17:05:41 +00:00
|
|
|
|
ctx->srl_rx_timeout_calc_started = 0;
|
2019-04-03 09:41:37 +00:00
|
|
|
|
|
2020-04-13 12:01:07 +00:00
|
|
|
|
ctx->port->CR1 |= USART_CR1_RE; // uruchamianie odbiornika
|
|
|
|
|
ctx->port->CR1 |= USART_CR1_RXNEIE; // przerwanie od przepe<70>nionego bufora odbioru
|
2017-08-20 12:41:17 +00:00
|
|
|
|
// PORT->CR1 |= USART_CR1_IDLEIE; // przerwanie od bezczynno<6E>ci szyny RS przy odbiorze
|
|
|
|
|
// spowodowanej zako<6B>czeniem transmisji przez urz<72>dzenie
|
2019-01-02 22:05:26 +00:00
|
|
|
|
return SRL_OK;
|
2017-08-20 12:41:17 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-09-26 20:33:43 +00:00
|
|
|
|
/**
|
|
|
|
|
* This function start the transfer with
|
|
|
|
|
*/
|
2020-08-25 18:05:04 +00:00
|
|
|
|
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;
|
|
|
|
|
|
2020-08-27 21:53:07 +00:00
|
|
|
|
if (num >= ctx->srl_rx_buf_ln)
|
2020-08-25 18:05:04 +00:00
|
|
|
|
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;
|
|
|
|
|
}
|
2020-09-02 20:19:01 +00:00
|
|
|
|
else {
|
|
|
|
|
ctx->srl_rx_state = SRL_RXING;
|
|
|
|
|
}
|
2020-08-25 18:05:04 +00:00
|
|
|
|
|
|
|
|
|
ctx->srl_enable_echo = echo;
|
|
|
|
|
ctx->srl_rx_bytes_counter = 0;
|
|
|
|
|
ctx->srl_rx_bytes_req = num;
|
|
|
|
|
|
2020-09-02 20:19:01 +00:00
|
|
|
|
if (len_addr != 0) {
|
|
|
|
|
ctx->srl_rx_lenght_param_addres = len_addr;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
ctx->srl_rx_lenght_param_addres = num + 1;
|
|
|
|
|
}
|
2020-08-25 18:05:04 +00:00
|
|
|
|
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<70>nionego bufora odbioru
|
|
|
|
|
// PORT->CR1 |= USART_CR1_IDLEIE; // przerwanie od bezczynno<6E>ci szyny RS przy odbiorze
|
|
|
|
|
// spowodowanej zako<6B>czeniem transmisji przez urz<72>dzenie
|
|
|
|
|
return SRL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2020-08-27 21:53:07 +00:00
|
|
|
|
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;
|
|
|
|
|
|
2020-09-25 17:43:53 +00:00
|
|
|
|
ctx->srl_rx_lenght_param_addres = ctx->srl_rx_buf_ln - 1;
|
2020-08-27 21:53:07 +00:00
|
|
|
|
ctx->srl_rx_lenght_param_modifier = 0;
|
|
|
|
|
|
|
|
|
|
ctx->srl_triggered_start = 0;
|
|
|
|
|
ctx->srl_triggered_stop = 0;
|
|
|
|
|
ctx->srl_enable_echo = 0;
|
2018-12-29 17:45:28 +00:00
|
|
|
|
|
2020-08-27 21:53:07 +00:00
|
|
|
|
ctx->srl_rx_timeout_calc_started = 0;
|
|
|
|
|
|
2020-09-25 17:43:53 +00:00
|
|
|
|
ctx->srl_rx_state = SRL_RXING;
|
|
|
|
|
ctx->port->CR1 |= USART_CR1_RE; // uruchamianie odbiornika
|
|
|
|
|
ctx->port->CR1 |= USART_CR1_RXNEIE;
|
2020-10-18 11:03:43 +00:00
|
|
|
|
ctx->port->CR1 |= USART_CR1_IDLEIE;
|
2020-09-25 17:43:53 +00:00
|
|
|
|
|
2020-10-18 06:42:37 +00:00
|
|
|
|
ctx->srl_rx_waiting_start_time = master_time;
|
|
|
|
|
ctx->srl_rx_start_time = master_time;
|
2020-08-27 21:53:07 +00:00
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
|
}
|
2018-12-29 17:45:28 +00:00
|
|
|
|
|
2020-04-12 17:05:41 +00:00
|
|
|
|
void srl_irq_handler(srl_context_t *ctx) {
|
2019-01-02 22:05:26 +00:00
|
|
|
|
|
2019-01-05 18:16:39 +00:00
|
|
|
|
// local variable for recalculating a stream length (how many bytes the driver should receives)
|
|
|
|
|
uint16_t len_temp = 0;
|
2019-01-02 22:05:26 +00:00
|
|
|
|
|
2019-01-05 18:16:39 +00:00
|
|
|
|
// set to one if there are conditions to stop receiving
|
|
|
|
|
uint8_t stop_rxing = 0;
|
2019-01-02 22:05:26 +00:00
|
|
|
|
|
2019-01-12 13:44:16 +00:00
|
|
|
|
// local variable to store
|
|
|
|
|
uint8_t value = 0;
|
|
|
|
|
|
2020-10-18 11:03:43 +00:00
|
|
|
|
if ((ctx->port->SR & USART_SR_IDLE) == USART_SR_IDLE) {
|
2022-08-21 14:56:45 +00:00
|
|
|
|
//ctx->srl_garbage_storage = (uint8_t)ctx->port->DR;
|
2020-10-18 11:03:43 +00:00
|
|
|
|
|
2020-11-01 20:39:18 +00:00
|
|
|
|
ctx->total_idle_counter++;
|
2020-10-18 06:42:37 +00:00
|
|
|
|
}
|
|
|
|
|
|
2019-01-02 22:05:26 +00:00
|
|
|
|
// if overrun happened, a byte hadn't been transferred from DR before the next byte is received
|
2020-04-12 17:05:41 +00:00
|
|
|
|
if ((ctx->port->SR & USART_SR_ORE) == USART_SR_ORE) {
|
|
|
|
|
switch (ctx->srl_rx_state) {
|
2019-01-05 18:16:39 +00:00
|
|
|
|
case SRL_RXING:
|
2020-04-13 12:01:07 +00:00
|
|
|
|
ctx->srl_garbage_storage = (uint8_t)ctx->port->DR;
|
2019-01-05 18:16:39 +00:00
|
|
|
|
|
|
|
|
|
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
|
2020-04-13 12:01:07 +00:00
|
|
|
|
ctx->srl_garbage_storage = (uint8_t)ctx->port->DR;
|
2019-01-05 18:16:39 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// if any data has been received by the UART controller
|
2020-04-12 17:05:41 +00:00
|
|
|
|
if ((ctx->port->SR & USART_SR_RXNE) == USART_SR_RXNE) {
|
2020-11-01 20:39:18 +00:00
|
|
|
|
|
|
|
|
|
// incremenet the received bytes counter
|
|
|
|
|
ctx->total_rx_bytes++;
|
|
|
|
|
|
2020-04-12 17:05:41 +00:00
|
|
|
|
switch (ctx->srl_rx_state) {
|
2019-01-12 13:44:16 +00:00
|
|
|
|
case SRL_RXING: {
|
2019-01-05 18:16:39 +00:00
|
|
|
|
|
2020-04-12 17:05:41 +00:00
|
|
|
|
ctx->srl_rx_start_time = master_time;
|
2019-04-03 09:41:37 +00:00
|
|
|
|
|
2019-01-13 20:55:09 +00:00
|
|
|
|
// raise a flag to signalize that timeout shall be calulated from now.
|
2020-04-12 17:05:41 +00:00
|
|
|
|
ctx->srl_rx_timeout_calc_started = 1;
|
2019-01-13 20:55:09 +00:00
|
|
|
|
|
2020-09-26 20:33:43 +00:00
|
|
|
|
// disable the waiting timeout
|
|
|
|
|
ctx->srl_rx_timeout_waiting_enable = 0;
|
|
|
|
|
|
2019-01-05 18:16:39 +00:00
|
|
|
|
// if there is any data remaining to receive
|
2020-04-12 17:05:41 +00:00
|
|
|
|
if (ctx->srl_rx_bytes_counter < ctx->srl_rx_bytes_req) {
|
2019-01-05 18:16:39 +00:00
|
|
|
|
|
|
|
|
|
// storing received byte into buffer
|
2020-04-13 12:01:07 +00:00
|
|
|
|
ctx->srl_rx_buf_pointer[ctx->srl_rx_bytes_counter] = (uint8_t)ctx->port->DR;
|
2019-01-05 18:16:39 +00:00
|
|
|
|
|
2020-09-26 19:03:28 +00:00
|
|
|
|
// 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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-05 18:16:39 +00:00
|
|
|
|
// checking if this byte in stream holds the protocol information about
|
|
|
|
|
// how many bytes needs to be received.
|
2020-04-12 17:05:41 +00:00
|
|
|
|
if (ctx->srl_rx_lenght_param_addres == ctx->srl_rx_bytes_counter) {
|
|
|
|
|
len_temp = ctx->srl_rx_buf_pointer[ctx->srl_rx_bytes_counter];
|
2019-01-05 18:16:39 +00:00
|
|
|
|
|
|
|
|
|
// adding (or substracting) a length modifier
|
2020-04-12 17:05:41 +00:00
|
|
|
|
len_temp += ctx->srl_rx_lenght_param_modifier;
|
2019-01-05 18:16:39 +00:00
|
|
|
|
|
|
|
|
|
// if the target length is bigger than buffer size switch to error state
|
2020-04-12 17:05:41 +00:00
|
|
|
|
if (len_temp >= ctx->srl_rx_buf_ln) {
|
2020-10-18 06:42:37 +00:00
|
|
|
|
ctx->srl_rx_error_reason = SRL_ERR_OVERFLOW;
|
2020-04-12 17:05:41 +00:00
|
|
|
|
ctx->srl_rx_state = SRL_RX_ERROR;
|
2019-01-05 18:16:39 +00:00
|
|
|
|
stop_rxing = 1;
|
|
|
|
|
}
|
|
|
|
|
else {
|
2020-04-12 17:05:41 +00:00
|
|
|
|
ctx->srl_rx_bytes_req = len_temp;
|
2019-01-05 18:16:39 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// moving buffer pointer forward
|
2020-04-12 17:05:41 +00:00
|
|
|
|
ctx->srl_rx_bytes_counter++;
|
2020-08-27 21:53:07 +00:00
|
|
|
|
|
2019-01-05 18:16:39 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// if the user want the driver to stop receiving after certain is received
|
2020-04-12 17:05:41 +00:00
|
|
|
|
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;
|
2019-01-13 14:57:59 +00:00
|
|
|
|
stop_rxing = 1;
|
2019-01-05 18:16:39 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// if after incrementing a pointer we reached the end of the buffer
|
2020-04-12 17:05:41 +00:00
|
|
|
|
if (ctx->srl_rx_bytes_counter >= ctx->srl_rx_bytes_req) {
|
2019-01-05 18:16:39 +00:00
|
|
|
|
|
|
|
|
|
// enabling a flag to disble receiver
|
|
|
|
|
stop_rxing = 1;
|
|
|
|
|
|
|
|
|
|
// setting a state to receive done
|
2020-04-12 17:05:41 +00:00
|
|
|
|
ctx->srl_rx_state = SRL_RX_DONE;
|
2019-01-05 18:16:39 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (stop_rxing == 1) {
|
2019-01-13 20:55:09 +00:00
|
|
|
|
|
2020-04-12 17:05:41 +00:00
|
|
|
|
ctx->srl_rx_timeout_calc_started = 0;
|
2019-01-13 20:55:09 +00:00
|
|
|
|
|
2019-01-05 18:16:39 +00:00
|
|
|
|
// disabling UART receiver and its interrupt
|
2020-04-12 17:05:41 +00:00
|
|
|
|
ctx->port->CR1 &= (0xFFFFFFFF ^ USART_CR1_RE);
|
|
|
|
|
ctx->port->CR1 &= (0xFFFFFFFF ^ USART_CR1_RXNEIE);
|
2020-10-18 11:03:43 +00:00
|
|
|
|
ctx->port->CR1 &= (0xFFFFFFFF ^ USART_CR1_IDLEIE);
|
2019-01-05 18:16:39 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
2019-01-12 13:44:16 +00:00
|
|
|
|
}
|
2019-01-05 18:16:39 +00:00
|
|
|
|
|
|
|
|
|
// the state when a driver is waiting for start character to appear on serial link
|
2019-01-12 13:44:16 +00:00
|
|
|
|
case SRL_WAITING_TO_RX: {
|
2019-01-05 18:16:39 +00:00
|
|
|
|
|
|
|
|
|
// 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
|
2020-04-12 17:05:41 +00:00
|
|
|
|
value = (uint8_t)ctx->port->DR;
|
2019-01-05 18:16:39 +00:00
|
|
|
|
|
|
|
|
|
// checking if start character was received
|
2020-04-12 17:05:41 +00:00
|
|
|
|
if (value == ctx->srl_start_trigger) {
|
2019-01-05 18:16:39 +00:00
|
|
|
|
|
|
|
|
|
// storing received byte in buffer as firts one
|
2020-04-12 17:05:41 +00:00
|
|
|
|
ctx->srl_rx_buf_pointer[ctx->srl_rx_bytes_counter] = value;
|
2019-01-05 18:16:39 +00:00
|
|
|
|
|
|
|
|
|
// increasing the counter value
|
2020-04-12 17:05:41 +00:00
|
|
|
|
ctx->srl_rx_bytes_counter++;
|
2019-01-05 18:16:39 +00:00
|
|
|
|
|
|
|
|
|
// change state to receiving
|
2020-04-12 17:05:41 +00:00
|
|
|
|
ctx->srl_rx_state = SRL_RXING;
|
2020-03-29 07:12:23 +00:00
|
|
|
|
|
|
|
|
|
// as receiving is started there is no point to calculate waiting timeout
|
2020-04-12 17:05:41 +00:00
|
|
|
|
ctx->srl_rx_timeout_waiting_enable = 0;
|
2019-01-05 18:16:39 +00:00
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
// if this is not start byte just store it in garbage buffer to clear interrupt condition
|
2020-04-12 17:05:41 +00:00
|
|
|
|
ctx->srl_garbage_storage = value;
|
2019-01-05 18:16:39 +00:00
|
|
|
|
}
|
|
|
|
|
break;
|
2019-01-12 13:44:16 +00:00
|
|
|
|
}
|
2019-01-02 22:05:26 +00:00
|
|
|
|
default: break;
|
|
|
|
|
}
|
2019-01-05 18:16:39 +00:00
|
|
|
|
|
2019-01-02 22:05:26 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// if one byte was successfully transferred from DR to shift register for transmission over USART
|
2020-04-13 12:01:07 +00:00
|
|
|
|
if ((ctx->port->SR & USART_SR_TXE) == USART_SR_TXE) {
|
2020-11-01 20:39:18 +00:00
|
|
|
|
|
|
|
|
|
// increment the transmitted bytes counter
|
|
|
|
|
ctx->total_tx_bytes++;
|
|
|
|
|
|
2020-04-12 17:05:41 +00:00
|
|
|
|
switch (ctx->srl_tx_state) {
|
2019-01-12 13:44:16 +00:00
|
|
|
|
case SRL_TXING:
|
2020-04-12 17:05:41 +00:00
|
|
|
|
if (ctx->srl_tx_bytes_counter < ctx->srl_tx_bytes_req) {
|
2021-05-26 20:18:11 +00:00
|
|
|
|
if (ctx->te_port != 0) {
|
2020-10-30 15:48:22 +00:00
|
|
|
|
GPIO_SetBits(ctx->te_port, ctx->te_pin);
|
2021-05-26 20:18:11 +00:00
|
|
|
|
}
|
2020-10-30 15:48:22 +00:00
|
|
|
|
|
2021-05-26 20:18:11 +00:00
|
|
|
|
ctx->port->DR = ctx->srl_tx_buf_pointer[ctx->srl_tx_bytes_counter++];
|
2019-01-12 13:44:16 +00:00
|
|
|
|
}
|
|
|
|
|
else {
|
2020-04-12 17:05:41 +00:00
|
|
|
|
while((ctx->port->SR & USART_SR_TC) != USART_SR_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->SR &= (0xFFFFFFFF ^ USART_SR_TC);
|
|
|
|
|
ctx->srl_tx_state = SRL_TX_IDLE;
|
|
|
|
|
|
2022-04-07 18:56:35 +00:00
|
|
|
|
// reset tx buffer pointer to internal one
|
|
|
|
|
ctx->srl_tx_buf_pointer = ctx->srl_tx_internal_buf_pointer;
|
|
|
|
|
ctx->srl_tx_buf_ln = ctx->srl_tx_internal_buf_ln;
|
|
|
|
|
|
2020-04-12 17:05:41 +00:00
|
|
|
|
if (ctx->te_port != 0)
|
|
|
|
|
GPIO_ResetBits(ctx->te_port, ctx->te_pin);
|
|
|
|
|
|
2019-01-12 13:44:16 +00:00
|
|
|
|
}
|
2019-02-10 16:16:37 +00:00
|
|
|
|
|
2020-04-13 12:01:07 +00:00
|
|
|
|
if (ctx->srl_tx_bytes_counter >= ctx->srl_tx_buf_ln ||
|
|
|
|
|
ctx->srl_tx_bytes_req >= ctx->srl_tx_buf_ln) {
|
2019-02-10 16:16:37 +00:00
|
|
|
|
|
2020-04-12 17:05:41 +00:00
|
|
|
|
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->SR &= (0xFFFFFFFF ^ USART_SR_TC);
|
|
|
|
|
ctx->srl_tx_state = SRL_TX_IDLE;
|
|
|
|
|
|
2022-04-07 18:56:35 +00:00
|
|
|
|
// reset tx buffer pointer to internal one
|
|
|
|
|
ctx->srl_tx_buf_pointer = ctx->srl_tx_internal_buf_pointer;
|
|
|
|
|
ctx->srl_tx_buf_ln = ctx->srl_tx_internal_buf_ln;
|
|
|
|
|
|
2020-04-12 17:05:41 +00:00
|
|
|
|
if (ctx->te_port != 0)
|
|
|
|
|
GPIO_ResetBits(ctx->te_port, ctx->te_pin);
|
|
|
|
|
//GPIO_ResetBits(GPIOA, GPIO_Pin_7);
|
2020-03-17 21:52:10 +00:00
|
|
|
|
|
2019-02-10 16:16:37 +00:00
|
|
|
|
}
|
|
|
|
|
|
2019-01-12 13:44:16 +00:00
|
|
|
|
break;
|
2019-01-02 22:05:26 +00:00
|
|
|
|
default: break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-12 13:44:16 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-04-12 17:05:41 +00:00
|
|
|
|
uint16_t srl_get_num_bytes_rxed(srl_context_t *ctx) {
|
|
|
|
|
return ctx->srl_rx_bytes_counter;
|
2019-02-10 16:16:37 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-04-12 17:05:41 +00:00
|
|
|
|
uint8_t* srl_get_rx_buffer(srl_context_t *ctx) {
|
|
|
|
|
return ctx->srl_rx_buf_pointer;
|
2017-08-20 12:41:17 +00:00
|
|
|
|
}
|
2019-01-13 14:57:59 +00:00
|
|
|
|
|
2020-09-26 19:03:28 +00:00
|
|
|
|
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->SR &= (0xFFFFFFFF ^ USART_SR_TC);
|
|
|
|
|
ctx->port->DR = ctx->srl_tx_buf_pointer[0];
|
|
|
|
|
|
2020-10-18 06:42:37 +00:00
|
|
|
|
ctx->srl_tx_bytes_counter = 1;
|
|
|
|
|
|
2020-09-26 19:03:28 +00:00
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-26 20:33:43 +00:00
|
|
|
|
/**
|
|
|
|
|
* This function controls the timeout which is calculated for data reception (when the
|
2020-10-18 06:42:37 +00:00
|
|
|
|
* 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
|
2020-09-26 20:33:43 +00:00
|
|
|
|
*/
|
2020-04-12 17:05:41 +00:00
|
|
|
|
void srl_switch_timeout(srl_context_t *ctx, uint8_t disable_enable, uint32_t value) {
|
2019-01-13 20:55:09 +00:00
|
|
|
|
if (disable_enable == 1)
|
2020-04-12 17:05:41 +00:00
|
|
|
|
ctx->srl_rx_timeout_enable = 1;
|
2019-01-13 20:55:09 +00:00
|
|
|
|
else if (disable_enable == 0)
|
2020-04-12 17:05:41 +00:00
|
|
|
|
ctx->srl_rx_timeout_enable = 0;
|
2020-08-10 21:54:18 +00:00
|
|
|
|
else {
|
|
|
|
|
;
|
|
|
|
|
}
|
2019-04-03 09:41:37 +00:00
|
|
|
|
|
|
|
|
|
if (value != 0) {
|
2020-04-12 17:05:41 +00:00
|
|
|
|
ctx->srl_rx_timeout_trigger_value_in_msec = value;
|
2019-04-03 09:41:37 +00:00
|
|
|
|
}
|
|
|
|
|
else {
|
2020-04-12 17:05:41 +00:00
|
|
|
|
ctx->srl_rx_timeout_trigger_value_in_msec = SRL_DEFAULT_RX_TIMEOUT_IN_MS;
|
2019-04-03 09:41:37 +00:00
|
|
|
|
}
|
2019-01-13 14:57:59 +00:00
|
|
|
|
}
|
2020-03-29 07:12:23 +00:00
|
|
|
|
|
2020-09-26 20:33:43 +00:00
|
|
|
|
/**
|
|
|
|
|
* 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)
|
|
|
|
|
*/
|
2020-04-12 17:05:41 +00:00
|
|
|
|
void srl_switch_timeout_for_waiting(srl_context_t *ctx, uint8_t disable_enable) {
|
2020-03-29 07:12:23 +00:00
|
|
|
|
if (disable_enable == 1)
|
2020-04-12 17:05:41 +00:00
|
|
|
|
ctx->srl_rx_timeout_waiting_enable = 1;
|
2020-03-29 07:12:23 +00:00
|
|
|
|
else if (disable_enable == 0)
|
2020-04-12 17:05:41 +00:00
|
|
|
|
ctx->srl_rx_timeout_waiting_enable = 0;
|
2020-08-10 21:54:18 +00:00
|
|
|
|
else {
|
|
|
|
|
;
|
|
|
|
|
}
|
2020-03-29 07:12:23 +00:00
|
|
|
|
|
2020-04-12 17:05:41 +00:00
|
|
|
|
if (ctx->srl_rx_timeout_trigger_value_in_msec == 0)
|
|
|
|
|
ctx->srl_rx_timeout_trigger_value_in_msec = SRL_DEFAULT_RX_TIMEOUT_IN_MS;
|
2020-03-29 07:12:23 +00:00
|
|
|
|
|
|
|
|
|
}
|