kopia lustrzana https://github.com/mikaelnousiainen/RS41ng
Clean up Si4063 APRS work and make APRS deviation configurable
rodzic
bdc3067703
commit
7556ebe9bb
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include <stdbool.h>
|
||||
#include <stm32f10x_gpio.h>
|
||||
#include <stm32f10x_tim.h>
|
||||
|
||||
#include "hal/hal.h"
|
||||
#include "hal/delay.h"
|
||||
|
@ -53,18 +54,6 @@
|
|||
|
||||
#define SI4063_DATA_RATE_APRS 4400
|
||||
|
||||
#define RF_DEVIATION_HZ_RTTY 200.0f
|
||||
#define RF_DEVIATION_HZ_APRS 1300.0f
|
||||
|
||||
#define OUTDIV_70CM 8
|
||||
#define OUTDIV_2M 24
|
||||
#define OUTDIV_DFM 10
|
||||
|
||||
#define FREQUENCY_DEVIATION_RTTY ((((uint32_t)1 << 19) * OUTDIV_2M * RF_DEVIATION_HZ_RTTY)/(2*SI4063_CLOCK))
|
||||
#define FREQUENCY_DEVIATION_APRS ((((uint32_t)1 << 19) * OUTDIV_2M * RF_DEVIATION_HZ_APRS)/(2*SI4063_CLOCK))
|
||||
#define FREQUENCY_DEVIATION_APRS_DFM ((((uint32_t)1 << 19) * OUTDIV_DFM * RF_DEVIATION_HZ_APRS)/(2*SI4063_CLOCK))
|
||||
#define FREQUENCY_DEVIATION_DFM 0x90000
|
||||
|
||||
/**
|
||||
* Filters from uTrak: https://github.com/thasti/utrak
|
||||
*
|
||||
|
@ -97,6 +86,9 @@ uint8_t si4063_filter_lp_4400[9] = {0xd5, 0xe9, 0x03, 0x20, 0x3d, 0x58, 0x6d, 0x
|
|||
*/
|
||||
uint8_t si4063_filter_6db_1200_4400[9] = {0x81, 0x9f, 0xc4, 0xee, 0x18, 0x3e, 0x5c, 0x70, 0x76};
|
||||
|
||||
uint32_t current_frequency_hz = 434000000UL;
|
||||
uint32_t current_deviation_hz = 0;
|
||||
|
||||
static inline void si4063_set_chip_select(bool select)
|
||||
{
|
||||
spi_set_chip_select(GPIO_SI4063_NSEL, GPIO_PIN_SI4063_NSEL, select);
|
||||
|
@ -226,6 +218,41 @@ void si4063_disable_tx()
|
|||
si4063_set_state(SI4063_STATE_SLEEP);
|
||||
}
|
||||
|
||||
static int si4063_get_outdiv(const uint32_t frequency_hz)
|
||||
{
|
||||
// Select the output divider according to the recommended ranges in the Si406x datasheet
|
||||
if (frequency_hz < 177000000UL) {
|
||||
return 24;
|
||||
} else if (frequency_hz < 239000000UL) {
|
||||
return 16;
|
||||
} else if (frequency_hz < 353000000UL) {
|
||||
return 12;
|
||||
} else if (frequency_hz < 525000000UL) {
|
||||
return 8;
|
||||
} else if (frequency_hz < 705000000UL) {
|
||||
return 6;
|
||||
}
|
||||
|
||||
return 4;
|
||||
}
|
||||
|
||||
static int si4063_get_band(const uint32_t frequency_hz)
|
||||
{
|
||||
if (frequency_hz < 177000000UL) {
|
||||
return 5;
|
||||
} else if (frequency_hz < 239000000UL) {
|
||||
return 4;
|
||||
} else if (frequency_hz < 353000000UL) {
|
||||
return 3;
|
||||
} else if (frequency_hz < 525000000UL) {
|
||||
return 2;
|
||||
} else if (frequency_hz < 705000000UL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void si4063_set_tx_frequency(const uint32_t frequency_hz)
|
||||
{
|
||||
uint8_t outdiv, band;
|
||||
|
@ -234,26 +261,8 @@ void si4063_set_tx_frequency(const uint32_t frequency_hz)
|
|||
|
||||
log_debug("Si4063: Set frequency %lu\n", frequency_hz);
|
||||
|
||||
/* Set the output divider according to the recommended ranges in the si406x datasheet */
|
||||
if (frequency_hz < 177000000UL) {
|
||||
outdiv = 24;
|
||||
band = 5;
|
||||
} else if (frequency_hz < 239000000UL) {
|
||||
outdiv = 16;
|
||||
band = 4;
|
||||
} else if (frequency_hz < 353000000UL) {
|
||||
outdiv = 12;
|
||||
band = 3;
|
||||
} else if (frequency_hz < 525000000UL) {
|
||||
outdiv = 8;
|
||||
band = 2;
|
||||
} else if (frequency_hz < 705000000UL) {
|
||||
outdiv = 6;
|
||||
band = 1;
|
||||
} else {
|
||||
outdiv = 4;
|
||||
band = 0;
|
||||
}
|
||||
outdiv = si4063_get_outdiv(frequency_hz);
|
||||
band = si4063_get_band(frequency_hz);
|
||||
|
||||
f_pfd = 2 * SI4063_CLOCK / outdiv;
|
||||
n = frequency_hz / f_pfd - 1;
|
||||
|
@ -291,6 +300,11 @@ void si4063_set_tx_frequency(const uint32_t frequency_hz)
|
|||
|
||||
si4063_send_command(SI4063_COMMAND_SET_PROPERTY, sizeof(data), data);
|
||||
}
|
||||
|
||||
current_frequency_hz = frequency_hz;
|
||||
|
||||
// Deviation depends on the frequency band
|
||||
si4063_set_frequency_deviation(current_deviation_hz);
|
||||
}
|
||||
|
||||
void si4063_set_tx_power(uint8_t power)
|
||||
|
@ -320,8 +334,18 @@ void si4063_set_frequency_offset(uint16_t offset)
|
|||
si4063_send_command(SI4063_COMMAND_SET_PROPERTY, sizeof(data), data);
|
||||
}
|
||||
|
||||
void si4063_set_frequency_deviation(uint32_t deviation)
|
||||
static uint32_t si4063_calculate_deviation(uint32_t deviation_hz)
|
||||
{
|
||||
uint8_t outdiv = si4063_get_outdiv(current_frequency_hz);
|
||||
|
||||
// SY_SEL = Div-by-2
|
||||
return (uint32_t) (((double) (1 << 19) * outdiv * deviation_hz) / (2 * SI4063_CLOCK));
|
||||
}
|
||||
|
||||
void si4063_set_frequency_deviation(uint32_t deviation_hz)
|
||||
{
|
||||
uint32_t deviation = si4063_calculate_deviation(deviation_hz);
|
||||
|
||||
uint8_t data[] = {
|
||||
0x20, // 0x20 = Group MODEM
|
||||
0x03, // Set 3 properties (3 bytes)
|
||||
|
@ -331,9 +355,11 @@ void si4063_set_frequency_deviation(uint32_t deviation)
|
|||
deviation & 0xFF
|
||||
};
|
||||
|
||||
log_debug("Si4063: Set freq deviation %lu\n", deviation);
|
||||
log_info("Si4063: Set frequency deviation to value %lu with %lu Hz\n", deviation, deviation_hz);
|
||||
|
||||
si4063_send_command(SI4063_COMMAND_SET_PROPERTY, sizeof(data), data);
|
||||
|
||||
current_deviation_hz = deviation_hz;
|
||||
}
|
||||
|
||||
void si4063_set_modulation_type(si4063_modulation_type type)
|
||||
|
@ -511,6 +537,7 @@ void si4063_configure()
|
|||
}
|
||||
}
|
||||
|
||||
// Not used yet, for future use
|
||||
void si4063_set_filter(const uint8_t *filter)
|
||||
{
|
||||
uint8_t data[12] = {
|
||||
|
@ -541,11 +568,11 @@ void si4063_configure_data_rate(uint32_t data_rate)
|
|||
si4063_send_command(SI4063_COMMAND_SET_PROPERTY, sizeof(data), data);
|
||||
}
|
||||
|
||||
// Not used yet, for future use
|
||||
void si4063_configure_aprs()
|
||||
{
|
||||
// For APRS in direct mode with GFSK modulation
|
||||
si4063_configure_data_rate(4400);
|
||||
si4063_set_frequency_deviation((uint16_t)(2*FREQUENCY_DEVIATION_APRS));
|
||||
si4063_configure_data_rate(SI4063_DATA_RATE_APRS);
|
||||
|
||||
// Used only for GFSK mode filtering
|
||||
uint32_t nco_mod = SI4063_CLOCK / 10;
|
||||
|
@ -563,6 +590,7 @@ void si4063_configure_aprs()
|
|||
si4063_send_command(SI4063_COMMAND_SET_PROPERTY, sizeof(data), data);
|
||||
}
|
||||
|
||||
// Not used yet, for future use
|
||||
void si4063_configure_rtty()
|
||||
{
|
||||
// For RTTY:
|
||||
|
@ -643,7 +671,9 @@ int si4063_init()
|
|||
si4063_set_tx_power(0x00);
|
||||
|
||||
si4063_set_frequency_offset(0);
|
||||
si4063_set_frequency_deviation(0x22);
|
||||
|
||||
// Set deviation to zero for non-FSK modulations
|
||||
si4063_set_frequency_deviation(0);
|
||||
|
||||
si4063_set_modulation_type(SI4063_MODULATION_TYPE_CW);
|
||||
|
||||
|
@ -651,3 +681,17 @@ int si4063_init()
|
|||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
void TIM1_BRK_TIM15_IRQHandler(void)
|
||||
{
|
||||
static bool pin_state = false;
|
||||
|
||||
if (TIM_GetITStatus(TIM15, TIM_IT_Update) != RESET) {
|
||||
TIM_ClearITPendingBit(TIM15, TIM_IT_Update);
|
||||
#ifdef DFM17
|
||||
// Restrict the interrupt to DFM17 only just in case this ISR gets called on RS41
|
||||
pin_state = !pin_state;
|
||||
si4063_set_direct_mode_pin(pin_state);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
#include "pwm.h"
|
||||
#include "log.h"
|
||||
#include "drivers/si4063/si4063.h"
|
||||
|
||||
uint16_t pwm_timer_dma_buffer[PWM_TIMER_DMA_BUFFER_SIZE];
|
||||
|
||||
|
@ -69,7 +68,7 @@ void pwm_timer_init(uint32_t frequency_hz_100)
|
|||
TIM_DeInit(TIM15);
|
||||
#ifdef RS41
|
||||
GPIO_PinRemapConfig(GPIO_Remap_TIM15, DISABLE);
|
||||
#endif //RS41
|
||||
#endif
|
||||
// Not needed: AFIO->MAPR2 |= AFIO_MAPR2_TIM15_REMAP;
|
||||
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM15, ENABLE);
|
||||
|
@ -110,7 +109,7 @@ void pwm_timer_init(uint32_t frequency_hz_100)
|
|||
TIM_OC2FastConfig(TIM15, TIM_OCFast_Enable);
|
||||
|
||||
TIM_CtrlPWMOutputs(TIM15, DISABLE);
|
||||
#endif //RS41
|
||||
#endif
|
||||
#ifdef DFM17
|
||||
// For DFM17 we don't have a PWM pin in the right place, so we manually toggle the pin in the ISR
|
||||
TIM_ClearITPendingBit(TIM15, TIM_IT_Update);
|
||||
|
@ -122,7 +121,7 @@ void pwm_timer_init(uint32_t frequency_hz_100)
|
|||
nvic_init.NVIC_IRQChannelSubPriority = 1;
|
||||
nvic_init.NVIC_IRQChannelCmd = ENABLE;
|
||||
NVIC_Init(&nvic_init);
|
||||
#endif //DFM17
|
||||
#endif
|
||||
|
||||
TIM_Cmd(TIM15, ENABLE);
|
||||
}
|
||||
|
@ -211,7 +210,7 @@ void pwm_timer_pwm_enable(bool enabled)
|
|||
{
|
||||
#ifdef RS41
|
||||
TIM_CtrlPWMOutputs(TIM15, enabled ? ENABLE : DISABLE);
|
||||
#endif //RS41
|
||||
#endif
|
||||
}
|
||||
|
||||
void pwm_timer_use(bool use)
|
||||
|
@ -220,7 +219,7 @@ void pwm_timer_use(bool use)
|
|||
// Remapping the TIM15 outputs will allow TIM15 channel 2 can be used to drive pin PB15,
|
||||
// which is connected to RS41 Si4032 SDI pin for direct modulation
|
||||
GPIO_PinRemapConfig(GPIO_Remap_TIM15, use ? ENABLE : DISABLE);
|
||||
#endif //RS41
|
||||
#endif
|
||||
}
|
||||
|
||||
void pwm_timer_uninit()
|
||||
|
@ -232,7 +231,7 @@ void pwm_timer_uninit()
|
|||
|
||||
#ifdef RS41
|
||||
GPIO_PinRemapConfig(GPIO_Remap_TIM15, DISABLE);
|
||||
#endif //RS41
|
||||
#endif
|
||||
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM15, DISABLE);
|
||||
}
|
||||
|
@ -253,22 +252,3 @@ inline void pwm_timer_set_frequency(uint32_t pwm_period)
|
|||
// TIM_Cmd(TIM15, ENABLE);
|
||||
// TIM_CtrlPWMOutputs(TIM15, ENABLE);
|
||||
}
|
||||
|
||||
static uint32_t Tim15Cnt = 0;
|
||||
volatile bool Tim15On = false;
|
||||
|
||||
void TIM1_BRK_TIM15_IRQHandler(void)
|
||||
{
|
||||
if (TIM_GetITStatus(TIM15, TIM_IT_Update) != RESET) {
|
||||
TIM_ClearITPendingBit(TIM15, TIM_IT_Update);
|
||||
#ifdef DFM17
|
||||
// Just in case this ISR gets called on RS41, we restrict this to DFM only
|
||||
|
||||
Tim15Cnt++;
|
||||
Tim15On = !Tim15On;
|
||||
si4063_set_direct_mode_pin(Tim15On);
|
||||
}
|
||||
#endif //DFM17
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,9 @@
|
|||
#include "radio_si4063.h"
|
||||
#include "codecs/mfsk/mfsk.h"
|
||||
|
||||
#define SI4063_DEVIATION_HZ_RTTY 200.0
|
||||
#define SI4063_DEVIATION_HZ_APRS 2600.0
|
||||
|
||||
#define CW_SYMBOL_RATE_MULTIPLIER 4
|
||||
|
||||
// TODO: Add support for multiple APRS baud rates
|
||||
|
@ -19,9 +22,7 @@
|
|||
#define symbol_delay_bell_202_1200bps_us 823
|
||||
#elif defined(DFM17)
|
||||
#define symbol_delay_bell_202_1200bps_us 820
|
||||
#else
|
||||
Improper definitions
|
||||
#endif // Sonde Type
|
||||
#endif
|
||||
|
||||
static volatile bool radio_si4063_state_change = false;
|
||||
static volatile uint32_t radio_si4063_freq = 0;
|
||||
|
@ -29,6 +30,7 @@ static volatile uint32_t radio_si4063_freq = 0;
|
|||
bool radio_start_transmit_si4063(radio_transmit_entry *entry, radio_module_state *shared_state)
|
||||
{
|
||||
uint16_t frequency_offset;
|
||||
uint32_t frequency_deviation = 0;
|
||||
si4063_modulation_type modulation_type;
|
||||
bool use_direct_mode;
|
||||
|
||||
|
@ -43,11 +45,13 @@ bool radio_start_transmit_si4063(radio_transmit_entry *entry, radio_module_state
|
|||
break;
|
||||
case RADIO_DATA_MODE_RTTY:
|
||||
frequency_offset = 0;
|
||||
frequency_deviation = SI4063_DEVIATION_HZ_RTTY;
|
||||
modulation_type = SI4063_MODULATION_TYPE_CW;
|
||||
use_direct_mode = false;
|
||||
break;
|
||||
case RADIO_DATA_MODE_APRS_1200:
|
||||
frequency_offset = 0;
|
||||
frequency_deviation = SI4063_DEVIATION_HZ_APRS;
|
||||
modulation_type = SI4063_MODULATION_TYPE_FSK;
|
||||
use_direct_mode = true;
|
||||
break;
|
||||
|
@ -69,6 +73,7 @@ bool radio_start_transmit_si4063(radio_transmit_entry *entry, radio_module_state
|
|||
si4063_set_tx_power(entry->tx_power);
|
||||
si4063_set_frequency_offset(frequency_offset);
|
||||
si4063_set_modulation_type(modulation_type);
|
||||
si4063_set_frequency_deviation(frequency_deviation);
|
||||
|
||||
si4063_enable_tx();
|
||||
|
||||
|
@ -151,7 +156,6 @@ static void radio_handle_main_loop_manual_si4063(radio_transmit_entry *entry, ra
|
|||
case RADIO_DATA_MODE_APRS_1200: {
|
||||
int8_t tone_index;
|
||||
|
||||
log_info("APRS TX starts\n");
|
||||
while ((tone_index = fsk_encoder_api->next_tone(fsk_enc)) >= 0) {
|
||||
pwm_timer_set_frequency(precalculated_pwm_periods[tone_index]);
|
||||
shared_state->radio_symbol_count_loop++;
|
||||
|
@ -160,7 +164,6 @@ static void radio_handle_main_loop_manual_si4063(radio_transmit_entry *entry, ra
|
|||
|
||||
radio_si4063_state_change = false;
|
||||
shared_state->radio_transmission_finished = true;
|
||||
log_info("APRS TX ends\n");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -304,4 +307,4 @@ bool radio_stop_transmit_si4063(radio_transmit_entry *entry, radio_module_state
|
|||
void radio_init_si4063()
|
||||
{
|
||||
}
|
||||
#endif //DFM17
|
||||
#endif
|
||||
|
|
Ładowanie…
Reference in New Issue