62 lines
3.5 KiB
Markdown
62 lines
3.5 KiB
Markdown
FARTrx
|
|
======
|
|
|
|
RX Path
|
|
-------
|
|
- Timer 1 runs continuously at 8khz.
|
|
- The HALs `pwm_hz` function is used to set up the timer,
|
|
as it is easier than setting the registers manually,
|
|
and we need the comparator match event to trigger the ADC.
|
|
- ADC conversions are triggered externally at each comparator match for Timer1 Channel1
|
|
- ADC runs ins Scan-mode, it samples PA2 first, then PA3
|
|
- DMA2 Stream 0 is set up to for device to memory, with memory increment,
|
|
transfer complete interrupt and double buffering disabled.
|
|
- The HAL requires the DMA transfer instance to take ownership of both buffers,
|
|
for the double buffered mode, to swap to the second buffer immediately,
|
|
once the first on is full. This means it would effectively require three buffers,
|
|
on to write to, one as a followup buffer and third one that's read by the program.
|
|
However, we can get away without double buffering, keeping the code a lot simpler.
|
|
There are 1/8kHz = 125uS between firing the transfer complete interrupt
|
|
once the first buffer is full and the next ADC conversion.
|
|
That's enough time swap buffers in the interrupt handler.
|
|
- In the DMA transfer complete interrupt the full buffer is moved out of the DMA transfer,
|
|
and replaced by the second buffer, so that the DSP code work on the full one.
|
|
- The buffer contains 128 alternating 16 bit wide samples from PA2 and PA3.
|
|
- An exponentionally smoothed average is used to remove the DC offset
|
|
- The samples are scaled by 2**10 and turned into an array of 128 complex numbers.
|
|
- A FIR-filter for filtering out the sideband is applied to the array
|
|
- The resulting audio is stored in the output buffer
|
|
- DMA1 Stream 7 is set up to transfer the output buffer into CCR3 of Timer4
|
|
- Similar to the ADC two buffers are used alternating.
|
|
they are swapped out in the transfer complete interrupt.
|
|
- Timer4 is set up to output PWM on Channel3 on PB8
|
|
- A new DMA Transfer is triggered on each channel 3 comparator match.
|
|
Actually the transfer should be triggered on each update event.
|
|
Unfortunately this does not seem to work reliably (probably a timing issue).
|
|
- Using DMA for PWM is not that well support in the HAL just yet,
|
|
so it requires some manually setup register and some unsafe code.
|
|
|
|
|
|
TX Path
|
|
-------
|
|
- Timer 1 runs continuously at 8khz.
|
|
- The HALs `pwm_hz` function is used to set up the timer,
|
|
as it is easier than setting the registers manually,
|
|
and we need the comparator match event to trigger the ADC.
|
|
- ADC conversions are triggered externally at each comparator match for Timer1 Channel1
|
|
- ADC runs ins Scan-mode, to keep it easier to switch between RX and TX
|
|
- Scan sequence only contains PA4, the microphone input
|
|
- DMA2 is set up to for device to memory, with memory increment,
|
|
transfer complete interrupt and double buffering disabled.
|
|
- In the DMA transfer complete interrupt the full buffer is moved out of the DMA transfer,
|
|
and replaced by the second buffer, so that the DSP code work on the full one.
|
|
- The buffer contains 128 16bit wide audio samples
|
|
- An exponentionally smoothed average is used to remove the DC offset
|
|
- The samples are scaled by 2**10 and turned into an array of 128 complex numbers,
|
|
by extending them with a zero imaginary part. This results into a double sideband signal.
|
|
-TODO:
|
|
- Extracting the amplitude and dominant frequency
|
|
- Predistorted the amplitudes using a LUT, to compensate for non-linearities of the MOSFETs
|
|
- Setup DMA transfers for I2C and bias PWM
|
|
- DMA1 - Stream 6 for I2C1 TX
|
|
- DMA1 - Stream 4 for TIM1 CH3 |