diff --git a/.cproject b/.cproject
index 6dcb8d2..9caa672 100644
--- a/.cproject
+++ b/.cproject
@@ -1,398 +1,202 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2dba6c9..d1736d1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,14 @@
+# 2.1.0 (2025-03-04)
+## New features
+* Digipeater disable input at PB0 (pull to GND to disable digipeater)
+* Digipeater active LED at PB1 (high state when active)
+## Bug fixes
+* Hopefully resolved KISS TX deadlock ultimately...
+* No more problems when entering callsigns without explicit SSID
+## Other
+* do...while(0) guards on multiline macros
+## Known bugs
+* none
# 2.0.1 (2025-02-06)
## New features
* none
@@ -6,7 +17,7 @@
## Other
* none
## Known bugs
-* none
+* KISS TX deadlock still present anyway...
# 2.0.0 (2023-09-09)
## New features
* New modems: AFSK Bell 103 (300 Bd, 1600/1800 Hz), GFSK G3RUH (9600 Bd), AFSK V.23 (1200 Bd, 1300/2100 Hz)
diff --git a/Core/Inc/digipeater.h b/Core/Inc/digipeater.h
index 8decfc9..01b478a 100644
--- a/Core/Inc/digipeater.h
+++ b/Core/Inc/digipeater.h
@@ -1,5 +1,5 @@
/*
-Copyright 2020-2023 Piotr Wilkon
+Copyright 2020-2025 Piotr Wilkon
This file is part of VP-Digi.
@@ -59,9 +59,14 @@ void DigiDigipeat(uint8_t *frame, uint16_t len);
void DigiStoreDeDupe(uint8_t *buf, uint16_t size);
/**
- * @brief Refresh viscous-delay buffers and push frames to TX buffer if necessary
+ * @brief Initialize digipeater
+ */
+void DigiInitialize(void);
+
+/**
+ * @brief Update internal digipeater state
* @attention Should be called in main loop
*/
-void DigiViscousRefresh(void);
+void DigiUpdateState(void);
#endif /* DIGIPEATER_H_ */
diff --git a/Core/Inc/drivers/digipeater_ll.h b/Core/Inc/drivers/digipeater_ll.h
new file mode 100644
index 0000000..666469b
--- /dev/null
+++ b/Core/Inc/drivers/digipeater_ll.h
@@ -0,0 +1,62 @@
+/*
+Copyright 2020-2025 Piotr Wilkon
+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
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+
+VP-Digi is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with VP-Digi. If not, see .
+*/
+
+/*
+ * This file is kind of HAL for digipeater external controls and signalization
+ */
+
+#ifndef DRIVERS_DIGIPEATER_LL_H_
+#define DRIVERS_DIGIPEATER_LL_H_
+
+#include
+
+#if defined(STM32F103xB) || defined(STM32F103x8)
+
+#include "stm32f1xx.h"
+
+#define DIGIPEATER_LL_LED_ON() (GPIOB->BSRR = GPIO_BSRR_BS1)
+#define DIGIPEATER_LL_LED_OFF() (GPIOB->BSRR = GPIO_BSRR_BR1)
+
+/**
+ * @brief Get external digipeater disable state
+ * @return True if disabled, false if enabled
+ */
+#define DIGIPEATER_LL_GET_DISABLE_STATE() (!(GPIOB->IDR & GPIO_IDR_IDR0))
+
+#define DIGIPEATER_LL_INITIALIZE_RCC() do { \
+ RCC->APB2ENR |= RCC_APB2ENR_IOPBEN; \
+} while(0); \
+
+#define DIGIPEATER_LL_INITIALIZE_INPUTS_OUTPUTS() do { \
+ /* Digi disable input: PB0 (active low - pull up); digi active output: PB1 (active high) */ \
+ /* Digi disable input: PB0 */ \
+ GPIOB->CRL &= ~GPIO_CRL_MODE0; \
+ GPIOB->CRL &= ~GPIO_CRL_CNF0_0; \
+ GPIOB->CRL |= GPIO_CRL_CNF0_1; \
+ GPIOB->BSRR = GPIO_BSRR_BS0; \
+ /* Digi active LED: PB1 */ \
+ GPIOB->CRL |= GPIO_CRL_MODE1_1; \
+ GPIOB->CRL &= ~GPIO_CRL_MODE1_0; \
+ GPIOB->CRL &= ~GPIO_CRL_CNF1; \
+} while(0); \
+
+
+
+#endif
+
+#endif
diff --git a/Core/Inc/drivers/modem_ll.h b/Core/Inc/drivers/modem_ll.h
index 90a3c82..70bf938 100644
--- a/Core/Inc/drivers/modem_ll.h
+++ b/Core/Inc/drivers/modem_ll.h
@@ -1,5 +1,5 @@
/*
-Copyright 2020-2023 Piotr Wilkon
+Copyright 2020-2025 Piotr Wilkon
This file is part of VP-Digi.
VP-Digi is free software: you can redistribute it and/or modify
@@ -49,42 +49,42 @@ along with VP-Digi. If not, see .
#define MODEM_LL_BAUDRATE_TIMER_IRQ TIM3_IRQn
#define MODEM_LL_DMA_TRANSFER_COMPLETE_FLAG (DMA1->ISR & DMA_ISR_TCIF2)
-#define MODEM_LL_DMA_CLEAR_TRANSFER_COMPLETE_FLAG() {DMA1->IFCR |= DMA_IFCR_CTCIF2;}
+#define MODEM_LL_DMA_CLEAR_TRANSFER_COMPLETE_FLAG() (DMA1->IFCR |= DMA_IFCR_CTCIF2)
-#define MODEM_LL_BAUDRATE_TIMER_CLEAR_INTERRUPT_FLAG() {TIM3->SR &= ~TIM_SR_UIF;}
-#define MODEM_LL_BAUDRATE_TIMER_ENABLE() {TIM3->CR1 = TIM_CR1_CEN;}
-#define MODEM_LL_BAUDRATE_TIMER_DISABLE() {TIM3->CR1 &= ~TIM_CR1_CEN;}
-#define MODEM_LL_BAUDRATE_TIMER_SET_RELOAD_VALUE(val) {TIM3->ARR = (val);}
+#define MODEM_LL_BAUDRATE_TIMER_CLEAR_INTERRUPT_FLAG() (TIM3->SR &= ~TIM_SR_UIF)
+#define MODEM_LL_BAUDRATE_TIMER_ENABLE() (TIM3->CR1 = TIM_CR1_CEN)
+#define MODEM_LL_BAUDRATE_TIMER_DISABLE() (TIM3->CR1 &= ~TIM_CR1_CEN)
+#define MODEM_LL_BAUDRATE_TIMER_SET_RELOAD_VALUE(val) (TIM3->ARR = (val))
-#define MODEM_LL_DAC_TIMER_CLEAR_INTERRUPT_FLAG {TIM1->SR &= ~TIM_SR_UIF;}
-#define MODEM_LL_DAC_TIMER_SET_RELOAD_VALUE(val) {TIM1->ARR = (val);}
-#define MODEM_LL_DAC_TIMER_SET_CURRENT_VALUE(val) {TIM1->CNT = (val);}
-#define MODEM_LL_DAC_TIMER_ENABLE() {TIM1->CR1 |= TIM_CR1_CEN;}
-#define MODEM_LL_DAC_TIMER_DISABLE() {TIM1->CR1 &= ~TIM_CR1_CEN;}
+#define MODEM_LL_DAC_TIMER_CLEAR_INTERRUPT_FLAG (TIM1->SR &= ~TIM_SR_UIF)
+#define MODEM_LL_DAC_TIMER_SET_RELOAD_VALUE(val) (TIM1->ARR = (val))
+#define MODEM_LL_DAC_TIMER_SET_CURRENT_VALUE(val) (TIM1->CNT = (val))
+#define MODEM_LL_DAC_TIMER_ENABLE() (TIM1->CR1 |= TIM_CR1_CEN)
+#define MODEM_LL_DAC_TIMER_DISABLE() (TIM1->CR1 &= ~TIM_CR1_CEN)
-#define MODEM_LL_ADC_TIMER_ENABLE() {TIM2->CR1 |= TIM_CR1_CEN;}
-#define MODEM_LL_ADC_TIMER_DISABLE() {TIM2->CR1 &= ~TIM_CR1_CEN;}
+#define MODEM_LL_ADC_TIMER_ENABLE() (TIM2->CR1 |= TIM_CR1_CEN)
+#define MODEM_LL_ADC_TIMER_DISABLE() (TIM2->CR1 &= ~TIM_CR1_CEN)
-#define MODEM_LL_PWM_PUT_VALUE(value) {TIM4->CCR1 = (value);}
+#define MODEM_LL_PWM_PUT_VALUE(value) (TIM4->CCR1 = (value))
-#define MODEM_LL_R2R_PUT_VALUE(value) {GPIOB->ODR &= ~0xF000; \
- GPIOB->ODR |= ((uint32_t)(value) << 12); }\
+#define MODEM_LL_R2R_PUT_VALUE(value) do {GPIOB->ODR &= ~0xF000; \
+ GPIOB->ODR |= ((uint32_t)(value) << 12); } while(0); \
-#define MODEM_LL_DCD_LED_ON() { \
+#define MODEM_LL_DCD_LED_ON() do { \
GPIOC->BSRR = GPIO_BSRR_BR13; \
GPIOB->BSRR = GPIO_BSRR_BS5; \
-} \
+} while(0); \
-#define MODEM_LL_DCD_LED_OFF() { \
+#define MODEM_LL_DCD_LED_OFF() do { \
GPIOC->BSRR = GPIO_BSRR_BS13; \
GPIOB->BSRR = GPIO_BSRR_BR5; \
-} \
+} while(0); \
-#define MODEM_LL_PTT_ON() {GPIOB->BSRR = GPIO_BSRR_BS7;}
-#define MODEM_LL_PTT_OFF() {GPIOB->BSRR = GPIO_BSRR_BR7;}
+#define MODEM_LL_PTT_ON() (GPIOB->BSRR = GPIO_BSRR_BS7)
+#define MODEM_LL_PTT_OFF() (GPIOB->BSRR = GPIO_BSRR_BR7)
-#define MODEM_LL_INITIALIZE_RCC() { \
+#define MODEM_LL_INITIALIZE_RCC() do { \
RCC->APB2ENR |= RCC_APB2ENR_IOPBEN; \
RCC->APB2ENR |= RCC_APB2ENR_IOPCEN; \
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN; \
@@ -94,9 +94,9 @@ along with VP-Digi. If not, see .
RCC->APB2ENR |= RCC_APB2ENR_ADC1EN; \
RCC->AHBENR |= RCC_AHBENR_DMA1EN; \
RCC->APB1ENR |= RCC_APB1ENR_TIM4EN; \
-} \
+} while(0); \
-#define MODEM_LL_INITIALIZE_OUTPUTS() { \
+#define MODEM_LL_INITIALIZE_OUTPUTS() do { \
/* DCD LEDs: PC13 (cathode driven - built-in LED on Blue Pill) and PB5 (anode driven) */ \
GPIOC->CRH |= GPIO_CRH_MODE13_1; \
GPIOC->CRH &= ~GPIO_CRH_MODE13_0; \
@@ -115,9 +115,9 @@ along with VP-Digi. If not, see .
GPIOB->CRL |= GPIO_CRL_CNF6_1; \
GPIOB->CRL |= GPIO_CRL_MODE6; \
GPIOB->CRL &= ~GPIO_CRL_CNF6_0; \
-} \
+} while(0); \
-#define MODEM_LL_INITIALIZE_ADC() { \
+#define MODEM_LL_INITIALIZE_ADC() do { \
/* ADC input: PA0 */ \
GPIOA->CRL &= ~GPIO_CRL_CNF0; \
GPIOA->CRL &= ~GPIO_CRL_MODE0; \
@@ -140,9 +140,9 @@ along with VP-Digi. If not, see .
; \
ADC1->CR2 |= ADC_CR2_EXTTRIG; \
ADC1->CR2 |= ADC_CR2_SWSTART; \
-} \
+} while(0); \
-#define MODEM_LL_INITIALIZE_DMA(buffer) { \
+#define MODEM_LL_INITIALIZE_DMA(buffer) do { \
/* 16 bit memory region */ \
DMA1_Channel2->CCR |= DMA_CCR_MSIZE_0; \
DMA1_Channel2->CCR &= ~DMA_CCR_MSIZE_1; \
@@ -154,28 +154,28 @@ along with VP-Digi. If not, see .
DMA1_Channel2->CPAR = (uintptr_t)&(ADC1->DR); \
DMA1_Channel2->CMAR = (uintptr_t)buffer; \
DMA1_Channel2->CCR |= DMA_CCR_EN; \
-} \
+} while(0); \
-#define MODEM_LL_ADC_TIMER_INITIALIZE() { \
+#define MODEM_LL_ADC_TIMER_INITIALIZE() do { \
/* 72 / 9 = 8 MHz */ \
TIM2->PSC = 8; \
/* enable DMA call instead of standard interrupt */ \
TIM2->DIER |= TIM_DIER_UDE; \
-} \
+} while(0); \
-#define MODEM_LL_DAC_TIMER_INITIALIZE() { \
+#define MODEM_LL_DAC_TIMER_INITIALIZE() do { \
/* 72 / 4 = 18 MHz */ \
TIM1->PSC = 3; \
TIM1->DIER |= TIM_DIER_UIE; \
-} \
+} while(0); \
-#define MODEM_LL_BAUDRATE_TIMER_INITIALIZE() { \
+#define MODEM_LL_BAUDRATE_TIMER_INITIALIZE() do { \
/* 72 / 4 = 18 MHz */ \
TIM3->PSC = 3; \
TIM3->DIER |= TIM_DIER_UIE; \
-} \
+} while(0); \
-#define MODEM_LL_PWM_INITIALIZE() { \
+#define MODEM_LL_PWM_INITIALIZE() do { \
/* 72 / 3 = 24 MHz to provide 8 bit resolution at around 100 kHz */ \
TIM4->PSC = 2; \
/* 24 MHz / 258 = 93 kHz */ \
@@ -183,9 +183,9 @@ along with VP-Digi. If not, see .
TIM4->CCMR1 |= TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2; \
TIM4->CCER |= TIM_CCER_CC1E; \
TIM4->CR1 |= TIM_CR1_CEN; \
-} \
+} while(0); \
-#define MODEM_LL_ADC_SET_SAMPLE_RATE(rate) {TIM2->ARR = (8000000 / (rate)) - 1;}
+#define MODEM_LL_ADC_SET_SAMPLE_RATE(rate) (TIM2->ARR = (8000000 / (rate)) - 1)
#define MODEM_LL_DAC_TIMER_CALCULATE_STEP(frequency) ((18000000 / (frequency)) - 1)
diff --git a/Core/Inc/drivers/uart_ll.h b/Core/Inc/drivers/uart_ll.h
index be7e033..d74ea7a 100644
--- a/Core/Inc/drivers/uart_ll.h
+++ b/Core/Inc/drivers/uart_ll.h
@@ -1,5 +1,5 @@
/*
-Copyright 2020-2023 Piotr Wilkon
+Copyright 2020-2025 Piotr Wilkon
This file is part of VP-Digi.
VP-Digi is free software: you can redistribute it and/or modify
@@ -27,22 +27,22 @@ along with VP-Digi. If not, see .
#include "stm32f1xx.h"
-#define UART_LL_ENABLE(port) {port->CR1 |= USART_CR1_RXNEIE | USART_CR1_TE | USART_CR1_RE | USART_CR1_UE | USART_CR1_IDLEIE;}
-#define UART_LL_DISABLE(port) {port->CR1 &= (~USART_CR1_RXNEIE) & (~USART_CR1_TE) & (~USART_CR1_RE) & (~USART_CR1_UE) & (~USART_CR1_IDLEIE);}
+#define UART_LL_ENABLE(port) (port->CR1 |= USART_CR1_RXNEIE | USART_CR1_TE | USART_CR1_RE | USART_CR1_UE | USART_CR1_IDLEIE)
+#define UART_LL_DISABLE(port) (port->CR1 &= (~USART_CR1_RXNEIE) & (~USART_CR1_TE) & (~USART_CR1_RE) & (~USART_CR1_UE) & (~USART_CR1_IDLEIE))
#define UART_LL_CHECK_RX_NOT_EMPTY(port) (port->SR & USART_SR_RXNE)
-#define UART_LL_CLEAR_RX_NOT_EMPTY(port) {port->SR &= ~USART_SR_RXNE;}
+#define UART_LL_CLEAR_RX_NOT_EMPTY(port) (port->SR &= ~USART_SR_RXNE)
#define UART_LL_CHECK_TX_EMPTY(port) (port->SR & USART_SR_TXE)
-#define UART_LL_ENABLE_TX_EMPTY_INTERRUPT(port) {port->CR1 |= USART_CR1_TXEIE;}
-#define UART_LL_DISABLE_TX_EMPTY_INTERRUPT(port) {port->CR1 &= ~USART_CR1_TXEIE;}
+#define UART_LL_ENABLE_TX_EMPTY_INTERRUPT(port) (port->CR1 |= USART_CR1_TXEIE)
+#define UART_LL_DISABLE_TX_EMPTY_INTERRUPT(port) (port->CR1 &= ~USART_CR1_TXEIE)
#define UART_LL_CHECK_ENABLED_TX_EMPTY_INTERRUPT(port) (port->CR1 & USART_CR1_TXEIE)
#define UART_LL_CHECK_RX_IDLE(port) (port->SR & USART_SR_IDLE)
#define UART_LL_GET_DATA(port) (port->DR)
-#define UART_LL_PUT_DATA(port, data) {port->DR = (data);}
+#define UART_LL_PUT_DATA(port, data) (port->DR = (data))
#define UART_LL_UART1_INTERUPT_HANDLER USART1_IRQHandler
@@ -54,7 +54,7 @@ along with VP-Digi. If not, see .
#define UART_LL_UART1_IRQ USART1_IRQn
#define UART_LL_UART2_IRQ USART2_IRQn
-#define UART_LL_UART1_INITIALIZE_PERIPHERAL(baudrate) { \
+#define UART_LL_UART1_INITIALIZE_PERIPHERAL(baudrate) do { \
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN; \
RCC->APB2ENR |= RCC_APB2ENR_USART1EN; \
GPIOA->CRH |= GPIO_CRH_MODE9_1; \
@@ -63,9 +63,9 @@ along with VP-Digi. If not, see .
GPIOA->CRH |= GPIO_CRH_CNF10_0; \
GPIOA->CRH &= ~GPIO_CRH_CNF10_1; \
UART_LL_UART1_STRUCTURE->BRR = (SystemCoreClock / baudrate); \
-} \
+} while(0); \
-#define UART_LL_UART2_INITIALIZE_PERIPHERAL(baudrate) { \
+#define UART_LL_UART2_INITIALIZE_PERIPHERAL(baudrate) do { \
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN; \
RCC->APB1ENR |= RCC_APB1ENR_USART2EN; \
GPIOA->CRL |= GPIO_CRL_MODE2_1; \
@@ -74,7 +74,7 @@ along with VP-Digi. If not, see .
GPIOA->CRL |= GPIO_CRL_CNF3_0; \
GPIOA->CRL &= ~GPIO_CRL_CNF3_1; \
UART_LL_UART2_STRUCTURE->BRR = (SystemCoreClock / (baudrate * 2)); \
-} \
+} while(0); \
#endif
diff --git a/Core/Inc/drivers/usb.h b/Core/Inc/drivers/usb.h
index a8c40a7..0b33672 100644
--- a/Core/Inc/drivers/usb.h
+++ b/Core/Inc/drivers/usb.h
@@ -1,5 +1,5 @@
/*
-Copyright 2020-2023 Piotr Wilkon
+Copyright 2020-2025 Piotr Wilkon
This file is part of VP-Digi.
@@ -27,7 +27,7 @@ along with VP-Digi. If not, see .
#include "stm32f1xx.h"
-#define USB_FORCE_REENUMERATION() { \
+#define USB_FORCE_REENUMERATION() do { \
/* Pull D+ to ground for a moment to force reenumeration */ \
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN; \
GPIOA->CRH |= GPIO_CRH_MODE12_1; \
@@ -36,7 +36,7 @@ along with VP-Digi. If not, see .
Delay(100); \
GPIOA->CRH &= ~GPIO_CRH_MODE12; \
GPIOA->CRH |= GPIO_CRH_CNF12_0; \
-} \
+} while(0); \
#endif
diff --git a/Core/Src/common.c b/Core/Src/common.c
index 1bc1237..5d9b5d0 100644
--- a/Core/Src/common.c
+++ b/Core/Src/common.c
@@ -32,7 +32,7 @@ struct _GeneralConfig GeneralConfig =
};
-const char versionString[] = "VP-Digi v. 2.0.1\r\nThe open-source standalone APRS digipeater controller and KISS TNC\r\n"
+const char versionString[] = "VP-Digi v. 2.1.0\r\nThe open-source standalone APRS digipeater controller and KISS TNC\r\n"
#ifdef ENABLE_FX25
"With FX.25 support compiled-in\r\n"
#endif
@@ -221,27 +221,27 @@ bool ParseCallsign(const char *in, uint16_t size, uint8_t *out)
bool ParseCallsignWithSsid(const char *in, uint16_t size, uint8_t *out, uint8_t *ssid)
{
- uint16_t ssidPosition = size;
+ uint16_t hyphenPosition = size;
for(uint16_t i = 0; i < size; i++)
{
if(in[i] == '-')
{
- ssidPosition = i;
+ hyphenPosition = i;
break;
}
}
- ssidPosition++;
- if(!ParseCallsign(in, ssidPosition - 1, out))
+ if(!ParseCallsign(in, hyphenPosition, out))
return false;
- if(ssidPosition == size)
+ if(hyphenPosition == size)
{
*ssid = 0;
return true;
}
- if(!ParseSsid(&in[ssidPosition], size - ssidPosition, ssid))
+ if(!ParseSsid(&in[hyphenPosition + 1], size - hyphenPosition - 1, ssid))
return false;
+
return true;
}
diff --git a/Core/Src/digipeater.c b/Core/Src/digipeater.c
index bf87e46..9da0967 100644
--- a/Core/Src/digipeater.c
+++ b/Core/Src/digipeater.c
@@ -1,5 +1,5 @@
/*
-Copyright 2020-2023 Piotr Wilkon
+Copyright 2020-2025 Piotr Wilkon
This file is part of VP-Digi.
@@ -25,6 +25,7 @@ along with VP-Digi. If not, see .
#include
#include
#include
+#include "drivers/digipeater_ll.h"
struct _DigiConfig DigiConfig;
@@ -77,7 +78,7 @@ static uint8_t viscousCheckAndRemove(uint32_t hash)
-void DigiViscousRefresh(void)
+static void DigiViscousRefresh(void)
{
if(DigiConfig.viscous == 0) //viscous digipeating disabled on every alias
{
@@ -310,7 +311,7 @@ static void makeFrame(uint8_t *frame, uint16_t elStart, uint16_t len, uint32_t h
void DigiDigipeat(uint8_t *frame, uint16_t len)
{
- if(!DigiConfig.enable)
+ if(!DigiConfig.enable || DIGIPEATER_LL_GET_DISABLE_STATE())
return;
uint16_t t = 13; //start from first byte that can contain path end bit
@@ -468,3 +469,24 @@ void DigiStoreDeDupe(uint8_t *buf, uint16_t size)
deDupeCount++;
}
+
+void DigiInitialize(void)
+{
+ DIGIPEATER_LL_INITIALIZE_RCC();
+ DIGIPEATER_LL_INITIALIZE_INPUTS_OUTPUTS();
+}
+
+void DigiUpdateState(void)
+{
+ if(DigiConfig.enable)
+ {
+ if(DIGIPEATER_LL_GET_DISABLE_STATE())
+ DIGIPEATER_LL_LED_OFF();
+ else
+ DIGIPEATER_LL_LED_ON();
+ }
+ else
+ DIGIPEATER_LL_LED_OFF();
+
+ DigiViscousRefresh();
+}
diff --git a/Core/Src/main.c b/Core/Src/main.c
index 1762f5c..c61e219 100644
--- a/Core/Src/main.c
+++ b/Core/Src/main.c
@@ -16,7 +16,7 @@
******************************************************************************
*/
/*
-Copyright 2020-2023 Piotr Wilkon
+Copyright 2020-2025 Piotr Wilkon
This file is part of VP-Digi.
@@ -230,6 +230,8 @@ int main(void)
Fx25Init();
#endif
+ DigiInitialize();
+
UartInit(&Uart1, UART_LL_UART1_STRUCTURE, Uart1.baudrate);
UartInit(&Uart2, UART_LL_UART2_STRUCTURE, Uart2.baudrate);
UartInit(&UartUsb, NULL, 1);
@@ -253,7 +255,7 @@ int main(void)
if(Ax25GetReceivedFrameBitmap())
handleFrame();
- DigiViscousRefresh(); //refresh viscous-delay buffers
+ DigiUpdateState(); //update digipeater state
Ax25TransmitBuffer(); //transmit buffer (will return if nothing to be transmitted)
@@ -272,7 +274,18 @@ int main(void)
TermParse(&UartUsb);
UartClearRx(&UartUsb);
}
- UartUsb.rxType = DATA_NOTHING;
+ //previously there was just UartUsb.rxType = DATA_NOTHING, which could introduce deadlocks
+ //assume that we were here, because rxType was DATA_USB, but in the meantime a new USB interrupt fired and rxType changed to DATA_KISS,
+ //and the KISS parsing handler would set kissProcessingOngoing to 1. Then, we change rxType to DATA_NOTHING and are left in an incorrect scenario, when
+ //rxType is DATA_NOTHING, and kissProcessingOngoing is 1, which is a clear deadlock, because then DATA_KISS can never be reached again.
+ //That's why it is necessary to disable interrupts and check one more time for rxType before clearing it
+ else
+ {
+ __disable_irq();
+ if(UartUsb.rxType == DATA_USB)
+ UartUsb.rxType = DATA_NOTHING;
+ __enable_irq();
+ }
}
if(Uart1.rxType != DATA_NOTHING)
{
diff --git a/Core/Src/uart.c b/Core/Src/uart.c
index a4f0e43..2d91a92 100644
--- a/Core/Src/uart.c
+++ b/Core/Src/uart.c
@@ -218,7 +218,9 @@ void UartConfig(Uart *port, uint8_t state)
void UartClearRx(Uart *port)
{
+ __disable_irq();
port->rxBufferHead = 0;
port->rxType = DATA_NOTHING;
+ __enable_irq();
}
diff --git a/doc/manual.md b/doc/manual.md
index 4dffe71..73ff9dc 100644
--- a/doc/manual.md
+++ b/doc/manual.md
@@ -1,5 +1,5 @@
# VP-Digi - documentation
-Copyright 2023-2024 Piotr Wilkoń\
+Copyright 2023-2025 Piotr Wilkoń\
Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is available under [LICENSE_FDL](LICENSE_FDL).\
The changelog is placed at the bottom of this document.
## Table of contents
@@ -33,7 +33,6 @@ The changelog is placed at the bottom of this document.
- [3.2.2.2. Transmission](#3222-transmission)
- [3.2.3. Digipeater](#323-digipeater)
- [4. Documentation changelog](#4-documentation-changelog)
- - [2023/09/06](#20230906)
## 1. Functional description
VP-Digi is a standalone AX.25 digipeater controller (e.g., APRS) and a KISS TNC controller. The software is equipped with the following modems:
@@ -350,6 +349,8 @@ If *viscous delay* functionality is enabled for the matched alias, the completed
In addition, the *viscous delay* buffer is regularly refreshed. If the specified time has passed, and the packet has not been removed from the buffer (see *the beginning of this section*), its hash is saved to the duplicate filter buffer, the packet is transmitted, and removed from the *viscous delay* buffer.
## 4. Documentation changelog
+### 2025/03/04
+- New schematic - Piotr Wilkoń
### 2024/05/16
- Default UART parameters and backspace handling - Piotr Wilkoń
### 2023/11/12
diff --git a/doc/manual_pl.md b/doc/manual_pl.md
index b42f2e9..e764ea3 100644
--- a/doc/manual_pl.md
+++ b/doc/manual_pl.md
@@ -1,5 +1,5 @@
# VP-Digi - dokumentacja
-Copyright 2023-2024 Piotr Wilkoń\
+Copyright 2023-2025 Piotr Wilkoń\
Zezwala się na kopiowanie, rozpowszechnianie i/lub modyfikowanie tego dokumentu na warunkach Licencji GNU Wolnej Dokumentacji (GNU Free Documentation License) w wersji 1.3 lub dowolnej nowszej opublikowanej przez Free Software Foundation,
bez żadnych Części nienaruszalnych, bez Tekstów przedniej
lub tylnej strony okładki. Egzemplarz licencji zamieszczono w pliku [LICENSE_FDL](LICENSE_FDL).\
@@ -35,7 +35,6 @@ Rejestr zmian dostępny jest na końcu tego dokumentu.
- [3.2.2.2. Nadawanie](#3222-nadawanie)
- [3.2.3. Digipeater](#323-digipeater)
- [4. Rejestr zmian dokumentacji](#4-rejestr-zmian-dokumentacji)
- - [2023/09/06](#20230906)
## 1. Opis funkcjonalny
VP-Digi jest samodzielnym sterownikiem digipeatera AX.25 (np. APRS) oraz kontrolerem TNC w standardzie KISS.\
@@ -334,6 +333,8 @@ Jeśli dla dopasowanego aliasu włączona jest funkcja *viscous delay*, to gotow
Ponadto regularnie odświeżany jest bufor funkcji *viscous delay*. Jeśli minął odpowiedni czas i pakiet nie został usunięty z bufora (patrz *początek tej sekcji*), to jego hasz jest zapisywany do bufora filtra duplikatów, pakiet jest wysyłany i usuwany z bufora *viscous delay*.
## 4. Rejestr zmian dokumentacji
+### 2025/03/04
+- Nowy schemat - Piotr Wilkoń
### 2024/05/16
- Dodanie informacji o domyślnej konfiguracji UART oraz obsłudze backspace - Piotr Wilkoń
### 2023/11/12
diff --git a/doc/schematic.png b/doc/schematic.png
index ccf9d29..5499c2c 100644
Binary files a/doc/schematic.png and b/doc/schematic.png differ