Updated to Rev 0.4a

This commit is contained in:
adrcs 2025-02-07 13:49:26 -07:00 committed by GitHub
parent 41fffe4785
commit a7b2b63790
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 253 additions and 54 deletions

View file

@ -29,6 +29,7 @@
#include "usart.h"
#define __USE_SETUP_PARAMS 1 // set to 1 to use setup parameters
#define US 0 // station is in the US
// defined elsewhere
extern char *modTypes[];

View file

@ -12,7 +12,7 @@
typedef uint8_t DATA_ELEMENT; // data element
#define BUFFER_EMPTY(x) (x.nDataBytes == 0)
#define BUFFER_NO_DATA 0
#define bufferSIZE 2048 // large buffer
#define bufferSIZE 512 // large buffer
#endif /* INC_STREAMBUFFER_H_ */

View file

@ -33,13 +33,15 @@ typedef uint16_t BUFFER_SIZE_T; // buffer size type
typedef uint8_t DATA_ELEMENT; // buffer data element
// uart HAL handle
extern UART_HandleTypeDef huart1;
extern UART_HandleTypeDef huart1; // console UART
extern UART_HandleTypeDef hlpuart1 ; // GPS UART
// logger defines
#define LOG_NOTICE 0 // notice
#define LOG_ERROR 1 // error
#define LOG_SEVERE 2 // severe error
// logger
void logger(int severity, char *format, ...);
// API calls
@ -51,4 +53,9 @@ BOOL USART_Send_String(const char *string, size_t len);
BOOL USART_Send_Char(const char c);
void USART_Print_string(char *format, ...);
// same as USART but for LPUART: no Tx functions
void LPUART_RxBuffer_reset(void);
size_t gpsbuffer_bytesInBuffer(void);
DATA_ELEMENT gpsbuffer_get(UART_TIMEOUT_T timeout);
#endif /* INC_USART_H_ */

View file

@ -33,26 +33,41 @@
#include <FreeRTOS.h>
#include <stm32wl3x_hal.h>
#include "config.h"
#include "frame.h"
#include "tasks.h"
#include "setup.h"
#include "utils.h"
#include "tod.h"
#include "usart.h"
// config
#define __ENABLE_GPS 0 // set to 1 if you have GPS attached
#define __SPEED_DAEMON 0 // send beacon every 5 seconds for testing purposes
// local defines
#define MAX_BEACON 80
#define GPS_FIX_LEN 20 // gps fix length
#define MAX_BEACON 80 // max beacon string
#define GPS_FIX_LEN 20 // gps fix length
#define GPS_BFR_SIZE 140 // GPS buffer size
// NMEA GGA Sentence fields
#define GGA_TAG 0 // message tag
#define GGA_TIMESTAMP 1 // time of fix
#define GGA_LATITUDE 2 // latitude
#define GGA_NS_HEMI 3 // latitude hemisphere
#define GGA_LONGITUDE 4 // longitude
#define GGA_EW_HEMI 5 // longitude hemisphere
char *nmeaMsgTag = "RMC"; // sentence we are processing
enum {
NMEA_TAG=0, // message tag
NMEA_TIMESTAMP, // time of fix'
NMEA_STATUS, // status
NMEA_LATITUDE, // latitude
NMEA_NS_HEMI, // latitude hemisphere
NMEA_LONGITUDE, // longitude
NMEA_EW_HEMI, // longitude hemisphere
NMEA_MIN_FLDS // minimum fields in GPS message
};
// NMEA processing states
enum {
NMEA_STATE_SOM=0, // start of message
NMEA_STATE_MSG, // in the message
};
// hemispheres
enum {
N_HEMI=0, // North
@ -68,27 +83,34 @@ uint8_t hemispheres[N_HEMIS] = {
uint32_t timerInitValue; // value to initialize timer
uint32_t timerCtrValue; // current counter
BEACON_HEADER beacon_hdr; // beacon header
uint8_t bcnPayload[MAX_BEACON]; // beacon payload
BOOL gpsMessageRx = FALSE;
BOOL GPSBusy=FALSE;
TIMEOFDAY wallClockTime;
#if __ENABLE_GPS
#define GPS_BUFFER_SIZE 200
// LPUART for GPS receiver
extern hlpuart1 UART_HandleTypeDef; // HAL Handle to LPUART
uint8_t GPSMsgBuf[GPS_BUFFER_SIZE];
// data for GPS
uint8_t GPSMsgBuf[GPS_BFR_SIZE];
uint8_t GPSEchoBuf[GPS_BFR_SIZE];
uint8_t GPSProcBuf[GPS_BFR_SIZE];
uint8_t *GPSBufPtr;
uint8_t GPSMsgSize;
uint8_t NMEAState;
//
BOOL haveGPSFix = FALSE;
BOOL gpsEchoReady=FALSE;
//
char GPSLat[GPS_FIX_LEN];
char GPSLong[GPS_FIX_LEN];
char GPSFixTime[GPS_FIX_LEN];
BOOL haveGPSFix = FALSE;
char *gpsFlds[GPS_FIX_LEN];
#else
TIMEOFDAY wallClockTime;
char *gpsFlds[GPS_BFR_SIZE];
// fwd Refs in this module in GPS mode
BOOL processGPSMessage(uint8_t *GPSMsgBuf, uint8_t bufferSize);
#endif
// fwd refs here..
//fwd refs w/o GPS
void GPSFormat(char *buffer, double value, uint8_t hePos, uint8_t heNeg);
// initialization: calculate the init value in
@ -107,9 +129,12 @@ void Beacon_Task_init(void)
// GPS Init
#if __ENABLE_GPS
HAL_LPUART_Receive_DMA(&hlpuart1, (uint8_t*)GPSMsgBuf, GPS_BUFFER_SIZE);
gpsMessageRx = FALSE;
haveGPSFix = FALSE;
gpsEchoReady = FALSE;
GPSBufPtr = GPSMsgBuf;
GPSBusy = FALSE;
NMEAState=NMEA_STATE_SOM;
#endif
}
@ -119,9 +144,11 @@ void Beacon_Task_exec(void)
{
#if __ENABLE_GPS
if(gpsMessageRx) {
gpsMessageRx = FALSE;
ifprocessGPSMessage(GPSMsgBuf, GPS_BUFFER_SIZE))
// process the message
if(processGPSMessage(GPSProcBuf, (uint8_t)strlen((char *)GPSProcBuf))) {
haveGPSFix = TRUE;
}
gpsMessageRx = FALSE;
}
#endif
@ -148,10 +175,13 @@ void Beacon_Task_exec(void)
if(haveGPSFix) {
strcpy(pPayload, "GPS,");
strcat(pPayload, GPSLat);
strcat(pPayload, ",");
strcat(pPayload, GPSLong);
strcat(pPayload, ",");
strcat(pPayload, GPSFixTime);
strcat(pPayload, ",");
} else {
#else
#endif
// setup struct generated payload
strcpy(pPayload, "FXD,");
pPayload += strlen(pPayload);
@ -161,7 +191,10 @@ void Beacon_Task_exec(void)
pPayload += strlen(pPayload);
double dlong = ascii2double(setup_memory.params.setup_data.longitude);
GPSFormat(pPayload, dlong, E_HEMI, W_HEMI);
strcat(pPayload, ",");
strcat(pPayload, ",,");
#if __ENABLE_GPS
}
#endif
pPayload += strlen(pPayload);
// Use RTC for time
@ -171,7 +204,6 @@ void Beacon_Task_exec(void)
// home grid square
strcat(pPayload, setup_memory.params.setup_data.gridSq);
#endif
// firmware version
int pos = strlen((char *)p2);
@ -206,39 +238,93 @@ void GPSFormat(char *buffer, double value, uint8_t hePos, uint8_t heNeg)
sprintf(buffer, "%d%02d.%05d%c", whole, min, ifract, hemispheres[hemi]);
}
/*
* Process GPS data from LPUART: runs at a higher priority
*/
void GPS_Task_exec(void)
{
#if __ENABLE_GPS
char c;
int nBytesinBuff;
if((nBytesinBuff=gpsbuffer_bytesInBuffer()) == 0)
return;
for(int i=0;i<nBytesinBuff;i++) {
c = (char)gpsbuffer_get(0);
switch(NMEAState) {
// waiting for a start of message
case NMEA_STATE_SOM:
if(c != '$')
break;
GPSBufPtr = GPSMsgBuf;
NMEAState=NMEA_STATE_MSG;
break;
// collecting chars in a message
case NMEA_STATE_MSG:
*GPSBufPtr++ = c;
GPSMsgSize = GPSBufPtr - GPSMsgBuf;
if((c == '*') || (GPSMsgSize >= GPS_BFR_SIZE)) {
*GPSBufPtr = '\0';
GPSMsgSize++;
memcpy(GPSEchoBuf, GPSMsgBuf, GPSMsgSize);
gpsMessageRx = TRUE;
memcpy(GPSProcBuf, GPSMsgBuf, GPSMsgSize);
memcpy(GPSEchoBuf, GPSMsgBuf, GPSMsgSize);
gpsEchoReady = TRUE;
NMEAState=NMEA_STATE_SOM;
}
break;
}
}
#else
return; // unused code
#endif
}
#if __ENABLE_GPS
/*
* Process an inbound GPS message
*/
BOOL processGPSMessage(GPSMsgBuf, GPS_BUFFER_SIZE)
BOOL processGPSMessage(uint8_t *GPSdata, uint8_t bufferSize)
{
int limit = (int)strlen(GPSMsgBuf);
nParams = explode_string(GPSMsgBuf, gpsFlds, limit, ',', '"');
if (nParams == 0)
char *msg = (char *)GPSdata;
uint8_t nParams = explode_string(msg, gpsFlds, bufferSize, ',', '"');
if ((nParams == 0) || (nParams < NMEA_MIN_FLDS))
return FALSE;
//brute force position fix
if(strcmp(gpsFlds[GGA_TAG[strlen(GGA_TAG)-strlen("GGA")]],"GGA"))
// brute force position fix
// check for message with GGA at the end
char *gpsTag = gpsFlds[NMEA_TAG];
gpsTag += strlen(gpsTag)-strlen(nmeaMsgTag);
if(strcmp(gpsTag, nmeaMsgTag))
return FALSE;
strpy(GPSFixTime, gpsFlds[GGA_TIMESTAMP]);
strcpy(GPSFixTime, gpsFlds[NMEA_TIMESTAMP]);
strcpy(GPSLat, gpsFlds[GGA_LATITUDE]);
strcat(GPSLat, gpsFlds[GGA_NS_HEMI]);
strcpy(GPSLat, gpsFlds[NMEA_LATITUDE]);
strcat(GPSLat, gpsFlds[NMEA_NS_HEMI]);
strcpy(GPSLong, gpsFlds[GGA_LONGITUDE]);
strcat(GPSLong, gpsFlds[GGA_EW_HEMI]);
strcpy(GPSLong, gpsFlds[NMEA_LONGITUDE]);
strcat(GPSLong, gpsFlds[NMEA_EW_HEMI]);
return TRUE;
}
/*
* callback from GPS receiver when rx is complete
* echo the last GPS message on the console
*/
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
void GPSEcho(void)
{
HAL_LPUART_Receive_DMA(&hlpuart1, (uint8_t*)GPSMsgBuf, GPS_BUFFER_SIZE);
gpsMessageRx = TRUE;
return;
if(!gpsEchoReady)
return;
USART_Print_string("%s\r\n", (char *)GPSEchoBuf);
gpsEchoReady=FALSE;
}
#endif

View file

@ -34,7 +34,6 @@
#include <stm32wl3x_nucleo.h>
#endif
#include <cmsis_os2.h>
#include <FreeRTOS.h>
#include <semphr.h>
@ -429,7 +428,7 @@ void Frame_Rxtask_exec(void)
case ICMP_TYPE:
Mesh_ProcessBeacon((void *)&rFrame, Stats.lastRSSI);
#if __DUMP_BEACON
EnqueChatFrame((void *)&rFrame, length);
EnqueChatFrame((void *)&rFrame, length+3);
#endif
Stats.nBeacons++;
break;

View file

@ -28,6 +28,7 @@
#include "tasks.h"
#include "utils.h"
#include "tod.h"
#include "config.h"
// menu state
uint8_t menuState; // menu state
@ -97,6 +98,7 @@ void Print_Frame_stats(FRAME_STATS *stats);
void Print_Radio_errors(uint32_t errs);
void Print_FSM_state(uint8_t state);
uint8_t getEntry(int activeMenu, int item);
uint8_t getKeyEntry(void);
// list of menus
enum {
@ -212,6 +214,13 @@ uint8_t setParam(void)
{
return(getEntry(activeMenu, sel_item));
}
#if __ENABLE_GPS
uint8_t gpsEcho(void)
{
GPSEcho();
return(getKeyEntry());
}
#endif
/*
* main menu definition
@ -226,12 +235,20 @@ struct menuItems_t {
};
// main menu
#if __ENABLE_GPS
#define N_MAINMENU 11 // additional menu item for GPS
#else
#define N_MAINMENU 10 // number of lines in the menu
#endif
struct menuItems_t mainMenu[N_MAINMENU] = {
{ "List setup parameters\r\n", 'A', printAllSetup },
{ "Mesh Status\r\n", 'B', listMesh },
{ "Chat Mode\r\n", 'C', chatMode },
{ "Dump Frame stats\r\n", 'D', showstats },
#if __ENABLE_GPS
{ "GPS Echo mode\r\n", 'G', gpsEcho },
#endif
{ "LED test\r\n", 'L', ledTest },
{ "Set Radio Parameters\r\n", 'R', setRadio },
{ "Set Station Parameters\r\n", 'S', setStation },

View file

@ -96,7 +96,13 @@ STN_PARAMS *GetStationParams(void) // get the station params
// returns true if callsigns match
BOOL CompareToMyCall(char *call)
{
if(!strncmp(call, setup_memory.params.setup_data.stnCall, MAX_CALL))
char expCall[20];
// make sure call sign is padded out to 6 characters b4 comparison
strcpy(expCall, setup_memory.params.setup_data.stnCall);
strcat(expCall, " ");
if(!strncmp(call, expCall, MAX_CALL))
return TRUE;
return FALSE;
}

View file

@ -29,6 +29,7 @@
#include <FreeRTOS.h>
#include <semphr.h>
#include "config.h"
#include "stream_buffer.h"
#include "types.h"
#include "streambuffer.h"
@ -46,33 +47,59 @@ StaticStreamBuffer_t USART_StreamBuffer;
SemaphoreHandle_t txCompleted; // tx completed semaphore
static DATA_ELEMENT USARTRxChar[10]; // last received character
uint8_t buffer_data[bufferSIZE];
uint8_t usart_data[bufferSIZE];
char usartPrintBuffer[200];
// fwd refs here...
void USART_Receive_char(void);
#if __ENABLE_GPS
#define LPUART_DMA_SIZE 32
static DATA_ELEMENT LPUARTRxChar[LPUART_DMA_SIZE];
void LPUART_Receive_char(void);
StreamBufferHandle_t LPUART_RxBuffer; // handle to buffer
StaticStreamBuffer_t LPUART_StreamBuffer;
uint8_t gps_data[bufferSIZE];
#endif
/*
* API for the rx data buffer
*/
void USART_API_init(void)
{
USART_RxBuffer = xStreamBufferCreateStatic(bufferSIZE, 1, buffer_data, &USART_StreamBuffer);
USART_RxBuffer_reset();
// create the tx completed semaphore
txCompleted = xSemaphoreCreateBinary();
// start the rx process
// start USART
USART_RxBuffer = xStreamBufferCreateStatic(bufferSIZE, 1, usart_data, &USART_StreamBuffer);
USART_RxBuffer_reset();
USART_Receive_char();
#if __ENABLE_GPS
LPUART_RxBuffer = xStreamBufferCreateStatic(bufferSIZE, 1, gps_data, &LPUART_StreamBuffer);
LPUART_RxBuffer_reset();
LPUART_Receive_char();
#endif
}
// reset the data buffer
void USART_RxBuffer_reset(void)
{
xStreamBufferReset(USART_RxBuffer);
return;
}
#if __ENABLE_GPS
// reset the LPUART Buffer
void LPUART_RxBuffer_reset(void)
{
xStreamBufferReset(LPUART_RxBuffer);
return;
}
#endif
// return the number of byte in the buffer
size_t databuffer_bytesInBuffer(void)
{
@ -99,6 +126,35 @@ DATA_ELEMENT databuffer_get(UART_TIMEOUT_T timeout)
return retval;
}
/*
* Similar but from GPS buffer
*/
#if __ENABLE_GPS
// return the number of byte in the buffer
size_t gpsbuffer_bytesInBuffer(void)
{
size_t nBytes = xStreamBufferBytesAvailable(LPUART_RxBuffer);
return nBytes;
}
// get a bytes
DATA_ELEMENT gpsbuffer_get(UART_TIMEOUT_T timeout)
{
DATA_ELEMENT retval;
TickType_t tickTimeout;
if(timeout == 0)
tickTimeout = portMAX_DELAY;
else
tickTimeout = pdMS_TO_TICKS(timeout);
if(xStreamBufferReceive(LPUART_RxBuffer, &retval, 1, tickTimeout) == 0)
return BUFFER_NO_DATA;
return retval;
}
#endif
// see if the buffer contains a keyword, save data up to it if needed
BOOL databuffer_contains(const char *tag, UART_TIMEOUT_T rx_timeout, BOOL saveData, char *SaveBuffer)
{
@ -193,13 +249,40 @@ void USART_Receive_char(void)
HAL_UART_Receive_IT(&huart1,(uint8_t *)USARTRxChar,1);
}
// callback function when rx is completed: overrides previous
// __weak definition
// NB: Console USART and GPS LPUART share the same HAL routine
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
// do not store any control chars
#if __ENABLE_GPS
// service the LPUART
if(huart->Instance == LPUART1) {
xStreamBufferSendFromISR(LPUART_RxBuffer, LPUARTRxChar, 1, NULL);
HAL_UART_Receive_IT(&hlpuart1,(uint8_t *)LPUARTRxChar,1);
return;
}
#endif
// service the USART
xStreamBufferSendFromISR(USART_RxBuffer, USARTRxChar, 1, NULL);
HAL_UART_Receive_IT(&huart1,(uint8_t *)USARTRxChar,1);
}
#if __ENABLE_GPS
// receive a byte with DMA, wait for DMA completed interrupt
void LPUART_Receive_char(void)
{
HAL_UART_Receive_IT(&hlpuart1,(uint8_t *)LPUARTRxChar,1);
// HAL_UARTEx_ReceiveToIdle_DMA(&hlpuart1,(uint8_t *)LPUARTRxChar,LPUART_DMA_SIZE);
//__HAL_DMA_DISABLE_IT(&hlpuart1, DMA_IT_HT);
}
// callback from GPS Rx
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
xStreamBufferSendFromISR(LPUART_RxBuffer, LPUARTRxChar, Size, NULL);
HAL_UARTEx_ReceiveToIdle_DMA(&hlpuart1,(uint8_t *)LPUARTRxChar,LPUART_DMA_SIZE);
}
#endif