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