WIP update of 446x driver and portab support of multi-radio

pull/4/head
CInsights 2018-07-31 11:36:15 +10:00
rodzic 0d1f3c3084
commit 886d241ae5
9 zmienionych plików z 326 dodań i 231 usunięć

Wyświetl plik

@ -21,13 +21,14 @@
#include "portab.h"
#include "usb.h"
#include "types.h"
#include "si446x.h"
#include <stdarg.h>
/*===========================================================================*/
/* Module local definitions. */
/*===========================================================================*/
const radio_band_t band_2m = {
/*const radio_band_t band_2m = {
.start = BAND_MIN_2M_FREQ,
.end = BAND_MAX_2M_FREQ,
.step = BAND_STEP_2M_HZ,
@ -39,7 +40,7 @@ const radio_band_t band_70cm = {
.end = BAND_MAX_70CM_FREQ,
.step = BAND_STEP_70CM_HZ,
.def_aprs = BAND_DEF_70CM_APRS
};
};*/
/*===========================================================================*/
/* Module exported variables. */
@ -49,10 +50,22 @@ typedef struct SysProviders {
} providers_t;
const si446x_mcuio_t radio1_io = {
.gpio0 = LINE_RADIO_GPIO0,
.gpio1 = LINE_RADIO_GPIO1,
.gpio2 = PAL_NOLINE,
.gpio3 = PAL_NOLINE,
.nirq = LINE_RADIO_NIRQ,
.sdn = LINE_RADIO_SDN,
.cs = LINE_RADIO_CS,
.spi = PKT_RADIO_SPI
};
const radio_config_t radio_list[] = {
{ /* Radio #1 */
.unit = PKT_RADIO_1,
.type = SI446X,
.io = (si446x_mcuio_t * const)&radio1_io,
.band = {
(radio_band_t * const)&band_2m,
NULL
@ -63,6 +76,7 @@ const radio_config_t radio_list[] = {
}
};
const SerialConfig debug_config = {
115200,
0,

Wyświetl plik

@ -100,7 +100,7 @@
*/
#define LINE_RADIO_CS PAL_LINE(GPIOC, 12U)
#define LINE_RADIO_SDN PAL_LINE(GPIOC, 10U)
#define LINE_RADIO_IRQ PAL_LINE(GPIOD, 2U)
#define LINE_RADIO_NIRQ PAL_LINE(GPIOD, 2U)
#define LINE_RADIO_GPIO0 PAL_LINE(GPIOB, 7U)
#define LINE_RADIO_GPIO1 PAL_LINE(GPIOB, 6U)
@ -138,7 +138,7 @@
#define LINE_PWM_MIRROR PAL_NOLINE
/* Radio ports. */
#define LINE_CCA LINE_RADIO_IRQ
#define LINE_CCA LINE_RADIO_NIRQ
#define LINE_ICU LINE_RADIO_GPIO1
//#define LINE_UART4_TX PAL_LINE(GPIOA, 12U)
@ -249,6 +249,7 @@
typedef struct radioConfig {
radio_unit_t unit;
radio_type_t type;
void *io;
radio_band_t *band[NUM_BANDS_PER_RADIO];
} radio_config_t;
@ -260,6 +261,9 @@ typedef struct radioConfig {
/* External declarations. */
/*===========================================================================*/
extern const radio_band_t band_2m;
extern const radio_band_t band_70cm;
#ifdef __cplusplus
extern "C" {
#endif

Wyświetl plik

@ -21,13 +21,14 @@
#include "portab.h"
#include "usb.h"
#include "types.h"
#include "si446x.h"
#include <stdarg.h>
/*===========================================================================*/
/* Module local definitions. */
/*===========================================================================*/
const radio_band_t band_2m = {
/*const radio_band_t band_2m = {
.start = BAND_MIN_2M_FREQ,
.end = BAND_MAX_2M_FREQ,
.step = BAND_STEP_2M_HZ,
@ -39,7 +40,7 @@ const radio_band_t band_70cm = {
.end = BAND_MAX_70CM_FREQ,
.step = BAND_STEP_70CM_HZ,
.def_aprs = BAND_DEF_70CM_APRS
};
};*/
/*===========================================================================*/
/* Module exported variables. */
@ -49,10 +50,22 @@ typedef struct SysProviders {
} providers_t;
const si446x_mcuio_t radio1_io = {
.gpio0 = LINE_RADIO_GPIO0,
.gpio1 = LINE_RADIO_GPIO1,
.gpio2 = PAL_NOLINE,
.gpio3 = PAL_NOLINE,
.nirq = LINE_RADIO_NIRQ,
.spi = PKT_RADIO_SPI,
.sdn = LINE_RADIO_SDN,
.cs = LINE_RADIO_CS,
};
const radio_config_t radio_list[] = {
{ /* Radio #1 */
.unit = PKT_RADIO_1,
.type = SI446X,
.io = (si446x_mcuio_t * const)&radio1_io,
.band = {
(radio_band_t * const)&band_2m,
NULL

Wyświetl plik

@ -99,7 +99,7 @@
*/
#define LINE_RADIO_CS PAL_LINE(GPIOC, 12U)
#define LINE_RADIO_SDN PAL_LINE(GPIOC, 10U)
#define LINE_RADIO_IRQ PAL_LINE(GPIOD, 2U)
#define LINE_RADIO_NIRQ PAL_LINE(GPIOD, 2U)
#define LINE_RADIO_GPIO0 PAL_LINE(GPIOB, 7U)
#define LINE_RADIO_GPIO1 PAL_LINE(GPIOB, 6U)
@ -137,7 +137,7 @@
#define LINE_PWM_MIRROR PAL_NOLINE
/* Radio ports. */
#define LINE_CCA LINE_RADIO_IRQ
#define LINE_CCA LINE_RADIO_NIRQ
#define LINE_ICU LINE_RADIO_GPIO1
//#define LINE_UART4_TX PAL_LINE(GPIOA, 12U)
@ -246,6 +246,7 @@
typedef struct radioConfig {
radio_unit_t unit;
radio_type_t type;
void *io;
radio_band_t *band[NUM_BANDS_PER_RADIO];
} radio_config_t;
@ -257,6 +258,9 @@ typedef struct radioConfig {
/* External declarations. */
/*===========================================================================*/
extern const radio_band_t band_2m;
extern const radio_band_t band_70cm;
#ifdef __cplusplus
extern "C" {
#endif

Wyświetl plik

@ -153,7 +153,7 @@ const conf_t conf_flash_default = {
.cca = 0x4F
},
// Digipeat transmission identity
.call = "VK2GJ-5",
.call = "VK2GJ-6",
.path = "WIDE2-1",
.symbol = SYM_DIGIPEATER,
.beacon = {

Wyświetl plik

@ -21,6 +21,7 @@
/* Module local variables. */
/*===========================================================================*/
/* TODO: Has to move into radio data struct. */
static int16_t lastTemp = 0x7FFF;
/*===========================================================================*/
@ -32,6 +33,7 @@ static int16_t lastTemp = 0x7FFF;
/* Module exported variables. */
/*===========================================================================*/
/* TODO: Have to move into radio data struct. */
si446x_part_t part_info;
si446x_func_t func_info;
@ -44,20 +46,30 @@ static const uint8_t Radio_Patch_Data_Array[] = {
0x00
};
/* TODO: Set the CS line dynamically per radio. */
static const SPIConfig ls_spicfg = {
.ssport = PAL_PORT(LINE_RADIO_CS),
.sspad = PAL_PAD(LINE_RADIO_CS),
.cr1 = SPI_CR1_MSTR
};
/**
* Get pointer to the radio specific MCU IO.
*/
static si446x_mcuio_t *Si446x_getMCUIO(const radio_unit_t radio) {
const radio_config_t *data = pktGetRadioData(radio);
return (si446x_mcuio_t *)data->io;
}
/**
* SPI write which uses CTS on GPIO1.
* Used when starting the radio up from shutdown state.
* @pre The MCU GPIO pin connected to 446x GPIO1 must be pre-configured.
*/
static bool Si446x_writeBoot(const uint8_t* txData, uint32_t len) {
static bool Si446x_writeBoot(const radio_unit_t radio, const uint8_t* txData, uint32_t len) {
/* Write data via SPI with CTS checked via GPIO1. */
/* TODO: Add radio unit ID and get specific radio SPI driver. */
(void)radio;
//uint8_t null_spi[len];
/* Acquire bus and then start SPI. */
@ -92,9 +104,11 @@ static bool Si446x_writeBoot(const uint8_t* txData, uint32_t len) {
}
static bool Si446x_write(const uint8_t* txData, uint32_t len) {
static bool Si446x_write(const radio_unit_t radio,
const uint8_t* txData, uint32_t len) {
// Transmit data by SPI
/* TODO: Add radio unit ID and get specific radio SPI driver. */
(void)radio;
uint8_t null_spi[len];
/* Acquire bus and then start SPI. */
@ -137,11 +151,12 @@ static bool Si446x_write(const uint8_t* txData, uint32_t len) {
* Use this when first taking radio out of shutdown.
* The MCU GPIO pin connected to 446x GPIO1 must be already configured.
*/
static bool Si446x_readBoot(const uint8_t* txData, uint32_t txlen,
static bool Si446x_readBoot(const radio_unit_t radio,
const uint8_t* txData, uint32_t txlen,
uint8_t* rxData, uint32_t rxlen) {
/* TODO: Add radio unit ID and get SPI configuration accordingly. */
(void)radio;
/* Acquire bus. */
spiAcquireBus(PKT_RADIO_SPI);
@ -196,11 +211,12 @@ static bool Si446x_readBoot(const uint8_t* txData, uint32_t txlen,
/**
* Read data from Si446x.
*/
static bool Si446x_read(const uint8_t* txData, uint32_t txlen,
static bool Si446x_read(const radio_unit_t radio,
const uint8_t* txData, uint32_t txlen,
uint8_t* rxData, uint32_t rxlen) {
/* TODO: Add radio unit ID and get SPI configuration accordingly. */
(void)radio;
/* Acquire bus and then start SPI. */
spiAcquireBus(PKT_RADIO_SPI);
spiStart(PKT_RADIO_SPI, &ls_spicfg);
@ -261,31 +277,35 @@ static bool Si446x_read(const uint8_t* txData, uint32_t txlen,
}
/* TODO: Make set property a single func with size parameter. */
static void Si446x_setProperty8(uint16_t reg, uint8_t val) {
static void Si446x_setProperty8(const radio_unit_t radio,
uint16_t reg, uint8_t val) {
uint8_t msg[] = {Si446x_SET_PROPERTY,
(reg >> 8) & 0xFF, 0x01, reg & 0xFF, val};
Si446x_write(msg, sizeof(msg));
Si446x_write(radio, msg, sizeof(msg));
}
static void Si446x_setProperty16(uint16_t reg, uint8_t val1, uint8_t val2) {
static void Si446x_setProperty16(const radio_unit_t radio,
uint16_t reg, uint8_t val1, uint8_t val2) {
uint8_t msg[] = {Si446x_SET_PROPERTY,
(reg >> 8) & 0xFF, 0x02, reg & 0xFF, val1, val2};
Si446x_write(msg, sizeof(msg));
Si446x_write(radio, msg, sizeof(msg));
}
static void Si446x_setProperty24(uint16_t reg, uint8_t val1,
static void Si446x_setProperty24(const radio_unit_t radio,
uint16_t reg, uint8_t val1,
uint8_t val2, uint8_t val3) {
uint8_t msg[] = {Si446x_SET_PROPERTY,
(reg >> 8) & 0xFF, 0x03, reg & 0xFF, val1, val2, val3};
Si446x_write(msg, sizeof(msg));
Si446x_write(radio, msg, sizeof(msg));
}
static void Si446x_setProperty32(uint16_t reg, uint8_t val1,
static void Si446x_setProperty32(const radio_unit_t radio,
uint16_t reg, uint8_t val1,
uint8_t val2, uint8_t val3, uint8_t val4) {
uint8_t msg[] = {Si446x_SET_PROPERTY,
(reg >> 8) & 0xFF, 0x04, reg & 0xFF,
val1, val2, val3, val4};
Si446x_write(msg, sizeof(msg));
Si446x_write(radio, msg, sizeof(msg));
}
/**
@ -329,7 +349,7 @@ static bool Si446x_init(const radio_unit_t radio) {
*
* The Si446x SDO pin is configured to SDO data by the POWER_UP command.
*/
Si446x_writeBoot(init_command, sizeof(init_command));
Si446x_writeBoot(radio, init_command, sizeof(init_command));
/*
* Next get the PART_INFO.
@ -339,7 +359,7 @@ static bool Si446x_init(const radio_unit_t radio) {
*/
const uint8_t get_part[] = {Si446x_GET_PART_INFO};
Si446x_readBoot(get_part, sizeof(get_part), (uint8_t *)&part_info,
Si446x_readBoot(radio, get_part, sizeof(get_part), (uint8_t *)&part_info,
sizeof(part_info));
/* Save the part number and ROM revision. */
@ -357,19 +377,19 @@ static bool Si446x_init(const radio_unit_t radio) {
Si446x_radioStartup(radio);
uint16_t i = 0;
while(Radio_Patch_Data_Array[i] != 0) {
Si446x_writeBoot(&Radio_Patch_Data_Array[i + 1], Radio_Patch_Data_Array[i]);
Si446x_writeBoot(radio, &Radio_Patch_Data_Array[i + 1], Radio_Patch_Data_Array[i]);
i += Radio_Patch_Data_Array[i] + 1;
}
const uint8_t init_command[] = {Si446x_POWER_UP, 0x81,
(Si446x_CLK_TCXO_EN & 0x1),
x3, x2, x1, x0};
Si446x_writeBoot(init_command, sizeof(init_command));
Si446x_writeBoot(radio, init_command, sizeof(init_command));
}
/* Get and save the patch ID from FUNC_INFO for reference. */
const uint8_t get_func[] = {Si446x_GET_FUNC_INFO};
Si446x_readBoot(get_func, sizeof(get_func), (uint8_t *)&func_info,
Si446x_readBoot(radio, get_func, sizeof(get_func), (uint8_t *)&func_info,
sizeof(func_info));
handler->radio_patch = (func_info.info[5] << 8) + func_info.info[6];
@ -390,7 +410,7 @@ static bool Si446x_init(const radio_unit_t radio) {
0x00 // GEN_CONFIG
};
Si446x_write(gpio_pin_cfg_command2, sizeof(gpio_pin_cfg_command2));
Si446x_write(radio, gpio_pin_cfg_command2, sizeof(gpio_pin_cfg_command2));
/* TODO: We should clear interrupts here with a GET_INT_STATUS. */
@ -398,23 +418,23 @@ static bool Si446x_init(const radio_unit_t radio) {
/* If Si446x is using its own xtal set the trim capacitor value. */
#if !Si446x_CLK_TCXO_EN
Si446x_setProperty8(Si446x_GLOBAL_XO_TUNE, 0x40);
Si446x_setProperty8(radio, Si446x_GLOBAL_XO_TUNE, 0x40);
#endif
/* Fast response registers - not used at this time. */
Si446x_setProperty8(Si446x_FRR_CTL_A_MODE, 0x00);
Si446x_setProperty8(Si446x_FRR_CTL_B_MODE, 0x00);
Si446x_setProperty8(Si446x_FRR_CTL_C_MODE, 0x00);
Si446x_setProperty8(Si446x_FRR_CTL_D_MODE, 0x00);
Si446x_setProperty8(radio, Si446x_FRR_CTL_A_MODE, 0x00);
Si446x_setProperty8(radio, Si446x_FRR_CTL_B_MODE, 0x00);
Si446x_setProperty8(radio, Si446x_FRR_CTL_C_MODE, 0x00);
Si446x_setProperty8(radio, Si446x_FRR_CTL_D_MODE, 0x00);
Si446x_setProperty8(Si446x_INT_CTL_ENABLE, 0x00);
Si446x_setProperty8(radio, Si446x_INT_CTL_ENABLE, 0x00);
/* Set combined FIFO mode = 0x70. */
Si446x_setProperty8(Si446x_GLOBAL_CONFIG, 0x70);
Si446x_setProperty8(radio, Si446x_GLOBAL_CONFIG, 0x70);
/* Clear TX & RX FIFO. */
const uint8_t reset_fifo[] = {Si446x_FIFO_INFO, 0x03};
Si446x_write(reset_fifo, sizeof(reset_fifo));
Si446x_write(radio, reset_fifo, sizeof(reset_fifo));
/* No need to unset bits... see si docs. */
@ -423,91 +443,91 @@ static bool Si446x_init(const radio_unit_t radio) {
* This would split up into AFSK and FSK for RX & TX.
* Leave only common setup and init here.
*/
Si446x_setProperty8(Si446x_PREAMBLE_TX_LENGTH, 0x00);
Si446x_setProperty8(Si446x_SYNC_CONFIG, 0x80);
Si446x_setProperty8(radio, Si446x_PREAMBLE_TX_LENGTH, 0x00);
Si446x_setProperty8(radio, Si446x_SYNC_CONFIG, 0x80);
/* 32K clock disabled. Divided clock disabled. */
Si446x_setProperty8(Si446x_GLOBAL_CLK_CFG, 0x00);
Si446x_setProperty8(Si446x_MODEM_RSSI_CONTROL, 0x00);
Si446x_setProperty8(radio, Si446x_GLOBAL_CLK_CFG, 0x00);
Si446x_setProperty8(radio, Si446x_MODEM_RSSI_CONTROL, 0x00);
/* TODO: Don't need this setting? */
Si446x_setProperty8(Si446x_PREAMBLE_CONFIG_STD_1, 0x14);
Si446x_setProperty8(Si446x_PKT_CONFIG1, 0x41);
Si446x_setProperty8(Si446x_MODEM_MAP_CONTROL, 0x00);
Si446x_setProperty8(Si446x_MODEM_DSM_CTRL, 0x07);
Si446x_setProperty8(Si446x_MODEM_CLKGEN_BAND, 0x0D);
Si446x_setProperty8(radio, Si446x_PREAMBLE_CONFIG_STD_1, 0x14);
Si446x_setProperty8(radio, Si446x_PKT_CONFIG1, 0x41);
Si446x_setProperty8(radio, Si446x_MODEM_MAP_CONTROL, 0x00);
Si446x_setProperty8(radio, Si446x_MODEM_DSM_CTRL, 0x07);
Si446x_setProperty8(radio, Si446x_MODEM_CLKGEN_BAND, 0x0D);
Si446x_setProperty24(Si446x_MODEM_FREQ_DEV, 0x00, 0x00, 0x79);
Si446x_setProperty8(Si446x_MODEM_TX_RAMP_DELAY, 0x01);
Si446x_setProperty8(Si446x_PA_TC, 0x3D);
Si446x_setProperty8(Si446x_FREQ_CONTROL_INTE, 0x41);
Si446x_setProperty24(Si446x_FREQ_CONTROL_FRAC, 0x0B, 0xB1, 0x3B);
Si446x_setProperty16(Si446x_FREQ_CONTROL_CHANNEL_STEP_SIZE, 0x0B, 0xD1);
Si446x_setProperty8(Si446x_FREQ_CONTROL_W_SIZE, 0x20);
Si446x_setProperty8(Si446x_FREQ_CONTROL_VCOCNT_RX_ADJ, 0xFA);
Si446x_setProperty8(Si446x_MODEM_MDM_CTRL, 0x80);
Si446x_setProperty8(Si446x_MODEM_IF_CONTROL, 0x08);
Si446x_setProperty24(Si446x_MODEM_IF_FREQ, 0x02, 0x80, 0x00);
Si446x_setProperty8(Si446x_MODEM_DECIMATION_CFG1, 0x70);
Si446x_setProperty8(Si446x_MODEM_DECIMATION_CFG0, 0x10);
Si446x_setProperty16(Si446x_MODEM_BCR_OSR, 0x01, 0xC3);
Si446x_setProperty24(Si446x_MODEM_BCR_NCO_OFFSET, 0x01, 0x22, 0x60);
Si446x_setProperty16(Si446x_MODEM_BCR_GAIN, 0x00, 0x91);
Si446x_setProperty8(Si446x_MODEM_BCR_GEAR, 0x00);
Si446x_setProperty8(Si446x_MODEM_BCR_MISC1, 0xC2);
Si446x_setProperty8(Si446x_MODEM_AFC_GEAR, 0x54);
Si446x_setProperty24(radio, Si446x_MODEM_FREQ_DEV, 0x00, 0x00, 0x79);
Si446x_setProperty8(radio, Si446x_MODEM_TX_RAMP_DELAY, 0x01);
Si446x_setProperty8(radio, Si446x_PA_TC, 0x3D);
Si446x_setProperty8(radio, Si446x_FREQ_CONTROL_INTE, 0x41);
Si446x_setProperty24(radio, Si446x_FREQ_CONTROL_FRAC, 0x0B, 0xB1, 0x3B);
Si446x_setProperty16(radio, Si446x_FREQ_CONTROL_CHANNEL_STEP_SIZE, 0x0B, 0xD1);
Si446x_setProperty8(radio, Si446x_FREQ_CONTROL_W_SIZE, 0x20);
Si446x_setProperty8(radio, Si446x_FREQ_CONTROL_VCOCNT_RX_ADJ, 0xFA);
Si446x_setProperty8(radio, Si446x_MODEM_MDM_CTRL, 0x80);
Si446x_setProperty8(radio, Si446x_MODEM_IF_CONTROL, 0x08);
Si446x_setProperty24(radio, Si446x_MODEM_IF_FREQ, 0x02, 0x80, 0x00);
Si446x_setProperty8(radio, Si446x_MODEM_DECIMATION_CFG1, 0x70);
Si446x_setProperty8(radio, Si446x_MODEM_DECIMATION_CFG0, 0x10);
Si446x_setProperty16(radio, Si446x_MODEM_BCR_OSR, 0x01, 0xC3);
Si446x_setProperty24(radio, Si446x_MODEM_BCR_NCO_OFFSET, 0x01, 0x22, 0x60);
Si446x_setProperty16(radio, Si446x_MODEM_BCR_GAIN, 0x00, 0x91);
Si446x_setProperty8(radio, Si446x_MODEM_BCR_GEAR, 0x00);
Si446x_setProperty8(radio, Si446x_MODEM_BCR_MISC1, 0xC2);
Si446x_setProperty8(radio, Si446x_MODEM_AFC_GEAR, 0x54);
if(is_part_Si4463(handler->radio_part))
Si446x_setProperty8(Si446x_MODEM_AFC_WAIT, 0x23);
Si446x_setProperty8(radio, Si446x_MODEM_AFC_WAIT, 0x23);
else
Si446x_setProperty8(Si446x_MODEM_AFC_WAIT, 0x36);
Si446x_setProperty8(radio, Si446x_MODEM_AFC_WAIT, 0x36);
Si446x_setProperty16(Si446x_MODEM_AFC_GAIN, 0x80, 0xAB);
Si446x_setProperty16(Si446x_MODEM_AFC_LIMITER, 0x02, 0x50);
Si446x_setProperty8(Si446x_MODEM_AFC_MISC, 0x80);
Si446x_setProperty16(radio, Si446x_MODEM_AFC_GAIN, 0x80, 0xAB);
Si446x_setProperty16(radio, Si446x_MODEM_AFC_LIMITER, 0x02, 0x50);
Si446x_setProperty8(radio, Si446x_MODEM_AFC_MISC, 0x80);
if(is_part_Si4463(handler->radio_part))
Si446x_setProperty8(Si446x_MODEM_AGC_CONTROL, 0xE0);
Si446x_setProperty8(radio, Si446x_MODEM_AGC_CONTROL, 0xE0);
else
Si446x_setProperty8(Si446x_MODEM_AGC_CONTROL, 0xE2);
Si446x_setProperty8(radio, Si446x_MODEM_AGC_CONTROL, 0xE2);
Si446x_setProperty8(Si446x_MODEM_AGC_WINDOW_SIZE, 0x11);
Si446x_setProperty8(Si446x_MODEM_AGC_RFPD_DECAY, 0x63);
Si446x_setProperty8(Si446x_MODEM_AGC_IFPD_DECAY, 0x63);
Si446x_setProperty8(radio, Si446x_MODEM_AGC_WINDOW_SIZE, 0x11);
Si446x_setProperty8(radio, Si446x_MODEM_AGC_RFPD_DECAY, 0x63);
Si446x_setProperty8(radio, Si446x_MODEM_AGC_IFPD_DECAY, 0x63);
if(is_part_Si4463(handler->radio_part))
Si446x_setProperty8(Si446x_MODEM_FSK4_GAIN1, 0x80);
Si446x_setProperty8(radio, Si446x_MODEM_FSK4_GAIN1, 0x80);
else
Si446x_setProperty8(Si446x_MODEM_FSK4_GAIN1, 0x00);
Si446x_setProperty8(radio, Si446x_MODEM_FSK4_GAIN1, 0x00);
Si446x_setProperty8(Si446x_MODEM_FSK4_GAIN0, 0x02);
Si446x_setProperty16(Si446x_MODEM_FSK4_TH, 0x35, 0x55);
Si446x_setProperty8(Si446x_MODEM_FSK4_MAP, 0x00);
Si446x_setProperty8(Si446x_MODEM_OOK_PDTC, 0x2A);
Si446x_setProperty8(Si446x_MODEM_OOK_CNT1, 0x85);
Si446x_setProperty8(Si446x_MODEM_OOK_MISC, 0x23);
Si446x_setProperty8(radio, Si446x_MODEM_FSK4_GAIN0, 0x02);
Si446x_setProperty16(radio, Si446x_MODEM_FSK4_TH, 0x35, 0x55);
Si446x_setProperty8(radio, Si446x_MODEM_FSK4_MAP, 0x00);
Si446x_setProperty8(radio, Si446x_MODEM_OOK_PDTC, 0x2A);
Si446x_setProperty8(radio, Si446x_MODEM_OOK_CNT1, 0x85);
Si446x_setProperty8(radio, Si446x_MODEM_OOK_MISC, 0x23);
if(is_part_Si4463(handler->radio_part))
Si446x_setProperty8(Si446x_MODEM_RAW_SEARCH2, 0xBC);
Si446x_setProperty8(radio, Si446x_MODEM_RAW_SEARCH2, 0xBC);
else
Si446x_setProperty8(Si446x_MODEM_RAW_SEARCH, 0xD6);
Si446x_setProperty8(radio, Si446x_MODEM_RAW_SEARCH, 0xD6);
Si446x_setProperty8(Si446x_MODEM_RAW_CONTROL, 0x8F);
Si446x_setProperty16(Si446x_MODEM_RAW_EYE, 0x00, 0x3B);
Si446x_setProperty8(Si446x_MODEM_ANT_DIV_MODE, 0x01);
Si446x_setProperty8(Si446x_MODEM_ANT_DIV_CONTROL, 0x80);
Si446x_setProperty8(Si446x_MODEM_RSSI_COMP, 0x40);
Si446x_setProperty8(radio, Si446x_MODEM_RAW_CONTROL, 0x8F);
Si446x_setProperty16(radio, Si446x_MODEM_RAW_EYE, 0x00, 0x3B);
Si446x_setProperty8(radio, Si446x_MODEM_ANT_DIV_MODE, 0x01);
Si446x_setProperty8(radio, Si446x_MODEM_ANT_DIV_CONTROL, 0x80);
Si446x_setProperty8(radio, Si446x_MODEM_RSSI_COMP, 0x40);
if(is_part_Si4463(handler->radio_part)) {
Si446x_setProperty8(Si446x_MODEM_SPIKE_DET, 0x03);
Si446x_setProperty8(Si446x_MODEM_DSA_CTRL1, 0xA0);
Si446x_setProperty8(Si446x_MODEM_DSA_CTRL2, 0x04);
Si446x_setProperty8(Si446x_MODEM_ONE_SHOT_AFC, 0x07);
Si446x_setProperty8(Si446x_MODEM_DSA_QUAL, 0x06);
Si446x_setProperty8(Si446x_MODEM_DSA_RSSI, 0x78);
Si446x_setProperty8(Si446x_MODEM_DECIMATION_CFG2, 0x0C);
Si446x_setProperty8(Si446x_MODEM_RSSI_MUTE, 0x00);
Si446x_setProperty8(Si446x_MODEM_DSA_MISC, 0x20);
Si446x_setProperty8(Si446x_PREAMBLE_CONFIG, 0x21);
Si446x_setProperty8(radio, Si446x_MODEM_SPIKE_DET, 0x03);
Si446x_setProperty8(radio, Si446x_MODEM_DSA_CTRL1, 0xA0);
Si446x_setProperty8(radio, Si446x_MODEM_DSA_CTRL2, 0x04);
Si446x_setProperty8(radio, Si446x_MODEM_ONE_SHOT_AFC, 0x07);
Si446x_setProperty8(radio, Si446x_MODEM_DSA_QUAL, 0x06);
Si446x_setProperty8(radio, Si446x_MODEM_DSA_RSSI, 0x78);
Si446x_setProperty8(radio, Si446x_MODEM_DECIMATION_CFG2, 0x0C);
Si446x_setProperty8(radio, Si446x_MODEM_RSSI_MUTE, 0x00);
Si446x_setProperty8(radio, Si446x_MODEM_DSA_MISC, 0x20);
Si446x_setProperty8(radio, Si446x_PREAMBLE_CONFIG, 0x21);
}
handler->radio_init = true;
@ -561,7 +581,8 @@ bool Si446x_setBandParameters(const radio_unit_t radio,
uint32_t sy_sel = 8;
uint8_t set_band_property_command[] = {Si446x_SET_PROPERTY,
0x20, 0x01, 0x51, (band + sy_sel)};
Si446x_write(set_band_property_command, sizeof(set_band_property_command));
Si446x_write(radio, set_band_property_command,
sizeof(set_band_property_command));
/* Set the PLL parameters. */
uint32_t f_pfd = 2 * Si446x_CCLK / outdiv;
@ -581,7 +602,7 @@ bool Si446x_setBandParameters(const radio_unit_t radio,
uint8_t set_frequency_property_command[] = {Si446x_SET_PROPERTY,
0x40, 0x04, 0x00, n,
m2, m1, m0, c1, c0};
Si446x_write(set_frequency_property_command,
Si446x_write(radio, set_frequency_property_command,
sizeof(set_frequency_property_command));
uint32_t x = ((((uint32_t)1 << 19) * outdiv * 1300.0)/(2*Si446x_CCLK))*2;
@ -589,7 +610,7 @@ bool Si446x_setBandParameters(const radio_unit_t radio,
uint8_t x1 = (x >> 8) & 0xFF;
uint8_t x0 = (x >> 0) & 0xFF;
uint8_t set_deviation[] = {Si446x_SET_PROPERTY, 0x20, 0x03, 0x0a, x2, x1, x0};
Si446x_write(set_deviation, sizeof(set_deviation));
Si446x_write(radio, set_deviation, sizeof(set_deviation));
return true;
}
@ -610,12 +631,12 @@ bool Si446x_setBandParameters(const radio_unit_t radio,
Si446x_write(set_modem_freq_dev_command, 7);
}*/
static void Si446x_setPowerLevel(const radio_pwr_t level)
{
static void Si446x_setPowerLevel(const radio_unit_t radio,
const radio_pwr_t level) {
// Set the Power
uint8_t set_pa_pwr_lvl_property_command[] = {Si446x_SET_PROPERTY,
0x22, 0x01, 0x01, level};
Si446x_write(set_pa_pwr_lvl_property_command,
Si446x_write(radio, set_pa_pwr_lvl_property_command,
sizeof(set_pa_pwr_lvl_property_command));
}
@ -626,34 +647,30 @@ static void Si446x_setPowerLevel(const radio_pwr_t level)
*/
static void Si446x_setModemAFSK_TX(const radio_unit_t radio) {
/* TODO: Hardware mapping. */
(void)radio;
// Setup the NCO modulo and oversampling mode
uint32_t s = Si446x_CCLK / 10;
uint8_t f3 = (s >> 24) & 0xFF;
uint8_t f2 = (s >> 16) & 0xFF;
uint8_t f1 = (s >> 8) & 0xFF;
uint8_t f0 = (s >> 0) & 0xFF;
Si446x_setProperty32(Si446x_MODEM_TX_NCO_MODE, f3, f2, f1, f0);
Si446x_setProperty32(radio, Si446x_MODEM_TX_NCO_MODE, f3, f2, f1, f0);
// Setup the NCO data rate for APRS
Si446x_setProperty24(Si446x_MODEM_DATA_RATE, 0x00, 0x33, 0x90);
Si446x_setProperty24(radio, Si446x_MODEM_DATA_RATE, 0x00, 0x33, 0x90);
// Use upsampled AFSK from FIFO (PH)
Si446x_setProperty8(Si446x_MODEM_MOD_TYPE, 0x02);
Si446x_setProperty8(radio, Si446x_MODEM_MOD_TYPE, 0x02);
// Set AFSK filter
const uint8_t coeff[] = {0x81, 0x9f, 0xc4, 0xee, 0x18, 0x3e, 0x5c, 0x70, 0x76};
uint8_t i;
for(i = 0; i < sizeof(coeff); i++) {
uint8_t msg[] = {0x11, 0x20, 0x01, 0x17-i, coeff[i]};
Si446x_write(msg, 5);
Si446x_write(radio, msg, 5);
}
}
static void Si446x_setModemAFSK_RX(const radio_unit_t radio) {
/* TODO: Hardware mapping. */
(void)radio;
// Setup the NCO modulo and oversampling mode
/* uint32_t s = Si446x_CCLK;
uint8_t f3 = (s >> 24) & 0xFF;
@ -663,51 +680,52 @@ static void Si446x_setModemAFSK_RX(const radio_unit_t radio) {
Si446x_setProperty32(Si446x_MODEM_TX_NCO_MODE, f3, f2, f1, f0);*/
// Setup the NCO data rate for APRS
//Si446x_setProperty24(Si446x_MODEM_DATA_RATE, 0x04, 0x07, 0x40);
//Si446x_setProperty24(radio, Si446x_MODEM_DATA_RATE, 0x04, 0x07, 0x40);
// Use 2FSK in DIRECT_MODE
Si446x_setProperty8(Si446x_MODEM_MOD_TYPE, 0x0A);
Si446x_setProperty8(radio, Si446x_MODEM_MOD_TYPE, 0x0A);
Si446x_setProperty8(Si446x_MODEM_CHFLT_RX1_CHFLT_COE13_7_0, 0xFF);
Si446x_setProperty8(Si446x_MODEM_CHFLT_RX1_CHFLT_COE12_7_0, 0xC4);
Si446x_setProperty8(Si446x_MODEM_CHFLT_RX1_CHFLT_COE11_7_0, 0x30);
Si446x_setProperty8(Si446x_MODEM_CHFLT_RX1_CHFLT_COE10_7_0, 0x7F);
Si446x_setProperty8(Si446x_MODEM_CHFLT_RX1_CHFLT_COE9_7_0, 0x5F);
Si446x_setProperty8(Si446x_MODEM_CHFLT_RX1_CHFLT_COE8_7_0, 0xB5);
Si446x_setProperty8(Si446x_MODEM_CHFLT_RX1_CHFLT_COE7_7_0, 0xB8);
Si446x_setProperty8(Si446x_MODEM_CHFLT_RX1_CHFLT_COE6_7_0, 0xDE);
Si446x_setProperty8(Si446x_MODEM_CHFLT_RX1_CHFLT_COE5_7_0, 0x05);
Si446x_setProperty8(Si446x_MODEM_CHFLT_RX1_CHFLT_COE4_7_0, 0x17);
Si446x_setProperty8(Si446x_MODEM_CHFLT_RX1_CHFLT_COE3_7_0, 0x16);
Si446x_setProperty8(Si446x_MODEM_CHFLT_RX1_CHFLT_COE2_7_0, 0x0C);
Si446x_setProperty8(Si446x_MODEM_CHFLT_RX1_CHFLT_COE1_7_0, 0x03);
Si446x_setProperty8(Si446x_MODEM_CHFLT_RX1_CHFLT_COE0_7_0, 0x00);
Si446x_setProperty8(Si446x_MODEM_CHFLT_RX1_CHFLT_COEM0, 0x15);
Si446x_setProperty8(Si446x_MODEM_CHFLT_RX1_CHFLT_COEM1, 0xFF);
Si446x_setProperty8(Si446x_MODEM_CHFLT_RX1_CHFLT_COEM2, 0x00);
Si446x_setProperty8(Si446x_MODEM_CHFLT_RX1_CHFLT_COEM3, 0x00);
Si446x_setProperty8(radio, Si446x_MODEM_CHFLT_RX1_CHFLT_COE13_7_0, 0xFF);
Si446x_setProperty8(radio, Si446x_MODEM_CHFLT_RX1_CHFLT_COE12_7_0, 0xC4);
Si446x_setProperty8(radio, Si446x_MODEM_CHFLT_RX1_CHFLT_COE11_7_0, 0x30);
Si446x_setProperty8(radio, Si446x_MODEM_CHFLT_RX1_CHFLT_COE10_7_0, 0x7F);
Si446x_setProperty8(radio, Si446x_MODEM_CHFLT_RX1_CHFLT_COE9_7_0, 0x5F);
Si446x_setProperty8(radio, Si446x_MODEM_CHFLT_RX1_CHFLT_COE8_7_0, 0xB5);
Si446x_setProperty8(radio, Si446x_MODEM_CHFLT_RX1_CHFLT_COE7_7_0, 0xB8);
Si446x_setProperty8(radio, Si446x_MODEM_CHFLT_RX1_CHFLT_COE6_7_0, 0xDE);
Si446x_setProperty8(radio, Si446x_MODEM_CHFLT_RX1_CHFLT_COE5_7_0, 0x05);
Si446x_setProperty8(radio, Si446x_MODEM_CHFLT_RX1_CHFLT_COE4_7_0, 0x17);
Si446x_setProperty8(radio, Si446x_MODEM_CHFLT_RX1_CHFLT_COE3_7_0, 0x16);
Si446x_setProperty8(radio, Si446x_MODEM_CHFLT_RX1_CHFLT_COE2_7_0, 0x0C);
Si446x_setProperty8(radio, Si446x_MODEM_CHFLT_RX1_CHFLT_COE1_7_0, 0x03);
Si446x_setProperty8(radio, Si446x_MODEM_CHFLT_RX1_CHFLT_COE0_7_0, 0x00);
Si446x_setProperty8(radio, Si446x_MODEM_CHFLT_RX1_CHFLT_COEM0, 0x15);
Si446x_setProperty8(radio, Si446x_MODEM_CHFLT_RX1_CHFLT_COEM1, 0xFF);
Si446x_setProperty8(radio, Si446x_MODEM_CHFLT_RX1_CHFLT_COEM2, 0x00);
Si446x_setProperty8(radio, Si446x_MODEM_CHFLT_RX1_CHFLT_COEM3, 0x00);
/* Si446x_setProperty8(Si446x_MODEM_CHFLT_RX2_CHFLT_COE13_7_0, 0xFF);
Si446x_setProperty8(Si446x_MODEM_CHFLT_RX2_CHFLT_COE12_7_0, 0xC4);
Si446x_setProperty8(Si446x_MODEM_CHFLT_RX2_CHFLT_COE11_7_0, 0x30);
Si446x_setProperty8(Si446x_MODEM_CHFLT_RX2_CHFLT_COE10_7_0, 0x7F);
Si446x_setProperty8(Si446x_MODEM_CHFLT_RX2_CHFLT_COE9_7_0, 0xF5);
Si446x_setProperty8(Si446x_MODEM_CHFLT_RX2_CHFLT_COE8_7_0, 0xB5);
Si446x_setProperty8(Si446x_MODEM_CHFLT_RX2_CHFLT_COE7_7_0, 0xB8);
Si446x_setProperty8(Si446x_MODEM_CHFLT_RX2_CHFLT_COE6_7_0, 0xDE);
Si446x_setProperty8(Si446x_MODEM_CHFLT_RX2_CHFLT_COE5_7_0, 0x05);
Si446x_setProperty8(Si446x_MODEM_CHFLT_RX2_CHFLT_COE4_7_0, 0x17);
Si446x_setProperty8(Si446x_MODEM_CHFLT_RX2_CHFLT_COE3_7_0, 0x16);
Si446x_setProperty8(Si446x_MODEM_CHFLT_RX2_CHFLT_COE2_7_0, 0x0C);
Si446x_setProperty8(Si446x_MODEM_CHFLT_RX2_CHFLT_COE1_7_0, 0x03);
Si446x_setProperty8(Si446x_MODEM_CHFLT_RX2_CHFLT_COE0_7_0, 0x00);
Si446x_setProperty8(Si446x_MODEM_CHFLT_RX2_CHFLT_COEM0, 0x15);
Si446x_setProperty8(Si446x_MODEM_CHFLT_RX2_CHFLT_COEM1, 0xFF);
Si446x_setProperty8(Si446x_MODEM_CHFLT_RX2_CHFLT_COEM2, 0x00);
Si446x_setProperty8(Si446x_MODEM_CHFLT_RX2_CHFLT_COEM3, 0x00);*/
/* Si446x_setProperty8(radio, Si446x_MODEM_CHFLT_RX2_CHFLT_COE13_7_0, 0xFF);
Si446x_setProperty8(radio, Si446x_MODEM_CHFLT_RX2_CHFLT_COE12_7_0, 0xC4);
Si446x_setProperty8(radio, Si446x_MODEM_CHFLT_RX2_CHFLT_COE11_7_0, 0x30);
Si446x_setProperty8(radio, Si446x_MODEM_CHFLT_RX2_CHFLT_COE10_7_0, 0x7F);
Si446x_setProperty8(radio, Si446x_MODEM_CHFLT_RX2_CHFLT_COE9_7_0, 0xF5);
Si446x_setProperty8(radio, Si446x_MODEM_CHFLT_RX2_CHFLT_COE8_7_0, 0xB5);
Si446x_setProperty8(radio, Si446x_MODEM_CHFLT_RX2_CHFLT_COE7_7_0, 0xB8);
Si446x_setProperty8(radio, Si446x_MODEM_CHFLT_RX2_CHFLT_COE6_7_0, 0xDE);
Si446x_setProperty8(radio, Si446x_MODEM_CHFLT_RX2_CHFLT_COE5_7_0, 0x05);
Si446x_setProperty8(radio, Si446x_MODEM_CHFLT_RX2_CHFLT_COE4_7_0, 0x17);
Si446x_setProperty8(radio, Si446x_MODEM_CHFLT_RX2_CHFLT_COE3_7_0, 0x16);
Si446x_setProperty8(radio, Si446x_MODEM_CHFLT_RX2_CHFLT_COE2_7_0, 0x0C);
Si446x_setProperty8(radio, Si446x_MODEM_CHFLT_RX2_CHFLT_COE1_7_0, 0x03);
Si446x_setProperty8(radio, Si446x_MODEM_CHFLT_RX2_CHFLT_COE0_7_0, 0x00);
Si446x_setProperty8(radio, Si446x_MODEM_CHFLT_RX2_CHFLT_COEM0, 0x15);
Si446x_setProperty8(radio, Si446x_MODEM_CHFLT_RX2_CHFLT_COEM1, 0xFF);
Si446x_setProperty8(radio, Si446x_MODEM_CHFLT_RX2_CHFLT_COEM2, 0x00);
Si446x_setProperty8(radio, Si446x_MODEM_CHFLT_RX2_CHFLT_COEM3, 0x00);*/
}
static void Si446x_setModem2FSK_TX(const uint32_t speed)
static void Si446x_setModem2FSK_TX(const radio_unit_t radio,
const uint32_t speed)
{
// Setup the NCO modulo and oversampling mode
uint32_t s = Si446x_CCLK / 10;
@ -715,20 +733,20 @@ static void Si446x_setModem2FSK_TX(const uint32_t speed)
uint8_t f2 = (s >> 16) & 0xFF;
uint8_t f1 = (s >> 8) & 0xFF;
uint8_t f0 = (s >> 0) & 0xFF;
Si446x_setProperty32(Si446x_MODEM_TX_NCO_MODE, f3, f2, f1, f0);
Si446x_setProperty32(radio, Si446x_MODEM_TX_NCO_MODE, f3, f2, f1, f0);
// Setup the NCO data rate for 2GFSK
Si446x_setProperty24(Si446x_MODEM_DATA_RATE, (uint8_t)(speed >> 16), (uint8_t)(speed >> 8), (uint8_t)speed);
Si446x_setProperty24(radio, Si446x_MODEM_DATA_RATE, (uint8_t)(speed >> 16), (uint8_t)(speed >> 8), (uint8_t)speed);
// Use 2GFSK from FIFO (PH)
Si446x_setProperty8(Si446x_MODEM_MOD_TYPE, 0x03);
Si446x_setProperty8(radio, Si446x_MODEM_MOD_TYPE, 0x03);
// Set 2GFSK filter (default per Si).
const uint8_t coeff[] = {0x01, 0x03, 0x08, 0x11, 0x21, 0x36, 0x4d, 0x60, 0x67};
uint8_t i;
for(i = 0; i < sizeof(coeff); i++) {
uint8_t msg[] = {0x11, 0x20, 0x01, 0x17-i, coeff[i]};
Si446x_write(msg, sizeof(msg));
Si446x_write(radio, msg, sizeof(msg));
}
}
@ -738,11 +756,9 @@ static void Si446x_setModem2FSK_TX(const uint32_t speed)
*/
static uint8_t __attribute__((unused)) Si446x_getChannel(const radio_unit_t radio) {
/* TODO: add hardware mapping. */
(void)radio;
const uint8_t state_info[] = {Si446x_REQUEST_DEVICE_STATE};
uint8_t rxData[4];
Si446x_read(state_info, sizeof(state_info), rxData, sizeof(rxData));
Si446x_read(radio, state_info, sizeof(state_info), rxData, sizeof(rxData));
return rxData[3];
}
@ -750,20 +766,18 @@ static uint8_t __attribute__((unused)) Si446x_getChannel(const radio_unit_t radi
* Radio FIFO
*/
static void Si446x_writeFIFO(uint8_t *msg, uint8_t size) {
/* TODO: add hardware mapping. */
static void Si446x_writeFIFO(const radio_unit_t radio,
uint8_t *msg, uint8_t size) {
uint8_t write_fifo[size+1];
write_fifo[0] = Si446x_WRITE_TX_FIFO;
memcpy(&write_fifo[1], msg, size);
Si446x_write(write_fifo, size+1);
Si446x_write(radio, write_fifo, size+1);
}
static uint8_t Si446x_getTXfreeFIFO(const radio_unit_t radio) {
/* TODO: add hardware mapping. */
(void)radio;
const uint8_t fifo_info[] = {Si446x_FIFO_INFO, 0x00};
uint8_t rxData[4];
Si446x_read(fifo_info, sizeof(fifo_info), rxData, sizeof(rxData));
Si446x_read(radio, fifo_info, sizeof(fifo_info), rxData, sizeof(rxData));
return rxData[3];
}
@ -772,55 +786,43 @@ static uint8_t Si446x_getTXfreeFIFO(const radio_unit_t radio) {
*/
radio_signal_t Si446x_getCurrentRSSI(const radio_unit_t radio) {
/* TODO: add hardware mapping. */
(void)radio;
/* Get status. Leave any pending interrupts intact. */
const uint8_t status_info[] = {Si446x_GET_MODEM_STATUS, 0xEF};
uint8_t rxData[11];
Si446x_read(status_info, sizeof(status_info), rxData, sizeof(rxData));
Si446x_read(radio, status_info, sizeof(status_info), rxData, sizeof(rxData));
return rxData[4];
}
static uint8_t Si446x_getState(const radio_unit_t radio) {
/* TODO: add hardware mapping. */
(void)radio;
const uint8_t state_info[] = {Si446x_REQUEST_DEVICE_STATE};
uint8_t rxData[4];
Si446x_read(state_info, sizeof(state_info), rxData, sizeof(rxData));
Si446x_read(radio, state_info, sizeof(state_info), rxData, sizeof(rxData));
return rxData[2] & 0xF;
}
static void Si446x_setTXState(const radio_unit_t radio, uint8_t chan, uint16_t size){
/* TODO: add hardware mapping. */
(void)radio;
uint8_t change_state_command[] = {Si446x_START_TX, chan,
(Si446x_STATE_READY << 4),
(size >> 8) & 0x1F, size & 0xFF};
Si446x_write(change_state_command, sizeof(change_state_command));
Si446x_write(radio, change_state_command, sizeof(change_state_command));
}
static void Si446x_setReadyState(const radio_unit_t radio) {
/* TODO: add hardware mapping. */
(void)radio;
const uint8_t change_state_command[] = {Si446x_CHANGE_STATE,
Si446x_STATE_READY};
Si446x_write(change_state_command, sizeof(change_state_command));
Si446x_write(radio, change_state_command, sizeof(change_state_command));
}
static void Si446x_setRXState(const radio_unit_t radio, uint8_t chan){
/* TODO: add hardware mapping. */
(void)radio;
const uint8_t change_state_command[] = {Si446x_START_RX, chan, 0x00, 0x00,
0x00, 0x00, 0x08, 0x08};
Si446x_write(change_state_command, sizeof(change_state_command));
Si446x_write(radio, change_state_command, sizeof(change_state_command));
}
static void Si446x_setStandbyState(const radio_unit_t radio) {
/* TODO: add hardware mapping. */
(void)radio;
const uint8_t change_state_command[] = {Si446x_CHANGE_STATE,
Si446x_STATE_STANDBY};
Si446x_write(change_state_command, sizeof(change_state_command));
Si446x_write(radio, change_state_command, sizeof(change_state_command));
}
/**
@ -831,7 +833,7 @@ void Si446x_radioStandby(const radio_unit_t radio) {
}
/**
* The GPIO LINE_RADIO_SDN is set high in board initialization.
* The GPIO connected to radio SDN is set high in board initialization.
* Thus the radio is in shutdown following board initialization.
* Si446x GPIO1 is configured to output CTS (option 8) during POR.
* We use the MCU GPIO connected to radio GPIO1 to check CTS here.
@ -843,20 +845,15 @@ bool Si446x_radioStartup(const radio_unit_t radio) {
TRACE_INFO("SI > Enable radio %i", radio);
/* Assert SDN low to perform POR wakeup. */
palClearLine(LINE_RADIO_SDN);
/* Assert SDN low to perform radio POR wakeup. */
palClearLine(Si446x_getMCUIO(radio)->sdn);
/*
* Set MCU GPIO input for POR and CTS of radio from GPIO0 and GPIO1.
* TODO: Add function to get radio_list record for this radio number.
* Then get LINE_GPIO_XXX from the radio record.
* Should these setups go into coreIO function?
*/
palSetLineMode(LINE_RADIO_GPIO0, PAL_MODE_INPUT_PULLDOWN);
palSetLineMode(LINE_RADIO_GPIO1, PAL_MODE_INPUT_PULLDOWN);
ioline_t cts = LINE_RADIO_GPIO1;
//return LINE_RADIO_GPIO1;
//ioline_t cts = pktSetLineModeRadioGPIO1(radio);
//pktSetLineModeRadioGPIO0(radio);
palSetLineMode(Si446x_getMCUIO(radio)->gpio0, PAL_MODE_INPUT_PULLDOWN);
palSetLineMode(Si446x_getMCUIO(radio)->gpio1, PAL_MODE_INPUT_PULLDOWN);
/* Wait for transceiver to wake up (maximum wakeup time is 6mS).
* During start up the POR state is on GPIO0.
* This goes from zero to one when POR completes.
@ -864,11 +861,11 @@ bool Si446x_radioStartup(const radio_unit_t radio) {
*/
chThdSleep(TIME_MS2I(10));
/* Return state of CTS after delay. */
return pktReadGPIOline(cts) == PAL_HIGH;
return pktReadGPIOline(Si446x_getMCUIO(radio)->gpio1) == PAL_HIGH;
}
/**
* The radio is shutdown by setting LINE_RADIO_SDN high.
* The radio is shutdown by setting SDN high.
*/
void Si446x_radioShutdown(const radio_unit_t radio) {
TRACE_INFO("SI > Disable radio %i", radio);
@ -876,12 +873,15 @@ void Si446x_radioShutdown(const radio_unit_t radio) {
//chDbgAssert(handler != NULL, "invalid radio ID");
palSetLine(LINE_RADIO_SDN);
palSetLine(Si446x_getMCUIO(radio)->sdn);
handler->radio_init = false;
chThdSleep(TIME_MS2I(1));
}
/* ====================================================================== Radio TX/RX ======================================================================= */
/*
* Radio TX/RX
*/
/**
* Get CCA over measurement interval.
@ -889,12 +889,12 @@ void Si446x_radioShutdown(const radio_unit_t radio) {
* If more than one pulse per millisecond is counted then CCA is not true.
*/
static bool Si446x_checkCCAthreshold(const radio_unit_t radio, uint8_t ms) {
/* TODO: Hardware mapping of radio. */
(void)radio;
/* Get the CCA line. */
ioline_t cca_line = Si446x_getMCUIO(radio)->nirq;
uint16_t cca = 0;
/* Measure sliced CCA instances in period. */
for(uint16_t i = 0; i < (ms * TIME_MS2I(1)); i++) {
cca += Si446x_getCCA();
cca += Si446x_getCCA(cca_line);
/* Sleep one tick. */
chThdSleep(1);
}
@ -935,7 +935,7 @@ static bool Si446x_transmit(const radio_unit_t radio,
/* Check for blind send request. */
if(rssi != PKT_SI446X_NO_CCA_RSSI) {
Si446x_setProperty8(Si446x_MODEM_RSSI_THRESH, rssi);
Si446x_setProperty8(radio, Si446x_MODEM_RSSI_THRESH, rssi);
/* Listen on the TX frequency. */
Si446x_setRXState(radio, chan);
@ -975,7 +975,7 @@ static bool Si446x_transmit(const radio_unit_t radio,
chThdSleep(TIME_MS2I(1));
}
/* Set power level and start transmit. */
Si446x_setPowerLevel(power);
Si446x_setPowerLevel(radio, power);
Si446x_setTXState(radio, chan, size);
// Wait until transceiver enters transmit state
@ -1029,7 +1029,7 @@ bool Si446x_receiveNoLock(const radio_unit_t radio,
TRACE_INFO("SI > Tune Si446x to %d.%03d MHz (RX)",
op_freq/1000000, (op_freq%1000000)/1000);
Si446x_setProperty8(Si446x_MODEM_RSSI_THRESH, rssi);
Si446x_setProperty8(radio, Si446x_MODEM_RSSI_THRESH, rssi);
Si446x_setRXState(radio, channel);
@ -1050,7 +1050,6 @@ bool Si4464_resumeReceive(const radio_unit_t radio,
radio_ch_t rx_chan,
radio_squelch_t rx_rssi,
mod_t rx_mod) {
(void)radio;
bool ret = true;
radio_freq_t op_freq = pktComputeOperatingFrequency(radio,
@ -1074,13 +1073,13 @@ bool Si4464_resumeReceive(const radio_unit_t radio,
}
/*
*
* Called when a packet RX channel is closed.
* If the receiver is active put it into standby.
*/
void Si446x_disableReceive(const radio_unit_t radio) {
/* FIXME: */
if(Si446x_getState(radio) == Si446x_STATE_RX) {
//rx_frequency = 0;
Si446x_radioShutdown(radio);
Si446x_radioStandby(radio);
}
}
@ -1095,7 +1094,9 @@ void Si446x_pauseReceive(const radio_unit_t radio) {
}
}
/* ==================================================================== AFSK Transmitter ==================================================================== */
/*
* AFSK Transmitter
*/
/*
*
@ -1131,7 +1132,7 @@ static uint8_t Si446x_getUpsampledNRZIbits(up_sampler_t *upsampler,
*
*/
static void Si446x_transmitTimeoutI(thread_t *tp) {
/* The tell the thread to terminate. */
/* Tell the thread to terminate. */
chEvtSignal(tp, SI446X_EVT_TX_TIMEOUT);
}
@ -1226,7 +1227,7 @@ THD_FUNCTION(bloc_si_fifo_feeder_afsk, arg) {
all *= SAMPLES_PER_BAUD;
/* Reset TX FIFO in case some remnant unsent data is left there. */
const uint8_t reset_fifo[] = {0x15, 0x01};
Si446x_write(reset_fifo, 2);
Si446x_write(radio, reset_fifo, 2);
up_sampler_t upsampler = {0};
upsampler.phase_delta = PHASE_DELTA_1200;
@ -1253,7 +1254,7 @@ THD_FUNCTION(bloc_si_fifo_feeder_afsk, arg) {
/* Initial FIFO load. */
for(uint16_t i = 0; i < c; i++)
localBuffer[i] = Si446x_getUpsampledNRZIbits(&upsampler, layer0);
Si446x_writeFIFO(localBuffer, c);
Si446x_writeFIFO(radio, localBuffer, c);
uint8_t lower = 0;
@ -1280,7 +1281,7 @@ THD_FUNCTION(bloc_si_fifo_feeder_afsk, arg) {
/* Load the FIFO. */
for(uint16_t i = 0; i < more; i++)
localBuffer[i] = Si446x_getUpsampledNRZIbits(&upsampler, layer0);
Si446x_writeFIFO(localBuffer, more); // Write into FIFO
Si446x_writeFIFO(radio, localBuffer, more); // Write into FIFO
c += more;
/*
@ -1378,7 +1379,9 @@ bool Si446x_blocSendAFSK(radio_task_object_t *rt) {
return true;
}
/* ===================================================================== AFSK Receiver ====================================================================== */
/*
* AFSK Receiver
*/
@ -1386,7 +1389,9 @@ void Si446x_stopDecoder(void) {
// TODO: Nothing yet here
}
/* ========================================================================== 2FSK ========================================================================== */
/*
* 2FSK
*/
/*
* New 2FSK send thread using minimized buffer space and burst send.
@ -1423,7 +1428,7 @@ THD_FUNCTION(bloc_si_fifo_feeder_fsk, arg) {
Si446x_setBandParameters(radio, rto->base_frequency, rto->step_hz);
/* Set parameters for 2FSK transmission. */
Si446x_setModem2FSK_TX(rto->tx_speed);
Si446x_setModem2FSK_TX(radio, rto->tx_speed);
/* Initialize variables for 2FSK encoder. */
@ -1483,7 +1488,7 @@ THD_FUNCTION(bloc_si_fifo_feeder_fsk, arg) {
/* Reset TX FIFO in case some remnant unsent data is left there. */
const uint8_t reset_fifo[] = {0x15, 0x01};
Si446x_write(reset_fifo, 2);
Si446x_write(radio, reset_fifo, 2);
/* Get the FIFO buffer amount currently available. */
uint8_t free = Si446x_getTXfreeFIFO(radio);
@ -1504,7 +1509,7 @@ THD_FUNCTION(bloc_si_fifo_feeder_fsk, arg) {
uint8_t *bufp = layer0;
/* Initial FIFO load. */
Si446x_writeFIFO(bufp, c);
Si446x_writeFIFO(radio, bufp, c);
bufp += c;
uint8_t lower = 0;
@ -1528,7 +1533,7 @@ THD_FUNCTION(bloc_si_fifo_feeder_fsk, arg) {
more = (more > (all - c)) ? (all - c) : more;
/* Load the FIFO. */
Si446x_writeFIFO(bufp, more); // Write into FIFO
Si446x_writeFIFO(radio, bufp, more); // Write into FIFO
bufp += more;
c += more;
@ -1628,14 +1633,15 @@ bool Si446x_blocSend2FSK(radio_task_object_t *rt) {
return true;
}
/* ========================================================================== Misc ========================================================================== */
/*
* Misc
*/
static int16_t Si446x_getTemperature(const radio_unit_t radio) {
/* TODO: Add hardware selection. */
(void)radio;
const uint8_t txData[] = {Si446x_GET_ADC_READING, 0x10};
uint8_t rxData[8];
Si446x_read(txData, sizeof(txData), rxData, sizeof(rxData));
Si446x_read(radio, txData, sizeof(txData), rxData, sizeof(rxData));
uint16_t adc = rxData[7] | ((rxData[6] & 0x7) << 8);
return (89900 * adc) / 4096 - 29300;
}

Wyświetl plik

@ -220,7 +220,7 @@
#define Si446x_getGPIO0() palReadLine(LINE_RADIO_GPIO0)
#define Si446x_getGPIO1() palReadLine(LINE_RADIO_GPIO1)
#define Si446x_getCCA() palReadLine(LINE_RADIO_IRQ)
#define Si446x_getCCA(cca_line) palReadLine(cca_line)
/* Frequency offset corrected oscillator frequency */
#define Si446x_CCLK ((Si446x_CLK) + (Si446x_CLK_OFFSET) \
@ -228,7 +228,8 @@
#define is_part_Si4463(part) (part == 0x4463)
#define is_Si4463_patch_required(part, rom) (is_part_Si4463(part) && rom == 0x6)
#define is_Si4463_patch_required(part, rom) \
(is_part_Si4463(part) && rom == 0x6)
/*===========================================================================*/
/* Module data structures and types. */
@ -242,6 +243,33 @@ typedef struct {
uint8_t current_byte;
} up_sampler_t;
/* MCU IO pin assignments for radio. */
typedef struct Si446x_MCUIO {
ioline_t gpio0;
ioline_t gpio1;
ioline_t gpio2;
ioline_t gpio3;
ioline_t nirq;
ioline_t sdn;
ioline_t cs;
SPIDriver *spi;
} si446x_mcuio_t;
/* Configuration of GPIO in radio. */
typedef struct Si446x_CHIPIO {
uint8_t gpio0;
uint8_t gpio1;
uint8_t gpio2;
uint8_t gpio3;
uint8_t nirq;
uint8_t sdo;
uint8_t cfg;
} si446x_chipio_t;
typedef struct Si446x_DAT {
int16_t lastTemp;
} si446x_data_t;
/* Si446x part info. */
typedef struct {
uint8_t info[10];

Wyświetl plik

@ -22,6 +22,24 @@
#include "debug.h"
#include "geofence.h"
/*===========================================================================*/
/* Module local definitions. */
/*===========================================================================*/
const radio_band_t band_2m = {
.start = BAND_MIN_2M_FREQ,
.end = BAND_MAX_2M_FREQ,
.step = BAND_STEP_2M_HZ,
.def_aprs = BAND_DEF_2M_APRS
};
const radio_band_t band_70cm = {
.start = BAND_MIN_70CM_FREQ,
.end = BAND_MAX_70CM_FREQ,
.step = BAND_STEP_70CM_HZ,
.def_aprs = BAND_DEF_70CM_APRS
};
/**
* @brief Process radio task requests.
* @notes Task objects posted to the queue are processed per radio.
@ -723,8 +741,8 @@ radio_freq_t pktCheckAllowedFrequency(const radio_unit_t radio,
if(list->band[x]->start <= freq
&& freq < list->band[x]->end)
return freq;
}
} /* End for bands */
} /* End for bands */
} /* if(!unit == radio) */
} /* End for radios*/
return FREQ_RADIO_INVALID;
}
@ -904,7 +922,7 @@ bool pktLLDradioEnableReceive(const radio_unit_t radio,
}
/**
*
* Disable receive when closing packet receive for the channel.
*/
void pktLLDradioDisableReceive(const radio_unit_t radio) {
/* TODO: Implement hardware mapping. */
@ -922,7 +940,7 @@ void pktLLDradioDisableReceive(const radio_unit_t radio) {
*
* @return status of the operation
* @retval true operation succeeded.
* retval false operation failed.
* @retval false operation failed.
*
* @notapi
*/

Wyświetl plik

@ -19,8 +19,9 @@
#ifndef PKT_PKTTYPES_H_
#define PKT_PKTTYPES_H_
/*
#ifdef PKT_IS_TEST_PROJECT
/* Modulation type. */
// Modulation type.
typedef enum {
MOD_NONE,
MOD_AFSK,
@ -28,7 +29,9 @@ typedef enum {
} mod_t;
#endif
*/
/*
#ifdef PKT_IS_TEST_PROJECT
inline const char *getModulation(uint8_t key) {
@ -36,6 +39,7 @@ inline const char *getModulation(uint8_t key) {
return val[key];
};
#endif
*/
/* Radio parameters. */
@ -85,6 +89,10 @@ typedef enum radioMode {
RADIO_TX
} radio_mode_t;
/* Forward declaration. */
//typedef struct radioBand radio_band_t;
/* Type for a radio band. */
typedef struct radioBand {
radio_freq_t start;
radio_freq_t end;