Browse Source

ax25 send, removed all mallocs

pull/25/head
sq8vps 2 years ago
parent
commit
665d210683
16 changed files with 270 additions and 268 deletions
  1. +8
    -1
      Inc/ax25.h
  2. +4
    -2
      Inc/drivers/systick.h
  3. +2
    -0
      Inc/drivers/uart.h
  4. +14
    -20
      Inc/terminal.h
  5. +2
    -2
      STM32F103C8Tx_FLASH.ld
  6. +35
    -10
      Src/ax25.c
  7. +4
    -4
      Src/beacon.c
  8. +1
    -1
      Src/config.c
  9. +9
    -14
      Src/digipeater.c
  10. +12
    -0
      Src/drivers/systick.c
  11. +5
    -46
      Src/drivers/uart.c
  12. +14
    -39
      Src/main.c
  13. +87
    -123
      Src/terminal.c
  14. +3
    -6
      Src/usbd_cdc_if.c
  15. +35
    -0
      vp-digi Debug.cfg
  16. +35
    -0
      vp-digi Release.cfg

+ 8
- 1
Inc/ax25.h View File

@ -41,6 +41,13 @@ struct Ax25ProtoConfig
extern struct Ax25ProtoConfig Ax25Config;
/**
* @brief Transmit one or more frames encoded in KISS format
* @param *buf Inout buffer
* @param len Buffer size
*/
void Ax25TxKiss(uint8_t *buf, uint16_t len);
/**
* @brief Write frame to transmit buffer
* @param *data Data to transmit
@ -63,7 +70,7 @@ void Ax25ClearReceivedFrameBitmap(void);
/**
* @brief Get next received frame (if available)
* @param **dst Destination buffer that this function allocates and fills
* @param **dst Pointer to internal buffer
* @param *size Actual frame size
* @param *signalLevel Frame signal level (RMS)
* @return True if frame was read, false if no more frames to read


+ 4
- 2
Inc/drivers/systick.h View File

@ -26,8 +26,10 @@ along with VP-Digi. If not, see <http://www.gnu.org/licenses/>.
extern volatile uint32_t ticks;
//void SysTick_Handler(void);
void SysTickInit(void);
uint32_t SysTickGet(void);
void Delay(uint32_t ms);
#endif /* SYSTICK_H_ */

+ 2
- 0
Inc/drivers/uart.h View File

@ -37,6 +37,7 @@ enum UartDataType
DATA_NOTHING = 0,
DATA_KISS,
DATA_TERM,
DATA_USB,
};
typedef struct
@ -53,6 +54,7 @@ typedef struct
uint8_t txBufferFull : 1;
enum UartMode mode;
uint32_t kissTimer;
uint16_t lastRxBufferHead; //for special characters handling
} Uart;
extern Uart Uart1, Uart2, UartUsb;


+ 14
- 20
Inc/terminal.h View File

@ -29,30 +29,24 @@ along with VP-Digi. If not, see <http://www.gnu.org/licenses/>.
*/
void TermSendToAll(enum UartMode mode, uint8_t *data, uint16_t size);
/**
* @brief Send signed number to all available ports
* @param mode Output mode/data type
* @param n Number to send
*/
void TermSendNumberToAll(enum UartMode mode, int32_t n);
//typedef enum
//{
// TERM_ANY,
// TERM_USB,
// TERM_UART1,
// TERM_UART2
//} Terminal_stream;
//
//#define TERMBUFLEN 300
//
///**
// * @brief Handle "special" terminal cases like backspace or local echo
// * @param[in] src Source: TERM_USB, TERM_UART1, TERM_UART2
// * @attention Must be called for every received data
// */
//void term_handleSpecial(Terminal_stream src);
//
//
/**
* \brief Parse and process received data
* \param *src UART structure
* @brief Handle "special" terminal cases like backspace or local echo
* @param *u UART structure
* @attention Must be called for every received data
*/
void TermHandleSpecial(Uart *u);
/**
* @brief Parse and process received data
* @param *src UART structure
*/
void TermParse(Uart *src);


+ 2
- 2
STM32F103C8Tx_FLASH.ld View File

@ -55,8 +55,8 @@ ENTRY(Reset_Handler)
/* Highest address of the user mode stack */
_estack = 0x20005000; /* end of RAM */
/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0x200; /* required amount of heap */
_Min_Stack_Size = 0x400; /* required amount of stack */
_Min_Heap_Size = 0x080; /* required amount of heap */
_Min_Stack_Size = 0x200; /* required amount of stack */
/* Specify the memory areas */
MEMORY


+ 35
- 10
Src/ax25.c View File

@ -21,11 +21,13 @@ along with VP-Digi. If not, see <http://www.gnu.org/licenses/>.
#include "common.h"
#include "drivers/systick.h"
#include <stdbool.h>
#include "digipeater.h"
struct Ax25ProtoConfig Ax25Config;
//values below must be kept consistent so that FRAME_BUFFER_SIZE >= FRAME_MAX_SIZE * FRAME_MAX_COUNT
#define FRAME_MAX_SIZE (150) //single frame max length for RX
#define FRAME_MAX_SIZE (308) //single frame max length for RX
//308 bytes is the theoretical max size assuming 2-byte Control, 256-byte info field and 5 digi address fields
#define FRAME_MAX_COUNT (10) //max count of frames in buffer
#define FRAME_BUFFER_SIZE (FRAME_MAX_COUNT * FRAME_MAX_SIZE) //circular frame buffer length
@ -111,6 +113,8 @@ static uint16_t rxMultiplexDelay = 0; //simple delay for decoder multiplexer to
static uint16_t txDelay; //number of TXDelay bytes to send
static uint16_t txTail; //number of TXTail bytes to send
static uint8_t outputFrameBuffer[FRAME_MAX_SIZE];
#define GET_FREE_SIZE(max, head, tail) (((head) < (tail)) ? ((tail) - (head)) : ((max) - (head) + (tail)))
#define GET_USED_SIZE(max, head, tail) (max - GET_FREE_SIZE(max, head, tail))
@ -140,6 +144,32 @@ void Ax25ClearReceivedFrameBitmap(void)
frameReceived = 0;
}
void Ax25TxKiss(uint8_t *buf, uint16_t len)
{
if(len < 18) //frame is too small
{
return;
}
for(uint16_t i = 0; i < len; i++)
{
if(buf[i] == 0xC0) //frame start marker
{
uint16_t end = i + 1;
while(end < len)
{
if(buf[end] == 0xC0)
break;
end++;
}
if(end == len) //no frame end marker found
return;
Ax25WriteTxFrame(&buf[i + 2], end - (i + 2)); //skip modem number and send frame
DigiStoreDeDupe(&buf[i + 2], end - (i + 2));
i = end; //move pointer to the next byte if there are more consecutive frames
}
}
}
void *Ax25WriteTxFrame(uint8_t *data, uint16_t size)
{
while(txStage != TX_STAGE_IDLE)
@ -172,12 +202,7 @@ bool Ax25ReadNextRxFrame(uint8_t **dst, uint16_t *size, uint16_t *signalLevel)
if((rxFrameHead == rxFrameTail) && !rxFrameBufferFull)
return false;
*dst = malloc(rxFrame[rxFrameTail].size);
if(NULL == dst)
{
*size = 0;
return false;
}
*dst = outputFrameBuffer;
for(uint16_t i = 0; i < rxFrame[rxFrameTail].size; i++)
{
@ -494,7 +519,7 @@ void Ax25TransmitBuffer(void)
if((txFrameHead != txFrameTail) || txFrameBufferFull)
{
txQuiet = (ticks + (Ax25Config.quietTime / SYSTICK_INTERVAL) + Random(0, 200 / SYSTICK_INTERVAL)); //calculate required delay
txQuiet = (SysTickGet() + (Ax25Config.quietTime / SYSTICK_INTERVAL) + Random(0, 200 / SYSTICK_INTERVAL)); //calculate required delay
txInitStage = TX_INIT_WAITING;
}
}
@ -530,7 +555,7 @@ void Ax25TransmitCheck(void)
if(ModemIsTxTestOngoing()) //TX test is enabled, wait for now
return;
if(txQuiet < ticks) //quit time has elapsed
if(txQuiet < SysTickGet()) //quit time has elapsed
{
if(!ModemDcdState()) //channel is free
{
@ -548,7 +573,7 @@ void Ax25TransmitCheck(void)
}
else //still trying
{
txQuiet = ticks + Random(100 / SYSTICK_INTERVAL, 500 / SYSTICK_INTERVAL); //try again after some random time
txQuiet = SysTickGet() + Random(100 / SYSTICK_INTERVAL, 500 / SYSTICK_INTERVAL); //try again after some random time
txRetries++;
}
}


+ 4
- 4
Src/beacon.c View File

@ -102,11 +102,11 @@ void BeaconCheck(void)
if(beacon[i].enable == 0)
continue;
if((beacon[i].interval > 0) && ((ticks >= beacon[i].next) || (beacon[i].next == 0)))
if((beacon[i].interval > 0) && ((SysTickGet() >= beacon[i].next) || (beacon[i].next == 0)))
{
if(beaconDelay[i] > ticks) //check for beacon delay (only for the very first transmission)
if(beaconDelay[i] > SysTickGet()) //check for beacon delay (only for the very first transmission)
return;
beacon[i].next = ticks + beacon[i].interval; //save next beacon timestamp
beacon[i].next = SysTickGet() + beacon[i].interval; //save next beacon timestamp
beaconDelay[i] = 0;
BeaconSend(i);
}
@ -121,7 +121,7 @@ void BeaconInit(void)
{
for(uint8_t i = 0; i < 8; i++)
{
beaconDelay[i] = (beacon[i].delay * SYSTICK_FREQUENCY) + ticks + (30000 / SYSTICK_INTERVAL); //set delay for beacons and add constant 30 seconds of delay
beaconDelay[i] = (beacon[i].delay * SYSTICK_FREQUENCY) + SysTickGet() + (30000 / SYSTICK_INTERVAL); //set delay for beacons and add constant 30 seconds of delay
beacon[i].next = 0;
}
}


+ 1
- 1
Src/config.c View File

@ -1,5 +1,5 @@
/*
This file is part of VP-DigiConfig.
This file is part of VP-Digi.
VP-Digi is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by


+ 9
- 14
Src/digipeater.c View File

@ -26,14 +26,14 @@ along with VP-DigiConfig. If not, see <http://www.gnu.org/licenses/>.
struct _DigiConfig DigiConfig;
#define VISCOUS_MAX_FRAME_COUNT 20 //max frames in viscous-delay buffer
#define VISCOUS_MAX_FRAME_COUNT 10 //max frames in viscous-delay buffer
#define VISCOUS_MAX_FRAME_SIZE 150
struct ViscousData
{
uint32_t hash;
uint32_t timeLimit;
uint8_t *frame;
uint8_t frame[VISCOUS_MAX_FRAME_SIZE];
uint16_t size;
};
static struct ViscousData viscous[VISCOUS_MAX_FRAME_COUNT];
@ -45,12 +45,12 @@ struct DeDupeData
uint32_t timeLimit;
};
#define DEDUPE_SIZE (40) //duplicate protection buffer size (number of hashes)
#define DEDUPE_SIZE (50) //duplicate protection buffer size (number of hashes)
static struct DeDupeData deDupe[DEDUPE_SIZE]; //duplicate protection hash buffer
static uint8_t deDupeCount = 0; //duplicate protection buffer index
#define DIGI_BUFFER_SIZE 200
#define DIGI_BUFFER_SIZE 308 //308 is the theoretical max under some assumptions, see ax25.c
static uint8_t buf[DIGI_BUFFER_SIZE];
/**
@ -66,9 +66,8 @@ static uint8_t viscousCheckAndRemove(uint32_t hash)
{
viscous[i].hash = 0; //clear slot
viscous[i].timeLimit = 0;
free(viscous[i].frame);
viscous[i].size = 0;
//term_sendMonitor((uint8_t*)"Digipeated frame received, dropping old frame from viscous-delay buffer\r\n", 0);
TermSendToAll(MODE_MONITOR, (uint8_t*)"Digipeated frame received, dropping old frame from viscous-delay buffer\r\n", 0);
return 1;
}
}
@ -86,7 +85,7 @@ void DigiViscousRefresh(void)
for(uint8_t i = 0; i < VISCOUS_MAX_FRAME_COUNT; i++)
{
if((viscous[i].timeLimit > 0) && (ticks >= viscous[i].timeLimit)) //it's time to transmit this frame
if((viscous[i].timeLimit > 0) && (SysTickGet() >= viscous[i].timeLimit)) //it's time to transmit this frame
{
void *handle = NULL;
if(NULL != (handle = Ax25WriteTxFrame(viscous[i].frame, viscous[i].size)))
@ -103,7 +102,6 @@ void DigiViscousRefresh(void)
viscous[i].hash = 0; //clear slot
viscous[i].timeLimit = 0;
free(viscous[i].frame);
viscous[i].size = 0;
}
}
@ -194,9 +192,6 @@ static void makeFrame(uint8_t *frame, uint16_t elStart, uint16_t len, uint32_t h
if((len + 7) > VISCOUS_MAX_FRAME_SIZE) //if frame length (+ 7 bytes for inserted call) is bigger than buffer size
return; //drop
viscous[viscousSlot].frame = malloc(len + 7);
if(NULL == viscous[viscousSlot].frame)
return;
buffer = viscous[viscousSlot].frame;
index = &(viscous[viscousSlot].size);
*index = 0;
@ -288,7 +283,7 @@ static void makeFrame(uint8_t *frame, uint16_t elStart, uint16_t len, uint32_t h
if((alias < 8) && (DigiConfig.viscous & (1 << alias)))
{
viscous[viscousSlot].hash = hash;
viscous[viscousSlot].timeLimit = ticks + (VISCOUS_HOLD_TIME / SYSTICK_INTERVAL);
viscous[viscousSlot].timeLimit = SysTickGet() + (VISCOUS_HOLD_TIME / SYSTICK_INTERVAL);
TermSendToAll(MODE_MONITOR, (uint8_t*)"Saving frame for viscous-delay digipeating\r\n", 0);
}
else
@ -339,7 +334,7 @@ void DigiDigipeat(uint8_t *frame, uint16_t len)
{
if(deDupe[i].hash == hash)
{
if(ticks < (deDupe[i].timeLimit))
if(SysTickGet() < (deDupe[i].timeLimit))
return; //filter out duplicate frame
}
}
@ -466,7 +461,7 @@ void DigiStoreDeDupe(uint8_t *buf, uint16_t size)
deDupeCount %= DEDUPE_SIZE;
deDupe[deDupeCount].hash = hash;
deDupe[deDupeCount].timeLimit = ticks + (DigiConfig.dupeTime * 10 / SYSTICK_INTERVAL);
deDupe[deDupeCount].timeLimit = SysTickGet() + (DigiConfig.dupeTime * 10 / SYSTICK_INTERVAL);
deDupeCount++;
}

+ 12
- 0
Src/drivers/systick.c View File

@ -30,3 +30,15 @@ void SysTickInit(void)
{
SysTick_Config(SystemCoreClock / SYSTICK_FREQUENCY); //SysTick every 10 ms
}
uint32_t SysTickGet(void)
{
return ticks;
}
void Delay(uint32_t ms)
{
uint32_t target = SysTickGet() + ms / SYSTICK_INTERVAL;
while(target > SysTickGet())
;
}

+ 5
- 46
Src/drivers/uart.c View File

@ -21,49 +21,10 @@ along with VP-Digi. If not, see <http://www.gnu.org/licenses/>.
#include "ax25.h"
#include "common.h"
#include <string.h>
#include "digipeater.h"
Uart Uart1, Uart2, UartUsb;
//uint8_t Uart_txKiss(uint8_t *buf, uint16_t len)
//{
// if(len < 10) //frame is too small
// {
// return 1;
// }
//
// uint16_t framebegin = 0;
// uint8_t framestatus = 0; //0 - frame not started, 1 - frame start found, 2 - in a frame, 3 - frame end found
//
// for(uint16_t i = 0; i < len; i++)
// {
// if(*(buf + i) == 0xc0) //found KISS frame delimiter
// {
// if((i > 2) && (framestatus == 2)) //we are already in frame, this is the ending marker
// {
// framestatus = 3;
// ax25.frameXmit[ax25.xmitIdx++] = 0xFF; //write frame separator
// Digi_storeDeDupeFromXmitBuf(framebegin); //store duplicate protection hash
// if((FRAMEBUFLEN - ax25.xmitIdx) < (len - i + 2)) //there might be next frame in input buffer, but if there is no space for it, drop it
// break;
// }
// }
// else if((*(buf + i) == 0x00) && (*(buf + i - 1) == 0xC0) && ((framestatus == 0) || (framestatus == 3))) //found frame delimiter, modem number (0x00) and we are not in a frame yet or preceding frame has been processed
// {
// framestatus = 1; //copy next frame
// framebegin = ax25.xmitIdx;
// }
// else if((framestatus == 1) || (framestatus == 2)) //we are in a frame
// {
// ax25.frameXmit[ax25.xmitIdx++] = *(buf + i); //copy data
// framestatus = 2;
// }
// }
//
// return 0;
//}
static void handleInterrupt(Uart *port)
{
if(port->port->SR & USART_SR_RXNE) //byte received
@ -72,13 +33,10 @@ static void handleInterrupt(Uart *port)
port->rxBuffer[port->rxBufferHead++] = port->port->DR; //store it
port->rxBufferHead %= UART_BUFFER_SIZE;
// if(port->port == USART1) //handle special functions and characters
// term_handleSpecial(TERM_UART1);
// else if(port->port == USART2)
// term_handleSpecial(TERM_UART2);
TermHandleSpecial(port);
if(port->mode == MODE_KISS)
port->kissTimer = ticks + (5000 / SYSTICK_INTERVAL); //set timeout to 5s in KISS mode
port->kissTimer = SysTickGet() + (5000 / SYSTICK_INTERVAL); //set timeout to 5s in KISS mode
}
if(port->port->SR & USART_SR_IDLE) //line is idle, end of data reception
{
@ -111,7 +69,7 @@ static void handleInterrupt(Uart *port)
}
}
if((port->kissTimer > 0) && (ticks >= port->kissTimer)) //KISS timer timeout
if((port->kissTimer > 0) && (SysTickGet() >= port->kissTimer)) //KISS timer timeout
{
port->kissTimer = 0;
port->rxBufferHead = 0;
@ -203,6 +161,7 @@ void UartInit(Uart *port, USART_TypeDef *uart, uint32_t baud)
port->mode = MODE_KISS;
port->enabled = 0;
port->kissTimer = 0;
port->lastRxBufferHead = 0;
memset(port->rxBuffer, 0, sizeof(port->rxBuffer));
memset(port->txBuffer, 0, sizeof(port->txBuffer));
}
@ -278,7 +237,7 @@ void UartClearRx(Uart *port)
void UartHandleKissTimeout(Uart *port)
{
if((port->kissTimer > 0) && (ticks >= port->kissTimer)) //KISS timer timeout
if((port->kissTimer > 0) && (SysTickGet() >= port->kissTimer)) //KISS timer timeout
{
port->kissTimer = 0;
port->rxBufferHead = 0;


+ 14
- 39
Src/main.c View File

@ -94,7 +94,7 @@ static void handleFrame(void)
uint8_t modemBitmap = Ax25GetReceivedFrameBitmap(); //store states
Ax25ClearReceivedFrameBitmap();
uint8_t *buf = NULL;
uint8_t *buf;
uint16_t size = 0;
uint16_t signalLevel = 0;
@ -113,7 +113,7 @@ static void handleFrame(void)
//for pure square wave it should be equal to the amplitude (around 4095)
//real data contains lots of imperfections (especially mark/space amplitude imbalance) and this value is far smaller than 2900 for standard frames
//division by 9 was selected by trial and error to provide a value of 100(%) when the input signal had peak-peak voltage of 3.3V
//this probably should be done in a different way, like some peak amplitude tracing
//TODO: this probably should be done in a different way, like some peak amplitude tracing
signalLevel /= 9;
if(signalLevel > 100)
@ -141,9 +141,11 @@ static void handleFrame(void)
TermSendToAll(MODE_MONITOR, (uint8_t*)"D", 1);
break;
case EMPHASIS_NONE:
default:
TermSendToAll(MODE_MONITOR, (uint8_t*)"F", 1);
break;
default:
TermSendToAll(MODE_MONITOR, (uint8_t*)"*", 1);
break;
}
}
else
@ -161,8 +163,6 @@ static void handleFrame(void)
DigiDigipeat(buf, size);
free(buf);
}
}
@ -200,9 +200,7 @@ int main(void)
GPIOA->CRH |= GPIO_CRH_MODE12_1;
GPIOA->CRH &= ~GPIO_CRH_CNF12;
GPIOA->BSRR = GPIO_BSRR_BR12;
uint32_t t = ticks + (100 / SYSTICK_INTERVAL);
while(t > ticks)
;
Delay(100);
GPIOA->CRH &= ~GPIO_CRH_MODE12;
GPIOA->CRH |= GPIO_CRH_CNF12_0;
@ -269,39 +267,16 @@ int main(void)
Ax25TransmitCheck(); //check for pending transmission request
// if(USBint) //USB "interrupt"
// {
// USBint = 0; //clear
//
// if(USBmode == MODE_KISS) //is USB in KISS mode?
// usbKissTimer = ticks + 500; //set timeout to 5s
//
// term_handleSpecial(TERM_USB); //handle special characters (e.g. backspace)
// if((usbcdcdata[0] == 0xc0) && /*(usbcdcdata[1] == 0x00) &&*/ (usbcdcdata[usbcdcidx - 1] == 0xc0)) //probably a KISS frame
// {
// USBrcvd = DATA_KISS;
// usbKissTimer = 0;
// }
//
// if(((usbcdcdata[usbcdcidx - 1] == '\r') || (usbcdcdata[usbcdcidx - 1] == '\n'))) //proabably a command
// {
// USBrcvd = DATA_TERM;
// usbKissTimer = 0;
// }
// }
//
// if((usbKissTimer > 0) && (ticks >= usbKissTimer)) //USB KISS timer timeout
// {
// usbcdcidx = 0;
// memset(usbcdcdata, 0, UARTBUFLEN);
// usbKissTimer = 0;
// }
if(UartUsb.rxType != DATA_NOTHING)
{
TermParse(&UartUsb);
UartClearRx(&UartUsb);
TermHandleSpecial(&UartUsb);
if(UartUsb.rxType != DATA_USB)
{
TermParse(&UartUsb);
UartClearRx(&UartUsb);
}
UartUsb.rxType = DATA_NOTHING;
}
if(Uart1.rxType != DATA_NOTHING)
{
@ -318,7 +293,7 @@ int main(void)
BeaconCheck(); //check beacons
if(ticks > 0xFFFFF000)
if(SysTickGet() > 0xFFFFF000)
NVIC_SystemReset();
}
/* USER CODE END 3 */


+ 87
- 123
Src/terminal.c View File

@ -22,91 +22,40 @@ along with VP-DigiConfig. If not, see <http://www.gnu.org/licenses/>.
#include "config.h"
#include "drivers/modem.h"
#include "ax25.h"
#include "drivers/systick.h"
void TermHandleSpecial(Uart *u)
{
if(u->mode == MODE_KISS) //don't do anything in KISS mode
{
u->lastRxBufferHead = 0;
return;
}
if(u->lastRxBufferHead >= u->rxBufferHead) //UART RX buffer index was probably cleared
u->lastRxBufferHead = 0;
//uint16_t spLastIdx[3] = {0, 0, 0}; //index buffer was "special" terminal cases
if(u->rxBuffer[u->rxBufferHead - 1] == '\b') //user entered backspace
{
if(u->rxBufferHead > 1) //there was some data in buffer
{
u->rxBufferHead -= 2; //remove backspace and preceding character
UartSendString(u, "\b \b", 3); //backspace (one character left), remove backspaced character (send space) and backspace again
if(u->lastRxBufferHead > 0)
u->lastRxBufferHead--; //1 character was removed
}
else //no preceding character
u->rxBufferHead = 0;
}
uint16_t t = u->rxBufferHead; //store last index
if(u->lastRxBufferHead < t) //local echo handling
{
UartSendString(u, &u->rxBuffer[u->lastRxBufferHead], t - u->lastRxBufferHead); //echo characters entered by user
if((u->rxBuffer[t - 1] == '\r') || (u->rxBuffer[t - 1] == '\n'))
UartSendString(u, "\r\n", 2);
u->lastRxBufferHead = t;
}
/**
* @brief Handle "special" terminal cases like backspace or local echo
* @param[in] src Source: TERM_USB, TERM_UART1, TERM_UART2
* @attention Must be called for every received data
*/
//void term_handleSpecial(Terminal_stream src)
//{
// if(src == TERM_USB)
// {
// if(USBmode == MODE_KISS) //don't do anything in KISS mode
// {
// spLastIdx[0] = 0;
// return;
// }
// if(spLastIdx[0] >= usbcdcidx) //USB RX buffer index was probably cleared
// spLastIdx[0] = 0;
//
// if(usbcdcdata[usbcdcidx - 1] == '\b') //user entered backspace
// {
// if(usbcdcidx > 1) //there was some data in buffer
// {
// usbcdcidx -= 2; //remove backspace and preceding character
// CDC_Transmit_FS((uint8_t*)"\b \b", 3); //backspace (one character left), remove backspaced character (send space) and backspace again
// if(spLastIdx[0] > 0)
// spLastIdx[0]--; //1 character was removed
// }
// else //there was only a backspace
// usbcdcidx = 0;
// }
// uint16_t t = usbcdcidx; //store last index
// if(spLastIdx[0] < t) //local echo handling
// {
// CDC_Transmit_FS(&usbcdcdata[spLastIdx[0]], t - spLastIdx[0]); //echo characters entered by user
// if((usbcdcdata[t - 1] == '\r') || (usbcdcdata[t - 1] == '\n'))
// CDC_Transmit_FS((uint8_t*)"\r\n", 2);
// spLastIdx[0] = t;
// }
// }
// else if((src == TERM_UART1) || (src == TERM_UART2))
// {
// Uart *u = &uart1;
// uint8_t nr = 1;
// if(src == TERM_UART2)
// {
// u = &uart2;
// nr = 2;
// }
//
//
// if(u->mode == MODE_KISS) //don't do anything in KISS mode
// {
// spLastIdx[nr] = 0;
// return;
// }
// if(spLastIdx[nr] >= u->bufrxidx) //UART RX buffer index was probably cleared
// spLastIdx[nr] = 0;
//
// if(u->bufrx[u->bufrxidx - 1] == '\b') //user entered backspace
// {
// if(u->bufrxidx > 1) //there was some data in buffer
// {
// u->bufrxidx -= 2; //remove backspace and preceding character
// uart_sendString(u, (uint8_t*)"\b \b", 3); //backspace (one character left), remove backspaced character (send space) and backspace again
// if(spLastIdx[nr] > 0)
// spLastIdx[nr]--; //1 character was removed
// }
// else //there was only a backspace
// u->bufrxidx = 0;
// }
// uint16_t t = u->bufrxidx; //store last index
// if(spLastIdx[nr] < t) //local echo handling
// {
// uart_sendString(u, &u->bufrx[spLastIdx[nr]], t - spLastIdx[nr]); //echo characters entered by user
// if((u->bufrx[t - 1] == '\r') || (u->bufrx[t - 1] == '\n'))
// uart_sendString(u, (uint8_t*)"\r\n", 2);
// spLastIdx[nr] = t;
// }
// uart_transmitStart(u);
// }
//
//}
}
static void sendKiss(Uart *port, uint8_t *buf, uint16_t len)
@ -165,6 +114,7 @@ static const char monitorHelp[] = "\r\nCommans available in monitor mode:\r\n"
"kiss - switches to KISS mode\r\n"
"config - switches to config mode\r\n"
"reboot - reboots the device\r\n"
"time - show time since boot\r\n"
"version - shows full firmware version info\r\n\r\n\r\n";
static const char configHelp[] = "\r\nCommands available in config mode:\r\n"
@ -174,6 +124,7 @@ static const char configHelp[] = "\r\nCommands available in config mode:\r\n"
"eraseall - erases all configurations and reboots the device\r\n"
"help - shows this help page\r\n"
"reboot - reboots the device\r\n"
"time - show time since boot\r\n"
"version - shows full firmware version info\r\n\r\n"
"call <callsign-SSID> - sets callsign with optional SSID\r\n"
"dest <address> - sets destination address\r\n"
@ -381,6 +332,12 @@ static void printConfig(Uart *src)
UartSendString(src, "Off\r\n", 0);
}
static void sendTime(Uart *src)
{
UartSendString(src, "Time since boot: ", 0);
UartSendNumber(src, SysTickGet() * SYSTICK_INTERVAL / 60000); //convert from ms to minutes
UartSendString(src, " minutes\r\n", 0);
}
void TermParse(Uart *src)
{
@ -414,7 +371,7 @@ void TermParse(Uart *src)
}
else if(!strncmp(cmd, "monitor", 7))
{
UartSendString(src, (uint8_t*)"USB switched to monitor mode\r\n", 0);
UartSendString(src, (uint8_t*)"Switched to monitor mode\r\n", 0);
src->mode = MODE_MONITOR;
return;
}
@ -423,7 +380,7 @@ void TermParse(Uart *src)
*/
else if((src->mode == MODE_KISS) && (src->rxType == DATA_KISS))
{
//Uart_txKiss(cmd, len); //if received KISS data, transmit KISS frame
Ax25TxKiss(src->rxBuffer, src->rxBufferHead);
return;
}
/*
@ -434,15 +391,22 @@ void TermParse(Uart *src)
if(!strncmp(cmd, "help", 4))
{
UartSendString(src, (char *)monitorHelp, 0);
return;
}
else if(!strncmp(cmd, "version", 7))
{
UartSendString(src, (char *)versionString, 0);
return;
}
else if(!strncmp(cmd, "reboot", 6))
{
NVIC_SystemReset();
}
else if(!strncmp(cmd, "time", 4))
{
sendTime(src);
return;
}
else if(!strncmp(cmd, "beacon ", 7))
{
if((cmd[7] >= '0') && (cmd[7] <= '7'))
@ -509,10 +473,17 @@ void TermParse(Uart *src)
if(!strncmp(cmd, "help", 4))
{
UartSendString(src, (uint8_t*)configHelp, 0);
return;
}
else if(!strncmp(cmd, "version", 7))
{
UartSendString(src, (uint8_t*)versionString, 0);
return;
}
else if(!strncmp(cmd, "time", 4))
{
sendTime(src);
return;
}
else if(!strncmp(cmd, "reboot", 6))
{
@ -531,6 +502,7 @@ void TermParse(Uart *src)
else if(!strncmp(cmd, "print", 5))
{
printConfig(src);
return;
}
else if(!strncmp(cmd, "list", 4)) //list calls in call filter table
{
@ -542,56 +514,60 @@ void TermParse(Uart *src)
if(DigiConfig.callFilter[i][0] != 0)
{
uint8_t cl[10] = {0};
uint8_t clidx = 0;
for(uint8_t h = 0; h < 6; h++)
uint8_t clIdx = 0;
for(uint8_t j = 0; j < 6; j++)
{
if(DigiConfig.callFilter[i][h] == 0xFF) //wildcard
if(DigiConfig.callFilter[i][j] == 0xFF) //wildcard
{
uint8_t g = h;
uint8_t j = 0;
while(g < 6)
bool partialWildcard = false;
for(uint8_t k = j; k < 6; k++) //check if there are all characters wildcarded
{
if(DigiConfig.callFilter[i][g] != 0xFF)
j = 1;
g++;
if(DigiConfig.callFilter[i][k] != 0xFF)
{
partialWildcard = true;
break;
}
}
if(j == 0)
if(partialWildcard == false) //all characters wildcarded
{
cl[clidx++] = '*';
cl[clIdx++] = '*';
break;
} else
}
else
{
cl[clidx++] = '?';
cl[clIdx++] = '?';
}
}
else
{
if(DigiConfig.callFilter[i][h] != ' ')
cl[clidx++] = DigiConfig.callFilter[i][h];
if(DigiConfig.callFilter[i][j] != ' ')
cl[clIdx++] = DigiConfig.callFilter[i][j];
}
}
if(DigiConfig.callFilter[i][6] == 0xFF)
if(DigiConfig.callFilter[i][6] == 0xFF) //wildcard on SSID
{
cl[clidx++] = '-';
cl[clidx++] = '*';
cl[clIdx++] = '-';
cl[clIdx++] = '*';
}
else if(DigiConfig.callFilter[i][6] != 0)
{
cl[clidx++] = '-';
cl[clIdx++] = '-';
if(DigiConfig.callFilter[i][6] > 9)
{
cl[clidx++] = (DigiConfig.callFilter[i][6] / 10) + 48;
cl[clidx++] = (DigiConfig.callFilter[i][6] % 10) + 48;
cl[clIdx++] = (DigiConfig.callFilter[i][6] / 10) + '0';
cl[clIdx++] = (DigiConfig.callFilter[i][6] % 10) + '0';
}
else cl[clidx++] = DigiConfig.callFilter[i][6] + 48;
else
cl[clIdx++] = DigiConfig.callFilter[i][6] + '0';
}
UartSendString(src, cl, 0);
}
else
UartSendString(src, "empty", 0);
UartSendString(src, "\r\n", 0);
return;
}
return;
}
/*
* Settings insertion handling
@ -604,11 +580,6 @@ void TermParse(Uart *src)
UartSendString(src, "Incorrect callsign!\r\n", 0);
return;
}
else
{
UartSendString(src, "OK\r\n", 0);
}
return;
}
else if(!strncmp(cmd, "dest", 4))
{
@ -617,10 +588,6 @@ void TermParse(Uart *src)
UartSendString(src, "Incorrect address!\r\n", 0);
return;
}
else
{
UartSendString(src, "OK\r\n", 0);
}
}
else if(!strncmp(cmd, "txdelay", 7))
{
@ -633,7 +600,6 @@ void TermParse(Uart *src)
else
{
Ax25Config.txDelayLength = (uint16_t)t;
UartSendString(src, "OK\r\n", 0);
}
}
else if(!strncmp(cmd, "txtail", 6))
@ -647,10 +613,8 @@ void TermParse(Uart *src)
else
{
Ax25Config.txTailLength = (uint16_t)t;
UartSendString(src, "OK\r\n", 0);
}
}
else if(!strncmp(cmd, "quiet", 5))
{
int64_t t = StrToInt(&cmd[6], len - 6);
@ -778,8 +742,6 @@ void TermParse(Uart *src)
{
err = true;
}
UartSendString(src, "OK\r\n", 0);
}
else if(!strncmp(cmd, "digi", 4))
{
@ -824,7 +786,6 @@ void TermParse(Uart *src)
UartSendString(src, "Incorrect alias!\r\n", 0);
return;
}
UartSendString(src, "OK\r\n", 0);
}
else if((!strncmp(&cmd[7], "max ", 4) || !strncmp(&cmd[7], "rep ", 4)) && (alno < 4))
{
@ -949,7 +910,7 @@ void TermParse(Uart *src)
uint8_t tmp[7] = {0};
uint16_t tmpIdx = 0;
for(uint16_t i = 0; i < len; i++)
for(uint16_t i = 0; i < (len - shift); i++)
{
if(cmd[shift + i] == '-') //SSID separator
{
@ -1042,7 +1003,10 @@ void TermParse(Uart *src)
err = true;
}
else
{
UartSendString(src, "Unknown command. For command list type \"help\"\r\n", 0);
return;
}
if(err)


+ 3
- 6
Src/usbd_cdc_if.c View File

@ -25,6 +25,7 @@
/* USER CODE BEGIN INCLUDE */
#include "drivers/uart.h"
#include "drivers/systick.h"
#include "terminal.h"
/* USER CODE END INCLUDE */
/* Private typedef -----------------------------------------------------------*/
@ -276,6 +277,7 @@ static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)
UartUsb.rxBufferHead %= UART_BUFFER_SIZE;
}
UartUsb.rxType = DATA_USB;
handleUsbInterrupt(&UartUsb);
return (USBD_OK);
@ -320,13 +322,8 @@ uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len)
/* USER CODE BEGIN PRIVATE_FUNCTIONS_IMPLEMENTATION */
static void handleUsbInterrupt(Uart *port)
{
// if(port->port == USART1) //handle special functions and characters
// term_handleSpecial(TERM_UART1);
// else if(port->port == USART2)
// term_handleSpecial(TERM_UART2);
if(port->mode == MODE_KISS)
port->kissTimer = ticks + (5000 / SYSTICK_INTERVAL); //set timeout to 5s in KISS mode
port->kissTimer = SysTickGet() + (5000 / SYSTICK_INTERVAL); //set timeout to 5s in KISS mode
if(port->rxBufferHead != 0)
{


+ 35
- 0
vp-digi Debug.cfg View File

@ -0,0 +1,35 @@
# This is an NUCLEO-F103RB board with a single STM32F103RBTx chip
#
# Generated by System Workbench for STM32
# Take care that such file, as generated, may be overridden without any early notice. Please have a look to debug launch configuration setup(s)
source [find interface/stlink.cfg]
set WORKAREASIZE 0x5000
transport select "hla_swd"
set CHIPNAME STM32F103RBTx
set BOARDNAME NUCLEO-F103RB
# CHIPNAMES state
set CHIPNAME_CPU0_ACTIVATED 1
# Enable debug when in low power modes
set ENABLE_LOW_POWER 1
# Stop Watchdog counters when halt
set STOP_WATCHDOG 1
# STlink Debug clock frequency
set CLOCK_FREQ 4000
# use software system reset
reset_config none
set CONNECT_UNDER_RESET 0
# BCTM CPU variables
source [find target/stm32f1x.cfg]

+ 35
- 0
vp-digi Release.cfg View File

@ -0,0 +1,35 @@
# This is an NUCLEO-F103RB board with a single STM32F103RBTx chip
#
# Generated by System Workbench for STM32
# Take care that such file, as generated, may be overridden without any early notice. Please have a look to debug launch configuration setup(s)
source [find interface/stlink.cfg]
set WORKAREASIZE 0x5000
transport select "hla_swd"
set CHIPNAME STM32F103RBTx
set BOARDNAME NUCLEO-F103RB
# CHIPNAMES state
set CHIPNAME_CPU0_ACTIVATED 1
# Enable debug when in low power modes
set ENABLE_LOW_POWER 1
# Stop Watchdog counters when halt
set STOP_WATCHDOG 1
# STlink Debug clock frequency
set CLOCK_FREQ 4000
# use software system reset
reset_config none
set CONNECT_UNDER_RESET 0
# BCTM CPU variables
source [find target/stm32f1x.cfg]

Loading…
Cancel
Save