diff --git a/Node Firmware/IP400/Inc/dataq.h b/Node Firmware/IP400/Inc/dataq.h deleted file mode 100644 index eec2c2f..0000000 --- a/Node Firmware/IP400/Inc/dataq.h +++ /dev/null @@ -1,61 +0,0 @@ -/*--------------------------------------------------------------------------- - Project: WL33_NUCLEO_UART - - Module: - - File Name: queue.h - - Date Created: Jan 9, 2025 - - Author: MartinA - - Description: - - Copyright © 2024-25, Alberta Digital Radio Communications Society, - All rights reserved - - - Revision History: - ----------------------------------------------------------------------------*/ - -#ifndef INC_DATAQ_H_ -#define INC_DATAQ_H_ - -#ifndef __CCALL -#ifdef __cplusplus -#define __CCALL extern "C" -#else -#define __CCALL -#endif -#endif - -#define Q_TYPECAST (struct qelem *) - -// queue structure -typedef struct qelem { - struct qelem *q_forw; - struct qelem *q_back; -} QUEUE_ELEM; - -// frame data queue -typedef struct frame_data_queue_t { - struct frame_data_queue_t *q_forw; // forwared pointer - struct frame_data_queue_t *q_back; // backward pointer - void *frame; // IP400 Frame - uint16_t length; // length (in some cases) -} FRAME_QUEUE; - -// queue functions -BOOL enqueFrame(FRAME_QUEUE *que, IP400_FRAME *fr); -IP400_FRAME *dequeFrame(FRAME_QUEUE *que); - -// queue management -void insque (struct qelem *elem, struct qelem *pred); -void remque (struct qelem *elem); - -// print memory stats -void Print_Memory_Stats(void); - - -#endif /* INC_DATAQ_H_ */ diff --git a/Node Firmware/IP400/Inc/frame.h b/Node Firmware/IP400/Inc/frame.h deleted file mode 100644 index 437f903..0000000 --- a/Node Firmware/IP400/Inc/frame.h +++ /dev/null @@ -1,208 +0,0 @@ -/*--------------------------------------------------------------------------- - Project: WL33_NUCLEO_UART - - Module: - - File Name: frame.h - - Date Created: Jan 8, 2025 - - Author: MartinA - - Description: - - Copyright © 2024-25, Alberta Digital Radio Communications Society, - All rights reserved - - - Revision History: - ----------------------------------------------------------------------------*/ - -#ifndef FRAME_H_ -#define FRAME_H_ - -#include -#include "types.h" - -// frame defines -#define N_CALL 4 // octets in the excess-40 compressed callsign -#define MAX_CALL 6 // max callsign size -#define EXT_CALL 4*MAX_CALL // extended call sign field -#define PAYLOAD_MIN 56 // min octets in payload -#define PAYLOAD_MAX 1053 // max octets in payload -#define MAX_CALL_BUFFER 20 // max buffering for callsign in payload -#define N_FEC 4 // number of bytes in the FEC -#define BROADCAST_ADDR 0xFF // broadcast address - -#define MAX_HOP_COUNT 15 // max hop count - -// transmit states -enum { - TX_IDLE=0, // idle - waiting for work - TX_SENDING, // sending a frame - TX_DONE // done -}; - -// radio error register -#define SEQ_COMPLETE_ERR 0x8000 // Sequencer error -#define SEQ_ACT_TIMEOUT 0x4000 // Sequencer action timeout -#define PLL_CALAMP_ERR 0x0800 // VCO amplitude calibration error -#define PLL_CALFREQ_ERR 0x0400 // VCO frequency calibration error -#define PLL_UNLOCK_ERR 0x0200 // PLL is unlocked -#define PLL_LOCK_FAIL 0x0100 // PLL lock failure -#define DBM_FIFO_ERR 0x0020 // Data buffer failure -#define N_RADIO_ERRS 7 // number of the above - -// radio FSM states -enum fsm_states_e { - FSM_IDLE=0, // idle - FSM_ENA_RF_REG, // enable RF registers - FSM_WAIT_ACTIVE2, // wait for active 2 - FSM_ACTIVE2, // active 2 - FSM_ENA_CURR, // enable current - FSM_SYNTH_SETUP, // synth setup - FSM_CALIB_VCO, // VCO calibration - FSM_LOCKRXTX, // lock Rx and Rx - FSM_LOCKONTX, // lock on Rx - FSM_EN_PA, // enable PA - FSM_TX, // transmit - FSM_PA_DWN_ANA, // Analog power down - FSM_END_TX, // end transmit - FSM_LOCKONRX, // lock on Rx - FSM_EN_RX, // Enable Rx - FSM_EN_LNA, // enable LNA - FSM_RX, // recieve - FSM_END_RX, // end rx - FSM_SYNTH_PWDN, // synth power down - FSM_N_FSM_STATES -}; - -// header flags -typedef struct frame_flags_t { - unsigned hop_count: 4; // hop count - unsigned coding: 4; // coding method - unsigned compression: 2; // compression method - unsigned hoptable: 1; // hop table is included - unsigned srcExt: 1; // source call is extended - unsigned destExt: 1; // dest call is extended - unsigned command: 1; // command packet - unsigned noconnect: 1; // connectionless - unsigned repeat: 1; // repeat flag -} IP400_FLAGS; - -// callsign field -typedef struct callsign_t { - union { - uint8_t bytes[N_CALL]; // compressed callsign - uint32_t encoded; - } callbytes; - uint16_t port; // port information -} IP400_CALL; - -// hop table -typedef struct hoptable_t { - union { - uint8_t bytes[N_CALL]; - uint32_t encoded; - } hopAddr; -} HOPTABLE; - -// complete frame -typedef struct ip400_frame_t { - IP400_CALL source; // source call sign - IP400_CALL dest; // destination call sign - union { - IP400_FLAGS flags; // flag bit field - uint16_t allflags; // all flags - } flagfld; - uint32_t seqNum; // packet sequence number - void *buf; // data to send - uint16_t length; // data length - void *hopTable; // hop table address -} IP400_FRAME; - -// min/max payload sizes -#define IP_400_PORT_SIZE sizeof(uint16_t) -#define IP_400_CALL_SIZE (N_CALL + IP_400_PORT_SIZE) -#define IP_400_FLAG_SIZE sizeof(uint16_t) -#define IP_400_HDR_SIZE (2*IP_400_CALL_SIZE + IP_400_FLAG_SIZE) -#define IP_400_LEN_SIZE sizeof(uint16_t) -#define MIN_FRAME_SIZE sizeof(IP400_FRAME) + PAYLOAD_MIN + N_FEC -#define MAX_FRAME_SIZE MIN_FRAME_SIZE - PAYLOAD_MIN + PAYLOAD_MAX - -// packet coding (type) -typedef enum { - UTF8_TEXT_PACKET=0, // Text packet (chat application) - COMPRESSED_AUDIO, // compressed audio packet - COMPREESSD_VIDEO, // compressed video packet - DATA_PACKET, // data packet - BEACON_PACKET, // beacon packet - IP_ENCAPSULATED, // IP encapsulated packet - AX_25_PACKET, // AX.25 encapsulated packet - RFC4733_DTMF, // DTMF packet - DMR_FRAME, // DMR Frame - DSTAR_FRAME, // Dstar Frame - P25_FRAME, // TIA project 25 - NXDN_FRAME, // NXDN - M17_FRAME, // M17 - TBD_1, - TBD_2, - LOCAL_COMMAND // local command frame -} IP400FrameType; - -// audio compression types -enum { - AUDIO_RAW, // raw 16-bit PCM - AUDIO_ULAW, // mu law compression - AUDIO_CODEC2, // codec 2 encoded - AUDIO_AMBE // AMBE encoded -}; - -// H.246 Video compression -enum { - H264_240_180_24, // H.264: 240x180, 24FPS - H264_320_240_24, // H.264: 320x240, 24FPS - H264_480_360_12, // H.264: 480x360, 12FPS - H264_640_480_6 // H.264: 640x480, 6FPS -}; - -// callsign fields -enum { - SRC_CALLSIGN=0, // dest for encode is source callsign - DEST_CALLSIGN // dest for encode is dest callsign -}; - -// frame stats -typedef struct frame_stats_t { - uint32_t TxFrameCnt; // transmit frame count - uint32_t RxFrameCnt; // good receive frame count - uint32_t CRCErrors; // CRC Errors - uint32_t TimeOuts; // Timeouts - uint32_t lastRSSI; // last RSSI reading - uint32_t framesOK; // processed frames - uint32_t dropped; // rejected frames - uint32_t duplicates; // duplicates - uint32_t nBeacons; // number of beacons processed - uint32_t nRepeated; // repeated frames -} FRAME_STATS; - -uint8_t getFrameStatus(void); - -// references -uint8_t callEncode(char *callsign, uint16_t port, IP400_FRAME *frame, uint8_t dest, uint8_t offset); -BOOL callDecode(IP400_CALL *encCall, char *callsign, uint16_t *port); - -// frame senders -BOOL SendTextFrame(char *srcCall, uint16_t srcPort, char *destCall, uint16_t dstPort, char *buf, uint16_t length, BOOL repeat); -void SendBeaconFrame(char *srcCall, uint8_t *payload, int bcnlen); -void SendSPIFrame(void *spiHdr, uint8_t *payload, int len); -// -BOOL EnqueChatFrame(void *Frame); // queue a chat frame -FRAME_STATS *GetFrameStats(void); // return the frame stats -uint32_t GetRadioStatus(void); // get the radio status -uint8_t GetFSMState(void); // get FSM state -// -uint8_t getFrameStatus(void); // get the frame status - -#endif /* FRAME_H_ */ diff --git a/Node Firmware/IP400/Inc/ip.h b/Node Firmware/IP400/Inc/ip.h deleted file mode 100644 index eea09ed..0000000 --- a/Node Firmware/IP400/Inc/ip.h +++ /dev/null @@ -1,75 +0,0 @@ -/*--------------------------------------------------------------------------- - Project: WL33_NUCLEO_UART - - File Name: ip.h - - Author: MartinA - - Creation Date: Jan 26, 2025 - - Description: Definitions for IP addressing - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version, provided this copyright notice - is included. - - Copyright (c) 2024-25 Alberta Digital Radio Communications Society - - Revision History: - ----------------------------------------------------------------------------*/ - -#ifndef INC_IP_H_ -#define INC_IP_H_ - -#include - -#include "types.h" -#include "config.h" - -/* If your port already typedef's sa_family_t, define SA_FAMILY_T_DEFINED - to prevent this code from redefining it. */ -#if !defined(sa_family_t) && !defined(SA_FAMILY_T_DEFINED) -typedef uint8_t sa_family_t; -#endif -/* If your port already typedef's in_port_t, define IN_PORT_T_DEFINED - to prevent this code from redefining it. */ -#if !defined(in_port_t) && !defined(IN_PORT_T_DEFINED) -typedef uint16_t in_port_t; -#endif - -// in_addr struct -struct in_addr_t { - union { - struct { uint8_t s_b1,s_b2,s_b3,s_b4; } S_un_b; - struct { uint16_t s_w1,s_w2; } S_un_w; - uint32_t S_addr; - } S_un; -}; -typedef struct in_addr_t IN_ADDR; - -/* members are in network byte order */ -struct sockaddr_in { - uint8_t sin_len; - sa_family_t sin_family; - in_port_t sin_port; - IN_ADDR sin_addr; -#define SIN_ZERO_LEN 8 - char sin_zero[SIN_ZERO_LEN]; -}; - -typedef struct sockaddr_in SOCKADDR_IN; - -// convert packed frame to IP address -void GetIP10Addr(IP400_CALL *fr, SOCKADDR_IN *ipaddr); -void GetIP172Addr(IP400_CALL *fr, SOCKADDR_IN *ipaddr); - -#if __IP_GROUP == IP_10_GROUP -#define GetIPAddr GetIP10Add -#else -#define GetIPAddr GetIP172Addr -#endif - -#endif /* INC_IP_H_ */ diff --git a/Node Firmware/IP400/Inc/led.h b/Node Firmware/IP400/Inc/led.h deleted file mode 100644 index 15b623f..0000000 --- a/Node Firmware/IP400/Inc/led.h +++ /dev/null @@ -1,43 +0,0 @@ -/*--------------------------------------------------------------------------- - Project: WL33_NUCLEO_UART - - File Name: led.h - - Author: MartinA - - Creation Date: Jan 26, 2025 - - Description: Definitions for the LED module - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version, provided this copyright notice - is included. - - Copyright (c) 2024-25 Alberta Digital Radio Communications Society - - Revision History: - ----------------------------------------------------------------------------*/ -#ifndef INC_LED_H_ -#define INC_LED_H_ - -// LED functions -enum { - - BICOLOR_OFF=0, // turn LED off - BICOLOR_RED, // red mode steady - BICOLOR_RED_FLASH, // red mode flashing - BICOLOR_GREEN, // green mode steady - BICOLOR_GREEN_FLASH, // green mode flashing - BICOLOR_RED_GREEN, // alternate RED/GREEN - TX_LED_ON, // tx LED on - TX_LED_OFF, // tx LED OFF - N_LED_MODE // modes1 -}; - -void SetLEDMode(uint8_t mode); - - -#endif /* INC_LED_H_ */ diff --git a/Node Firmware/IP400/Inc/newlib-freertos.h b/Node Firmware/IP400/Inc/newlib-freertos.h deleted file mode 100644 index b6911c9..0000000 --- a/Node Firmware/IP400/Inc/newlib-freertos.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * FreeRTOS Kernel V10.6.2 - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * SPDX-License-Identifier: MIT - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * https://www.FreeRTOS.org - * https://github.com/FreeRTOS - * - */ - -#ifndef INC_NEWLIB_FREERTOS_H -#define INC_NEWLIB_FREERTOS_H - -/* Note Newlib support has been included by popular demand, but is not - * used by the FreeRTOS maintainers themselves. FreeRTOS is not - * responsible for resulting newlib operation. User must be familiar with - * newlib and must provide system-wide implementations of the necessary - * stubs. Be warned that (at the time of writing) the current newlib design - * implements a system-wide malloc() that must be provided with locks. - * - * See the third party link http://www.nadler.com/embedded/newlibAndFreeRTOS.html - * for additional information. */ - -#include - -#define configUSE_C_RUNTIME_TLS_SUPPORT 1 - -#ifndef configTLS_BLOCK_TYPE - #define configTLS_BLOCK_TYPE struct _reent -#endif - -#ifndef configINIT_TLS_BLOCK - #define configINIT_TLS_BLOCK( xTLSBlock, pxTopOfStack ) _REENT_INIT_PTR( &( xTLSBlock ) ) -#endif - -#ifndef configSET_TLS_BLOCK - #define configSET_TLS_BLOCK( xTLSBlock ) ( _impure_ptr = &( xTLSBlock ) ) -#endif - -#ifndef configDEINIT_TLS_BLOCK - #define configDEINIT_TLS_BLOCK( xTLSBlock ) _reclaim_reent( &( xTLSBlock ) ) -#endif - -#endif /* INC_NEWLIB_FREERTOS_H */ diff --git a/Node Firmware/IP400/Inc/setup.h b/Node Firmware/IP400/Inc/setup.h deleted file mode 100644 index e6a0d3a..0000000 --- a/Node Firmware/IP400/Inc/setup.h +++ /dev/null @@ -1,135 +0,0 @@ -/*--------------------------------------------------------------------------- - Project: WL33_NUCLEO_UART - - File Name: setup.h - - Author: MartinA - - Creation Date: Jan 13, 2025 - - Description: Definitions for setup data - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version, provided this copyright notice - is included. - - Copyright (c) 2024-25 Alberta Digital Radio Communications Society - - Revision History: - ----------------------------------------------------------------------------*/ -#ifndef INC_SETUP_H_ -#define INC_SETUP_H_ - -#include - -#include "frame.h" -#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[]; -extern char *paModes[]; - -typedef struct setup_flags_t { - unsigned fsk: 1; // can run FSK - unsigned ofdm: 1; // can run OFDM - unsigned aredn: 1; // is an AREDN node - unsigned repeat: 1; // repeat mode default - unsigned ext: 1; // use extended callsign - unsigned rate: 3; // data rate in use -} SETUP_FLAGS; - -// data rates in the flag field (FSK mode) -enum { - FSK_1200, - FSK_9600, - FSK_56K, - FSK_100K, - FSK_200K, - FSK_400K, - FSK_600K -}; - -// setup data struct -typedef struct setup_data_t { - SETUP_FLAGS flags; // flags - char stnCall[MAX_CALL]; // station call sign - char extCall[EXT_CALL]; // extended call sign - char latitude[10]; // latititude - char longitude[10]; // longitude - char gridSq[10]; // grid square - uint16_t beaconInt; // beacon interval -} SETUP_DATA; - -// Radio setup struct -typedef struct radio_setup_t { - uint32_t lFrequencyBase; /*!< Specifies the base carrier frequency (in Hz) */ - MRSubGModSelect xModulationSelect; /*!< Specifies the modulation @ref MRSubGModSelect */ - uint32_t lDatarate; /*!< Specifies the datarate expressed in sps.*/ - uint32_t lFreqDev; /*!< Specifies the frequency deviation expressed in Hz. */ - uint32_t lBandwidth; /*!< Specifies the channel filter bandwidth expressed in Hz. */ - uint8_t dsssExp; /*!< Specifies the DSSS spreading exponent. Use 0 to disable DSSS. */ - uint8_t outputPower; /*!< PA value to write expressed in dBm. */ - MRSubG_PA_DRVMode PADrvMode; /*!< PA drive mode. */ - int16_t rxSquelch; // rx squelch level -} RADIO_SETUP; - -// setup struct -typedef struct stn_params_t { - SETUP_DATA setup_data; // basic setup data - RADIO_SETUP radio_setup; // radio setup - uint8_t FirmwareVerMajor; // firmware major rev - uint8_t FirmwareVerMinor; // firmware minor vers - uint32_t Magic; // magic number: "DEBEADEF" - uint32_t SetupCRC; // CRC -} STN_PARAMS; - -// beacon header -typedef union { - struct beacon_hdr_t { - SETUP_FLAGS flags; - uint8_t txPower; - uint8_t FirmwareMajor; - uint8_t FirmwareMinor; - } setup; - uint8_t hdrBytes[sizeof(struct beacon_hdr_t)]; -} BEACON_HEADER; - -#define SETUP_MAGIC 0xDEBEADEF // magic number - -typedef union { - STN_PARAMS params; - uint8_t bytes[sizeof(STN_PARAMS)]; - uint32_t flashwords[sizeof(STN_PARAMS)/sizeof(uint32_t)]; -} SETUP_MEMORY; - -extern SETUP_MEMORY setup_memory; -extern SETUP_MEMORY def_params; -extern CRC_HandleTypeDef hcrc; - -// validations used by key entry -#if US -#define MIN_FREQ 420000000 // min freq (US only) -#else -#define MIN_FREQ 430000000 // min freq (CAN only) -#endif - -// links in -void printStationSetup(void); // print setup struct -void printRadioSetup(void); // print radio setup -char *GetMyCall(void); // return the station's callsign -STN_PARAMS *GetStationParams(void); // get the station params -BOOL CompareToMyCall(char *call); -// -BOOL VerifySetup(void); -BOOL ReadSetup(void); -BOOL WriteSetup(void); -void SetDefSetup(void); -BOOL UpdateSetup(void); - -#endif /* INC_SETUP_H_ */ diff --git a/Node Firmware/IP400/Inc/spi.h b/Node Firmware/IP400/Inc/spi.h deleted file mode 100644 index 8f855a3..0000000 --- a/Node Firmware/IP400/Inc/spi.h +++ /dev/null @@ -1,71 +0,0 @@ -/*--------------------------------------------------------------------------- - Project: WL33_NUCLEO_UART - - File Name: spi.h - - Author: MartinA - - Creation Date: Jan 26, 2025 - - Description: Definitions for SPI mod - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version, provided this copyright notice - is included. - - Copyright (c) 2024-25 Alberta Digital Radio Communications Society - - Revision History: - ----------------------------------------------------------------------------*/ - -#ifndef INC_SPI_H_ -#define INC_SPI_H_ - -#include "frame.h" - -// SPI frame header -typedef struct spi_hdr_t { - uint8_t eye[4]; // 'IP4X' - uint8_t status; // status byte - uint8_t offset_hi; // high offset - uint8_t offset_lo; // low offset - uint8_t length_hi; // length hi - uint8_t length_lo; // length lo - uint8_t fromCall[N_CALL]; // from callsign - uint8_t fromPort[IP_400_PORT_SIZE]; // from port - uint8_t toCall[N_CALL]; // to callsign - uint8_t toPort[IP_400_PORT_SIZE]; // to port - uint8_t coding; // packet coding - uint8_t hopCount; // hop count - uint8_t flags; // remaining flags -} SPI_HEADER; - -#define SPI_BUFFER_LEN 400 // 400 bytes/transfer -#define SPI_RAW_LEN SPI_BUFFER_LEN + sizeof(struct spi_hdr_t) - -// status values -typedef enum { - NO_DATA=0, // no data available - SINGLE_FRAME, // single frame - FRAGMENT, // fragment - LAST_FRAGMENT, // last fragment - NUM_STATS // number of stats -} spiFrameStatus; - -// data buffer struct -typedef union { - struct { - SPI_HEADER hdr; // header - uint8_t buffer[SPI_BUFFER_LEN]; - } spiData; - uint8_t rawData[SPI_RAW_LEN]; -} SPI_BUFFER; - -#define SPI_TIMEOUT 100 // SPI timeout - -BOOL EnqueSPIFrame(void *raw); - -#endif /* INC_SPI_H_ */ diff --git a/Node Firmware/IP400/Inc/streambuffer.h b/Node Firmware/IP400/Inc/streambuffer.h deleted file mode 100644 index bcad0da..0000000 --- a/Node Firmware/IP400/Inc/streambuffer.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * streambuffer.h - * - * Created on: Jan 11, 2025 - * Author: MartinA - */ - -#ifndef INC_STREAMBUFFER_H_ -#define INC_STREAMBUFFER_H_ - -// data buffer defs -typedef uint8_t DATA_ELEMENT; // data element -#define BUFFER_EMPTY(x) (x.nDataBytes == 0) -#define BUFFER_NO_DATA 0 -#define bufferSIZE 512 // large buffer - - -#endif /* INC_STREAMBUFFER_H_ */ diff --git a/Node Firmware/IP400/Inc/tod.h b/Node Firmware/IP400/Inc/tod.h deleted file mode 100644 index 2867da6..0000000 --- a/Node Firmware/IP400/Inc/tod.h +++ /dev/null @@ -1,40 +0,0 @@ -/*--------------------------------------------------------------------------- - Project: WL33_NUCLEO_UART - - File Name: tod.h - - Author: MartinA - - Creation Date: Jan 23, 2025 - - Description: - -// TOD struct -typedef struct tod_t { - uint8_t Seconds; - uint8_t Minutes; - uint8_t Hours; -} TIMEOFDAY; - -// links in -void TOD_10SecTimer(void); // 10 second timer -void getTOD(TIMEOFDAY *time); -BOOL setTOD(char *todString); - -#endif /* INC_TOD_H_ */ diff --git a/Node Firmware/IP400/Inc/types.h b/Node Firmware/IP400/Inc/types.h deleted file mode 100644 index 92bf64f..0000000 --- a/Node Firmware/IP400/Inc/types.h +++ /dev/null @@ -1,54 +0,0 @@ -/*--------------------------------------------------------------------------- - Project: WL33_NUCLEO_UART - - Module: Type definitions - - File Name: types.h - - Date Created: Jan 9, 2025 - - Author: MartinA - - Description: Useful data types - - Copyright © 2024-25, Alberta Digital Radio Communications Society, - All rights reserved - - - Revision History: - ----------------------------------------------------------------------------*/ - -#ifndef INC_TYPES_H_ -#define INC_TYPES_H_ - -#include -#include - -// boolean type -#ifndef BOOL -typedef uint8_t BOOL; // boolean -typedef uint8_t BOOLEAN; // alternate -#endif - -#ifndef TRUE -#define TRUE ((BOOL)1U) -#endif - -#ifndef FALSE -#define FALSE ((BOOL)0U) -#endif - -#ifndef __CCALL -#ifdef __cplusplus -#define __CCALL extern "C" -#else -#define __CCALL -#endif -#endif - -// macros -#define islower(c) ((c >= 'a') && (c <= 'z')) -#define toupper(c) (c-0x20) - -#endif /* INC_TYPES_H_ */ diff --git a/Node Firmware/IP400/Inc/usart.h b/Node Firmware/IP400/Inc/usart.h deleted file mode 100644 index a823ff7..0000000 --- a/Node Firmware/IP400/Inc/usart.h +++ /dev/null @@ -1,62 +0,0 @@ -/*--------------------------------------------------------------------------- - Project: WL33_NUCLEO_UART - - File Name: usart.h - - Author: MartinA - - Creation Date: Jan 12, 2025 - - Description: -#include -#include -#include -#include -#include -#include -#include - -#include "config.h" -#include "frame.h" -#include "tasks.h" -#include "setup.h" -#include "utils.h" -#include "tod.h" -#include "usart.h" - -// config -#define __SPEED_DAEMON 0 // send beacon every 5 seconds for testing purposes - -// local defines -#define MAX_BEACON 80 // max beacon string -#define GPS_FIX_LEN 20 // gps fix length -#define GPS_BFR_SIZE 140 // GPS buffer size - -#if __ENABLE_GPS -// NMEA GGA Sentence fields -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 -}; - -#define N_NMEA_SEN 14 // number of NMEA sentences -enum { - NMEA_CMD_DISABLED=0, // disabled - NMEA_CMD_ONCE, // once per fix - NMEA_CMD_2FIX, // once every 2 fixes - NMEA_CMD_3FIX, // once every 3 fixes - NMEA_CMD_4FIX, // once every 4 fixes - NMEA_CMD_5FIX, // once every 5 fixes -}; - -char *nmeaCmd = "$PMTK314"; // command -uint8_t senCmds[N_NMEA_SEN] = { - NMEA_CMD_DISABLED, // 0:GLL disabled - NMEA_CMD_ONCE, // 1: RMC once - NMEA_CMD_DISABLED, // 2: VTG disabled - NMEA_CMD_DISABLED, // 3: GGA disabled - NMEA_CMD_DISABLED, // 4: GSA disabled - NMEA_CMD_DISABLED, // 5: GSV disabled - NMEA_CMD_DISABLED, // 6 not used - NMEA_CMD_DISABLED, // 7 - NMEA_CMD_DISABLED, // 13 - NMEA_CMD_DISABLED, // 14 - NMEA_CMD_DISABLED, // 15 - NMEA_CMD_DISABLED, // 16 - NMEA_CMD_DISABLED, // 17 - NMEA_CMD_DISABLED // 18 -}; -#endif - -// hemispheres -enum { - N_HEMI=0, // North - S_HEMI, // South - E_HEMI, // East - W_HEMI, // West - N_HEMIS -}; - -uint8_t hemispheres[N_HEMIS] = { - 'N', 'S', 'E', 'W' -}; - -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 -// 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; -char cmdBuf[MAX_BEACON]; -// -BOOL haveGPSFix = FALSE; -BOOL gpsEchoReady=FALSE; -// -char GPSLat[GPS_FIX_LEN]; -char GPSLong[GPS_FIX_LEN]; -char GPSFixTime[GPS_FIX_LEN]; -char *gpsFlds[GPS_BFR_SIZE]; - -// fwd Refs in this module in GPS mode -BOOL processGPSMessage(uint8_t *GPSMsgBuf, uint8_t bufferSize); -void sendGPSCmd(void); -#endif - -//fwd refs w/o GPS -void GPSFormat(char *buffer, double value, uint8_t hePos, uint8_t heNeg); - -// initialization: calculate the init value in -// quanta of MAIN_TASK_SCHED -void Beacon_Task_init(void) -{ -// higher speed for testing... -#if __SPEED_DAEMON - timerInitValue = 5 *1000/MAIN_TASK_SCHED; // every 5 seconds for testing - timerCtrValue = 0; -#else - uint32_t timerTick = 60 * 1000/MAIN_TASK_SCHED; - timerInitValue = setup_memory.params.setup_data.beaconInt * timerTick; - timerCtrValue = 0; // set to timerInitValue to wait -#endif - - // GPS Init -#if __ENABLE_GPS - gpsMessageRx = FALSE; - haveGPSFix = FALSE; - gpsEchoReady = FALSE; - GPSBufPtr = GPSMsgBuf; - GPSBusy = FALSE; - NMEAState=NMEA_STATE_SOM; -#endif - -} - -// this runs every MAIN_TASK_SCHED ms -void Beacon_Task_exec(void) -{ -#if __ENABLE_GPS - if(gpsMessageRx) { - // process the message - if(processGPSMessage(GPSProcBuf, (uint8_t)strlen((char *)GPSProcBuf))) { - haveGPSFix = TRUE; - } - gpsMessageRx = FALSE; - } -#endif - - if(timerCtrValue > 0) { - timerCtrValue--; - return; - } - timerCtrValue = timerInitValue; - -#if __ENABLE_GPS - // send a command to the GPS every beacon interval - sendGPSCmd(); -#endif - - // start with the header - beacon_hdr.setup.flags = setup_memory.params.setup_data.flags; - beacon_hdr.setup.txPower = setup_memory.params.radio_setup.outputPower; - uint8_t *buf = bcnPayload; - - // beacon header: flags, txpower and firmware version - // brute force copy: compiler rounds SETUP_FLAGS to 32 bits - *buf++ = beacon_hdr.hdrBytes[0]; - *buf++ = beacon_hdr.hdrBytes[4]; - - // firmware version - *buf++ = def_params.params.FirmwareVerMajor + '0'; - *buf++ = def_params.params.FirmwareVerMinor + '0'; - - char *pPayload = (char *)buf; - char *p2 = pPayload; - -#if __ENABLE_GPS - //GPS generated payload - if(haveGPSFix) { - strcpy(pPayload, "GPS,"); - strcat(pPayload, GPSLat); - strcat(pPayload, ","); - strcat(pPayload, GPSLong); - strcat(pPayload, ","); - strcat(pPayload, GPSFixTime); - strcat(pPayload, ","); - } else { -#endif - // setup struct generated payload - strcpy(pPayload, "FXD,"); - pPayload += strlen(pPayload); - double dlat = ascii2double(setup_memory.params.setup_data.latitude); - GPSFormat(pPayload, dlat, N_HEMI, S_HEMI); - strcat(pPayload, ","); - pPayload += strlen(pPayload); - double dlong = ascii2double(setup_memory.params.setup_data.longitude); - GPSFormat(pPayload, dlong, E_HEMI, W_HEMI); - strcat(pPayload, ",,"); -#if __ENABLE_GPS - } -#endif - pPayload += strlen(pPayload); - - // Use RTC for time - getTOD(&wallClockTime); - sprintf(pPayload, "%02d%02d%02d", wallClockTime.Hours, wallClockTime.Minutes, wallClockTime.Seconds); - strcat(pPayload, ","); - - // home grid square - strcat(pPayload, setup_memory.params.setup_data.gridSq); - - int pos = strlen((char *)p2); - buf[pos++] = '\0'; // null terminated - - pos += 2*sizeof(uint8_t); // account for firmware field - - // time to send a beacon frame.. - SendBeaconFrame(setup_memory.params.setup_data.stnCall, bcnPayload, pos+1); -} - -/* - * Format the +/-ddd.dddd lat/long format into DDMM.MMMMM format - */ -void GPSFormat(char *buffer, double value, uint8_t hePos, uint8_t heNeg) -{ - // Set hemi, get abs value - uint8_t hemi = value > 0.00 ? hePos : heNeg; - value = fabs(value); - - // separate whole and fractional - int whole = (int)value; - double fract = value - (double)whole; - - // calculate minutes and fraction - double dmin = 60.0 * fract; - dmin = round(dmin * 100.0)/100.0; - - int min = floor(dmin); - int ifract = (int)ceil((dmin-min) * 100000); - - 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= 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 -/* - * Send a command to the GPS device to limit traffic - */ -void sendGPSCmd(void) -{ - uint8_t cksum = 0; - char *buf = cmdBuf; - strcpy(buf, nmeaCmd); - buf += strlen(nmeaCmd); - - for(int j=1;j - -#include "types.h" -#include "frame.h" - -#define RADIX_40 40 // alphabet radix - -// Radix 40 callsign alphabet -char alphabet[RADIX_40] = { -// 0 1 2 3 4 5 6 7 8 9 - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - -// 10 11 12 13 14 15 16 17 18 19 - ' ', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', - -// 20 21 22 23 24 25 26 27 28 29 - 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', - -// 30 31 32 33 34 35 36 37 38 39 - 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '(', ')', '-' -}; - -// encode a char into the alphabet -uint32_t alphaEncode(char byte) -{ - byte = islower(byte) ? toupper(byte) : byte; - - for(uint32_t i=0;i= 0) && (alpha <= 9)) - return '0' + alpha; - - // special cases: see alphabet table - - switch(alpha) { - - case 10: - return ' '; - - case 37: - return '('; - - case 38: - return ')'; - - case 39: - return '@'; - - default: - return 'A' + (alpha - 11); - } - return ' '; -} - -void EncodeChunk(char *src, int len, uint32_t *enc) -{ - uint32_t chunk=alphaEncode(src[0]); - - // less than 2 characters - if(len < 2) { - *enc = chunk; - return; - } - - // 2 or more - for(int i=1;ibuf; - p += offset; - - if(dest == DEST_CALLSIGN) - frame->dest.port = port; - else - frame->source.port = port; - - // broadcast address - if(!strcmp(callsign, "FFFF")) { - if(dest == DEST_CALLSIGN) - frame->dest.callbytes.encoded = 0xFFFFFFFF; - else - frame->source.callbytes.encoded = 0xFFFFFFFF; - return 0; - } - - // ensure the callsign is padded out to at least 6 characters - char paddedCall[50]; - strcpy(paddedCall, callsign); - strcat(paddedCall, " "); - - // non-broadcast: break it up into chunks of 6 characters - int nChunks = len/MAX_CALL; - if ((len % MAX_CALL) > 0) - nChunks++; - - char *cll = paddedCall; - - for(int k=0;kdest.callbytes.encoded = encChunk; - else - frame->source.callbytes.encoded = encChunk; - // callsign less than or equal to MAX_CALL - if(nChunks == 1) { - return 0; - } - } else { - *p++ = encChunk; - cll += MAX_CALL; - if(dest == DEST_CALLSIGN) - frame->flagfld.flags.destExt = TRUE; - else - frame->flagfld.flags.srcExt = TRUE; - } - } - *p++ = 0xFF000000; - // return the offset in the buffer - return (p-(uint32_t *)frame->buf) + sizeof(uint32_t); -} - -// decode a callsign -BOOL callDecode(IP400_CALL *encCall, char *callsign, uint16_t *port) -{ - char tmpBuf[10], *p = tmpBuf; - int i; - - uint32_t encoded = encCall->callbytes.encoded; - for(i=0;i=0;i--) - *callsign++ = tmpBuf[i]; - - *callsign = '\0'; - *port = encCall->port; - - return TRUE; -} diff --git a/Node Firmware/IP400/Src/chat.c b/Node Firmware/IP400/Src/chat.c deleted file mode 100644 index e6b4128..0000000 --- a/Node Firmware/IP400/Src/chat.c +++ /dev/null @@ -1,301 +0,0 @@ -/*--------------------------------------------------------------------------- - Project: WL33_NUCLEO_UART - - File Name: chat.c - - Author: MartinA - - Description: This code contains the chat application. It gathers key until the CR - is hit to send a packet. Two internal operations are exit and set the - destination. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version, provided this copyright notice - is included. - - Copyright (c) Alberta Digital Radio Communications Society - All rights reserved. - - Revision History: - ----------------------------------------------------------------------------*/ -#include -#include -#include - -#include "setup.h" -#include "frame.h" -#include "types.h" -#include "usart.h" -#include "streambuffer.h" -#include "dataq.h" - -#define MAX_KEY 140 // max keys in a buffer -#define MAX_DEST 20 // max chars in dest callsign -#define BROADCAST "FFFF" // broadcast address - -static char keyBuffer[MAX_KEY]; // buffer for keystrokes -uint8_t keyPos; // current position - -#define KEY_EOL 0x0D // carriage return -#define KEY_RPT 0x12 // change repeat status -#define KEY_EXIT 0x1A // exit key -#define KEY_ESC 0x1B // escape key -#define KEY_DEL 0x7F // delete key -#define KEY_BKSP 0x08 // backspace key -#define KEY_DUMP 0x04 // toggle dump mode - -char dest_call[MAX_DEST]; // broadcast destination -char *dp = dest_call; // pointer to dest call characters -char *entCall = "Enter Destination Callsign"; -char *rptMode[] = { - "Repeat mode->off", - "Repeat mode->on" -}; - -char *dumpStrings[] = { - "Dump mode->off", - "Dump mode->on" -}; - -char *welcome = "Welcome to chat. ESC to set destination, CTRL/R to toggle repeat, CTRL/Z to exit"; - -BOOL destEnt = FALSE; // not entering destination -BOOL repeat = TRUE; // repeating by default -BOOL deleteMode = FALSE; // delete mode -BOOL welcomed = FALSE; // welcome mat is out -BOOL dumpMode = FALSE; - -FRAME_QUEUE chatQueue; // queue for inbound frames - -// fwd refs -void sendLine(char *buffer, int len); -void PrintFrame(IP400_FRAME *FrameBytes); - -// init entry -void Chat_Task_init(void) -{ - strcpy(dest_call, BROADCAST); - destEnt = FALSE; - chatQueue.q_forw = &chatQueue; - chatQueue.q_back = &chatQueue; - keyPos = 0; -} - -void Chat_Task_welcome(void) -{ - // start with welcome message - USART_Print_string("%s\r\n", welcome); - USART_Print_string("%s; ", rptMode[repeat]); - - if(!strcmp(dest_call, BROADCAST)) - USART_Print_string("%s; Destination callsign->(Broadcast)\r\n\n"); - else - USART_Print_string("%s; Destination callsign->%s\r\n\n", dest_call); - - welcomed = TRUE; -} - -/* - * place a frame on the queue frame content is copied - * to alloc'd memory - */ -BOOL EnqueChatFrame(void *raw) -{ - IP400_FRAME *qFrame, *SrcFrame = (IP400_FRAME *)raw; - uint8_t *frameBuffer; - - // if the welcome mat is not out, then discard any pending frames - if(!welcomed) - return FALSE; - - // allocate an IP400 frame - if((qFrame=malloc(sizeof(IP400_FRAME)))== NULL) - return FALSE; - memcpy(qFrame, SrcFrame, sizeof(IP400_FRAME)); - - // alloc the data portion of the frame - if((frameBuffer=malloc(SrcFrame->length)) == NULL) { - return FALSE; - } - - memcpy(frameBuffer, (uint8_t *)SrcFrame->buf, SrcFrame->length); - qFrame->buf = frameBuffer; - qFrame->length = SrcFrame->length; - - if(!enqueFrame(&chatQueue, qFrame)) - return FALSE; - - return TRUE; -} - -/* - * chat task main entry - * return: TRUE if return to main menu is required - * FALSE: more to go - */ -BOOL Chat_Task_exec(void) -{ - if(!welcomed) - Chat_Task_welcome(); - - char c; - int nBytesinBuff; - IP400_FRAME *fr; - - // process any inbound frames first.. - if((fr=dequeFrame(&chatQueue)) != NULL) { - PrintFrame(fr); - free(fr->buf); - free(fr); - } - - if((nBytesinBuff=databuffer_bytesInBuffer()) == 0) - return FALSE; - - for(int i=0;i 0) { - USART_Print_string("%c", keyBuffer[--keyPos]); - } else { - USART_Print_string("\\\r\n"); - deleteMode = FALSE; - } - } - continue; - } else { - // processing a key - - switch (c) { - - // CTRL/R: change repeat flag - case KEY_RPT: - repeat = repeat ? FALSE : TRUE; - char *r = rptMode[repeat]; - USART_Print_string("%s\r\n",r); - break; - - // CTRL/D: change dump mode - case KEY_DUMP: - dumpMode = dumpMode ? FALSE : TRUE; - char *d = dumpStrings[dumpMode]; - USART_Print_string("%s\r\n",d); - break; - - // escape key: get a destination call sign - case KEY_ESC: - if(destEnt) { - strcpy(dest_call, BROADCAST); - USART_Print_string("Destination set to broadcast\r\n"); - destEnt=FALSE; - break; - } - if(keyPos == 0) { - USART_Print_string("%s->", entCall); - dp = dest_call; - destEnt = TRUE; - } - break; - - // EOL key: sent the packet - case KEY_EOL: - USART_Print_string("\r\n"); - if(destEnt) { - int cpyLen = keyPos > MAX_CALL ? MAX_CALL : keyPos; - strncpy(dest_call, keyBuffer, cpyLen); - destEnt = FALSE; - } else { - if(keyPos != 0) { - keyBuffer[keyPos++] = '\0'; - sendLine(keyBuffer, keyPos); - } else { - USART_Print_string(">>>not sent\r\n"); - } - } - keyPos = 0; - break; - - case KEY_EXIT: - welcomed = FALSE; - return TRUE; - - case KEY_DEL: - case KEY_BKSP: - if(keyPos > 0) { - USART_Print_string("\\%c", keyBuffer[--keyPos]); - deleteMode = TRUE; - } - break; - - default: - USART_Send_Char(c); - if(keyPos < MAX_KEY) - keyBuffer[keyPos++] = c; - break; - } - } - } - return FALSE; -} - -// send a line of text -void sendLine(char *buffer, int len) -{ - SendTextFrame(setup_memory.params.setup_data.stnCall, 0, dest_call, 0, buffer, len, repeat); -} - -/* - * Print a received frame on the console - */ -void PrintFrame(IP400_FRAME *FrameBytes) -{ - char printBuf[250]; - char decCall[100]; - uint16_t port; - uint16_t dataLen = FrameBytes->length; - - // dump mode for header debugging - if(dumpMode) { - /* print the received data */ - USART_Print_string("RX - Data received: [ "); - - for(uint8_t i=0; isource, decCall, &port); - USART_Print_string("%s(%d)>", decCall, port); - - // dest call - if((FrameBytes->dest.callbytes.bytes[0] == BROADCAST_ADDR) && - (FrameBytes->dest.callbytes.bytes[1] == BROADCAST_ADDR)) { - USART_Print_string("BROADCAST(%d)", FrameBytes->dest.port); - } else { - callDecode(&FrameBytes->dest, decCall, &port); - USART_Print_string("%s(%d)", decCall, port); - } - - // flags - USART_Print_string("[%d:%04d]:", FrameBytes->flagfld.flags.hop_count, FrameBytes->seqNum); - - // now dump the data - memcpy(printBuf, FrameBytes->buf, dataLen); - printBuf[dataLen] = '\0'; - USART_Print_string("%s\r\n", printBuf); - -} diff --git a/Node Firmware/IP400/Src/dataq.c b/Node Firmware/IP400/Src/dataq.c deleted file mode 100644 index 7ff73c9..0000000 --- a/Node Firmware/IP400/Src/dataq.c +++ /dev/null @@ -1,66 +0,0 @@ -/*--------------------------------------------------------------------------- - Project: WL33_NUCLEO_UART - - File Name: dataq.c - - Author: MartinA - - Description: This module enques and deques an IP400 Frame type on a queue - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version, provided this copyright notice - is included. - - Copyright (c) Alberta Digital Radio Communications Society - All rights reserved. - - Revision History: - ----------------------------------------------------------------------------*/ -#include - -#include "types.h" -#include "frame.h" -#include "dataq.h" - -/* - * Enque a frame. The frame data buffer must have - * alredy been allocated - */ -BOOL enqueFrame(FRAME_QUEUE *que, IP400_FRAME *fr) -{ - FRAME_QUEUE *f; - if((f = malloc(sizeof(FRAME_QUEUE))) == NULL) - return FALSE; - - // set the frame buffer - f->frame = fr; - f->length = fr->length + sizeof(IP400_FRAME); - - insque((QUEUE_ELEM *)f, (QUEUE_ELEM *)que->q_back); - return TRUE; - -} - -/* - * Deqeue a frame - * Returns null if no frame is one the queue - * Does NOT dealloc data or frame or q - */ -IP400_FRAME *dequeFrame(FRAME_QUEUE *que) -{ - IP400_FRAME *ipFrame; - - if(que->q_back == que) - return NULL; - - FRAME_QUEUE *f = que->q_forw; - remque((struct qelem *)f); - - ipFrame = f->frame; - - free(f); - return ipFrame; -} diff --git a/Node Firmware/IP400/Src/frame.c b/Node Firmware/IP400/Src/frame.c deleted file mode 100644 index 642b315..0000000 --- a/Node Firmware/IP400/Src/frame.c +++ /dev/null @@ -1,647 +0,0 @@ -/*--------------------------------------------------------------------------- - Project: IP400 - - Module: Frame transmit and receive tasks - - File Name: frame.c - - Author: MartinA - - Creation Date: Jan 8, 2025 - - Description: Handle the transmission and reception of frames - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version, provided this copyright notice - is included. - - Copyright (c) Alberta Digital Radio Communications Society - All rights reserved. - - - Revision History: - ----------------------------------------------------------------------------*/ -#include -#include -#include -#include - -#include -#if _BOARD_TYPE==NUCLEO_BOARD -#include -#endif - -#include -#include -#include - -#include "frame.h" -#include "dataq.h" -#include "setup.h" -#include "tasks.h" -#include "led.h" -#include "spi.h" -#include "usart.h" - -// local defines -#define RX_TIMEOUT 2 // return to OS after 5 ms timeout - -// conditionals -#define __DUMP_BEACON 0 // dump a beacon frame to console using chat - -// locals -uint8_t txState; // transmitter state -uint8_t radioCmd; // current radio command -uint8_t prevCmd; // previous state -FRAME_QUEUE txQueue; // transmitter frame queue -uint32_t subgIRQStatus; // interrupt status -BOOL txDone; // transmitter is done -BOOL rxDone; // rx is done... -BOOL rxReady; // frame ready for further processing -FRAME_STATS Stats; // collected stats -uint32_t nextSeq; // next frame sequence number - -// from setup... -int16_t rxSquelch; // rx squlech -IP400_CALL stnCall; // station callsign - - -// internal fwd references -void QueueTxFrame(IP400_FRAME *txframe); // send a frame -void EnableRx(void); // enable the rx - -// processed frames -static IP400_FRAME rFrame; -static HOPTABLE rxHopTable[MAX_HOP_COUNT]; - -/* - * These are in dedicated buffer memory - */ -#if USE_BUFFER_RAM -static uint8_t rawTxFrame[MAX_FRAME_SIZE] __attribute__((section("BUFFERS"), aligned(4))); -static uint8_t rawRxFrame[MAX_FRAME_SIZE] __attribute__((section("BUFFERS"), aligned(4))); -#else -static uint8_t rawTxFrame[MAX_FRAME_SIZE]; -static uint8_t rawRxFrame[MAX_FRAME_SIZE]; -#endif - -// intialize the transmit task -void Frame_task_init(void) -{ - txState = TX_IDLE; - txQueue.q_forw = &txQueue; - txQueue.q_back = &txQueue; - - // init stats and counters - memset(&Stats, 0, sizeof(FRAME_STATS)); - nextSeq = 0xFFFFFFFF; - - // set Rx threshold - STN_PARAMS *params = GetStationParams(); - rxSquelch = params->radio_setup.rxSquelch; - HAL_MRSubG_SetRSSIThreshold(rxSquelch); - - // enable the interrupt - __HAL_MRSUBG_SET_RFSEQ_IRQ_ENABLE( - MR_SUBG_GLOB_DYNAMIC_RFSEQ_IRQ_ENABLE_RX_OK_E - | MR_SUBG_GLOB_DYNAMIC_RFSEQ_IRQ_ENABLE_TX_DONE_E - | MR_SUBG_GLOB_DYNAMIC_RFSEQ_IRQ_ENABLE_RX_TIMEOUT_E - | MR_SUBG_GLOB_DYNAMIC_RFSEQ_IRQ_ENABLE_RX_CRC_ERROR_E - ); - HAL_NVIC_EnableIRQ(MR_SUBG_IRQn); - - // enable the Rx - rxDone = FALSE; - rxReady = FALSE; - EnableRx(); -} - -/* - * return the stats - */ -FRAME_STATS *GetFrameStats(void) -{ - return &Stats; -} -// return the radio status -uint32_t GetRadioStatus(void) -{ - uint32_t radioStats = READ_REG(MR_SUBG_GLOB_STATUS->RFSEQ_STATUS_DETAIL); - return radioStats; -} -// get the FSM state -uint8_t GetFSMState(void) -{ - uint32_t fsmState = READ_REG(MR_SUBG_GLOB_STATUS->RADIO_FSM_INFO); - return (uint8_t)(fsmState & MR_SUBG_GLOB_STATUS_RADIO_FSM_INFO_RADIO_FSM_STATE_Msk); -} - -/* - * Send a text frame. Buf is not malloc'ed, can be static in ram - */ -BOOL SendTextFrame(char *srcCall, uint16_t srcPort, char *destCall, uint16_t dstPort, char *buf, uint16_t length, BOOL repeat) -{ - IP400_FRAME *txFrame; - - if((txFrame=malloc(sizeof(IP400_FRAME))) == NULL) - return FALSE; - - if((txFrame->buf=malloc(length + MAX_CALL_BUFFER)) == NULL) - return FALSE; - - txFrame->flagfld.allflags = 0; // start with all flags cleared - - // format the header - uint8_t offset = callEncode(srcCall, srcPort, txFrame, SRC_CALLSIGN, 0); - offset = callEncode(destCall, dstPort, txFrame, DEST_CALLSIGN, offset); - - // copy the payload in - uint8_t *f = (uint8_t *)txFrame->buf; - f += offset*sizeof(uint32_t); - memcpy(f, (const uint8_t *)buf, length); - - txFrame->length = length + offset; - txFrame->flagfld.flags.hop_count = 0; - txFrame->flagfld.flags.coding |= UTF8_TEXT_PACKET; - txFrame->flagfld.flags.repeat = repeat; - txFrame->flagfld.flags.hoptable = 0; - txFrame->hopTable = NULL; - txFrame->seqNum = nextSeq++; - - QueueTxFrame(txFrame); - - return TRUE; -} - -/* - * compose and send a beacon frame (ping frame with broadcast destination - */ -void SendBeaconFrame(char *srcCall, uint8_t *payload, int bcnlen) -{ - IP400_FRAME *bcnFrame; - - if((bcnFrame=malloc(sizeof(IP400_FRAME))) == NULL) - return; - - if((bcnFrame->buf=malloc(bcnlen + MAX_CALL_BUFFER)) == NULL) - return; - - bcnFrame->flagfld.allflags = 0; // start with all flags cleared - - // broadcast frame - uint8_t offset = callEncode(srcCall, 0, bcnFrame, SRC_CALLSIGN, 0); - callEncode("FFFF", 0, bcnFrame, DEST_CALLSIGN, 0); - - // since this is the first frame out of the gate, - // record the src callsign - stnCall.callbytes.encoded = bcnFrame->source.callbytes.encoded; - - // adjust starting data point, add payload - uint8_t *f = (uint8_t *)bcnFrame->buf; - f += offset*sizeof(uint32_t); - memcpy(f, payload, bcnlen); - - bcnFrame->length = bcnlen + offset; - bcnFrame->flagfld.flags.hop_count = 0; - bcnFrame->flagfld.flags.coding |= BEACON_PACKET; - bcnFrame->flagfld.flags.repeat = TRUE; - bcnFrame->flagfld.flags.hoptable = 0; - bcnFrame->hopTable = NULL; - bcnFrame->seqNum = nextSeq++; - - QueueTxFrame(bcnFrame); -} - -void SendSPIFrame(void *spi, uint8_t *payload, int len) -{ - IP400_FRAME *spiFrame; - - SPI_HEADER *spiHdr = (SPI_HEADER *)spi; - - // validate the frame type - switch(spiHdr->coding) { - - // beacon packets are not sent - case BEACON_PACKET: - return; - - // all others are - } - - if((spiFrame=malloc(sizeof(IP400_FRAME))) == NULL) - return; - - if((spiFrame->buf=malloc(len)) == NULL) { - free(spiFrame); - return; - } - - // hop table is in the first part of the payload buffer - uint16_t nHops = spiHdr->hopCount; - uint16_t htblSize = nHops * sizeof(HOPTABLE); - HOPTABLE *hTable; - if(nHops) { - if((hTable=malloc(htblSize)) == NULL) { - free(spiFrame->buf); - free(spiFrame); - return; - } - memcpy(hTable, payload, htblSize); - payload += htblSize; - len -= htblSize; - spiFrame->hopTable = (void *)hTable; - } - - // debug option to use a supplied call instead of the station callsign - // NB: use the station one in normal use, as a different call could cause havoc - uint8_t *srcCall; -#if DEBUG_RX_CALL - srcCall = spiHdr->fromCall; -#else - srcCall = stnCall.callbytes.bytes; -#endif - - memcpy(spiFrame->source.callbytes.bytes, srcCall, N_CALL); - spiFrame->source.port = (uint16_t)(spiHdr->fromPort[0]<<8) + (uint16_t)(spiHdr->fromPort[1]); - - memcpy(spiFrame->dest.callbytes.bytes, spiHdr->toCall, N_CALL); - spiFrame->dest.port = (uint16_t)(spiHdr->toPort[0]<<8) + (uint16_t)(spiHdr->toPort[1]); - - spiFrame->flagfld.allflags = (uint16_t)(spiHdr->hopCount) + (uint16_t)(spiHdr->coding<<4) + (uint16_t)(spiHdr->flags<<8); - if(spiFrame->flagfld.flags.hop_count) - spiFrame->flagfld.flags.hoptable = TRUE; - spiFrame->seqNum = nextSeq++; - - memcpy(spiFrame->buf, payload, len); - - QueueTxFrame(spiFrame); - -} - -// check to see if a frame came from me -// returns true if I originated the frame -BOOL FrameisMine(IP400_FRAME *frame) -{ - char decCall[30]; - uint16_t port;; - - // check if I am the originator call sign - callDecode(&frame->source, decCall, &port); - if(CompareToMyCall(decCall)) - return TRUE; - - // now check to see if I repeated this frame - if(frame->flagfld.flags.hoptable == 0) - return FALSE; - - // check my call is in the table - HOPTABLE *htable = (HOPTABLE *)frame->hopTable; - for(int i=0;iflagfld.flags.hop_count; i++) - if(htable[i].hopAddr.encoded == stnCall.callbytes.encoded) - return TRUE; - - return FALSE; -} - -/* - * Repeat a frame. Do not send it if we were the originator - * Inbound frame is static, not malloc'd - */ -void RepeatFrame(IP400_FRAME *frame) -{ - IP400_FRAME *rptFrame; - - // copy the frame - if((rptFrame=malloc(sizeof(IP400_FRAME))) == NULL) - return; - memcpy(rptFrame, frame, sizeof(IP400_FRAME)); - - // copy the data - rptFrame->length = frame->length; - if((rptFrame->buf=malloc(frame->length)) == NULL) { - free(rptFrame); - return; - } - memcpy(rptFrame->buf, frame->buf, frame->length); - - // allocate a new hop table - uint8_t hopCount= frame->flagfld.flags.hop_count; - if((rptFrame->hopTable=malloc(sizeof(HOPTABLE)*(hopCount+1))) == NULL) { - free(rptFrame->buf); - free(rptFrame); - } - - // copy the existing one and add me to the end of it - if(frame->flagfld.flags.hoptable) { - memcpy(rptFrame->hopTable, frame->hopTable, sizeof(HOPTABLE)*hopCount); - } - HOPTABLE *table = (HOPTABLE *)rptFrame->hopTable; - table[hopCount].hopAddr.encoded = stnCall.callbytes.encoded; - rptFrame->flagfld.flags.hoptable = TRUE; - rptFrame->flagfld.flags.hop_count = hopCount + 1; - - Stats.nRepeated++; - QueueTxFrame(rptFrame); -} - -/* - * queue a frame for transmission by the tx task - */ -void QueueTxFrame(IP400_FRAME *txframe) -{ - enqueFrame(&txQueue, txframe); -} - -/* - * Enable the receiver - */ -void EnableRx(void) -{ - __HAL_MRSUBG_SET_RX_MODE(RX_NORMAL); - __HAL_MRSUBG_SET_DATABUFFER_SIZE(MAX_FRAME_SIZE); - MR_SUBG_GLOB_STATIC->DATABUFFER0_PTR = (uint32_t)&rawRxFrame; - - // set the command - radioCmd = CMD_RX; - __HAL_MRSUBG_STROBE_CMD(radioCmd); - - SetLEDMode(BICOLOR_GREEN); -} - -/* - * main entry for tx task. Pick frames from the transmit queue - */ -void Frame_Txtask_exec(void) -{ - static IP400_FRAME *tFrame; - int frameLen = 0; - - switch(txState) { - - // idle: waiting for work - case TX_IDLE: - - tFrame = dequeFrame(&txQueue); - uint8_t *rawFrame = (uint8_t *)rawTxFrame; - - if(tFrame == NULL) - return; - - frameLen = tFrame->length; - - /* - * Build the raw frame bytes: see IP400_FRAME struct - */ - // Source call + port (6 bytes) - memcpy(rawFrame, (uint8_t *)&tFrame->source, IP_400_CALL_SIZE); - rawFrame += IP_400_CALL_SIZE; - // Dest call + port (6 bytes) - memcpy(rawFrame, (uint8_t *)&tFrame->dest, IP_400_CALL_SIZE); - rawFrame += IP_400_CALL_SIZE; - // flag byte (2 byte) - memcpy(rawFrame, (uint8_t *)&tFrame->flagfld, IP_400_FLAG_SIZE); - rawFrame += IP_400_FLAG_SIZE; - // frame sequence number (4 bytes) - memcpy(rawFrame, (uint32_t *)&tFrame->seqNum, sizeof(uint32_t)); - rawFrame += sizeof(uint32_t); - // frame length (2 bytes) - memcpy(rawFrame, (uint8_t *)&tFrame->length, sizeof(uint16_t)); - rawFrame += IP_400_LEN_SIZE; - - // add in the hop table - if(tFrame->flagfld.flags.hoptable) { - uint16_t hopLen = (uint16_t)(tFrame->flagfld.flags.hop_count) * sizeof(HOPTABLE); - memcpy(rawFrame, (uint8_t *)(tFrame->hopTable), hopLen); - rawFrame += hopLen; - free(tFrame->hopTable); - } - - // and now the data... - if((tFrame->buf != NULL) && (tFrame->length != 0)) - memcpy(rawFrame, tFrame->buf, tFrame->length); - - // free the allocations in the reverse order... - if(tFrame->buf != NULL) - free(tFrame->buf); - - free(tFrame); - - // ensure packet length is a multiple of 4 bytes - int pktLen = (rawFrame - rawTxFrame) + frameLen; - pktLen += (pktLen % 4); - - HAL_MRSubG_PktBasicSetPayloadLength(frameLen + pktLen); - - // abort the current rx operation - if(radioCmd == CMD_RX) { - __HAL_MRSUBG_STROBE_CMD(CMD_SABORT); - uint32_t reject=0, abortDone=0; - do { - subgIRQStatus = READ_REG(MR_SUBG_GLOB_STATUS->RFSEQ_IRQ_STATUS); - reject = subgIRQStatus & MR_SUBG_GLOB_STATUS_RFSEQ_IRQ_STATUS_COMMAND_REJECTED_F; - abortDone = subgIRQStatus & MR_SUBG_GLOB_STATUS_RFSEQ_IRQ_STATUS_SABORT_DONE_F; - } while ((abortDone == 0) && (reject == 0)); - if(abortDone) - __HAL_MRSUBG_CLEAR_RFSEQ_IRQ_FLAG(MR_SUBG_GLOB_STATUS_RFSEQ_IRQ_STATUS_SABORT_DONE_F); - if(reject) - __HAL_MRSUBG_CLEAR_RFSEQ_IRQ_FLAG(MR_SUBG_GLOB_STATUS_RFSEQ_IRQ_STATUS_COMMAND_REJECTED_F); - } - - __HAL_MRSUBG_SET_DATABUFFER0_POINTER((uint32_t)rawTxFrame); - __HAL_MRSUBG_SET_TX_MODE(TX_NORMAL); - - txDone = FALSE; - prevCmd = radioCmd; - radioCmd = CMD_TX; - __HAL_MRSUBG_STROBE_CMD(radioCmd); - - // set tx indication: bicolor off and Tx on - SetLEDMode(BICOLOR_OFF); - SetLEDMode(TX_LED_ON); - - txState = TX_SENDING; - break; - - // sending a frame - case TX_SENDING: - // still busy sending - if(!txDone) - return; - - txState = TX_DONE; - break; - - // done - case TX_DONE: - // restart the receiver, if needed - EnableRx(); - - SetLEDMode(TX_LED_OFF); - txState = TX_IDLE; - break; - } -} - -/* - * Main entry of the rx task - */ -void Frame_Rxtask_exec(void) -{ - // wait for completion.. - if(!rxDone) - return; - rxDone = FALSE; - - uint8_t *RxRaw = rawRxFrame; - uint8_t *cpyDest; - uint32_t rawLength = __HAL_MRSUBG_GET_DATABUFFER_SIZE(); - - /* - * Do the opposite of the transmitter... - */ - // Source call + port (6 bytes) - cpyDest = (uint8_t *)&rFrame.source.callbytes.bytes; - memcpy(cpyDest, RxRaw, IP_400_CALL_SIZE); - RxRaw += IP_400_CALL_SIZE; - - // Dest call + port (6 bytes) - cpyDest = (uint8_t *)&rFrame.dest.callbytes.bytes; - memcpy(cpyDest, RxRaw, IP_400_CALL_SIZE); - RxRaw += IP_400_CALL_SIZE; - - // flag byte (2 byte) - cpyDest = (uint8_t *)&rFrame.flagfld.allflags; - memcpy(cpyDest, RxRaw, IP_400_FLAG_SIZE); - RxRaw += IP_400_FLAG_SIZE; - - // frame sequence number (4 bytes) - cpyDest = (uint8_t *)&rFrame.seqNum; - memcpy(cpyDest, RxRaw, sizeof(uint32_t)); - RxRaw += sizeof(uint32_t); - - // frame length (2 bytes) - cpyDest = (uint8_t *)&rFrame.length; - memcpy(cpyDest, RxRaw, sizeof(uint16_t)); - RxRaw += IP_400_LEN_SIZE; - - // copy the hop table - uint8_t nHops = rFrame.flagfld.flags.hop_count; - if(nHops != 0) { - uint16_t hopLen = (uint16_t)nHops*sizeof(HOPTABLE); - memcpy(rxHopTable, RxRaw, hopLen); - RxRaw += hopLen; - rFrame.hopTable = rxHopTable; - } else { - rFrame.hopTable = NULL; - } - - rFrame.buf = RxRaw; - - // find a reason to reject a frame... - BOOL isMine = FrameisMine(&rFrame); - - // process the frame if it is not mine and unique - // do a sanity check on the length - if(!isMine && (rFrame.length < rawLength)) { - - IP400FrameType frameType = rFrame.flagfld.flags.coding; - - switch(frameType) { - - // process a beacon frame - case BEACON_PACKET: - if(Mesh_Accept_Frame((void *)&rFrame, Stats.lastRSSI)) { - Mesh_ProcessBeacon((void *)&rFrame, Stats.lastRSSI); -#if __DUMP_BEACON - EnqueChatFrame((void *)&rFrame); -#endif - EnqueSPIFrame(&rFrame); - Stats.nBeacons++; - } - break; - - // process a local chat frame - case UTF8_TEXT_PACKET: - if(Mesh_Accept_Frame((void *)&rFrame, Stats.lastRSSI)) { - EnqueChatFrame((void *)&rFrame); - Stats.framesOK++; - } - break; - - // frames passed on to the host - case COMPRESSED_AUDIO: // compressed audio packet - case COMPREESSD_VIDEO: // compressed video packet - case DATA_PACKET: // data packet - case IP_ENCAPSULATED: // IP encapsulated packet - case AX_25_PACKET: // AX.25 encapsulated packet - case RFC4733_DTMF: // DTMF packet - case DMR_FRAME: // DMR Frame - case DSTAR_FRAME: // Dstar Frame - case P25_FRAME: // TIA project 25 - case NXDN_FRAME: // NXDN - case M17_FRAME: // M17 - if(Mesh_Accept_Frame((void *)&rFrame, Stats.lastRSSI)) { - EnqueSPIFrame((void *)&rFrame); - Stats.framesOK++; - } - break; - - //reserved for future use - case LOCAL_COMMAND: // local command frame - break; - - default: - Stats.dropped++; - logger(LOG_ERROR, "Frame Received with unknown coding: %d\r\n", rFrame.flagfld.flags.coding); - break; - } - } - - // repeat the frame if the repeat flag is set and the hop count is not exhausted - if(!isMine) { - if(rFrame.flagfld.flags.repeat && (rFrame.flagfld.flags.hop_count < MAX_HOP_COUNT)) - RepeatFrame(&rFrame); - } - - if(isMine) - Stats.dropped++; - - // restart the receiver - EnableRx(); - -} -// frame interrupt callback -void HAL_MRSubG_IRQ_Callback(void) -{ - subgIRQStatus = READ_REG(MR_SUBG_GLOB_STATUS->RFSEQ_IRQ_STATUS); - - // Process transmitter interrupts - if(subgIRQStatus & MR_SUBG_GLOB_STATUS_RFSEQ_IRQ_STATUS_TX_DONE_F) { - __HAL_MRSUBG_CLEAR_RFSEQ_IRQ_FLAG(MR_SUBG_GLOB_STATUS_RFSEQ_IRQ_STATUS_TX_DONE_F); - Stats.TxFrameCnt++; - txDone = TRUE; - } - - // process receiver interrupts - if(subgIRQStatus & MR_SUBG_GLOB_STATUS_RFSEQ_IRQ_STATUS_RX_CRC_ERROR_F) { - Stats.CRCErrors++; - __HAL_MRSUBG_CLEAR_RFSEQ_IRQ_FLAG(MR_SUBG_GLOB_STATUS_RFSEQ_IRQ_STATUS_RX_CRC_ERROR_F); - } - - if (subgIRQStatus & MR_SUBG_GLOB_STATUS_RFSEQ_IRQ_STATUS_RX_TIMEOUT_F) { - Stats.TimeOuts++; - __HAL_MRSUBG_CLEAR_RFSEQ_IRQ_FLAG(MR_SUBG_GLOB_STATUS_RFSEQ_IRQ_STATUS_RX_TIMEOUT_F); - } - - if (subgIRQStatus & MR_SUBG_GLOB_STATUS_RFSEQ_IRQ_STATUS_RX_OK_F ) { - Stats.RxFrameCnt++; - __HAL_MRSUBG_CLEAR_RFSEQ_IRQ_FLAG(MR_SUBG_GLOB_STATUS_RFSEQ_IRQ_STATUS_RX_OK_F); - Stats.lastRSSI = READ_REG_FIELD(MR_SUBG_GLOB_STATUS->RX_INDICATOR, MR_SUBG_GLOB_STATUS_RX_INDICATOR_RSSI_LEVEL_ON_SYNC); - rxDone = TRUE; - } - - EnableRx(); -} diff --git a/Node Firmware/IP400/Src/insque.c b/Node Firmware/IP400/Src/insque.c deleted file mode 100644 index 814df9a..0000000 --- a/Node Firmware/IP400/Src/insque.c +++ /dev/null @@ -1,48 +0,0 @@ -/* insque(3C) routines - This file is in the public domain. */ - -/* - -@deftypefn Supplemental void insque (struct qelem *@var{elem}, @ - struct qelem *@var{pred}) -@deftypefnx Supplemental void remque (struct qelem *@var{elem}) - -Routines to manipulate queues built from doubly linked lists. The -@code{insque} routine inserts @var{elem} in the queue immediately -after @var{pred}. The @code{remque} routine removes @var{elem} from -its containing queue. These routines expect to be passed pointers to -structures which have as their first members a forward pointer and a -back pointer, like this prototype (although no prototype is provided): - -@example -struct qelem @{ - struct qelem *q_forw; - struct qelem *q_back; - char q_data[]; -@}; -@end example - -@end deftypefn - -*/ - -struct qelem { - struct qelem *q_forw; - struct qelem *q_back; -}; - - -void insque (struct qelem *elem, struct qelem *pred) -{ - elem -> q_forw = pred -> q_forw; - pred -> q_forw -> q_back = elem; - elem -> q_back = pred; - pred -> q_forw = elem; -} - - -void remque (struct qelem *elem) -{ - elem -> q_forw -> q_back = elem -> q_back; - elem -> q_back -> q_forw = elem -> q_forw; -} diff --git a/Node Firmware/IP400/Src/ip.c b/Node Firmware/IP400/Src/ip.c deleted file mode 100644 index 047d22f..0000000 --- a/Node Firmware/IP400/Src/ip.c +++ /dev/null @@ -1,88 +0,0 @@ -/*--------------------------------------------------------------------------- - Project: IP400 - - Module: Calculate IP address for a node - - File Name: ip.c - - Author: MartinA - - Creation Date: Mar 3, 2025 - - Description: Calculate the IP address from an IP400 Frame structure - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version, provided this copyright notice - is included. - - Copyright (c) Alberta Digital Radio Communications Society - All rights reserved. - - - Revision History: - ----------------------------------------------------------------------------*/ -#include "types.h" -#include "frame.h" -#include "ip.h" - -#define AF_INET 2 // internet address family -#define IP_10_NETWORK 10 // ip network address -#define IP_172_NETWORK 172 // alt network address -#define IP_172_START 16 // start of 172 range - -uint8_t netmask10[] = { - 0xFF, 0xFF, 0xFF, 0xF8 -}; - -uint8_t netmask172[] = { - 0xFF, 0x30, 0xFF, 0xFF -}; - -#define NETMASK 0xF8 // mask for last byte - -// return the IP address -void GetIP10Addr(IP400_CALL *fr, SOCKADDR_IN *ipaddr) -{ - ipaddr->sin_family = AF_INET; - - // first byte is fixed - ipaddr->sin_addr.S_un.S_un_b.s_b1 = IP_10_NETWORK & netmask10[0]; - - // next two are sums of callsign bytes - ipaddr->sin_addr.S_un.S_un_b.s_b2 = (fr->callbytes.bytes[0] ^ fr->callbytes.bytes[2]) & netmask10[1]; - ipaddr->sin_addr.S_un.S_un_b.s_b3 = (fr->callbytes.bytes[1] ^ fr->callbytes.bytes[3]) & netmask10[2]; - - // last digit from sum - int macsum = 0; - for (int i = 0; i < N_CALL; i++) - macsum += fr->callbytes.bytes[i]; - ipaddr->sin_addr.S_un.S_un_b.s_b4 = (uint8_t)(macsum & netmask10[3]); - - // port number from source - ipaddr->sin_port = fr->port; -} - -void GetIP172Addr(IP400_CALL *fr, SOCKADDR_IN *ipaddr) -{ - ipaddr->sin_family = AF_INET; - ipaddr->sin_addr.S_un.S_addr = 0; - - // first byte is fixed - ipaddr->sin_addr.S_un.S_un_b.s_b1 = IP_172_NETWORK & netmask172[0]; - - // next two are sums of callsign bytes - uint8_t b3 = (fr->callbytes.bytes[0] ^ fr->callbytes.bytes[2]) & netmask172[2]; - uint8_t b4 = (fr->callbytes.bytes[1] ^ fr->callbytes.bytes[3]) & netmask172[3]; - uint8_t b2 = (b3 + b4) & 0xf; - - // compose the address - ipaddr->sin_addr.S_un.S_un_b.s_b2 = b2 + IP_172_START; - ipaddr->sin_addr.S_un.S_un_b.s_b3 = b3; - ipaddr->sin_addr.S_un.S_un_b.s_b4 = b4; - - // port number from source - ipaddr->sin_port = fr->port; -} diff --git a/Node Firmware/IP400/Src/led.c b/Node Firmware/IP400/Src/led.c deleted file mode 100644 index 123cc4d..0000000 --- a/Node Firmware/IP400/Src/led.c +++ /dev/null @@ -1,289 +0,0 @@ -/*--------------------------------------------------------------------------- - Project: WL33_NUCLEO_UART - - File Name: led.c - - Author: MartinA - - Description: Handler for the LED's on nucleo or PI boards - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version, provided this copyright notice - is included. - - Copyright (c) Alberta Digital Radio Communications Society - All rights reserved. - - Revision History: - ----------------------------------------------------------------------------*/ -/* - * notes for different implementations. - * On the Pi there are two LED's a dedicated red and a bicolor red-green. - * TX: On when transmitting - * BICOLOR: Green solid when Rx is enabled - * Red solid when HAL error or NMI occurred - * - * On the NUCLEO board, there are three, red, green and blue - * BLUE (LD1) Duplicats the TX LED - * GREEN (LD2) Duplicates the GREEN bi-color function - * RED (LD3) Duplicates the RED Bi-color function - */ - -#include "types.h" -#include "led.h" -#include "usart.h" -#include - -// include LED defs from the right place -#if _BOARD_TYPE==NUCLEO_BOARD -#include -#else -#include -#endif - -// config -#define REVERSE_LEADS 1 // reverse Bi-color LED leads - -// local defines -#define FLASH_OFF 0 // LED flashing: off state -#define FLASH_ON 1 // LED flashing: on state - -// timer for 1/2 second when flashing -#define LED_TIMER 5 // timer -#define TEST_TIMER 20 // test timer - -// internals -void SetLEDMode(uint8_t mode); -void LED_SetOff(void); -void LED_SetRed(void); -void LED_SetGreen(void); -void LED_SetError(void); -void setTxLED(BOOL state); - -// vars -BOOL ToggleEnable; // led toggling enabled -uint8_t ledColour; // direction (colour) -uint8_t ledMode; // led mode -uint8_t ledState; // state on/off -uint8_t ledTimer; // timer for led test -uint8_t testNum; // test number -uint8_t testTimer; // test timer -uint8_t saveMode; // saved mode - -// -// Notes on timer setup for STM32H732 -// Prescaler value of 0 allows 64MHz clock to drive timer -// 1 reduces it to 32MHz -// Period divider of 6400 yeilds 100uSec time base -// -#define N_LED 5 -struct led_tests_t { - char *testName; - uint8_t testMode; -} LEDTests[N_LED] = { - {"Bicolor RED On", BICOLOR_RED }, - {"Bicolor GREEN On", BICOLOR_GREEN }, - {"Bicolor off", BICOLOR_OFF }, - {"Tx LED On", TX_LED_ON }, - {"Tx LED Off", TX_LED_OFF } -}; -// Initialization -void Led_Task_Init(void) -{ - ToggleEnable = FALSE; - ledColour = BICOLOR_RED; - ledState = BICOLOR_OFF; - ledTimer = LED_TIMER; - LED_SetOff(); - setTxLED(FALSE); - testTimer = 0; - testNum = 0; -} - -// We handle the flashing here... -// for the bicolor led, we can be solid red, solid green, -// or red-green flashing -void Led_Task_Exec(void) -{ - - if(ToggleEnable) { - - if(ledTimer != 0) { - ledTimer--; - return; - } - - ledTimer--; - - // blink LED if enabled - switch(ledMode) { - - case BICOLOR_RED_FLASH: - case BICOLOR_GREEN_FLASH: - ledState = (ledState == FLASH_ON) ? FLASH_OFF : FLASH_ON; - break; - - case BICOLOR_RED_GREEN: - ledState = (ledState == FLASH_ON) ? FLASH_OFF : FLASH_ON; - ledColour = (ledColour == BICOLOR_RED) ? BICOLOR_GREEN : BICOLOR_RED; - break; - } - - // update the LED state - if(ledState == FLASH_OFF) { - LED_SetOff(); - } else { - if(ledColour == BICOLOR_RED) - LED_SetRed(); - else - LED_SetGreen(); - } - } -} - -// led test mode -BOOL LedTest(void) -{ - - if(testTimer == 0) { - if(testNum == 0) - saveMode = ledMode; - if(testNum == N_LED) { - testNum = 0; - SetLEDMode(saveMode); - return TRUE; - } - - USART_Print_string("%s\r\n", LEDTests[testNum].testName); - SetLEDMode(LEDTests[testNum].testMode); - testTimer = TEST_TIMER; - testNum++; - return FALSE; - } - - testTimer--; - return FALSE; -} - -// API routines: set the LED mode -void SetLEDMode(uint8_t mode) -{ - ledMode = mode; - - switch(ledMode) { - - case BICOLOR_OFF: - LED_SetOff(); - ToggleEnable = FALSE; - ledState = FLASH_OFF; - break; - - case BICOLOR_RED: - LED_SetRed(); - ToggleEnable = FALSE; - ledColour = BICOLOR_RED; - ledState = FLASH_ON; - break; - - case BICOLOR_RED_FLASH: - LED_SetRed(); - ToggleEnable = TRUE; - ledColour = BICOLOR_RED; - ledState = FLASH_ON; - break; - - case BICOLOR_GREEN: - LED_SetGreen(); - ToggleEnable = FALSE; - ledColour = BICOLOR_GREEN; - ledState = FLASH_ON; - break; - - case BICOLOR_GREEN_FLASH: - LED_SetGreen(); - ToggleEnable = TRUE; - ledColour = BICOLOR_GREEN; - ledState = FLASH_ON; - break; - - case BICOLOR_RED_GREEN: - LED_SetRed(); - ToggleEnable = TRUE; - ledColour = BICOLOR_RED; - ledState = FLASH_ON; - break; - - case TX_LED_ON: - setTxLED(TRUE); - break; - - case TX_LED_OFF: - setTxLED(FALSE); - break; - - } -} - -// do the actual updates -void LED_SetOff(void) -{ -#if _BOARD_TYPE - BSP_LED_Off(LED_RED); - BSP_LED_Off(LED_GREEN); - BSP_LED_Off(LED_BLUE); -#else - HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET); - HAL_GPIO_WritePin(LED_A_GPIO_Port, LED_A_Pin, GPIO_PIN_RESET); - HAL_GPIO_WritePin(LED_K_GPIO_Port, LED_K_Pin, GPIO_PIN_RESET); -#endif -} - -void setTxLED(BOOL state) -{ -#if _BOARD_TYPE - if(state) - BSP_LED_On(LED_BLUE); - else - BSP_LED_Off(LED_BLUE); -#else - if(state) - HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET); - else - HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET); -#endif -} -// set fwd direction for bidir LED -#if REVERSE_LEADS -void LED_SetGreen(void) -#else -void LED_SetRed(void) -#endif -{ -#if _BOARD_TYPE - BSP_LED_On(LED_GREEN); -#else - HAL_GPIO_WritePin(LED_A_GPIO_Port, LED_A_Pin, GPIO_PIN_SET); - HAL_GPIO_WritePin(LED_K_GPIO_Port, LED_K_Pin, GPIO_PIN_RESET); -#endif -} - -// set bwd direction for bidir LED -#if REVERSE_LEADS -void LED_SetRed(void) -#else -void LED_SetGreen(void) -#endif -{ -#if _BOARD_TYPE - BSP_LED_On(LED_RED); -#else - HAL_GPIO_WritePin(LED_A_GPIO_Port, LED_A_Pin, GPIO_PIN_RESET); - HAL_GPIO_WritePin(LED_K_GPIO_Port, LED_K_Pin, GPIO_PIN_SET); -#endif -} - - - diff --git a/Node Firmware/IP400/Src/logger.c b/Node Firmware/IP400/Src/logger.c deleted file mode 100644 index ad6bbde..0000000 --- a/Node Firmware/IP400/Src/logger.c +++ /dev/null @@ -1,63 +0,0 @@ -/*--------------------------------------------------------------------------- - Project: MMDLTX - - Module: Logger - - File Name: audio.c - - Author: MartinA - - Revision: 1.00 - - Description: Log an error message. On the nucleo, we send it out to the - console UAR/T, on the E04, it goes out to the LPUART which - is connected to the VCOM port. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version, provided this copyright notice - is included. - - Copyright (c) Alberta Digital Radio Communications Society - All rights reserved. - - - Revision History: - ----------------------------------------------------------------------------*/ -#include -#include - -#include "usart.h" - -char errmsg[200]; - -// need to figure out how to talk to UART on board... -void logger(int severity, char *format, ...) -{ - - // process the arg list - va_list argptr; - va_start(argptr, format); - vsprintf(errmsg,format, argptr); - va_end(argptr); - - switch(severity) { - - case LOG_NOTICE: - USART_Print_string("Notice: %s\r\n", errmsg); - break; - - case LOG_ERROR: - USART_Print_string("Notice: %s\r\n", errmsg); - break; - - case LOG_SEVERE: - USART_Print_string("Notice: %s\r\n", errmsg); - break; - } - -} - - diff --git a/Node Firmware/IP400/Src/menu.c b/Node Firmware/IP400/Src/menu.c deleted file mode 100644 index 52026c9..0000000 --- a/Node Firmware/IP400/Src/menu.c +++ /dev/null @@ -1,839 +0,0 @@ -/*--------------------------------------------------------------------------- - Project: WL33_NUCLEO_UART - - File Name: menu.c - - Author: MartinA - - Description: Menu handler - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version, provided this copyright notice - is included. - - Copyright (c) Alberta Digital Radio Communications Society - All rights reserved. - - Revision History: - ----------------------------------------------------------------------------*/ -#include -#include - -#include "types.h" -#include "usart.h" -#include "streambuffer.h" -#include "setup.h" -#include "tasks.h" -#include "utils.h" -#include "tod.h" -#include "config.h" - -// menu state -uint8_t menuState; // menu state -enum { - MENU_OFF, // off - MENU_SHOWING, // showing the menu - MENU_SELECTING, // getting a selection - MENU_SELECTED, // item has been selected - MENU_PAUSED // pausing a while... -}; - -// key entry state -uint8_t entryState; // state of keyboard entry -enum { - NO_ENTRY=0, // no entry yet.. - ENTERING, // entering a value - VALIDATING, // validating the entry -}; - -// menu items -#define NO_ITEM -1 // no item selected -#define __MEM_DEBUG 1 // memory debug - -// DEC VT100 Escape sequences -#define ASCII_TAB 0x09 -#define ASCII_RET 0x0D -#define ASCII_ESC 0x1B // escape char -#define DEC_LEADIN '[' // lead-in character -#define MAX_SEQ 6 // max sequence length - -// control codes.. -enum { - CONTROL_CLEAR=0, // clear screen - CONTROL_HOME, // cursor home - CONTROL_DOUBLE_TOP, // double wide and height (top) - CONTROL_DOUBLE_BOTTOM, // double wide and height (bottom) - CONTROL_SINGLE, // single wide and height - NCONTROL_CODES // number of conrol codes -}; - -struct controlCodes_t { - char sequence[MAX_SEQ]; // sequence - uint8_t len; // length -} controlCodes[NCONTROL_CODES] = { - {{ASCII_ESC, DEC_LEADIN, '2', 'J'}, 4}, - {{ASCII_ESC, DEC_LEADIN, 'H'}, 3}, - {{ASCII_ESC, '#', '3'}, 3}, - {{ASCII_ESC, '#', '4'}, 3}, - {{ASCII_ESC, '#', '5'}, 3}, -}; - -// strings common to all menu types -char *whatItem = "??Try again->"; -char *menuSpacer = "\r\n\n"; -char *pauseString = "Hit enter to continue->"; -char *selectItem = "Select an item->"; - -static char menu[100]; // Buffer for file items -int sel_item = 0; // selected item -uint8_t activeMenu; // active menu - -// forward refs in this module -void printMenu(void); // print the menu -int getMenuItem(void); // get a menu item -void sendControlCode(uint8_t code); -BOOL pause(void); -void Print_Frame_stats(FRAME_STATS *stats); -void Print_Memory_Stats(void); -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 { - MAIN_MENU=0, // main menu - RADIO_MENU, // radio params menu - STATION_MENU, // Station params menu - N_MENUS // number of menus -}; - -// menu return functions -enum { - RET_MORE=0, // more to do - RET_DONE, // done - RET_PAUSE // pause before leaving -}; - -/* - * The first part of this code contains the menus and processing routines - * handle the various menu options - * return TRUE if done, else FALSE - */ -uint8_t printAllSetup(void) -{ - TIMEOFDAY tod; - getTOD(&tod); - - USART_Print_string("Current firmware is at %d.%d\r\n",def_params.params.FirmwareVerMajor, - def_params.params.FirmwareVerMinor); - USART_Print_string("System time is %02d:%02d:%02d\r\n\n", tod.Hours, tod.Minutes, tod.Seconds); - - printStationSetup(); - printRadioSetup(); - return RET_PAUSE; -} -// -uint8_t printStnSetup(void) -{ - printStationSetup(); - return RET_PAUSE; -} -// -uint8_t printRadSetup(void) -{ - printRadioSetup(); - return RET_PAUSE; -} -// list mesh status -uint8_t listMesh(void) -{ - Mesh_ListStatus(); - return RET_PAUSE; -} - -// enter chat mode -uint8_t chatMode(void) -{ - if(Chat_Task_exec()) - return RET_PAUSE; - return RET_MORE; -} - -// dump the rx stats -uint8_t showstats(void) -{ - Print_Frame_stats(GetFrameStats()); - Print_Radio_errors(GetRadioStatus()); - Print_FSM_state(GetFSMState()); - return RET_PAUSE; -} - -// set the radio entry mode -uint8_t setRadio(void) -{ - activeMenu = RADIO_MENU; - menuState = MENU_OFF; - return RET_DONE; -} - -// set the station entry mode -uint8_t setStation(void) -{ - activeMenu = STATION_MENU; - menuState = MENU_OFF; - return RET_DONE; -} -// enter chat mode -uint8_t ledTest(void) -{ - if(LedTest()) - return RET_PAUSE; - return RET_MORE; -} -// write the flash memory -uint8_t writeSetup(void) -{ - if(!UpdateSetup()) { - USART_Print_string("Error in writing flash: setup may be corrupt\r\n"); - } else { - USART_Print_string("Flash written successfully\r\n"); - } - menuState = MENU_OFF; - return RET_PAUSE; -} -// exit the current menu -uint8_t exitMenu(void) -{ - activeMenu = MAIN_MENU; - menuState = MENU_OFF; - return RET_DONE; -} -// set a parameter value -uint8_t setParam(void) -{ - return(getEntry(activeMenu, sel_item)); -} -/* - * These are conditional - */ -#if __ENABLE_GPS -uint8_t gpsEcho(void) -{ - GPSEcho(); - return(getKeyEntry()); -} -#endif -#if __MEM_DEBUG -// memory statistics -uint8_t memStats(void) -{ - Print_Memory_Stats(); - return RET_PAUSE; -} -#endif - - -/* - * main menu definition - * 1) define the number of line items - * 2) create menuitms struct - * 3) add to menucontents struct - */ -struct menuItems_t { - char *menuLine; // text of menu line - char selChar; // character to select it - uint8_t (*func)(void); // processing function -}; - -// main menu -#if __ENABLE_GPS -#define N_GPS 1 // additional menu item for GPS -#else -#define N_GPS 0 -#endif - -#if __MEM_DEBUG -#define N_MEM 1 // additional menu item for memory -#else -#define N_MEM 0 -#endif - -#define N_MAINMENU (11+N_GPS+N_MEM) // additional menu item for GPS - -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 }, -#if __MEM_DEBUG - { "Memory Status\r\n", 'M', memStats }, -#endif - { "Set Radio Parameters\r\n", 'R', setRadio }, - { "Set Station Parameters\r\n", 'S', setStation }, - { "Set clock (HH:MM)\r\n\n", 'T', setParam }, - { "Write Setup Values\r\n", 'W', writeSetup }, - { "Exit\r\n\n", 'X', exitMenu } -}; - -// radio menu -#define N_RADIOMENU 8 -struct menuItems_t radioMenu[N_RADIOMENU] = { - { "RF Frequency\r\n", 'A', setParam }, - { "Data Rate\r\n", 'B', setParam }, - { "Peak Deviation\r\n", 'C', setParam }, - { "Channel Filter BW\r\n", 'D', setParam }, - { "Output Power (dBm)\r\n", 'E', setParam }, - { "Rx Squelch (dBm)\r\n\n", 'F', setParam }, - { "List Settings\r\n", 'L', printRadSetup }, - { "Return to main menu\r\n\n", 'X', exitMenu } -}; - -// these need to correspond to the items above - -// station menu -#define N_STATIONMENU 8 -struct menuItems_t stationMenu[N_STATIONMENU] = { - { "Callsign\r\n", 'A', setParam }, - { "Latitude\r\n", 'B', setParam }, - { "Longitude\r\n", 'C', setParam }, - { "Grid Square\r\n", 'D', setParam }, - { "Repeat Default\r\n", 'E', setParam }, - { "Beacon Interval\r\n\n", 'F', setParam }, - { "List Settings\r\n", 'L', printStnSetup }, - { "Return to main menu\r\n\n", 'X', exitMenu } -}; - -// menu contents -struct menuContents_t { - char *title; // title of the menu - int nMenuLines; // number of lines - struct menuItems_t *menus; // menu items -} menuContents[N_MENUS] = { -#if _BOARD_TYPE==NUCLEO_BOARD - { " IP400 Nucleo Main menu\r\n", N_MAINMENU, mainMenu }, -#else - { " IP400 Pi menu\r\n", N_MAINMENU, mainMenu }, -#endif - { " Radio setup menu\r\n", N_RADIOMENU, radioMenu }, - { " Station Setup menu\r\n", N_STATIONMENU, stationMenu } -}; - -// menu (main) task -void Menu_Task_Init(void) -{ - // start off with the menu showing - activeMenu = MAIN_MENU; - menuState = MENU_SHOWING; - entryState = NO_ENTRY; -} - -// send a control code -void sendControlCode(uint8_t code) -{ - USART_Send_String(controlCodes[code].sequence, controlCodes[code].len); -} - -// send a control code -void sendTextString(char *string) -{ - strcpy(menu, string); - USART_Send_String(menu, strlen(string)); -} - -// process our time slot -void Menu_Task_Exec(void) -{ - int nBytesinBuff = 0; - char c; - struct menuItems_t *m; - - switch(menuState) { - - // if there is a return in the console buffer, - // bring up the menu - case MENU_OFF: - if((nBytesinBuff=databuffer_bytesInBuffer()) == 0) - return; - for(int i=0;ifunc)()) { - - case RET_MORE: - break; - - case RET_PAUSE: - sendTextString(pauseString); - menuState = MENU_PAUSED; - break; - - case RET_DONE: - menuState = MENU_SHOWING; - break; - } - break; - - case MENU_PAUSED: - if(pause()) - menuState = MENU_SHOWING; - break; - - } -} - -// print the main menu -void printMenu(void) -{ - struct menuItems_t *m; - - // title - sendControlCode(CONTROL_CLEAR); - sendControlCode(CONTROL_HOME); - -#if _BOARD_TYPE==NUCLEO_BOARD - // only use double wide mode with Nucleo - sendControlCode(CONTROL_DOUBLE_TOP); - sendTextString(menuContents[activeMenu].title); - sendControlCode(CONTROL_DOUBLE_BOTTOM); - sendTextString(menuContents[activeMenu].title); - sendControlCode(CONTROL_SINGLE); - sendTextString(menuSpacer); -#else - sendTextString(menuContents[activeMenu].title); - sendTextString(menuSpacer); -#endif - - // lines - int nMenuLines = menuContents[activeMenu].nMenuLines; - for(int i=0;iselChar; - strcpy(&menu[1], ") "); - strcat(menu, m->menuLine); - USART_Send_String(menu, strlen(menu)); - } - - // selection - sendTextString(selectItem); -} - -// get a menu item and dispatch the correct processing routine -int getMenuItem(void) -{ - int nBytesinBuff =0; - struct menuItems_t *m; - char c; - - if((nBytesinBuff=databuffer_bytesInBuffer()) == 0) - return NO_ITEM; - - for(int i=0;iselChar == c) { - sendTextString(menuSpacer); - return j; - } - } - } - } - sendTextString(whatItem); - return NO_ITEM; -} - -BOOL pause(void) -{ - if(databuffer_bytesInBuffer() == 0) - return FALSE; - - if(databuffer_get(0) == ASCII_RET) - return TRUE; - - return FALSE; - -} - -/* - * This part pertains to getting an entry and validating it.. - */ - -// keys in entry mode -#define KEY_EOL 0x0D // carriage return -#define KEY_ESC 0x1B // escape key -#define KEY_DEL 0x7F // delete key -#define KEY_BKSP 0x08 // backspace key - -#define MAX_ENTRY 40 // max entry chars - -BOOL delMode = FALSE; -int pos = 0; -char keyBuffer[MAX_ENTRY]; - -// forward refs -uint8_t validateEntry(int activeMenu, int item, char *keyBuffer); - -/* - * Get a key entry: basically stolen from chat.c - */ -uint8_t getKeyEntry(void) -{ - - char c; - int nBytesinBuff; - - if((nBytesinBuff=databuffer_bytesInBuffer()) == 0) - return RET_MORE; - - for(int i=0;i 0) { - USART_Print_string("%c", keyBuffer[--pos]); - } else { - USART_Print_string("\\\r\n"); - delMode = FALSE; - } - } - continue; - } else { - // processing a key - - switch (c) { - - // EOL key: sent the packet - case KEY_EOL: - USART_Print_string("\r\n"); - keyBuffer[pos++] = '\0'; - return RET_DONE; - break; - - // escape key: abort the entry - case KEY_ESC: - return RET_PAUSE; - break; - - case KEY_DEL: - case KEY_BKSP: - USART_Print_string("\\%c", keyBuffer[--pos]); - delMode = TRUE; - break; - - default: - USART_Send_Char(c); - if(pos < MAX_ENTRY) - keyBuffer[pos++] = c; - break; - } - } - } - return RET_MORE; -} - -/* - * Get an entry and validate it - */ -uint8_t getEntry(int activeMenu, int item) -{ - struct menuItems_t *m; - - switch(entryState) { - - case NO_ENTRY: - delMode = FALSE; - pos = 0; - entryState = ENTERING; - m=menuContents[activeMenu].menus; - m += item; - USART_Print_string("%s->", m->menuLine); - return RET_MORE; - - case ENTERING: - int keyStat = getKeyEntry(); - if(keyStat == RET_DONE) { - entryState = VALIDATING; - return RET_MORE; - } - return keyStat; - - case VALIDATING: - entryState = NO_ENTRY; - return validateEntry(activeMenu, item, keyBuffer); - } - - return RET_MORE; -} - -// data types we are updating -enum { - uint8_type, // uint8 field - int16_type, // int16 field - uint32_type, // uint32 field - float_type, // floating point - char_type, // character type - field_type // field type -}; - -// struct to hold validation values -typedef struct field_validator_t { - int MinVal; // minimum value - int MaxVal; // maximum value - void *setupVal; // pointer to setup value - int type; // type of entry - uint32_t scalar; // scalar to convert to decimal -} FIELD_VALIDATOR; - -// validators for radio mmenu -FIELD_VALIDATOR radioValidators[] = { - { MIN_FREQ, 450000000, &setup_memory.params.radio_setup.lFrequencyBase, uint32_type, 1000000 }, - { 9600, 600000, &setup_memory.params.radio_setup.lDatarate, uint32_type, 1000 }, - { 12500, 150000, &setup_memory.params.radio_setup.lFreqDev, uint32_type, 1000 }, - { 2600, 1600000, &setup_memory.params.radio_setup.lBandwidth, uint32_type, 1000 }, - { 0, 20, &setup_memory.params.radio_setup.outputPower, uint8_type, 1 }, - { -115, 0, &setup_memory.params.radio_setup.rxSquelch, int16_type, 1 }, -}; - -FIELD_VALIDATOR stationValidators[] = { - { 4, 6, &setup_memory.params.setup_data.stnCall, char_type, 0 }, - { 2, 14, &setup_memory.params.setup_data.latitude, char_type, 0 }, - { 2, 14, &setup_memory.params.setup_data.longitude, char_type, 0 }, - { 6, 6, &setup_memory.params.setup_data.gridSq, char_type, 0 }, - { 0, 0x8, &setup_memory.params.setup_data.flags, field_type, 0 }, - { 1, 100, &setup_memory.params.setup_data.beaconInt, int16_type, 0 } -}; - -uint8_t validateEntry(int activeMenu, int item, char *keyBuffer) -{ - - int newValue, min, max; - - //NB: the cases here must jive with the menu items - switch(activeMenu) { - - case MAIN_MENU: // the only menu item here is the clock - setTOD(keyBuffer); - break; - - case RADIO_MENU: - // convert a floating point entry to the required decimal - if(isfloat(keyBuffer)) - newValue = (int)(ascii2double(keyBuffer)*radioValidators[item].scalar); - else newValue = ascii2Dec(keyBuffer); - max = radioValidators[item].MaxVal; - min = radioValidators[item].MinVal; - if((newValuemax)) { - USART_Print_string("Must be in the range of %d to %d\r\n", min, max); - return RET_PAUSE; - } - switch(radioValidators[item].type){ - - case uint8_type: - uint8_t *v8 = (uint8_t *)radioValidators[item].setupVal; - *v8 = (uint8_t)newValue; - break; - - case int16_type: - int16_t *v16 = (int16_t *)radioValidators[item].setupVal; - *v16 = (int16_t)newValue; - break; - - case uint32_type: - uint32_t *v32 = (uint32_t *)radioValidators[item].setupVal; - *v32 = (uint32_t)newValue; - break; - } - - break; - - case STATION_MENU: - switch(stationValidators[item].type){ - - case int16_type: - newValue = ascii2Dec(keyBuffer); - max = stationValidators[item].MaxVal; - min = stationValidators[item].MinVal; - if((newValuemax)) { - USART_Print_string("Must be in the range of %d to %d\r\n", min, max); - return RET_PAUSE; - } - uint16_t *v8 = (uint16_t *)stationValidators[item].setupVal; - *v8 = (uint16_t)newValue; - break; - - case char_type: - size_t len = strlen(keyBuffer); - max = stationValidators[item].MaxVal; - min = stationValidators[item].MinVal; - if((lenmax)) { - USART_Print_string("String must be %d to %d in length\r\n", min, max); - return RET_PAUSE; - } - strcpy((char *)stationValidators[item].setupVal, keyBuffer); - break; - - case field_type: - uint8_t val = keyBuffer[0] == 'T' ? 1 : 0; - uint8_t *f8= (uint8_t *)stationValidators[item].setupVal; - if(val) - *f8 |= (uint8_t)stationValidators[item].MinVal; - else - *f8 &= (uint8_t)stationValidators[item].MinVal; - break; - } - break; - - } - - // falls to here when done... - return RET_DONE; -} - - -/* - * Print the frame stats - */ -void Print_Frame_stats(FRAME_STATS *stats) -{ - USART_Print_string("Frame Statistics\r\n\n"); - - USART_Print_string("Transmitted frames->%d\r\n", stats->TxFrameCnt); - USART_Print_string("CRC Errors->%d\r\n", stats->CRCErrors); - USART_Print_string("Rx Timeouts->%d\r\n", stats->TimeOuts); - USART_Print_string("Frames with good CRC->%d\r\n", stats->RxFrameCnt); - USART_Print_string("Beacon frames->%d\r\n", stats->nBeacons); - USART_Print_string("Repeated frames->%d\r\n", stats->nRepeated); - - USART_Print_string("Processed Frames->%d\r\n", stats->RxFrameCnt); - USART_Print_string("Dropped frames->%d\r\n", stats->dropped); - USART_Print_string("Duplicate frames->%d\r\n", stats->duplicates); - USART_Print_string("Repeated frames->%d\r\n", stats->duplicates); - - -} -/* - * Print the radio error stats - */ -struct radio_errs_t { - uint32_t mask; - char *errmsg; -} radio_errs[N_RADIO_ERRS] = { - { SEQ_COMPLETE_ERR, "Sequencer Error" }, - { SEQ_ACT_TIMEOUT, "Sequencer action timeout" }, - { PLL_CALAMP_ERR, "VCO Amplitude calibration error" }, - { PLL_CALFREQ_ERR, "VCO Frequency calibration error" }, - { PLL_UNLOCK_ERR, "PLL Unlocked" }, - { PLL_LOCK_FAIL, "PLL Lock failure" }, - { DBM_FIFO_ERR, "Data buffer FIFO error" } -}; -// -void Print_Radio_errors(uint32_t errs) -{ - if(errs == 0){ - USART_Print_string("No radio errors\r\n"); - return; - } - for(int i=0;i FSM_N_FSM_STATES) { - USART_Print_string("\r\n?Unknown FSM state\r\n"); - return; - } - USART_Print_string("\r\nRadio FSM State: %d: %s\r\n", state, fsm_states[state]); -} - -#if __MEM_DEBUG -/* - * dump memory statistics - * uses the mallinfo structure - */ -void Print_Memory_Stats(void) -{ - - struct mallinfo memStats; - - memStats = mallinfo(); - - USART_Print_string("Memory Statistics\r\n\n"); - - USART_Print_string("Total non-mapped bytes (arena)->%ld\r\n", memStats.arena); - USART_Print_string("Chunks not in use->%ld\r\n", memStats.ordblks); - USART_Print_string("Free fast bin blocks->%ld\r\n", memStats.smblks); - USART_Print_string("Mapped Regions->%ld\r\n", memStats.hblks); - USART_Print_string("Bytes in mapped regions->%ld\r\n\n", memStats.hblkhd); - - USART_Print_string("Free bytes in fast bins->%ld\r\n", memStats.fsmblks); - USART_Print_string("Total Allocated Space->%ld\r\n", memStats.uordblks); - USART_Print_string("Total Space not in use->%ld\r\n", memStats.fordblks); - USART_Print_string("Topmost releasable block->%ld\r\n", memStats.keepcost); - -} -#endif diff --git a/Node Firmware/IP400/Src/mesh.c b/Node Firmware/IP400/Src/mesh.c deleted file mode 100644 index f5e208f..0000000 --- a/Node Firmware/IP400/Src/mesh.c +++ /dev/null @@ -1,303 +0,0 @@ -/*--------------------------------------------------------------------------- - Project: WL33_NUCLEO_UART - - File Name: mesh.c - - Author: MartinA - - Description: This code builds and lists the mesh status - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version, provided this copyright notice - is included. - - Copyright (c) Alberta Digital Radio Communications Society - All rights reserved. - - Revision History: - ----------------------------------------------------------------------------*/ -#include -#include -#include -#include -#include -#include -#include - -#include "tasks.h" -#include "frame.h" -#include "usart.h" -#include "dataq.h" -#include "setup.h" -#include "tod.h" -#include "ip.h" - -#define EXPIRY_TIME 100 // seconds since last heard -#define RSSI_SCALAR 161 // 95-Gain(rx), appros 65 - -char *FSKSpeeds[] = { - "FSK 1200", - "FSK 9600", - "FSK_56K", - "FSK_100K", - "FSK_200K", - "FSK_300K", - "FSK_400K", - "FSK_600K" -}; - -// table entry status -typedef enum { - MESHTBL_UNUSED=0, // unused entry - MESHTBL_VALID, // valid entry - MESHTBL_LOST // lost in space -} MeshTableStatus; - -// mesh entry struct -typedef struct mesh_entry_t { - MeshTableStatus status; // status - IP400_CALL encCall; // encoded callsign - uint32_t nextSeq; // next sequence number - int16_t lastRssi; // signal strength - uint8_t txPower; // transmit power - SETUP_FLAGS capabilities; // capabilities - TIMEOFDAY lastHeard; // last heard - uint8_t hopCount; // hop count - uint32_t ipAddress; // IP address -} MESH_ENTRY; - -// mesh table definitions -#define MAX_MESH_MEMORY 2048 // max amount of mesh memory used -#define MAX_MESH_ENTRIES (MAX_MESH_MEMORY/sizeof(MESH_ENTRY)) -#define ENTRY_NOTFOUND -1 // not found in the table - -// table size is limited to by memory defintion -static MESH_ENTRY MeshTable[MAX_MESH_ENTRIES] __attribute__((section("MESHTABLE"))); -int nMeshEntries = 0; - -BEACON_HEADER mesh_bcn_hdr; // beacon header -uint32_t seqNum; // sequence number received - -// forward refs in this module -int findCall(IP400_CALL *call); -void AddMeshEntry(IP400_FRAME *frameData, int16_t rssi, BOOL isBeacon); - -// task initialization -void Mesh_Task_Init(void) -{ - for(int i=0;isource)) != ENTRY_NOTFOUND) { - - // if it is repeated frame with a higher hop count, ignore it - if(MeshTable[entryNum].hopCount < frameData->flagfld.flags.hop_count) - return; - - MeshTable[entryNum].lastHeard.Hours = current.Hours; - MeshTable[entryNum].lastHeard.Minutes = current.Minutes; - MeshTable[entryNum].lastHeard.Seconds = current.Seconds; - MeshTable[entryNum].lastRssi = actRSSI; - MeshTable[entryNum].nextSeq = frameData->seqNum == 0xFFFFFFFF ? 0 : ++frameData->seqNum; - - //ugly, but necessary - memset(mesh_bcn_hdr.hdrBytes, 0, sizeof(BEACON_HEADER)); - uint8_t *p = (uint8_t *)frameData->buf; - mesh_bcn_hdr.hdrBytes[0] = *p++; - mesh_bcn_hdr.hdrBytes[4] = *p; - - MeshTable[entryNum].capabilities = mesh_bcn_hdr.setup.flags; - MeshTable[entryNum].txPower = mesh_bcn_hdr.setup.txPower; - - // all done - return; - } - - // beacon from a new station - AddMeshEntry(frameData, actRSSI, TRUE); -} - -/* - * add a new station to the mesh table - */ -void AddMeshEntry(IP400_FRAME *frameData, int16_t actRSSI, BOOL isBeacon) -{ - // check for room first - if(nMeshEntries >= MAX_MESH_ENTRIES) - return; - - MESH_ENTRY newEntry; - - TIMEOFDAY current; - getTOD(¤t); - SOCKADDR_IN ipAddr; - - // grab call and capabilities - newEntry.encCall = frameData->source; - newEntry.lastHeard.Hours = current.Hours; - newEntry.lastHeard.Minutes = current.Minutes; - newEntry.lastHeard.Seconds = current.Seconds; - newEntry.nextSeq = frameData->seqNum == 0xFFFFFFFF ? 0 : ++frameData->seqNum; - newEntry.lastRssi = actRSSI; - newEntry.txPower = 0; - newEntry.hopCount = frameData->flagfld.flags.hop_count; - - GetIPAddr(&newEntry.encCall, &ipAddr); - newEntry.ipAddress = ipAddr.sin_addr.S_un.S_addr; - - if(isBeacon) { - memcpy(mesh_bcn_hdr.hdrBytes, (struct beacon_hdr_t *)frameData->buf, sizeof(BEACON_HEADER)); - newEntry.capabilities = mesh_bcn_hdr.setup.flags; - newEntry.txPower = mesh_bcn_hdr.setup.txPower; - } else { - memset(&newEntry.capabilities, 0, sizeof(SETUP_FLAGS)); - } - - // insert this at the end of the queue - newEntry.status = MESHTBL_VALID; - memcpy(&MeshTable[nMeshEntries++], &newEntry, sizeof(MESH_ENTRY)); -} - -/* - * reject a duplicate frame that may have been repeated - * TRUE: keep it, FALSE: reject it - */ -BOOL Check_Sender_Address(void *rxFrame, uint32_t rssi) -{ - IP400_FRAME *frameData = (IP400_FRAME *)rxFrame; - int entryNum; - - if((entryNum = findCall(&frameData->source)) != ENTRY_NOTFOUND) { - // rebooted - if(frameData->seqNum == 0xFFFFFFFF) - MeshTable[entryNum].nextSeq = 0; - // reject if the seq is lower - if(frameData->seqNum < MeshTable[entryNum].nextSeq) - return FALSE; - MeshTable[entryNum].nextSeq = frameData->seqNum + 1; - return TRUE; - } - - // sender is unknown: add him for now.. - int16_t actRSSI = rssi/2 - RSSI_SCALAR; - AddMeshEntry(frameData, actRSSI, FALSE); - return TRUE; -} - -/* - * Check if the frame can be accepted. - * Accept a broadcast or my address if: - * -the sender is not in the mesh table - * -the sequence is not out of order - * Else reject it - */ -BOOL Mesh_Accept_Frame(void *rxFrame, uint32_t rssi) -{ - IP400_FRAME *frameData = (IP400_FRAME *)rxFrame; - char decCall[30]; - uint16_t port;; - - // frame is sent a broadcast address - if((frameData->dest.callbytes.bytes[0] == BROADCAST_ADDR) - && (frameData->dest.callbytes.bytes[0] == BROADCAST_ADDR)) - return Check_Sender_Address(rxFrame, rssi); - - callDecode(&frameData->dest, decCall, &port); - if(CompareToMyCall(decCall)) - return Check_Sender_Address(rxFrame, rssi); - - // not for me - return FALSE; -} - -// find a callsign in the list -int findCall(IP400_CALL *call) -{ - for(int i=0;icallbytes.encoded) - return i; - } - return ENTRY_NOTFOUND; -} - -char capabilties[50]; -// return the capabilities of a node -char *GetCapabilities(SETUP_FLAGS cap) -{ - mesh_bcn_hdr.setup.flags = cap; - - if(mesh_bcn_hdr.hdrBytes[0] == 0) { - strcpy(capabilties, "Unknown"); - } - - // modes - if(cap.fsk) { - sprintf(capabilties, "%s", FSKSpeeds[cap.rate]); - } - else if(cap.ofdm) { - strcat(capabilties, " OFDM"); - } - else if(cap.aredn) { - strcat(capabilties, "AREDN"); - } - - // repeat mode is on.. - if(cap.repeat) { - strcat(capabilties, " RPT"); - } - - return capabilties; -} - -// list the mesh status: walk the mesh entries -void Mesh_ListStatus(void) -{ - USART_Print_string("Stations Heard: %d\r\n", nMeshEntries); - if(nMeshEntries == 0) - return; - - // process the list - char decodedCall[20]; - uint16_t port; - SOCKADDR_IN ipAddr; - - USART_Print_string("Call(Port)\tIP Addr\t\tRSSI\tNext Seq\tLast Heard\tHops\tCapabilities\r\n"); - - for(int i=0;i -#include -#include -#include - -#include "types.h" -#include "setup.h" -#include "usart.h" - -#define USE_HAL - -// flash stuff -#define FLASH_PAGE_ADDR ((uint32_t)0x1007F800) -#define FLASH_PAGE_NUM 127 -static FLASH_EraseInitTypeDef EraseInitStruct; - -// Default Setup Data -SETUP_MEMORY setup_memory; - -SETUP_MEMORY def_params = { - .params.setup_data.flags = { 1, 0, 0 , 1, 0, FSK_100K }, // LSB specified first - .params.setup_data.stnCall ="NOCALL", - .params.setup_data.gridSq = "DO21vd", - .params.setup_data.latitude = "51.08", - .params.setup_data.longitude = "-114.10", - .params.setup_data.beaconInt = 5, - // - .params.radio_setup.lFrequencyBase = 445750000, - .params.radio_setup.xModulationSelect = MOD_4FSK, - .params.radio_setup.lDatarate = 100000, - .params.radio_setup.lFreqDev = 25000, - .params.radio_setup.lBandwidth = 200000, - .params.radio_setup.dsssExp = 0, - .params.radio_setup.outputPower = 14, - .params.radio_setup.PADrvMode = PA_DRV_TX_HP, - .params.radio_setup.rxSquelch = -95, - // - .params.FirmwareVerMajor = 1, // current rev is 1.0 - .params.FirmwareVerMinor = 0, - .params.Magic = SETUP_MAGIC, - .params.SetupCRC = 0 -}; - -char prtBuf[100]; - -// enum fields in setup struct -// modulation type -char *modTypes[] = { - "2FSK", - "4FSK", - "2GFSK05", - "2GFSK1", - "4GFSK05", - "4GFSK1", - "ASK", - "OOK", - "POLAR", - "CW" -}; - -// PA modes -char *paModes[] = { - "TX 10dBm Max", - "HP 14dBm Max", - "TX_HP 20dBm Max" -}; - -// return the setup struct -STN_PARAMS *GetStationParams(void) // get the station params -{ - return &setup_memory.params; -} - -// compare call to station callsign -// returns true if callsigns match -BOOL CompareToMyCall(char *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; -} - -/* - * Print the setup struct - */ -void printStationSetup(void) -{ - // station callsign first - USART_Print_string("Station Callsign->%s\r\n", setup_memory.params.setup_data.stnCall); - if(setup_memory.params.setup_data.flags.ext) - USART_Print_string("Extended Callsign->%s\r\n"); - - USART_Print_string("Latitude->%s\r\n", setup_memory.params.setup_data.latitude); - USART_Print_string("Longitude->%s\r\n", setup_memory.params.setup_data.longitude); - USART_Print_string("Grid Square->%s\r\n", setup_memory.params.setup_data.gridSq); - - USART_Print_string("Capabilities->"); - if(setup_memory.params.setup_data.flags.fsk) - USART_Print_string("FSK "); - if(setup_memory.params.setup_data.flags.ofdm) - USART_Print_string("OFDM "); - if(setup_memory.params.setup_data.flags.aredn) - USART_Print_string("AREDN "); - if(setup_memory.params.setup_data.flags.repeat) - USART_Print_string("\r\nRepeat mode on by default\r\n"); - else - USART_Print_string("\r\nRepeat mode off by default\r\n"); - USART_Print_string("Beacon Interval->%d mins\r\n\n", setup_memory.params.setup_data.beaconInt); -} - -void printRadioSetup(void) -{ - // dump the radio init struct - uint16_t fWhole = setup_memory.params.radio_setup.lFrequencyBase/1e6; - uint16_t fFract = setup_memory.params.radio_setup.lFrequencyBase/1e3 - fWhole*1e3; - USART_Print_string("RF Frequency->%d.%d MHz\r\n", fWhole, fFract); - - USART_Print_string("Modulation method->%s\r\n", modTypes[setup_memory.params.radio_setup.xModulationSelect]); - - uint16_t dWhole = setup_memory.params.radio_setup.lDatarate/1000; - uint16_t dFract = setup_memory.params.radio_setup.lDatarate - dWhole*1000; - USART_Print_string("Data Rate->%d.%d Kbps\r\n", dWhole, dFract); - - uint16_t pWhole = setup_memory.params.radio_setup.lFreqDev/1000; - uint16_t pFract = setup_memory.params.radio_setup.lFreqDev - pWhole*1000; - USART_Print_string("Peak Deviation->%d.%d KHz\r\n", pWhole, pFract); - - uint16_t bWhole = setup_memory.params.radio_setup.lBandwidth/1000; - uint16_t bFract = setup_memory.params.radio_setup.lBandwidth - bWhole*1000; - USART_Print_string("Channel Filter Bandwidth->%d.%d KHz\r\n", bWhole, bFract); - - USART_Print_string("Output Power->%d dBm\r\n", setup_memory.params.radio_setup.outputPower); - USART_Print_string("PA Mode->%s\r\n", paModes[setup_memory.params.radio_setup.PADrvMode]); - USART_Print_string("Rx Squelch->%d\r\n\n\n", setup_memory.params.radio_setup.rxSquelch); -} - -/* - * This code manages saving and reading the setup params - */ -// internals -uint32_t CalcSetupCRC(void); - -BOOL UpdateSetup(void) -{ - // update CRC before writing - setup_memory.params.SetupCRC = CalcSetupCRC(); - - if(WriteSetup() != HAL_OK) { - return FALSE; - } - - if(!ReadSetup()) { - return FALSE; - } - - if(!VerifySetup()) { - return FALSE; - } - - return TRUE; // only one iteration required -} - -// verify that the current setup record is valid -BOOL VerifySetup(void) -{ - // if the magic number matches, then all is well - if(setup_memory.params.Magic != SETUP_MAGIC) - return FALSE; - - uint32_t SetupCRC = CalcSetupCRC(); - - if(SetupCRC == setup_memory.params.SetupCRC) - return TRUE; - - return FALSE; -} - -// set the default setup -void SetDefSetup(void) -{ - memcpy((void *)&setup_memory.bytes, (const void *)&def_params.bytes, sizeof(SETUP_MEMORY)); -} - -// Read setup from Flash memory -// data is stored in the last flash page -BOOL ReadSetup(void) -{ - __IO uint32_t data32 = 0;; - - uint32_t memAddr = FLASH_PAGE_ADDR; - - uint32_t *dst_addr = setup_memory.flashwords; - uint16_t nwords = sizeof(STN_PARAMS)/sizeof(uint32_t); - - while(nwords--){ - data32 = *(__IO uint32_t *)memAddr; - *dst_addr++ = data32; - memAddr += sizeof(uint32_t); - } - - return TRUE; -} - -// write the setup to OTP memory -HAL_StatusTypeDef WriteSetup(void) -{ - HAL_StatusTypeDef status=0; - uint32_t PageError; - - __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS); - - // erase it first - EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES; - EraseInitStruct.Page = FLASH_PAGE_NUM; - EraseInitStruct.NbPages = 1; - if ((status=HAL_FLASHEx_Erase(&EraseInitStruct, &PageError)) != HAL_OK) - return status; - - // waste some time... - for(int i=0;i<1000;i++); - - // now write - uint32_t memAddr = FLASH_PAGE_ADDR; - uint32_t *src_addr = setup_memory.flashwords; - uint16_t nwords = sizeof(SETUP_MEMORY)/sizeof(uint32_t); - - while(nwords--) - { - uint32_t data32 = *(__IO uint32_t *)src_addr++; - - if ((status=HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, memAddr, data32)) != HAL_OK) - return status; - memAddr += sizeof(uint32_t); - } - return status; -} - -// calcuate the setup CRC -uint32_t CalcSetupCRC(void) -{ - uint32_t CRCValue; -#ifdef USE_HAL - CRCValue = HAL_CRC_Calculate(&hcrc, (uint32_t *)&setup_memory.bytes, sizeof(setup_memory) - sizeof(uint32_t)); -#else - - uint32_t cnt, count = sizeof(setup_memory) - sizeof(uint32_t); - uint8_t *arr = setup_memory.bytes; - - /* Reset CRC data register if necessary */ - CRC->CR = CRC_CR_RESET; - - - /* Calculate number of 32-bit blocks */ - cnt = count >> 2; - - /* Calculate */ - while (cnt--) { - /* Set new value */ - CRC->DR = *(uint32_t *)arr; - - /* Increase by 4 */ - arr += 4; - } - - /* Calculate remaining data as 8-bit */ - cnt = count % 4; - - /* Calculate */ - while (cnt--) { - /* Set new value */ - *((uint8_t *)&CRC->DR) = *arr++; - } - - /* Return data */ - CRCValue = CRC->DR; -#endif - return(CRCValue); -} diff --git a/Node Firmware/IP400/Src/spi.c b/Node Firmware/IP400/Src/spi.c deleted file mode 100644 index b350e5d..0000000 --- a/Node Firmware/IP400/Src/spi.c +++ /dev/null @@ -1,364 +0,0 @@ -/*--------------------------------------------------------------------------- - Project: NucleoCC2 - - File Name: spi.c - - Author: Martin, VE6VH - - Description: SPI task. responds to commands from the host, implementing a quasi- - memory device - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version, provided this copyright notice - is included. - - Copyright (c) Alberta Digital Radio Communications Society - All rights reserved. - - Revision History: - ----------------------------------------------------------------------------*/ -#include -#include -#include -#include -#include -#include - -#include "types.h" -#include "main.h" -#include "spi.h" -#include "dataq.h" -#include "tasks.h" - -#define SPI_MAX_TIME 200 // 200 ms max no activity timeout -#define NO_SPI_TIMEOUT (SPI_MAX_TIME/SPI_TASK_SCHED) // timeout in schedule ticks - -// transmitter states -enum { - SPITXIDLE=0, // idle - SPITXFRAG // next fragment -}; - -// receiver states -enum { - SPIRXIDLE=0, // idle - SPIRXFRAG // next fragment -}; - -uint8_t SPITxState; // transmitter state -uint8_t SPIRxState; // receiver state - -// frame queue -FRAME_QUEUE spiTxQueue; // queue for outbound - -// frame buffers -#if USE_BUFFER_RAM -static SPI_BUFFER spiTxBuffer __attribute__((section("BUFFERS"), aligned(4))); -static SPI_BUFFER spiRxBuffer __attribute__((section("BUFFERS"), aligned(4))); -static uint8_t rxFrameBuffer[PAYLOAD_MAX] __attribute__((section("BUFFERS"), aligned(4))); -#else -static SPI_BUFFER spiTxBuffer; -static SPI_BUFFER spiRxBuffer; -static uint8_t rxFrameBuffer[PAYLOAD_MAX]; -#endif - -uint8_t SPI_State; // current state -extern SPI_HandleTypeDef hspi1; // spi handle -HAL_StatusTypeDef spiXfer; // last transfer status -BOOL spiExchangeComplete; // spi exchange has been completed -BOOL spiErrorOccurred; -BOOL spiActive; -uint16_t spiActivityTimer; // no activity timer - -// validate an inbound frame -BOOL isIP400Frame(uint8_t *eye); - -/* - * place a frame on the queue frame content is copied - * to alloc'd memory - */ -BOOL EnqueSPIFrame(void *ip400frame) -{ - IP400_FRAME *qFrame, *SrcFrame = (IP400_FRAME *)ip400frame; - uint8_t *frameBuffer; - - // spi is not running... - if(!spiActive) - return FALSE; - - // allocate an IP400 frame - if((qFrame=malloc(sizeof(IP400_FRAME)))== NULL) - return FALSE; - memcpy(qFrame, SrcFrame, sizeof(IP400_FRAME)); - - int16_t hopCount = qFrame->flagfld.flags.hop_count; - int16_t hTblSize = hopCount * sizeof(HOPTABLE); - - // hop table is in the first part of the payload - // alloc enough for both - if((frameBuffer=malloc(SrcFrame->length+hTblSize)) == NULL) { - free(qFrame); - return FALSE; - } - - if(hopCount) { - memcpy(frameBuffer, qFrame->hopTable, hTblSize); - frameBuffer += hTblSize; - } - - memcpy(frameBuffer, (uint8_t *)SrcFrame->buf, SrcFrame->length); - qFrame->buf = frameBuffer; - qFrame->length = SrcFrame->length + hTblSize; - - if(!enqueFrame(&spiTxQueue, qFrame)) - return FALSE; - - return TRUE; -} - -/* - * clean up any queued frames - */ -void EmptySPIFrameQ(void) -{ - while(dequeFrame(&spiTxQueue) != NULL); - return; -} - -/* - * Initialize the task - */ -void SPI_Task_init(void) -{ - // create the rx completed semaphore - spiExchangeComplete = FALSE; - spiErrorOccurred = FALSE; - - spiTxBuffer.spiData.hdr.eye[0] = 'I'; - spiTxBuffer.spiData.hdr.eye[1] = 'P'; - spiTxBuffer.spiData.hdr.eye[2] = '4'; - spiTxBuffer.spiData.hdr.eye[3] = 'C'; - - spiTxBuffer.spiData.hdr.status = NO_DATA; - spiRxBuffer.spiData.hdr.status = NO_DATA; - - SPITxState = SPITXIDLE; - SPIRxState = SPIRXIDLE; - - // tx (outbound) frame queue - spiTxQueue.q_forw = &spiTxQueue; - spiTxQueue.q_back = &spiTxQueue; - - spiActive = FALSE; // no activity yet - spiActivityTimer = 0; - - // start the ball rolling.. - if((spiXfer = HAL_SPI_TransmitReceive_DMA(&hspi1, spiTxBuffer.rawData, spiRxBuffer.rawData, SPI_RAW_LEN)) != HAL_OK) - spiErrorOccurred = TRUE; - -} - -// execute the task -void SPI_Task_Exec(void) -{ - static IP400_FRAME *txFrame; - static uint16_t txSegLength, txPayloadRoom, hopSize; - static uint8_t *prxData, *ptxData, nHops; - static uint16_t rxSegLen; - - // check the status first: repost Rx if an error occurred and it is now ready - if(spiErrorOccurred) { - if(hspi1.State == HAL_SPI_STATE_READY) { - if((spiXfer = HAL_SPI_TransmitReceive_DMA(&hspi1, spiTxBuffer.rawData, spiRxBuffer.rawData, SPI_RAW_LEN)) == HAL_OK) { - spiErrorOccurred = FALSE; - } - } - } - - /* - * Here we wait for an exchange to be completed - * If there is no activity for NO_SPI_TIMEOUT, then - * the other end is probably dead, so clean up - * any pending frames - */ - if(!spiExchangeComplete) { - spiActivityTimer += 1; - if(spiActivityTimer >= NO_SPI_TIMEOUT) { - EmptySPIFrameQ(); - spiActive = FALSE; - spiActivityTimer = 0; - } - return; - } - - spiExchangeComplete = FALSE; // reset exchange done - spiActive = TRUE; // indicate that the SPI is active.. - spiActivityTimer = 0; // reset no activity timer - -// scope trigger on nucleo board -#if _BOARD_TYPE==NUCLEO_BOARD // board type in use - HAL_GPIO_TogglePin(SCOPE_GPIO_Port, SCOPE_Pin); -#endif - - /* - * process an outbound frame - * Fragment it if longer that 500 bytes - */ - switch(SPITxState) { - - case SPITXIDLE: - if((txFrame=dequeFrame(&spiTxQueue)) == NULL) { - spiTxBuffer.spiData.hdr.status = NO_DATA; - break; - } - txSegLength = txFrame->length; - nHops = txFrame->flagfld.flags.hop_count; - hopSize = (uint16_t)nHops * sizeof(HOPTABLE); - txPayloadRoom = SPI_BUFFER_LEN - hopSize; - spiTxBuffer.spiData.hdr.status = SINGLE_FRAME; - - // fragment the frame if needed - if(txFrame->length > txPayloadRoom) { - txSegLength = txPayloadRoom; - spiTxBuffer.spiData.hdr.status = FRAGMENT; - SPITxState = SPITXFRAG; - } - - // copy the address fields - memcpy(&spiTxBuffer.spiData.hdr.fromCall, txFrame->source.callbytes.bytes, N_CALL); - spiTxBuffer.spiData.hdr.fromPort[0] = (uint8_t)(txFrame->source.port << 8); - spiTxBuffer.spiData.hdr.fromPort[1] = (uint8_t)(txFrame->source.port & 0xff); - memcpy(spiTxBuffer.spiData.hdr.toCall, txFrame->dest.callbytes.bytes, N_CALL); - spiTxBuffer.spiData.hdr.toPort[0] = (uint8_t)(txFrame->dest.port << 8); - spiTxBuffer.spiData.hdr.toPort[1] = (uint8_t)(txFrame->dest.port & 0xff); - - // flag fields - spiTxBuffer.spiData.hdr.coding = txFrame->flagfld.flags.coding; - spiTxBuffer.spiData.hdr.hopCount = txFrame->flagfld.flags.hop_count; - spiTxBuffer.spiData.hdr.flags = (uint8_t)((txFrame->flagfld.allflags >> 8) & 0xFF); - - ptxData = spiTxBuffer.spiData.buffer; - - // hop table - if(txFrame->flagfld.flags.hoptable) { - memcpy(ptxData, txFrame->hopTable, hopSize); - ptxData += hopSize; - free(txFrame->hopTable); - } - - // and now the data - memcpy(ptxData, txFrame->buf, txSegLength); - spiTxBuffer.spiData.hdr.offset_hi = spiTxBuffer.spiData.hdr.offset_lo = 0; - spiTxBuffer.spiData.hdr.length_hi = ((txSegLength + hopSize) >> 8); - spiTxBuffer.spiData.hdr.length_lo = ((txSegLength + hopSize) & 0xFF); - - // release memory if only a single frame - if(spiTxBuffer.spiData.hdr.status == SINGLE_FRAME) - { - free(txFrame->buf); - free(txFrame); - } - break; - - case SPITXFRAG: - uint16_t offset = ((uint16_t)(spiTxBuffer.spiData.hdr.offset_hi) << 8) + (uint16_t)spiTxBuffer.spiData.hdr.offset_lo; - uint16_t prevLen = ((uint16_t)(spiTxBuffer.spiData.hdr.length_hi) << 8) + (uint16_t)spiTxBuffer.spiData.hdr.length_lo; - offset += prevLen; - txFrame->length -= prevLen; - txSegLength = txFrame->length; - if(txFrame->length > SPI_BUFFER_LEN) { - spiTxBuffer.spiData.hdr.status = FRAGMENT; - txSegLength = SPI_BUFFER_LEN; - } else { - spiTxBuffer.spiData.hdr.status = LAST_FRAGMENT; - SPITxState = SPITXIDLE; - } - - // send the next fragment - void *fragAddr = txFrame->buf + offset; - memcpy(spiTxBuffer.spiData.buffer, fragAddr, txSegLength); - spiTxBuffer.spiData.hdr.offset_hi = (offset >> 8); - spiTxBuffer.spiData.hdr.offset_lo = (offset & 0xff); - spiTxBuffer.spiData.hdr.length_hi = (txSegLength >> 8); - spiTxBuffer.spiData.hdr.length_lo = (txSegLength & 0xFF); - - // done with frame - if(spiTxBuffer.spiData.hdr.status == LAST_FRAGMENT) - { - free(txFrame->buf); - free(txFrame); - } - break; - } - - /* - * Inbound frame. Reassemble fragments if needed... - */ - - switch(SPIRxState) { - - case SPIRXIDLE: - spiFrameStatus rstat = spiRxBuffer.spiData.hdr.status; - if((rstat == NO_DATA) || (rstat >= NUM_STATS)) - break; - - if(!isIP400Frame(spiRxBuffer.spiData.hdr.eye)) - break; - - rxSegLen = (spiRxBuffer.spiData.hdr.length_hi << 8) + spiRxBuffer.spiData.hdr.length_lo; - if(rstat != SINGLE_FRAME) { - prxData = rxFrameBuffer + (spiRxBuffer.spiData.hdr.offset_hi << 8) + spiRxBuffer.spiData.hdr.offset_lo; - memcpy(prxData, spiRxBuffer.spiData.buffer, rxSegLen); - SPIRxState = SPIRXFRAG; - } else { - SendSPIFrame(&spiRxBuffer.spiData.hdr, spiRxBuffer.spiData.buffer, rxSegLen); - } - break; - - case SPIRXFRAG: - uint8_t fragStat = spiRxBuffer.spiData.hdr.status; - uint16_t offset = (spiTxBuffer.spiData.hdr.offset_hi << 8) + spiTxBuffer.spiData.hdr.offset_lo; - prxData = rxFrameBuffer + offset; - rxSegLen = (spiRxBuffer.spiData.hdr.length_hi << 8) + spiRxBuffer.spiData.hdr.length_lo; - memcpy(prxData, spiRxBuffer.spiData.buffer, rxSegLen); - - if(fragStat == LAST_FRAGMENT) { - uint16_t frameLen = offset + rxSegLen; - spiRxBuffer.spiData.hdr.length_hi = (frameLen >> 8); - spiRxBuffer.spiData.hdr.length_lo = (frameLen & 0xFF); - // process frame for tx here... - SPIRxState = SPIRXIDLE; // placeholder - } - break; - } - -} - -// rx done callback -void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef * hspi) -{ - // set data valid and start a new transfer - if(hspi->State == HAL_SPI_STATE_READY) { - spiExchangeComplete = TRUE; - spiXfer = HAL_SPI_TransmitReceive_DMA(&hspi1, spiTxBuffer.rawData, spiRxBuffer.rawData, SPI_RAW_LEN); - if(spiXfer != HAL_OK) - spiErrorOccurred = TRUE; - return; - } - spiErrorOccurred = TRUE; // spi not ready -} - -// test an incoming frame -BOOL isIP400Frame(uint8_t *eye) -{ - if((eye[0] != 'I') || (eye[1] != 'P')) - return FALSE; - - if((eye[2] != '4') || (eye[3] != 'C')) - return FALSE; - - return TRUE; -} diff --git a/Node Firmware/IP400/Src/tod.c b/Node Firmware/IP400/Src/tod.c deleted file mode 100644 index eebc124..0000000 --- a/Node Firmware/IP400/Src/tod.c +++ /dev/null @@ -1,80 +0,0 @@ -/*--------------------------------------------------------------------------- - Project: WL33_NUCLEO_UART - - File Name: tod.c - - Author: MartinA - - Description: Time of Day clock - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version, provided this copyright notice - is included. - - Copyright (c) Alberta Digital Radio Communications Society - All rights reserved. - - Revision History: - ----------------------------------------------------------------------------*/ -#include "types.h" -#include "tod.h" -#include "utils.h" - -TIMEOFDAY tod = { 0, 0, 0 }; // where we hold the TOD - -// routines -void TOD_10SecTimer(void) // 10 second timer -{ - // handle seconds - tod.Seconds += 10; - if(tod.Seconds >= 60) { - tod.Minutes += tod.Seconds/60; - tod.Seconds %= 60; - } - - // handle minutes - if(tod.Minutes >= 60) { - tod.Hours += tod.Minutes/60; - tod.Minutes %= 60; - } - - // handle hours - if(tod.Hours > 24) - tod.Hours %= 24; -} - -// return pointer to Time of Day -void getTOD(TIMEOFDAY *time) -{ - time->Hours = tod.Hours; - time->Minutes = tod.Minutes; - time->Seconds = tod.Seconds; -} - -// set the TOD from HH:MM string -// somewhat brute force parser -BOOL setTOD(char *todString) -{ - char *todValues[5]; - - int nParams = explode_string(todString, todValues, 5, ':', '"'); - if(nParams != 2) - return FALSE; - - int nHours = ascii2Dec(todValues[0]); - if((nHours < 0) || (nHours > 24)) - return FALSE; - - int nMins = ascii2Dec(todValues[1]); - if((nHours < 0) || (nHours > 60)) - return FALSE; - - tod.Hours = nHours; - tod.Minutes = nMins; - tod.Seconds = 0; - - return TRUE; -} diff --git a/Node Firmware/IP400/Src/usart.c b/Node Firmware/IP400/Src/usart.c deleted file mode 100644 index b4f0d73..0000000 --- a/Node Firmware/IP400/Src/usart.c +++ /dev/null @@ -1,300 +0,0 @@ -/*--------------------------------------------------------------------------- - Project: IP400 Modem - - File Name: usart.c - - Author: Martin C. Alcock, VE6VH - - Revision: 1.05 - - Description: API for USART handling - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version, provided this copyright notice - is included. - - Copyright (c) Alberta Digital Radio Communications Society - All rights reserved. - - Revision History: - ----------------------------------------------------------------------------*/ -#include -#include -#include - -#include -#include -#include - -#include "config.h" -#include "stream_buffer.h" -#include "types.h" -#include "streambuffer.h" -#include "usart.h" - -// local defines -#define RX_TIMEOUT 10000 // 10 second rx timeout -#define TX_TIMEOUT 1000 // 1s transmit timeout - -// stream buffer -StreamBufferHandle_t USART_RxBuffer; // handle to buffer -StaticStreamBuffer_t USART_StreamBuffer; - -// UART/T Support -SemaphoreHandle_t txCompleted; // tx completed semaphore -static DATA_ELEMENT USARTRxChar[10]; // last received character - -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) -{ - // create the tx completed semaphore - txCompleted = xSemaphoreCreateBinary(); - - // 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) -{ - size_t nBytes = xStreamBufferBytesAvailable(USART_RxBuffer); - return nBytes; -} - -// get a byte from the buffer: blocks if timeout is zero, -// else returns BUFFER_NO_DATA if timeout exceeded -DATA_ELEMENT databuffer_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(USART_RxBuffer, &retval, 1, tickTimeout) == 0) - return BUFFER_NO_DATA; - - 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) -{ - DATA_ELEMENT c; - - uint8_t tagSize = (uint8_t)(strlen(tag) & 0xff); - uint8_t tagLen = tagSize; - - const char *tagAddr = tag; - - while ((c = databuffer_get(rx_timeout)) != BUFFER_NO_DATA) { - if (c == *tagAddr) { - if (--tagLen == 0) { - if(saveData) { - *SaveBuffer++ = c; - *SaveBuffer = '\0'; - } - return TRUE; - } - tagAddr++; - } - else { - tagAddr = tag; - tagLen = tagSize; - } - if(saveData) - *SaveBuffer++ = c; - } - if(saveData) - *SaveBuffer = '\0'; - return FALSE; -} - -/* - * Low level HAL interaction functions - */ - -// send a packet (with timeout) -BOOL USART_Send_String(const char *string, size_t len) -{ - // send using DMA - uint16_t dataLen = (uint16_t)len; - if((HAL_UART_Transmit_DMA(&huart1, (const uint8_t *)string, dataLen)) != HAL_OK) - return FALSE; - - // wait for completion.. - if((xSemaphoreTake(txCompleted, pdMS_TO_TICKS(TX_TIMEOUT))) == pdTRUE) - return TRUE; - - return FALSE; -} - -// send a packet (with timeout) -BOOL USART_Send_Char(const char c) -{ - - // send using interrupt - HAL_UART_Transmit_IT(&huart1, (const uint8_t *)&c, 1); - - // wait for completion.. - if((xSemaphoreTake(txCompleted, pdMS_TO_TICKS(TX_TIMEOUT))) == pdTRUE) - return TRUE; - - return FALSE; -} - -// print a string to the UAR/T -void USART_Print_string(char *format, ...) -{ - // process the arg list - va_list argptr; - va_start(argptr, format); - vsprintf(usartPrintBuffer,format, argptr); - va_end(argptr); - - USART_Send_String(usartPrintBuffer, strlen(usartPrintBuffer)); -} - - -// Transmit completed: trigger semaphore -void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) -{ -#if __ENABLE_GPS - // Not interested in LPUART - if(huart->Instance == LPUART1) - return; -#endif - BaseType_t xHigherPriorityTaskWoken = pdFALSE; - xSemaphoreGiveFromISR(txCompleted, &xHigherPriorityTaskWoken); - -} - -// receive a byte with DMA, wait for DMA completed interrupt -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) -{ -#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 -// send a string to the LPUART -void LPUART_Send_String(char *str, uint16_t len) -{ - // send using interrupt - HAL_UART_Transmit_IT(&hlpuart1, (const uint8_t *)str, len); -} - - -// 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 diff --git a/Node Firmware/IP400/Src/utils.c b/Node Firmware/IP400/Src/utils.c deleted file mode 100644 index 6d5e370..0000000 --- a/Node Firmware/IP400/Src/utils.c +++ /dev/null @@ -1,146 +0,0 @@ -/*--------------------------------------------------------------------------- - Project: WL33_NUCLEO_UART - - File Name: utils.c - - Author: MartinA - - Description: utility routines - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version, provided this copyright notice - is included. - - Copyright (c) Alberta Digital Radio Communications Society - All rights reserved. - - Revision History: - ----------------------------------------------------------------------------*/ -#include - -#include "types.h" -#include "utils.h" - -// ascii to decimal -int ascii2Dec(char *dec) -{ - int retval = 0; - int sgn = 1; - while (*dec) { - if(*dec == '-') - sgn = -1; - else retval = retval*10 + (*dec - '0'); - dec++; - } - - return retval*sgn; -} - -// nibble to ascii -char nib2ascii(uint8_t nib) -{ - char anib = (char)(nib + '0'); - anib = (anib > '9') ? anib+('A'-'9') : anib; - return anib; -} - -// hex to ascii -void hex2ascii(uint8_t hex, char *buf) -{ - *buf++= nib2ascii(hex>>4); - *buf = nib2ascii(hex & 0xf); -} - -// see if an entry is floating point -BOOL isfloat(char *val) -{ - while(*val) - if(*val++ == '.') - return 1U; - return 0U; -} - -// convert an ascii string to a double -// until we encounter the decimal place, treat it the same as an integer. -// after that, scale each digit down appropriately -// -double ascii2double(char *val) -{ - double retval = 0; - int power = -1, inc = 1; - int sgn = 1; - - while(*val) { - - switch(*val) { - - case '-': - sgn = -1; - break; - - case '.': - power = -1; - inc = -1; - break; - - default: - if(inc > 0) { - retval = retval*10 + (*val - '0'); - } else { - retval += pow(10.0, power) * (*val - '0'); - power += inc; - } - break; - } - val++; - } - return retval * sgn; -} - -// Your basic linux-stle (argv, argc) parser based on delimiters -// string is destroyed -int explode_string(char *str, char *strp[], int limit, char delim, char quote) -{ -int i,l,inquo; - - inquo = 0; - i = 0; - strp[i++] = str; - if (!*str) - { - strp[0] = 0; - return(0); - } - for(l = 0; *str && (l < limit) ; str++) - { - if(quote) - { - if (*str == quote) - { - if (inquo) - { - *str = 0; - inquo = 0; - } - else - { - strp[i - 1] = str + 1; - inquo = 1; - } - } - } - if ((*str == delim) && (!inquo)) - { - *str = 0; - l++; - strp[i++] = str + 1; - } - } - strp[i] = 0; - return(i); - -} -