kopia lustrzana https://github.com/sq2ips/m20-custom-firmware
92 wiersze
4.0 KiB
C
92 wiersze
4.0 KiB
C
/*
|
|
* fsk4.c
|
|
* By SQ2DK
|
|
*/
|
|
|
|
#include "fsk4.h"
|
|
#include "adf.h"
|
|
#include "main.h"
|
|
#include "config.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;
|
|
|
|
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
|
|
|
|
//TIM2->CR1 &= (uint16_t)(~((uint16_t)TIM_CR1_CEN)); // Disable the TIM Counter
|
|
//TIM2->ARR = timer1StartValue; //set timer counter max value to pre-set value for baudrate (auto-reload register)
|
|
//TIM2->CNT = 0; //reset timer
|
|
//TIM2->CR1 |= TIM_CR1_CEN; //enable timer again
|
|
|
|
}
|
|
|
|
|
|
|
|
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, PA_FSK4); //turn on radio TX
|
|
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
|
|
}
|