add TAS sources
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
This commit is contained in:
parent
10611d0415
commit
1ac9e53b1f
@ -393,7 +393,7 @@ if(EIVE_ADD_JSON_LIB)
|
|||||||
add_subdirectory(${LIB_JSON_PATH})
|
add_subdirectory(${LIB_JSON_PATH})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_subdirectory(thirdparty/rapidcsv)
|
add_subdirectory(thirdparty)
|
||||||
|
|
||||||
if(EIVE_ADD_LINUX_FILES)
|
if(EIVE_ADD_LINUX_FILES)
|
||||||
add_subdirectory(${LIB_ARCSEC_PATH})
|
add_subdirectory(${LIB_ARCSEC_PATH})
|
||||||
|
5
thirdparty/CMakeLists.txt
vendored
Normal file
5
thirdparty/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
if(EIVE_ADD_LINUX_FILES)
|
||||||
|
add_subdirectory(tas)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_subdirectory(rapidcsv)
|
80
thirdparty/tas/hdlc.c
vendored
Normal file
80
thirdparty/tas/hdlc.c
vendored
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
//**************************************************************************************
|
||||||
|
/*! \copyright: 2020-2021 Thales Alenia Space Deutschland GmbH
|
||||||
|
* \project: multiMIND
|
||||||
|
* \file: (name of source file: hdlc.c)
|
||||||
|
* \date: (09.02.2022)
|
||||||
|
* \author: (Stelios Filippopoulos)
|
||||||
|
* \brief: (hdlc functions)
|
||||||
|
* \language: (C)
|
||||||
|
**************************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "hdlc.h"
|
||||||
|
#include "spacepacket.h"
|
||||||
|
#include "crc.h"
|
||||||
|
|
||||||
|
static void hdlc_add_byte(uint8_t ch, uint8_t *buff, uint16_t *pos)
|
||||||
|
{
|
||||||
|
uint16_t templen = *pos;
|
||||||
|
|
||||||
|
if ((ch == 0x7E) ||
|
||||||
|
(ch == 0x7D) ||
|
||||||
|
(ch == 0x7C))
|
||||||
|
{
|
||||||
|
buff[templen++] = 0x7D;
|
||||||
|
ch ^= 0x20;
|
||||||
|
}
|
||||||
|
buff[templen++] = ch;
|
||||||
|
|
||||||
|
*pos = templen;
|
||||||
|
}
|
||||||
|
|
||||||
|
void hdlc_add_framing(uint8_t *src, uint16_t slen, uint8_t *dst, uint16_t *dlen)
|
||||||
|
{
|
||||||
|
uint16_t tlen = 0;
|
||||||
|
uint16_t ii;
|
||||||
|
uint16_t crc16;
|
||||||
|
uint8_t bt;
|
||||||
|
|
||||||
|
// calc crc16
|
||||||
|
crc16 = calc_crc16_buff_reflected( src, slen );
|
||||||
|
|
||||||
|
dst[tlen++] = 0x7E;
|
||||||
|
for (ii = 0; ii < slen; ii++)
|
||||||
|
{
|
||||||
|
bt = *src++;
|
||||||
|
hdlc_add_byte(bt, dst, &tlen);
|
||||||
|
}
|
||||||
|
|
||||||
|
// hdlc crc16 is in little endian format
|
||||||
|
hdlc_add_byte((uint8_t) (crc16 & 0xFF), dst, &tlen);
|
||||||
|
hdlc_add_byte((uint8_t) ((crc16 >> 8) & 0xFF), dst, &tlen);
|
||||||
|
|
||||||
|
dst[tlen++] = 0x7C;
|
||||||
|
*dlen = tlen;
|
||||||
|
}
|
||||||
|
|
||||||
|
void hdlc_remove_framing(uint8_t *src, uint16_t slen, uint8_t *dst, uint16_t *dlen)
|
||||||
|
{
|
||||||
|
uint16_t tlen = 0;
|
||||||
|
uint16_t ii;
|
||||||
|
uint8_t bt;
|
||||||
|
|
||||||
|
*dlen = 0;
|
||||||
|
if (slen == 0) return;
|
||||||
|
if ((src[tlen] != 0x7E) && (src[slen-1] != 0x7C)) return;
|
||||||
|
for (ii = 1; ii < slen-1; ii++)
|
||||||
|
{
|
||||||
|
bt = *src++;
|
||||||
|
|
||||||
|
if (bt == 0x7D)
|
||||||
|
{
|
||||||
|
bt = *src++ ^ 0x20;
|
||||||
|
}
|
||||||
|
dst[tlen++] = bt;
|
||||||
|
}
|
||||||
|
*dlen = tlen;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
26
thirdparty/tas/hdlc.h
vendored
Normal file
26
thirdparty/tas/hdlc.h
vendored
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
//**************************************************************************************
|
||||||
|
/*! \copyright: 2020-2021 Thales Alenia Space Deutschland GmbH
|
||||||
|
* \project: multiMIND
|
||||||
|
* \file: (name of source file: hdlc.h)
|
||||||
|
* \date: (09.02.2022)
|
||||||
|
* \author: (Stelios Filippopoulos)
|
||||||
|
* \brief: (hdlc header file)
|
||||||
|
* \language: (C)
|
||||||
|
**************************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LIB_HDLC_H_
|
||||||
|
#define LIB_HDLC_H_
|
||||||
|
|
||||||
|
#define HDLC_ENABLE
|
||||||
|
|
||||||
|
#define HDLC_START_BYTE (0x7Eu)
|
||||||
|
#define HDLC_ESC_BYTE (0x7Du)
|
||||||
|
#define HDLC_END_BYTE (0x7Cu)
|
||||||
|
#define HDLC_ESCAPE_CHAR (0x20u)
|
||||||
|
|
||||||
|
void hdlc_add_framing(uint8_t *src, uint16_t slen, uint8_t *dst, uint16_t *dlen);
|
||||||
|
|
||||||
|
void hdlc_remove_framing(uint8_t *src, uint16_t slen, uint8_t *dst, uint16_t *dlen);
|
||||||
|
|
||||||
|
#endif /* LIB_HDLC_H_ */
|
603
thirdparty/tas/uart.c
vendored
Normal file
603
thirdparty/tas/uart.c
vendored
Normal file
@ -0,0 +1,603 @@
|
|||||||
|
//**************************************************************************************
|
||||||
|
/*! \copyright: 2020-2021 Thales Alenia Space Deutschland GmbH
|
||||||
|
* \project: multiMIND
|
||||||
|
* \file: (name of source file: uart.c)
|
||||||
|
* \date: (20.05.2021)
|
||||||
|
* \author: (Sarthak Kelapure)
|
||||||
|
* \brief: (UART thread to collect data on serial interface)
|
||||||
|
* \language: (C)
|
||||||
|
**************************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uart.h"
|
||||||
|
#include "hdlc.h"
|
||||||
|
|
||||||
|
#ifdef HDLC_ENABLE
|
||||||
|
#define HDLC_RX_STATE_IDLE (0u)
|
||||||
|
#define HDLC_RX_STATE_RECEIVING (1u)
|
||||||
|
#define HDLC_RX_STATE_ESCAPE (2u)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @struct Serial device structure.
|
||||||
|
* Encapsulates a serial connection.
|
||||||
|
*/
|
||||||
|
struct serial_s {
|
||||||
|
int fd; //>! Connection file descriptor.
|
||||||
|
int state; //>! Signifies connection state.
|
||||||
|
int running; //>! Signifies thread state.
|
||||||
|
|
||||||
|
char rxbuff[BUFF_SIZE]; //>! Buffer for RX data.
|
||||||
|
int start, end; //>! Pointers to start and end of buffer.
|
||||||
|
|
||||||
|
pthread_t rx_thread; //>! Listening thread.
|
||||||
|
};
|
||||||
|
|
||||||
|
// --------------- Internal Functions ---------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connect to a serial device.
|
||||||
|
* @param s - serial structure.
|
||||||
|
* @param device - serial device name.
|
||||||
|
* @param baud - baud rate for connection.
|
||||||
|
* @return -ve on error, 0 on success.
|
||||||
|
*/
|
||||||
|
static int serial_connect(serial_t* s, char device[], int baud);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the serial structure.
|
||||||
|
* Convenience method to allocate memory
|
||||||
|
* and instantiate objects.
|
||||||
|
* @return serial structure.
|
||||||
|
*/
|
||||||
|
static serial_t* serial_create();
|
||||||
|
|
||||||
|
static int serial_resolve_baud(int baud);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recieve data.
|
||||||
|
* Retrieves data from the serial device.
|
||||||
|
* @param s - serial structure.
|
||||||
|
* @param data - pointer to a buffer to read data into.
|
||||||
|
* @param maxLength - size of input buffer.
|
||||||
|
* @return amount of data recieved.
|
||||||
|
*/
|
||||||
|
static int serial_recieve(serial_t* obj, uint8_t data[], int maxLength);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Serial Listener Thread.
|
||||||
|
* This blocks waiting for data to be recieved from the serial device,
|
||||||
|
* and calls the serial_callback method with appropriate context when
|
||||||
|
* data is recieved.
|
||||||
|
* Exits when close method is called, or serial error occurs.
|
||||||
|
* @param param - context passed from thread instantiation.
|
||||||
|
*/
|
||||||
|
static void *serial_data_listener(void *param);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Start the serial threads.
|
||||||
|
* This spawns the listening and transmitting threads
|
||||||
|
* if they are not already running.
|
||||||
|
* @param s - serial structure.
|
||||||
|
* @return 0 on success, or -1 on error.
|
||||||
|
*/
|
||||||
|
static int serial_start(serial_t* s);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stop serial listener thread.
|
||||||
|
* @param s - serial structure.
|
||||||
|
* @return 0;
|
||||||
|
*/
|
||||||
|
static int serial_stop(serial_t* s);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback to handle recieved data.
|
||||||
|
* Puts recieved data into the rx buffer.
|
||||||
|
* @param s - serial structure.
|
||||||
|
* @param data - data to be stored.
|
||||||
|
* @param length - length of recieved data.
|
||||||
|
*/
|
||||||
|
static void serial_rx_callback(serial_t* s, char data[], int length);
|
||||||
|
|
||||||
|
// Put character in rx buffer.
|
||||||
|
static int buffer_put(serial_t* s, char c)
|
||||||
|
{
|
||||||
|
//if there is space in the buffer
|
||||||
|
if ( s->end != ((s->start + BUFF_SIZE - 1) % BUFF_SIZE)) {
|
||||||
|
s->rxbuff[s->end] = c;
|
||||||
|
s->end ++;
|
||||||
|
s->end = s->end % BUFF_SIZE;
|
||||||
|
//printf("Put: %x start: %d, end: %d\r\n", c, s->start, s->end);
|
||||||
|
return 0; //No error
|
||||||
|
} else {
|
||||||
|
//buffer is full, this is a bad state
|
||||||
|
return -1; //Report error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get character from rx buffer.
|
||||||
|
static char buffer_get(serial_t* s)
|
||||||
|
{
|
||||||
|
char c = (char)0;
|
||||||
|
//if there is data to process
|
||||||
|
if (s->end != s->start) {
|
||||||
|
c = (s->rxbuff[s->start]);
|
||||||
|
s->start ++;
|
||||||
|
//wrap around
|
||||||
|
s->start = s->start % BUFF_SIZE;
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
//printf("Get: %x start: %d, end: %d\r\n", c, s->start, s->end);
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Get data available in the rx buffer.
|
||||||
|
static int buffer_available(serial_t* s)
|
||||||
|
{
|
||||||
|
return (s->end - s->start + BUFF_SIZE) % BUFF_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------- External Functions ---------------
|
||||||
|
|
||||||
|
//Create serial object.
|
||||||
|
serial_t* serial_create()
|
||||||
|
{
|
||||||
|
//Allocate serial object.
|
||||||
|
serial_t* s = malloc(sizeof(serial_t));
|
||||||
|
//Reconfigure buffer object.
|
||||||
|
s->start = 0;
|
||||||
|
s->end = 0;
|
||||||
|
//Return pointer.
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void uart_destroy(serial_t* s)
|
||||||
|
{
|
||||||
|
free(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Connect to serial device.
|
||||||
|
int serial_connect(serial_t* s, char device[], int baud)
|
||||||
|
{
|
||||||
|
struct termios oldtio;
|
||||||
|
|
||||||
|
// Resolve baud.
|
||||||
|
int speed = serial_resolve_baud(baud);
|
||||||
|
if (speed < 0) {
|
||||||
|
printf("Error: Baud rate not recognized.\r\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Open device.
|
||||||
|
s->fd = open(device, O_RDWR | O_NOCTTY);
|
||||||
|
//Catch file open error.
|
||||||
|
if (s->fd < 0) {
|
||||||
|
perror(device);
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
//Retrieve settings.
|
||||||
|
tcgetattr(s->fd, &oldtio);
|
||||||
|
//Set baud rate.
|
||||||
|
cfsetspeed(&oldtio, speed);
|
||||||
|
//Flush cache.
|
||||||
|
tcflush(s->fd, TCIFLUSH);
|
||||||
|
|
||||||
|
//Set UART settings, standard ones. 8N1
|
||||||
|
oldtio.c_cflag = (oldtio.c_cflag & ~CSIZE) | CS8; // 8-bit chars
|
||||||
|
// disable IGNBRK for mismatched speed tests; otherwise receive break
|
||||||
|
// as \000 chars
|
||||||
|
oldtio.c_iflag &= ~IGNBRK; // disable break processing
|
||||||
|
oldtio.c_lflag = 0; // no signaling chars, no echo,
|
||||||
|
// no canonical processing
|
||||||
|
oldtio.c_oflag = 0; // no remapping, no delays
|
||||||
|
oldtio.c_cc[VMIN] = 0; // read doesn't block
|
||||||
|
oldtio.c_cc[VTIME] = 5; // 0.5 seconds read timeout
|
||||||
|
|
||||||
|
oldtio.c_iflag &= ~(IXON | IXOFF | IXANY); // shut off xon/xoff ctrl
|
||||||
|
oldtio.c_iflag &= ~(IGNCR | ICRNL | INLCR); // CR and LF characters are not affected
|
||||||
|
|
||||||
|
oldtio.c_cflag |= (CLOCAL | CREAD);// ignore modem controls,
|
||||||
|
// enable reading
|
||||||
|
oldtio.c_cflag &= ~(PARENB | PARODD); // shut off parity
|
||||||
|
oldtio.c_cflag |= 0;
|
||||||
|
oldtio.c_cflag &= ~CSTOPB;
|
||||||
|
oldtio.c_cflag &= ~(020000000000);
|
||||||
|
//Apply settings.
|
||||||
|
if(tcsetattr(s->fd, TCSANOW, &oldtio) !=0){
|
||||||
|
printf("ERROR: serial settings failed\r\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Start listener thread.
|
||||||
|
int res = serial_start(s);
|
||||||
|
//Catch error.
|
||||||
|
if (res < 0) {
|
||||||
|
printf("Error: serial thread could not be spawned\r\n");
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Indicate connection was successful.
|
||||||
|
s->state = 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
serial_t* uart_init(char device[], int baud)
|
||||||
|
{
|
||||||
|
serial_t* s = serial_create();
|
||||||
|
if(serial_connect(s, device, baud)< 0)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Send data.
|
||||||
|
uint32_t uart_length_send(serial_t* s, uint8_t data[], int length)
|
||||||
|
{
|
||||||
|
// uint16_t ii;
|
||||||
|
// int res;
|
||||||
|
// for (ii = 0; ii < length; ii++)
|
||||||
|
// {
|
||||||
|
// res = write(s->fd, &data[ii], 1);
|
||||||
|
// }
|
||||||
|
int res = write(s->fd, data, length);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void uart_send(serial_t* s, uint8_t data)
|
||||||
|
{
|
||||||
|
char arr[1];
|
||||||
|
arr[0] = data;
|
||||||
|
write(s->fd, arr, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Determine characters available.
|
||||||
|
int uart_available(serial_t* s)
|
||||||
|
{
|
||||||
|
return buffer_available(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Fetch a character.
|
||||||
|
char uart_get(serial_t* s)
|
||||||
|
{
|
||||||
|
char c = buffer_get(s);
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
int uart_length_get(serial_t* s, char* buff, int len, bool start_of_packet)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
if (len > 0 && len < BUFF_SIZE)
|
||||||
|
{
|
||||||
|
#ifdef HDLC_ENABLE
|
||||||
|
uint8_t ch;
|
||||||
|
uint8_t hdlc_rx_state;
|
||||||
|
int rxb = 0;
|
||||||
|
|
||||||
|
if (start_of_packet)
|
||||||
|
hdlc_rx_state = HDLC_RX_STATE_IDLE;
|
||||||
|
else
|
||||||
|
hdlc_rx_state = HDLC_RX_STATE_RECEIVING;
|
||||||
|
|
||||||
|
while (rxb < len)
|
||||||
|
{
|
||||||
|
ch = uart_blocking_get(s);
|
||||||
|
|
||||||
|
switch (hdlc_rx_state)
|
||||||
|
{
|
||||||
|
case HDLC_RX_STATE_IDLE:
|
||||||
|
if (ch == HDLC_START_BYTE)
|
||||||
|
{
|
||||||
|
rxb = 0;
|
||||||
|
ret = 0;
|
||||||
|
hdlc_rx_state = HDLC_RX_STATE_RECEIVING;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case HDLC_RX_STATE_RECEIVING:
|
||||||
|
if (ch == HDLC_START_BYTE)
|
||||||
|
{
|
||||||
|
rxb = 0;
|
||||||
|
ret = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (ch == HDLC_ESC_BYTE)
|
||||||
|
{
|
||||||
|
hdlc_rx_state = HDLC_RX_STATE_ESCAPE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
buff[rxb++] = ch;
|
||||||
|
ret++;
|
||||||
|
break;
|
||||||
|
case HDLC_RX_STATE_ESCAPE:
|
||||||
|
if (ch == HDLC_START_BYTE)
|
||||||
|
{
|
||||||
|
rxb = 0;
|
||||||
|
ret = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
buff[rxb++] = ch ^ HDLC_ESCAPE_CHAR;
|
||||||
|
ret++;
|
||||||
|
hdlc_rx_state = HDLC_RX_STATE_RECEIVING;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
for (int i=0;i<len;i++)
|
||||||
|
{
|
||||||
|
buff[i] = uart_blocking_get(s);
|
||||||
|
ret++;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t uart_get_hdlc_packet(serial_t* s, uint8_t *buff, uint16_t buff_len)
|
||||||
|
{
|
||||||
|
uint8_t hdlc_rx_state = HDLC_RX_STATE_IDLE;
|
||||||
|
uint8_t ch;
|
||||||
|
uint16_t buff_pos = 0u;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
ch = uart_blocking_get(s);
|
||||||
|
|
||||||
|
switch (hdlc_rx_state)
|
||||||
|
{
|
||||||
|
case HDLC_RX_STATE_IDLE:
|
||||||
|
if (ch == HDLC_START_BYTE)
|
||||||
|
{
|
||||||
|
buff_pos = 0u;
|
||||||
|
hdlc_rx_state = HDLC_RX_STATE_RECEIVING;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HDLC_RX_STATE_RECEIVING:
|
||||||
|
if (ch == HDLC_START_BYTE)
|
||||||
|
{
|
||||||
|
buff_pos = 0u;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (ch == HDLC_END_BYTE)
|
||||||
|
{
|
||||||
|
if (buff_pos > 2u) // do not include HDLC CRC16
|
||||||
|
{
|
||||||
|
return buff_pos;
|
||||||
|
}
|
||||||
|
buff_pos = 0u;
|
||||||
|
hdlc_rx_state = HDLC_RX_STATE_IDLE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (ch == HDLC_ESC_BYTE)
|
||||||
|
{
|
||||||
|
hdlc_rx_state = HDLC_RX_STATE_ESCAPE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (buff_pos >= buff_len)
|
||||||
|
{
|
||||||
|
hdlc_rx_state = HDLC_RX_STATE_RECEIVING;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
buff[buff_pos++] = ch;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HDLC_RX_STATE_ESCAPE:
|
||||||
|
if ((ch == HDLC_START_BYTE) || (ch == HDLC_END_BYTE))
|
||||||
|
{
|
||||||
|
buff_pos = 0;
|
||||||
|
hdlc_rx_state = HDLC_RX_STATE_RECEIVING;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (buff_pos >= buff_len)
|
||||||
|
{
|
||||||
|
hdlc_rx_state = HDLC_RX_STATE_RECEIVING;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
buff[buff_pos++] = ch ^ HDLC_ESCAPE_CHAR;
|
||||||
|
hdlc_rx_state = HDLC_RX_STATE_RECEIVING;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
buff_pos = 0u;
|
||||||
|
hdlc_rx_state = HDLC_RX_STATE_IDLE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char uart_blocking_get(serial_t* s)
|
||||||
|
{
|
||||||
|
while (uart_available(s) == 0);
|
||||||
|
return uart_get(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
void uart_clear(serial_t* s)
|
||||||
|
{
|
||||||
|
//Clear the buffer.
|
||||||
|
while (buffer_available(s)) {
|
||||||
|
buffer_get(s);
|
||||||
|
}
|
||||||
|
tcflush(s->fd, TCIFLUSH);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Close serial port.
|
||||||
|
int uart_close(serial_t* s)
|
||||||
|
{
|
||||||
|
//Stop thread.
|
||||||
|
serial_stop(s);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void uart_deinit(serial_t* s){
|
||||||
|
uart_clear(s);
|
||||||
|
uart_close(s);
|
||||||
|
uart_destroy(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------- Internal Functions --------------
|
||||||
|
|
||||||
|
//Stop serial listener thread.
|
||||||
|
static int serial_stop(serial_t* s)
|
||||||
|
{
|
||||||
|
s->running = 0;
|
||||||
|
return close(s->fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Resolves standard baud rates to linux constants.
|
||||||
|
static int serial_resolve_baud(int baud)
|
||||||
|
{
|
||||||
|
int speed;
|
||||||
|
// Switch common baud rates to temios constants.
|
||||||
|
switch (baud) {
|
||||||
|
case 9600:
|
||||||
|
speed = B9600;
|
||||||
|
break;
|
||||||
|
case 19200:
|
||||||
|
speed = B19200;
|
||||||
|
break;
|
||||||
|
case 38400:
|
||||||
|
speed = B38400;
|
||||||
|
break;
|
||||||
|
case 57600:
|
||||||
|
speed = B57600;
|
||||||
|
break;
|
||||||
|
case 115200:
|
||||||
|
speed = B115200;
|
||||||
|
break;
|
||||||
|
case 230400:
|
||||||
|
speed = B230400;
|
||||||
|
break;
|
||||||
|
case 460800:
|
||||||
|
speed = B460800;
|
||||||
|
break;
|
||||||
|
case 500000:
|
||||||
|
speed = B500000;
|
||||||
|
break;
|
||||||
|
case 576000:
|
||||||
|
speed = B576000;
|
||||||
|
break;
|
||||||
|
case 921600:
|
||||||
|
speed = B921600;
|
||||||
|
break;
|
||||||
|
case 1000000:
|
||||||
|
speed = B1000000;
|
||||||
|
break;
|
||||||
|
case 1152000:
|
||||||
|
speed = B1152000;
|
||||||
|
break;
|
||||||
|
case 1500000:
|
||||||
|
speed = B1500000;
|
||||||
|
break;
|
||||||
|
case 2000000:
|
||||||
|
speed = B2000000;
|
||||||
|
break;
|
||||||
|
case 3000000:
|
||||||
|
speed = B3000000;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
speed = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Return.
|
||||||
|
return speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start serial listener.
|
||||||
|
static int serial_start(serial_t* s)
|
||||||
|
{
|
||||||
|
//Only start if it is not currently running.
|
||||||
|
if (s->running != 1) {
|
||||||
|
//Set running.
|
||||||
|
s->running = 1;
|
||||||
|
//Spawn thread.
|
||||||
|
int res;
|
||||||
|
res = pthread_create(&s->rx_thread, NULL, serial_data_listener, (void*) s);
|
||||||
|
if (res != 0) {
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
//Return result.
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//Recieve data.
|
||||||
|
static int serial_recieve(serial_t* s, uint8_t data[], int maxLength)
|
||||||
|
{
|
||||||
|
return read(s->fd, data, maxLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Callback to store data in buffer.
|
||||||
|
static void serial_rx_callback(serial_t* s, char data[], int length)
|
||||||
|
{
|
||||||
|
//Put data into buffer.
|
||||||
|
int i;
|
||||||
|
//Put data into buffer.
|
||||||
|
for (i = 0; i < length; i++) {
|
||||||
|
buffer_put(s, data[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//Serial data listener thread.
|
||||||
|
static void *serial_data_listener(void *param)
|
||||||
|
{
|
||||||
|
int res = 0;
|
||||||
|
int err = 0;
|
||||||
|
struct pollfd ufds;
|
||||||
|
uint8_t buff[BUFF_SIZE];
|
||||||
|
|
||||||
|
//Retrieve paramaters and store locally.
|
||||||
|
serial_t* serial = (serial_t*) param;
|
||||||
|
int fd = serial->fd;
|
||||||
|
|
||||||
|
//Set up poll file descriptors.
|
||||||
|
ufds.fd = fd; //Attach socket to watch.
|
||||||
|
ufds.events = POLLIN; //Set events to notify on.
|
||||||
|
|
||||||
|
//Run until ended.
|
||||||
|
while (serial->running != 0) {
|
||||||
|
//Poll socket for data.
|
||||||
|
res = poll(&ufds, 1, POLL_TIMEOUT);
|
||||||
|
//If data was recieved.
|
||||||
|
if (res > 0) {
|
||||||
|
//Fetch the data.
|
||||||
|
int count = serial_recieve(serial, buff, BUFF_SIZE - 1);
|
||||||
|
//If data was recieved.
|
||||||
|
if (count > 0) {
|
||||||
|
//Pad end of buffer to ensure there is a termination symbol.
|
||||||
|
buff[count] = '\0';
|
||||||
|
// Call the serial callback.
|
||||||
|
serial_rx_callback(serial, (char *)buff, count);
|
||||||
|
//If an error occured.
|
||||||
|
} else if (count < 0) {
|
||||||
|
//Inform user and exit thread.
|
||||||
|
printf("Error: Serial disconnect\r\n");
|
||||||
|
err = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//If there was an error.
|
||||||
|
} else if (res < 0) {
|
||||||
|
//Inform user and exit thread.
|
||||||
|
printf("Error: Polling error in serial thread");
|
||||||
|
err = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//Otherwise, keep going around.
|
||||||
|
}
|
||||||
|
//If there was an error, close socket.
|
||||||
|
if (err) {
|
||||||
|
uart_close(serial);
|
||||||
|
//raise(SIGLOST);
|
||||||
|
}
|
||||||
|
//Close file.
|
||||||
|
res = close(serial->fd);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
124
thirdparty/tas/uart.h
vendored
Normal file
124
thirdparty/tas/uart.h
vendored
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
//**************************************************************************************
|
||||||
|
/*! \copyright: 2020-2021 Thales Alenia Space Deutschland GmbH
|
||||||
|
* \project: multiMIND
|
||||||
|
* \file: (name of source file: uart.h)
|
||||||
|
* \date: (20.05.2021)
|
||||||
|
* \author: (Sarthak Kelapure)
|
||||||
|
* \brief: (UART thread to collect data on serial interface)
|
||||||
|
* \language: (C)
|
||||||
|
**************************************************************************************
|
||||||
|
*/
|
||||||
|
#ifndef LIB_UART_H
|
||||||
|
#define LIB_UART_H
|
||||||
|
|
||||||
|
#define BUFF_SIZE 512
|
||||||
|
#define POLL_TIMEOUT 2000
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <termios.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <poll.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct serial_s serial_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroy the serial structure
|
||||||
|
*/
|
||||||
|
void uart_destroy(serial_t* s);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the serial connection
|
||||||
|
* @param device - serial device name.
|
||||||
|
* @param baud - baud rate for connection.
|
||||||
|
* @return serial structure.
|
||||||
|
*/
|
||||||
|
serial_t* uart_init(char device[], int baud);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send data.
|
||||||
|
* @param s - serial structure.
|
||||||
|
* @param data - character array to transmit.
|
||||||
|
* @param length - size of the data array.
|
||||||
|
*/
|
||||||
|
uint32_t uart_length_send(serial_t* s, uint8_t data[], int length);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a single character.
|
||||||
|
* @param s - serial structure.
|
||||||
|
* @param data - single character to be sent.
|
||||||
|
*/
|
||||||
|
void uart_send(serial_t* s, uint8_t data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine how much data is available
|
||||||
|
* in the serial buffer.
|
||||||
|
* @param s - serial structure.
|
||||||
|
* @return number of characters available.
|
||||||
|
*/
|
||||||
|
int uart_available(serial_t* s);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch one char from the serial buffer.
|
||||||
|
* @param s - serial structure.
|
||||||
|
* @return character. Null if empty.
|
||||||
|
*/
|
||||||
|
char uart_get(serial_t* s);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch length of chars from the serial buffer.
|
||||||
|
* @param s - serial structure.
|
||||||
|
* @param buff - readback storage
|
||||||
|
* @param len - length to get
|
||||||
|
* @return length. zero if empty.
|
||||||
|
*/
|
||||||
|
int uart_length_get(serial_t* s, char* buff, int len, bool start_of_packet);
|
||||||
|
|
||||||
|
uint16_t uart_get_hdlc_packet(serial_t* s, uint8_t *buff, uint16_t buff_len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch one char from the serial buffer.
|
||||||
|
* Blocks until data becomes available.
|
||||||
|
* @param s - serial structure.
|
||||||
|
* @return character.
|
||||||
|
*/
|
||||||
|
char uart_blocking_get(serial_t* s);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear the serial buffer.
|
||||||
|
* @param s - serial structure.
|
||||||
|
*/
|
||||||
|
void uart_clear(serial_t* s);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close the serial port.
|
||||||
|
* @param s - serial structure.
|
||||||
|
* @return value of close().
|
||||||
|
*/
|
||||||
|
int uart_close(serial_t* s);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deinitializes the UART
|
||||||
|
* @param s - serial structure.
|
||||||
|
*/
|
||||||
|
void uart_deinit(serial_t* s);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif //LIB_UART_H
|
Loading…
Reference in New Issue
Block a user