kopia lustrzana https://github.com/sq2ips/m20-custom-firmware
101 wiersze
3.8 KiB
C
101 wiersze
3.8 KiB
C
/*
|
|
* fsk4.c
|
|
* By SQ2DK
|
|
*/
|
|
|
|
#include "fsk4.h"
|
|
#include "adf.h"
|
|
#include "config.h"
|
|
#include "main.h"
|
|
|
|
/*
|
|
* In this file i will try to prepare procedure for transmitting earlier
|
|
* prepared message using 4fsk We will be using adf.c - library for handling
|
|
* ADF7012 chip. Frequency setting and initialization of chip will be done
|
|
* outside of this library idea is to use frequency correction register for
|
|
* shifting base frequency, which should produce 244Hz steps in frequency. This
|
|
* will limit minimum baud rate to 100bd and its multipliers. As experience
|
|
* showed, 244Hz tone-spacing is not sufficient for efficient decoding of
|
|
* packets using standard 270Hz shift Thus generation of 9MHz signal for radio
|
|
* chip was required via STM32 PLL to achieve spacing close to 270Hz. Baud rate
|
|
* will be generated by microcontroler's timer. we will use timer2 for this,
|
|
* setting prescaler to (cpu_freuency/100000)-1, so, for 100bd single pulse we
|
|
* should set counter to 1000-1
|
|
*/
|
|
|
|
static uint16_t current_2_bit = 0;
|
|
static bool FSK_Active = false;
|
|
static char *buffer;
|
|
static uint8_t buffer_len;
|
|
static uint8_t QRGCounter = 0;
|
|
|
|
void FSK4_stop_TX() {
|
|
TIM2->DIER &= ~(TIM_DIER_UIE); // Disable the interrupt
|
|
adf_RF_off(); // turn TX off
|
|
FSK_Active = false;
|
|
}
|
|
|
|
static void FSK4_send_2bit(uint8_t bits_to_send) { // sends 2 bit value
|
|
bits_to_send =
|
|
(bits_to_send & 3); // make sure to take only 2 last bites of value - we
|
|
// cannot send more than 2 bits at the same time
|
|
adf_4fsk_fone(bits_to_send * FSK4_SPACE_MULTIPLIER);
|
|
}
|
|
|
|
bool FSK4_is_active() { // returns 1 if transmitter is active for 4FSK
|
|
return FSK_Active;
|
|
}
|
|
|
|
static void FSK4_write(char *buff, uint16_t address_2bit) {
|
|
int full_bytes = address_2bit / 4; // number of full bytes of address
|
|
int fraction_part =
|
|
address_2bit -
|
|
(full_bytes * 4); // fraction part of address (number of 2bytes offset)
|
|
uint8_t byte_to_send = (buff[full_bytes] >> (6 - (fraction_part * 2)) &
|
|
3); // returns 2 bytes of buffer at address
|
|
FSK4_send_2bit(byte_to_send); // sends those 2 bytes
|
|
}
|
|
|
|
void FSK4_timer_handler() { // called out by interrupt handling procedure in
|
|
// main
|
|
|
|
TIM2->CNT = 0; // reset timer - make sure to have it at the beginning of
|
|
// procedure, otherwise there will be some delays.
|
|
if (current_2_bit < (FSK4_HEADER_LENGTH * 4)) { // we are still in header
|
|
uint8_t tmp_offset = ((0xD8 >> current_2_bit % 4) & 3);
|
|
|
|
FSK4_send_2bit(tmp_offset);
|
|
} else {
|
|
FSK4_write(buffer,
|
|
(current_2_bit -
|
|
(FSK4_HEADER_LENGTH *
|
|
4))); // send 2 bits of data from address of current_2_bit * 2
|
|
}
|
|
current_2_bit++;
|
|
|
|
if (current_2_bit > ((buffer_len + FSK4_HEADER_LENGTH) * 4)) {
|
|
FSK4_stop_TX();
|
|
} // if we got to the end of data - finish transmitting
|
|
}
|
|
|
|
void FSK4_start_TX(char *buff, uint8_t len) {
|
|
buffer = buff;
|
|
buffer_len = len;
|
|
// adf_setup();
|
|
current_2_bit = 0; // reset counter of current position of bit address
|
|
adf_RF_on(QRG_FSK4[QRGCounter++], PA_FSK4); // turn on radio TX
|
|
if (QRGCounter >= sizeof(QRG_FSK4) / sizeof(QRG_FSK4[0]))
|
|
QRGCounter = 0;
|
|
FSK_Active = true; // change status
|
|
TIM2->CR1 &= (uint16_t)(~((uint16_t)TIM_CR1_CEN)); // Disable the TIM Counter
|
|
uint16_t timer2StartValue =
|
|
(100000 / FSK4_BAUD) -
|
|
1; // timer value calculated according to baud rate 999 for 100bd
|
|
TIM2->ARR = timer2StartValue; // set timer counter max value to pre-set value
|
|
// for baudrate (auto-reload register)
|
|
TIM2->CR1 |= TIM_CR1_CEN; // enable timer again
|
|
TIM2->DIER |= TIM_DIER_UIE; // Enable the interrupt
|
|
FSK4_timer_handler(); // force execution of procedure responsible for
|
|
// interrupt handling
|
|
}
|