@ -15,13 +15,14 @@ You should have received a copy of the GNU General Public License
along with VP - Digi . If not , see < http : / / www . gnu . org / licenses / > .
*/
# include "drivers/modem.h"
# include "drivers/systick.h"
# include "drivers/modem.h"
# include "ax25.h"
# include "stm32f1xx.h"
# include <math.h>
# include <stdlib.h>
# include "common.h"
# include <string.h>
# include "stm32f1xx.h"
/*
@ -53,10 +54,10 @@ along with VP-Digi. If not, see <http://www.gnu.org/licenses/>.
# define DCD300_INC 5
# define DCD300_PLLTUNE 0
# define N1200 8 / / samples per symbol
# define N9600 4
# define N300 16
# define NMAX 16 / / keep this value equal to the biggest Nx
# define N1200 8 / / samples per symbol @ fs=9600, oversampling = 38400 Hz
# define N9600 4 / / fs=38400, oversampling = 153600 Hz
# define N300 32 / / fs=9600, oversampling = 38400 Hz
# define NMAX 32 / / keep this value equal to the biggest Nx
# define PLL1200_STEP (((uint64_t)1 << 32) / N1200) / / PLL tick increment value
# define PLL9600_STEP (((uint64_t)1 << 32) / N9600)
@ -69,8 +70,9 @@ along with VP-Digi. If not, see <http://www.gnu.org/licenses/>.
# define PLL300_LOCKED_TUNE 0.74f
# define PLL300_NOT_LOCKED_TUNE 0.50f
# define AGC9600_ATTACK 0.08f
# define AGC9600_DECAY 0.0008f
/ / for 9600 modem AGC , but not used
/ / # define AGC9600_ATTACK 0.08f / / 0.08
/ / # define AGC9600_DECAY 0.0008f
# define DAC_SINE_SIZE 32 / / DAC sine table size
@ -86,6 +88,7 @@ static uint16_t dacSine[DAC_SINE_SIZE]; //sine samples for DAC
static uint8_t dacSineIdx ; / / current sine sample index
static uint16_t samples [ 4 ] ; / / very raw received samples , filled directly by DMA
static uint8_t currentSymbol ; / / current symbol for NRZI encoding
static uint8_t scrambledSymbol ; / / current symbol after scrambling
static float markFreq ; / / mark frequency
static float spaceFreq ; / / space frequency
static float baudRate ; / / baudrate
@ -94,12 +97,12 @@ static uint8_t spaceStep; //space timer step
static uint16_t baudRateStep ; / / baudrate timer step
static int16_t coeffHiI [ NMAX ] , coeffLoI [ NMAX ] , coeffHiQ [ NMAX ] , coeffLoQ [ NMAX ] ; / / correlator IQ coefficients
static uint8_t dcd = 0 ; / / multiplexed DCD state from both demodulators
static uint32_t lfsr = 0 ; / / LFSR for 9600 Bd
static uint32_t lfsr = 0xFFFFF ; / / LFSR for 9600 Bd
/**
* @ brief BPF filter with 2200 Hz tone 6 dB preemphasis ( it actually attenuates 1200 Hz tone by 6 dB )
*/
static int16_t bpf1200 [ 8 ] =
static const int16_t bpf1200 [ 8 ] =
{
728 ,
- 13418 ,
@ -114,7 +117,7 @@ static int16_t bpf1200[8] =
/**
* @ brief BPF filter with 2200 Hz tone 6 dB deemphasis
*/
static int16_t bpf1200Inv [ 8 ] =
static const int16_t bpf1200Inv [ 8 ] =
{
- 10513 ,
- 10854 ,
@ -126,29 +129,23 @@ static int16_t bpf1200Inv[8] =
- 879
} ;
/ / fs = 48 00, rectangular , fc1 = 14 00 , fc2 = 20 00, 0 dB @ 1600 Hz and 1800 Hz , N = 15 , gain 65536
static int16_t bpf300 [ 15 ] =
/ / fs = 96 00, rectangular , fc1 = 15 00 , fc2 = 19 00, 0 dB @ 1600 Hz and 1800 Hz , N = 15 , gain 65536
static const int16_t bpf300 [ 15 ] =
{
- 2327 , 3557 , 1048 , - 9284 , 12210 , - 3989 , - 9849 , 17268 , - 9849 , - 3989 , 12210 , - 9284 , 1048 , 3557 , - 2327 ,
186 , 8887 , 8184 , - 1662 , - 10171 , - 8509 , 386 , 5394 , 386 , - 8509 , - 10171 , - 1662 , 8184 , 8887 , 186 ,
} ;
# define BPF_MAX_TAPS 15
/ / fs = 48 00 Hz , raised cosine , fc = 300 Hz ( BR = 600 Bd ) , beta = 0.8 , N = 14 , gain = 65536
static int16_t lpf300 [ 14 ] =
/ / fs = 96 00 Hz , raised cosine , fc = 300 Hz ( BR = 600 Bd ) , beta = 0.8 , N = 14 , gain = 65536
static const int16_t lpf300 [ 14 ] =
{
741 , 1834 , 3216 , 4756 , 6268 , 7547 , 8402 , 8402 , 7547 , 6268 , 4756 , 3216 , 1834 , 741 ,
4385 , 4515 , 4627 , 4720 , 4793 , 4846 , 4878 , 4878 , 4846 , 4793 , 4720 , 4627 , 4515 , 4385 ,
} ;
# ifdef EXPERIMENTAL_LPF1200
/ / fs = 9600 Hz , raised cosine , fc = 600 Hz ( BR = 1200 Bd ) , beta = 0.8 , N = 14 , gain = 65536
static const int16_t lpf1200 [ 14 ] =
{
741 , 1834 , 3216 , 4756 , 6268 , 7547 , 8402 , 8402 , 7547 , 6268 , 4756 , 3216 , 1834 , 741 ,
} ;
# define LPF_MAX_TAPS 14
# else
static int16_t lpf1200 [ 15 ] =
/ / I don ' t remember what are this filter parameters ,
/ / but it seems to be the best among all I have tested
static const int16_t lpf1200 [ 15 ] =
{
- 6128 ,
- 5974 ,
@ -167,14 +164,11 @@ static int16_t lpf1200[15] =
- 6128
} ;
# define LPF_MAX_TAPS 15
# endif
/ / fs = 38400 Hz , Gaussian , fc = 4800 Hz ( 9600 Bd ) , N = 9 , gain = 65536
/ / seems like there is no difference between N = 9 and any higher order
/ / seems like there is almost no difference between N = 9 and any higher order
static int16_t lpf9600 [ 9 ] = { 497 , 2360 , 7178 , 13992 , 17478 , 13992 , 7178 , 2360 , 497 } ;
# define LPF_MAX_TAPS 15
# define FILTER_MAX_TAPS ((LPF_MAX_TAPS > BPF_MAX_TAPS) ? LPF_MAX_TAPS : BPF_MAX_TAPS)
@ -265,10 +259,8 @@ uint8_t ModemIsTxTestOngoing(void)
void ModemClearRMS ( uint8_t modem )
{
demodState [ modem ] . RMSenergy = 0 ;
demodState [ modem ] . RMSsampleCount = 0 ;
}
uint16_t ModemGetRMS ( uint8_t modem )
@ -287,16 +279,26 @@ enum ModemPrefilter ModemGetFilterType(uint8_t modem)
*/
static void setDcd ( uint8_t state )
{
if ( state )
{
GPIOC - > BSRR = GPIO_BSRR_BR13 ;
GPIOB - > BSRR = GPIO_BSRR_BS5 ;
}
else
{
GPIOC - > BSRR = GPIO_BSRR_BS13 ;
GPIOB - > BSRR = GPIO_BSRR_BR5 ;
}
if ( state )
{
GPIOC - > BSRR = GPIO_BSRR_BR13 ;
GPIOB - > BSRR = GPIO_BSRR_BS5 ;
}
else
{
GPIOC - > BSRR = GPIO_BSRR_BS13 ;
GPIOB - > BSRR = GPIO_BSRR_BR5 ;
}
}
static inline uint8_t descramble ( uint8_t in )
{
/ / G3RUH descrambling ( x ^ 17 + x ^ 12 + 1 )
uint8_t bit = ( ( lfsr & 0x10000 ) > 0 ) ^ ( ( lfsr & 0x800 ) > 0 ) ^ ( in > 0 ) ;
lfsr < < = 1 ;
lfsr | = in ;
return bit ;
}
static inline uint8_t scramble ( uint8_t in )
@ -311,14 +313,13 @@ static inline uint8_t scramble(uint8_t in)
/**
* @ brief ISR for demodulator
* Called at 9600 Hz by DMA
*/
void DMA1_Channel2_IRQHandler ( void ) __attribute__ ( ( interrupt ) ) ;
void DMA1_Channel2_IRQHandler ( void )
{
if ( DMA1 - > ISR & DMA_ISR_TCIF2 )
{
DMA1 - > IFCR | = DMA_IFCR_CTCIF2 ;
if ( DMA1 - > ISR & DMA_ISR_TCIF2 )
{
DMA1 - > IFCR | = DMA_IFCR_CTCIF2 ;
int32_t sample = ( ( samples [ 0 ] + samples [ 1 ] + samples [ 2 ] + samples [ 3 ] ) > > 1 ) - 4095 ; / / calculate input sample ( decimation )
@ -345,83 +346,95 @@ void DMA1_Channel2_IRQHandler(void)
}
}
/**
* @ brief ISR for pushing DAC samples
*/
void TIM1_UP_IRQHandler ( void ) __attribute__ ( ( interrupt ) ) ;
void TIM1_UP_IRQHandler ( void )
void TIM1_UP_IRQHandler ( void ) __attribute__ ( ( interrupt ) ) ;
void TIM1_UP_IRQHandler ( void )
{
TIM1 - > SR & = ~ TIM_SR_UIF ;
int32_t sample = 0 ;
if ( ModemConfig . modem = = MODEM_9600 )
{
if ( ModemConfig . usePWM )
sample = scrambledSymbol ? 89 : 0 ;
else
sample = scrambledSymbol ? 15 : 0 ;
sample = filter ( & demodState [ 0 ] . lpf , sample ) ;
if ( sample < 0 )
sample = 0 ;
else if ( sample > 15 )
sample = 15 ;
}
else
{
sample = dacSine [ dacSineIdx ] ;
dacSineIdx + + ;
dacSineIdx & = ( DAC_SINE_SIZE - 1 ) ;
}
if ( ModemConfig . usePWM )
{
TIM4 - > CCR1 = sample ;
}
else
{
GPIOB - > ODR & = ~ 0xF000 ; / / zero 4 oldest bits
GPIOB - > ODR | = ( sample < < 12 ) ; / / write sample to 4 oldest bits
}
}
void txBit ( )
{
TIM1 - > SR & = ~ TIM_SR_UIF ;
int32_t sample = 0 ;
if ( ModemConfig . modem = = MODEM_9600 )
{
if ( ModemConfig . usePWM )
sample = currentSymbol ? 90 : 0 ;
else
sample = currentSymbol ? 15 : 1 ;
sample = filter ( & demodState [ 0 ] . lpf , sample ) ;
}
else
{
sample = dacSine [ dacSineIdx ] ;
dacSineIdx + + ;
dacSineIdx & = ( DAC_SINE_SIZE - 1 ) ;
}
if ( ModemConfig . usePWM )
if ( Ax25GetTxBit ( ) = = 0 ) / / get next bit and check if it ' s 0
{
TIM4 - > CCR1 = sample ;
}
else
{
GPIOB - > ODR & = ~ 0xF000 ; / / zero 4 oldest bits
GPIOB - > ODR | = ( sample < < 12 ) ; / / write sample to 4 oldest bits
currentSymbol ^ = 1 ; / / change symbol - NRZI encoding
}
/ / if 1 , no symbol change
scrambledSymbol = scramble ( currentSymbol ) ;
}
/**
* @ brief ISR for baudrate generator timer . NRZI encoding is done here .
*/
void TIM3_IRQHandler ( void ) __attribute__ ( ( interrupt ) ) ;
void TIM3_IRQHandler ( void )
{
TIM3 - > SR & = ~ TIM_SR_UIF ;
if ( txTestState = = TEST_DISABLED ) / / transmitting normal data
{
if ( Ax25GetTxBit ( ) = = 0 ) / / get next bit and check if it ' s 0
{
currentSymbol ^ = 1 ; / / change symbol - NRZI encoding
}
/ / if 1 , no symbol change
}
else / / transmit test mode
{
currentSymbol ^ = 1 ; / / change symbol
}
TIM1 - > CNT = 0 ;
if ( ModemConfig . modem = = MODEM_9600 )
{
current Symbol = scramble ( currentSymbol ) ;
}
else
{
if ( currentSymbol ) / / current symbol is space
TIM1 - > ARR = spaceStep ;
else / / mark
TIM1 - > ARR = markStep ;
}
}
void TIM3_IRQHandler ( void ) __attribute__ ( ( interrupt ) ) ;
void TIM3_IRQHandler ( void )
{
TIM3 - > SR & = ~ TIM_SR_UIF ;
if ( txTestState = = TEST_DISABLED ) / / transmitting normal data
{
if ( Ax25GetTxBit ( ) = = 0 ) / / get next bit and check if it ' s 0
{
currentSymbol ^ = 1 ; / / change symbol - NRZI encoding
}
/ / if 1 , no symbol change
}
else / / transmit test mode
{
currentSymbol ^ = 1 ; / / change symbol
}
TIM1 - > CNT = 0 ;
if ( ModemConfig . modem = = MODEM_9600 )
{
scrambled Symbol = scramble ( currentSymbol ) ;
}
else
{
if ( currentSymbol ) / / current symbol is space
TIM1 - > ARR = spaceStep ;
else / / mark
TIM1 - > ARR = markStep ;
}
}
/**
@ -468,6 +481,7 @@ static int32_t demodulate(int16_t sample, struct DemodState *dem)
}
/ / DCD using PLL
/ / PLL is running nominally at 1200 Hz ( = baudrate )
/ / PLL timer is counting up and eventually overflows to a minimal negative value
@ -480,11 +494,11 @@ static int32_t demodulate(int16_t sample, struct DemodState *dem)
/ / when configured properly , it ' s generally immune to noise , as the detected tone changes much faster than 1200 baud
/ / it ' s also important to set some maximum value for DCD counter , otherwise the DCD is " sticky "
dem - > dcdPll = ( signed ) ( ( unsigned ) ( dem - > dcdPll ) + ( ( unsigned ) dem - > pll ) ) ; / / keep PLL ticking at the frequency equal to baudrate
dem - > dcdPll = ( signed ) ( ( unsigned ) ( dem - > dcdPll ) + ( unsigned ) ( dem - > pllStep ) ) ; / / keep PLL ticking at the frequency equal to baudrate
if ( ( sample > 0 ) ! = dem - > dcdLastSymbol ) / / tone changed
{
if ( abs ( dem - > dcdPll ) < dem - > dcdInc ) / / tone change occurred near zero
if ( abs ( dem - > dcdPll ) < dem - > pllStep ) / / tone change occurred near zero
dem - > dcdCounter + = dem - > dcdInc ; / / increase DCD counter
else / / tone change occurred far from zero
{
@ -504,43 +518,41 @@ static int32_t demodulate(int16_t sample, struct DemodState *dem)
else / / below DCD threshold
dem - > dcd = 0 ; / / no DCD
/ / TODO : check if demodulator works well after all changes
sample = filter ( & dem - > lpf , sample ) ;
if ( ModemConfig . modem = = MODEM_9600 )
{
/ / AGC
if ( sample > = dem - > peak )
{
dem - > peak + = ( ( ( int32_t ) ( AGC9600_ATTACK * ( float ) 32768 ) * ( int32_t ) ( sample - dem - > peak ) ) > > 15 ) ;
}
else
{
dem - > peak + = ( ( ( int32_t ) ( AGC9600_DECAY * ( float ) 32768 ) * ( int32_t ) ( sample - dem - > peak ) ) > > 15 ) ;
}
if ( sample < = dem - > valley )
{
dem - > valley + = ( ( ( int32_t ) ( AGC9600_ATTACK * ( float ) 32768 ) * ( int32_t ) ( sample - dem - > valley ) ) > > 15 ) ;
}
else
{
dem - > valley + = ( ( ( int32_t ) ( AGC9600_DECAY * ( float ) 32768 ) * ( int32_t ) ( sample - dem - > valley ) ) > > 15 ) ;
}
/ / remove DC component ( subtract average value of peaks )
/ / and normalize to 32768 peak - to - peak ( - 16384 : 16384 )
/ / 32768 is equal to 1 < < 15
if ( dem - > peak > dem - > valley )
{
sample = ( ( ( ( int32_t ) ( sample ) - ( ( int32_t ) ( dem - > peak + dem - > valley ) > > 1 ) ) < < 15 ) / ( int32_t ) ( dem - > peak - dem - > valley ) ) ;
}
}
/ / if ( ModemConfig . modem = = MODEM_9600 )
/ / {
/ / / / AGC , seems to be not needed
/ / if ( sample > = dem - > peak )
/ / {
/ / dem - > peak + = ( ( ( int32_t ) ( AGC9600_ATTACK * ( float ) 32768 ) * ( int32_t ) ( sample - dem - > peak ) ) > > 15 ) ;
/ / }
/ / else
/ / {
/ / dem - > peak + = ( ( ( int32_t ) ( AGC9600_DECAY * ( float ) 32768 ) * ( int32_t ) ( sample - dem - > peak ) ) > > 15 ) ;
/ / }
/ / if ( sample < = dem - > valley )
/ / {
/ / dem - > valley + = ( ( ( int32_t ) ( AGC9600_ATTACK * ( float ) 32768 ) * ( int32_t ) ( sample - dem - > valley ) ) > > 15 ) ;
/ / }
/ / else
/ / {
/ / dem - > valley + = ( ( ( int32_t ) ( AGC9600_DECAY * ( float ) 32768 ) * ( int32_t ) ( sample - dem - > valley ) ) > > 15 ) ;
/ / }
/ / / / remove DC component ( subtract average value of peaks )
/ / / / and normalize to 32768 peak - to - peak ( - 16384 : 16384 )
/ / / / 32768 is equal to 1 < < 15
/ / if ( dem - > peak > dem - > valley )
/ / {
/ / sample = ( ( ( ( int32_t ) ( sample ) - ( ( int32_t ) ( dem - > peak + dem - > valley ) > > 1 ) ) < < 15 ) / ( int32_t ) ( dem - > peak - dem - > valley ) ) ;
/ / }
/ / }
return sample > 0 ;
}
/**
* @ brief Decode received symbol : bit recovery , NRZI decoding and pass the decoded bit to higher level protocol
* @ param [ in ] symbol Received symbol
@ -555,7 +567,7 @@ static void decode(uint8_t symbol, uint8_t demod)
/ / Current symbol is sampled at PLL counter overflow , so symbol transition should occur at PLL counter zero
int32_t previous = dem - > pll ; / / store last clock state
dem - > pll = ( signed ) ( ( unsigned ) ( dem - > pll ) + ( unsigned ) dem - > pllStep ) ; / / keep PLL running
dem - > pll = ( signed ) ( ( unsigned ) ( dem - > pll ) + ( unsigned ) ( dem - > pllStep ) ) ; / / keep PLL running
dem - > rawSymbols < < = 1 ; / / store received unsynchronized symbol
dem - > rawSymbols | = ( symbol & 1 ) ;
@ -572,7 +584,7 @@ static void decode(uint8_t symbol, uint8_t demod)
sym = 0 ;
if ( ModemConfig . modem = = MODEM_9600 )
sym = scramble ( sym ) ; / / descramble
sym = de scramble( sym ) ; / / descramble
dem - > syncSymbols | = sym ;
@ -589,12 +601,11 @@ static void decode(uint8_t symbol, uint8_t demod)
if ( ( ( dem - > rawSymbols & 0x03 ) = = 0 b10 ) | | ( ( dem - > rawSymbols & 0x03 ) = = 0 b01 ) ) / / if there was a symbol transition , adjust PLL
{
if ( Ax25GetRxStage ( demod ) ! = RX_STAGE_FRAME ) / / not in a frame
if ( ! dem - > dcd ) / / PLL not locked
{
dem - > pll = ( int ) ( dem - > pll * dem - > pllNotLockedAdjust ) ; / / adjust PLL faster
}
else / / in a frame
else / / PLL locked
{
dem - > pll = ( int ) ( dem - > pll * dem - > pllLockedAdjust ) ; / / adjust PLL slower
}
@ -606,62 +617,62 @@ static void decode(uint8_t symbol, uint8_t demod)
void ModemTxTestStart ( enum ModemTxTestMode type )
{
if ( txTestState ! = TEST_DISABLED ) / / TX test is already running
ModemTxTestStop ( ) ; / / stop this test
setPtt ( 1 ) ; / / PTT on
txTestState = type ;
TIM2 - > CR1 & = ~ TIM_CR1_CEN ; / / disable RX timer
TIM1 - > CR1 | = TIM_CR1_CEN ; / / enable DAC timer
NVIC_DisableIRQ ( DMA1_Channel2_IRQn ) ; / / disable RX DMA interrupt
NVIC_EnableIRQ ( TIM1_UP_IRQn ) ; / / enable DAC interrupt
if ( type = = TEST_MARK )
{
TIM1 - > ARR = markStep ;
}
else if ( type = = TEST_SPACE )
{
TIM1 - > ARR = spaceStep ;
}
else / / alternating tones
{
/ / enable baudrate generator
TIM3 - > CR1 = TIM_CR1_CEN ; / / enable timer
NVIC_EnableIRQ ( TIM3_IRQn ) ; / / enable interrupt in NVIC
}
if ( txTestState ! = TEST_DISABLED ) / / TX test is already running
ModemTxTestStop ( ) ; / / stop this test
setPtt ( 1 ) ; / / PTT on
txTestState = type ;
TIM2 - > CR1 & = ~ TIM_CR1_CEN ; / / disable RX timer
TIM1 - > CR1 | = TIM_CR1_CEN ; / / enable DAC timer
NVIC_DisableIRQ ( DMA1_Channel2_IRQn ) ; / / disable RX DMA interrupt
NVIC_EnableIRQ ( TIM1_UP_IRQn ) ; / / enable DAC interrupt
if ( type = = TEST_MARK )
{
TIM1 - > ARR = markStep ;
}
else if ( type = = TEST_SPACE )
{
TIM1 - > ARR = spaceStep ;
}
else / / alternating tones
{
/ / enable baudrate generator
TIM3 - > CR1 = TIM_CR1_CEN ; / / enable timer
NVIC_EnableIRQ ( TIM3_IRQn ) ; / / enable interrupt in NVIC
}
}
void ModemTxTestStop ( void )
{
txTestState = TEST_DISABLED ;
txTestState = TEST_DISABLED ;
TIM3 - > CR1 & = ~ TIM_CR1_CEN ; / / disable baudrate timer
TIM1 - > CR1 & = ~ TIM_CR1_CEN ; / / disable DAC timer
TIM2 - > CR1 | = TIM_CR1_CEN ; / / enable RX timer
TIM3 - > CR1 & = ~ TIM_CR1_CEN ; / / disable baudrate timer
TIM1 - > CR1 & = ~ TIM_CR1_CEN ; / / disable DAC timer
TIM2 - > CR1 | = TIM_CR1_CEN ; / / enable RX timer
NVIC_DisableIRQ ( TIM3_IRQn ) ;
NVIC_DisableIRQ ( TIM1_UP_IRQn ) ;
NVIC_EnableIRQ ( DMA1_Channel2_IRQn ) ;
NVIC_DisableIRQ ( TIM3_IRQn ) ;
NVIC_DisableIRQ ( TIM1_UP_IRQn ) ;
NVIC_EnableIRQ ( DMA1_Channel2_IRQn ) ;
setPtt ( 0 ) ; / / PTT off
setPtt ( 0 ) ; / / PTT off
}
void ModemTransmitStart ( void )
{
setPtt ( 1 ) ; / / PTT on
setPtt ( 1 ) ; / / PTT on
TIM3 - > CR1 = TIM_CR1_CEN ;
TIM1 - > CR1 = TIM_CR1_CEN ;
TIM2 - > CR1 & = ~ TIM_CR1_CEN ;
TIM3 - > CR1 = TIM_CR1_CEN ;
TIM1 - > CR1 = TIM_CR1_CEN ;
TIM2 - > CR1 & = ~ TIM_CR1_CEN ;
NVIC_DisableIRQ ( DMA1_Channel2_IRQn ) ;
NVIC_EnableIRQ ( TIM1_UP_IRQn ) ;
NVIC_EnableIRQ ( TIM3_IRQn ) ;
NVIC_DisableIRQ ( DMA1_Channel2_IRQn ) ;
NVIC_EnableIRQ ( TIM1_UP_IRQn ) ;
NVIC_EnableIRQ ( TIM3_IRQn ) ;
}
@ -689,10 +700,10 @@ void ModemTransmitStop(void)
*/
static void setPtt ( uint8_t state )
{
if ( state )
GPIOB - > BSRR = GPIO_BSRR_BS7 ;
else
GPIOB - > BSRR = GPIO_BSRR_BR7 ;
if ( state )
GPIOB - > BSRR = GPIO_BSRR_BS7 ;
else
GPIOB - > BSRR = GPIO_BSRR_BR7 ;
}
@ -710,86 +721,108 @@ void ModemInit(void)
* TIM2 is the RX sampling timer with no software interrupt , but it directly calls DMA
*/
RCC - > APB2ENR | = RCC_APB2ENR_IOPBEN ;
RCC - > APB2ENR | = RCC_APB2ENR_IOPCEN ;
RCC - > APB2ENR | = RCC_APB2ENR_IOPAEN ;
RCC - > APB1ENR | = RCC_APB1ENR_TIM2EN ;
RCC - > APB1ENR | = RCC_APB1ENR_TIM3EN ;
RCC - > APB2ENR | = RCC_APB2ENR_TIM1EN ;
RCC - > APB2ENR | = RCC_APB2ENR_ADC1EN ;
RCC - > AHBENR | = RCC_AHBENR_DMA1EN ;
RCC - > APB2ENR | = RCC_APB2ENR_IOPBEN ;
RCC - > APB2ENR | = RCC_APB2ENR_IOPCEN ;
RCC - > APB2ENR | = RCC_APB2ENR_IOPAEN ;
RCC - > APB1ENR | = RCC_APB1ENR_TIM2EN ;
RCC - > APB1ENR | = RCC_APB1ENR_TIM3EN ;
RCC - > APB2ENR | = RCC_APB2ENR_TIM1EN ;
RCC - > APB2ENR | = RCC_APB2ENR_ADC1EN ;
RCC - > AHBENR | = RCC_AHBENR_DMA1EN ;
GPIOC - > CRH | = GPIO_CRH_MODE13_1 ; / / DCD LED on PC13
GPIOC - > CRH & = ~ GPIO_CRH_MODE13_0 ;
GPIOC - > CRH & = ~ GPIO_CRH_CNF13 ;
GPIOC - > CRH | = GPIO_CRH_MODE13_1 ; / / DCD LED on PC13
GPIOC - > CRH & = ~ GPIO_CRH_MODE13_0 ;
GPIOC - > CRH & = ~ GPIO_CRH_CNF13 ;
GPIOB - > CRH & = ~ 0xFFFF0000 ; / / R2R output on PB12 - PB15
GPIOB - > CRH | = 0x22220000 ;
GPIOB - > CRH & = ~ 0xFFFF0000 ; / / R2R output on PB12 - PB15
GPIOB - > CRH | = 0x22220000 ;
GPIOA - > CRL & = ~ GPIO_CRL_CNF0 ; / / ADC input on PA0
GPIOA - > CRL & = ~ GPIO_CRL_MODE0 ;
GPIOA - > CRL & = ~ GPIO_CRL_CNF0 ; / / ADC input on PA0
GPIOA - > CRL & = ~ GPIO_CRL_MODE0 ;
GPIOB - > CRL | = GPIO_CRL_MODE7_1 ; / / PTT output on PB7
GPIOB - > CRL & = ~ GPIO_CRL_MODE7_0 ;
GPIOB - > CRL & = ~ GPIO_CRL_CNF7 ;
GPIOB - > CRL | = GPIO_CRL_MODE7_1 ; / / PTT output on PB7
GPIOB - > CRL & = ~ GPIO_CRL_MODE7_0 ;
GPIOB - > CRL & = ~ GPIO_CRL_CNF7 ;
GPIOB - > CRL | = GPIO_CRL_MODE5_1 ; / / 2 nd DCD LED on PB5
GPIOB - > CRL & = ~ GPIO_CRL_MODE5_0 ;
GPIOB - > CRL & = ~ GPIO_CRL_CNF5 ;
GPIOB - > CRL | = GPIO_CRL_MODE5_1 ; / / 2 nd DCD LED on PB5
GPIOB - > CRL & = ~ GPIO_CRL_MODE5_0 ;
GPIOB - > CRL & = ~ GPIO_CRL_CNF5 ;
RCC - > CFGR | = RCC_CFGR_ADCPRE_1 ; / / ADC prescaler / 6
RCC - > CFGR & = ~ RCC_CFGR_ADCPRE_0 ;
RCC - > CFGR | = RCC_CFGR_ADCPRE_1 ; / / ADC prescaler / 6
RCC - > CFGR & = ~ RCC_CFGR_ADCPRE_0 ;
ADC1 - > CR2 | = ADC_CR2_CONT ; / / continuous conversion
ADC1 - > CR2 | = ADC_CR2_EXTSEL ;
ADC1 - > SQR1 & = ~ ADC_SQR1_L ; / / 1 conversion
ADC1 - > SMPR2 | = ADC_SMPR2_SMP0_2 ; / / 41.5 cycle sampling
ADC1 - > SQR3 & = ~ ADC_SQR3_SQ1 ; / / channel 0 is first in the sequence
ADC1 - > CR2 | = ADC_CR2_ADON ; / / ADC on
ADC1 - > CR2 | = ADC_CR2_CONT ; / / continuous conversion
ADC1 - > CR2 | = ADC_CR2_EXTSEL ;
ADC1 - > SQR1 & = ~ ADC_SQR1_L ; / / 1 conversion
ADC1 - > SMPR2 | = ADC_SMPR2_SMP0_2 ; / / 41.5 cycle sampling
ADC1 - > SQR3 & = ~ ADC_SQR3_SQ1 ; / / channel 0 is first in the sequence
ADC1 - > CR2 | = ADC_CR2_ADON ; / / ADC on
ADC1 - > CR2 | = ADC_CR2_RSTCAL ; / / calibrate ADC
while ( ADC1 - > CR2 & ADC_CR2_RSTCAL )
;
ADC1 - > CR2 | = ADC_CR2_CAL ;
while ( ADC1 - > CR2 & ADC_CR2_CAL )
;
ADC1 - > CR2 | = ADC_CR2_RSTCAL ; / / calibrate ADC
while ( ADC1 - > CR2 & ADC_CR2_RSTCAL )
;
ADC1 - > CR2 | = ADC_CR2_CAL ;
while ( ADC1 - > CR2 & ADC_CR2_CAL )
;
ADC1 - > CR2 | = ADC_CR2_EXTTRIG ;
ADC1 - > CR2 | = ADC_CR2_SWSTART ; / / start ADC conversion
ADC1 - > CR2 | = ADC_CR2_EXTTRIG ;
ADC1 - > CR2 | = ADC_CR2_SWSTART ; / / start ADC conversion
/ / prepare DMA
DMA1_Channel2 - > CCR | = DMA_CCR_MSIZE_0 ; / / 16 bit memory region
DMA1_Channel2 - > CCR & = ~ DMA_CCR_MSIZE_1 ;
DMA1_Channel2 - > CCR | = DMA_CCR_PSIZE_0 ;
DMA1_Channel2 - > CCR & = ~ DMA_CCR_PSIZE_1 ;
/ / prepare DMA
DMA1_Channel2 - > CCR | = DMA_CCR_MSIZE_0 ; / / 16 bit memory region
DMA1_Channel2 - > CCR & = ~ DMA_CCR_MSIZE_1 ;
DMA1_Channel2 - > CCR | = DMA_CCR_PSIZE_0 ;
DMA1_Channel2 - > CCR & = ~ DMA_CCR_PSIZE_1 ;
DMA1_Channel2 - > CCR | = DMA_CCR_MINC | DMA_CCR_CIRC | DMA_CCR_TCIE ; / / circular mode , memory increment and interrupt
DMA1_Channel2 - > CNDTR = 4 ; / / 4 samples
DMA1_Channel2 - > CPAR = ( uint32_t ) & ( ADC1 - > DR ) ; / / ADC data register address
DMA1_Channel2 - > CMAR = ( uint32_t ) samples ; / / sample buffer address
DMA1_Channel2 - > CCR | = DMA_CCR_EN ; / / enable DMA
DMA1_Channel2 - > CCR | = DMA_CCR_MINC | DMA_CCR_CIRC | DMA_CCR_TCIE ; / / circular mode , memory increment and interrupt
DMA1_Channel2 - > CNDTR = 4 ; / / 4 samples
DMA1_Channel2 - > CPAR = ( uint32_t ) & ( ADC1 - > DR ) ; / / ADC data register address
DMA1_Channel2 - > CMAR = ( uint32_t ) samples ; / / sample buffer address
DMA1_Channel2 - > CCR | = DMA_CCR_EN ; / / enable DMA
NVIC_EnableIRQ ( DMA1_Channel2_IRQn ) ;
NVIC_EnableIRQ ( DMA1_Channel2_IRQn ) ;
/ / RX sampling timer
TIM2 - > PSC = 8 ; / / 72 / 9 = 8 MHz
TIM2 - > DIER | = TIM_DIER_UDE ; / / enable calling DMA on timer tick
/ / RX sampling timer
TIM2 - > PSC = 8 ; / / 72 / 9 = 8 MHz
TIM2 - > DIER | = TIM_DIER_UDE ; / / enable calling DMA on timer tick
/ / TX DAC timer
TIM1 - > PSC = 17 ; / / 72 / 18 = 4 MHz
TIM1 - > DIER | = TIM_DIER_UIE ;
/ / TX DAC timer
TIM1 - > PSC = 17 ; / / 72 / 18 = 4 MHz
TIM1 - > DIER | = TIM_DIER_UIE ;
/ / baudrate timer
TIM3 - > PSC = 71 ; / / 72 / 72 = 1 MHz
TIM3 - > DIER | = TIM_DIER_UIE ;
/ / baudrate timer
TIM3 - > PSC = 71 ; / / 72 / 72 = 1 MHz
TIM3 - > DIER | = TIM_DIER_UIE ;
if ( ( ModemConfig . modem = = MODEM_1200 ) | | ( ModemConfig . modem = = MODEM_1200_V23 ) )
if ( ( ModemConfig . modem = = MODEM_1200 ) | | ( ModemConfig . modem = = MODEM_1200_V23 )
# ifdef ENABLE_PSK
| | ( ModemConfig . modem = = MODEM_BPSK_1200 ) | | ( ModemConfig . modem = = MODEM_QPSK_1200 )
# endif
)
{
demodCount = 2 ;
/ / use one modem in FX .25 mode
/ / FX .25 ( RS ) functions are not reentrant
/ / also they are BIG
if (
# ifdef ENABLE_FX25
Ax25Config . fx25
# else
0
# endif
# ifdef ENABLE_PSK
| | ( ModemConfig . modem = = MODEM_BPSK_1200 ) | | ( ModemConfig . modem = = MODEM_QPSK_1200 )
# endif
)
demodCount = 1 ;
else
demodCount = 2 ;
N = N1200 ;
baudRate = 1200.f ;
@ -811,27 +844,39 @@ void ModemInit(void)
demodState [ 1 ] . dcdDec = DCD1200_DEC ;
demodState [ 1 ] . dcdAdjust = DCD1200_PLLTUNE ;
demodState [ 0 ] . prefilter = PREFILTER_NONE ;
demodState [ 0 ] . lpf . coeffs = lpf1200 ;
demodState [ 0 ] . lpf . taps = sizeof ( lpf1200 ) / sizeof ( * lpf1200 ) ;
demodState [ 0 ] . lpf . gainShift = 0 ; / / not important , output is always compared with 0
demodState [ 1 ] . lpf . coeffs = lpf1200 ;
demodState [ 1 ] . prefilter = PREFILTER_NONE ;
demodState [ 1 ] . lpf . coeffs = ( int16_t * ) lpf1200 ;
demodState [ 1 ] . lpf . taps = sizeof ( lpf1200 ) / sizeof ( * lpf1200 ) ;
demodState [ 1 ] . lpf . gainShift = 0 ; / / not important , output is always compared with 0
demodState [ 1 ] . lpf . gainShift = 15 ;
demodState [ 0 ] . lpf . coeffs = ( int16_t * ) lpf1200 ;
demodState [ 0 ] . lpf . taps = sizeof ( lpf1200 ) / sizeof ( * lpf1200 ) ;
demodState [ 0 ] . lpf . gainShift = 15 ;
demodState [ 0 ] . prefilter = PREFILTER_NONE ;
# ifdef ENABLE_PSK
if ( ( ModemConfig . modem ! = MODEM_BPSK_1200 ) & & ( ModemConfig . modem ! = MODEM_QPSK_1200 ) )
{
# endif
if ( ModemConfig . flatAudioIn ) / / when used with flat audio input , use deemphasis and flat modems
{
demodState [ 1 ] . prefilter = PREFILTER_DEEMPHASIS ;
demodState [ 1 ] . bpf . coeffs = bpf1200Inv ;
demodState [ 1 ] . bpf . taps = sizeof ( bpf1200Inv ) / sizeof ( * bpf1200Inv ) ;
demodState [ 1 ] . bpf . gainShift = 15 ;
# ifdef ENABLE_FX25
if ( Ax25Config . fx25 )
demodState [ 0 ] . prefilter = PREFILTER_NONE ;
else
# endif
demodState [ 0 ] . prefilter = PREFILTER_DEEMPHASIS ;
demodState [ 0 ] . bpf . coeffs = ( int16_t * ) bpf1200Inv ;
demodState [ 0 ] . bpf . taps = sizeof ( bpf1200Inv ) / sizeof ( * bpf1200Inv ) ;
demodState [ 0 ] . bpf . gainShift = 15 ;
}
else / / when used with normal ( filtered ) audio input , use flat and preemphasis modems
{
demodState [ 1 ] . prefilter = PREFILTER_PREEMPHASIS ;
demodState [ 1 ] . bpf . coeffs = bpf1200 ;
demodState [ 1 ] . bpf . taps = sizeof ( bpf1200 ) / sizeof ( * bpf1200 ) ;
demodState [ 1 ] . bpf . gainShift = 15 ;
demodState [ 0 ] . prefilter = PREFILTER_PREEMPHASIS ;
demodState [ 0 ] . bpf . coeffs = ( int16_t * ) bpf1200 ;
demodState [ 0 ] . bpf . taps = sizeof ( bpf1200 ) / sizeof ( * bpf1200 ) ;
demodState [ 0 ] . bpf . gainShift = 15 ;
}
if ( ModemConfig . modem = = MODEM_1200 ) / / Bell 202
@ -844,6 +889,13 @@ void ModemInit(void)
markFreq = 1300.f ;
spaceFreq = 2100.f ;
}
# ifdef ENABLE_PSK
}
else
{
markFreq = 1700.f ; / / use as center frequency in PSK
}
# endif
TIM2 - > ARR = 207 ; / / 8 MHz / 208 = ~ 38400 Hz ( 4 * 9600 Hz for 4 x oversampling )
}
@ -865,14 +917,14 @@ void ModemInit(void)
demodState [ 0 ] . dcdAdjust = DCD300_PLLTUNE ;
demodState [ 0 ] . prefilter = PREFILTER_FLAT ;
demodState [ 0 ] . bpf . coeffs = bpf300 ;
demodState [ 0 ] . bpf . coeffs = ( int16_t * ) bpf300 ;
demodState [ 0 ] . bpf . taps = sizeof ( bpf300 ) / sizeof ( * bpf300 ) ;
demodState [ 0 ] . bpf . gainShift = 16 ;
demodState [ 0 ] . lpf . coeffs = lpf300 ;
demodState [ 0 ] . lpf . coeffs = ( int16_t * ) lpf300 ;
demodState [ 0 ] . lpf . taps = sizeof ( lpf300 ) / sizeof ( * lpf300 ) ;
demodState [ 0 ] . lpf . gainShift = 0 ; / / not important , output is always compared with 0
demodState [ 0 ] . lpf . gainShift = 15 ;
TIM2 - > ARR = 416 ; / / 8 MHz / 416 = ~ 192 00 Hz ( 4 * 48 00 Hz for 4 x oversampling )
TIM2 - > ARR = 207 ; / / 8 MHz / 208 = ~ 384 00 Hz ( 4 * 96 00 Hz for 4 x oversampling )
}
else if ( ModemConfig . modem = = MODEM_9600 )
{
@ -891,7 +943,7 @@ void ModemInit(void)
demodState [ 0 ] . prefilter = PREFILTER_NONE ;
/ / this filter will be used for RX and TX
demodState [ 0 ] . lpf . coeffs = lpf9600 ;
demodState [ 0 ] . lpf . coeffs = ( int16_t * ) lpf9600 ;
demodState [ 0 ] . lpf . taps = sizeof ( lpf9600 ) / sizeof ( * lpf9600 ) ;
demodState [ 0 ] . lpf . gainShift = 16 ;
@ -925,21 +977,21 @@ void ModemInit(void)
if ( ModemConfig . usePWM )
{
RCC - > APB1ENR | = RCC_APB1ENR_TIM4EN ; / / configure timer
RCC - > APB1ENR | = RCC_APB1ENR_TIM4EN ; / / configure timer
GPIOB - > CRL | = GPIO_CRL_CNF6_1 ; / / configure pin for PWM
GPIOB - > CRL | = GPIO_CRL_MODE6 ;
GPIOB - > CRL & = ~ GPIO_CRL_CNF6_0 ;
GPIOB - > CRL | = GPIO_CRL_CNF6_1 ; / / configure pin for PWM
GPIOB - > CRL | = GPIO_CRL_MODE6 ;
GPIOB - > CRL & = ~ GPIO_CRL_CNF6_0 ;
/ / set up PWM generation
TIM4 - > PSC = 7 ; / / 72 MHz / 8 = 9 MHz
TIM4 - > ARR = 90 ; / / 9 MHz / 90 = 100 kHz
/ / set up PWM generation
TIM4 - > PSC = 7 ; / / 72 MHz / 8 = 9 MHz
TIM4 - > ARR = 90 ; / / 9 MHz / 90 = 100 kHz
TIM4 - > CCMR1 | = TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2 ;
TIM4 - > CCER | = TIM_CCER_CC1E ;
TIM4 - > CCR1 = 44 ; / / initial duty cycle
TIM4 - > CCMR1 | = TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2 ;
TIM4 - > CCER | = TIM_CCER_CC1E ;
TIM4 - > CCR1 = 44 ; / / initial duty cycle
TIM4 - > CR1 | = TIM_CR1_CEN ;
TIM4 - > CR1 | = TIM_CR1_CEN ;
}
}