WIP of PWM buffer management to reduce memory footprint

- Implement buffer chaining
- Enable PWM buffers to be moved into CCM
pull/4/head
bob 2018-06-13 09:07:41 +10:00
rodzic 86b0e8c9b0
commit 8910a99d77
17 zmienionych plików z 7200 dodań i 6937 usunięć

Wyświetl plik

@ -1,27 +1,31 @@
##############################################################################
# Multi-project makefile rules
#
all:
@echo
@echo ============== Building for pp10a ==================================
@make --no-print-directory -f ./make/pp10a.make all
@echo ====================================================================
@echo
@echo ============== Building for pp10b ==================================
@make --no-print-directory -f ./make/pp10b.make all
@echo ====================================================================
@echo
clean:
@echo
-@make --no-print-directory -f ./make/pp10a.make clean
@echo
-@make --no-print-directory -f ./make/pp10b.make clean
burna:
@echo
-@make --no-print-directory -f ./make/pp10a.make burn-pp10a
burnb:
@echo
-@make --no-print-directory -f ./make/pp10b.make burn-pp10b
##############################################################################
# Multi-project makefile rules
#
all:
@$(MAKE) --version
@echo
@echo ============== Building for pp10a ==================================
@$(MAKE) --no-print-directory -f ./make/pp10a.make all
@echo ====================================================================
@echo
@echo ============== Building for pp10b ==================================
@$(MAKE) --no-print-directory -f ./make/pp10b.make all
@echo ====================================================================
@echo
clean:
@echo
-@$(MAKE) --no-print-directory -f ./make/pp10a.make clean
@echo
-@$(MAKE) --no-print-directory -f ./make/pp10b.make clean
burna:
@echo
-@$(MAKE) --no-print-directory -f ./make/pp10a.make burn-pp10a
burnb:
@echo
-@$(MAKE) --no-print-directory -f ./make/pp10b.make burn-pp10b
##############################################################################

Wyświetl plik

@ -1,209 +1,217 @@
/*
Aerospace Decoder - Copyright (C) 2018 Bob Anderson (VK2GJ)
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*/
#ifndef PORTAB_H_
#define PORTAB_H_
/*===========================================================================*/
/* Module constants. */
/*===========================================================================*/
/*
* Serial port definitions
*/
#define SERIAL_CFG_DEBUG_DRIVER &SD3
//#define SERIAL_CFG_PACKET_DRIVER &SD4
#define USE_SPI_ATTACHED_RADIO TRUE
#define DUMP_PACKET_TO_SERIAL FALSE
/*
* TODO: Need to use radio unit ID to set assigned GPIO & SPI.
* Only if there is a multi radio board...
*/
/*
* Radio SPI definitions.
*/
#define PKT_RADIO_SPI &SPID3
/*
* Radio GPIO definitions.
*/
#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_GPIO0 PAL_LINE(GPIOB, 7U)
#define LINE_RADIO_GPIO1 PAL_LINE(GPIOB, 6U)
#define LINE_SPI_SCK PAL_LINE(GPIOB, 3U)
#define LINE_SPI_MISO PAL_LINE(GPIOB, 4U)
#define LINE_SPI_MOSI PAL_LINE(GPIOB, 5U)
#define BAND_MIN_2M_FREQ 144000000 /* Minimum allowed frequency in Hz */
#define BAND_MAX_2M_FREQ 148000000 /* Maximum allowed frequency in Hz */
#define BAND_STEP_2M_HZ 12500
#define BAND_DEF_2M_APRS 144800000 /* Default frequency in Hz. */
#define BAND_MIN_70CM_FREQ 420000000 /* Minimum allowed frequency in Hz */
#define BAND_MAX_70CM_FREQ 450000000 /* Maximum allowed frequency in Hz */
#define BAND_STEP_70CM_HZ 25000
#define BAND_DEF_70CM_APRS 439100000 /* Default frequency in Hz. */
#define DEFAULT_OPERATING_FREQ 144800000
#define Si446x_CLK STM32_HSECLK /* Oscillator frequency in Hz */
#define Si446x_CLK_OFFSET 22 /* Oscillator frequency drift in ppm */
#define Si446x_CLK_TCXO_EN true /* Set this true, if a TCXO is used, false for XTAL */
#define NUM_PKT_RADIOS 1
#define NUM_BANDS_PER_RADIO 2
/* LED status indicators (set to PAL_NOLINE if not available). */
#define LINE_OVERFLOW_LED PAL_NOLINE
#define LINE_DECODER_LED LINE_IO_BLUE
#define LINE_SQUELCH_LED PAL_NOLINE
#define LINE_NO_FIFO_LED PAL_NOLINE
/* Diagnostic PWM mirror port. */
#define LINE_PWM_MIRROR PAL_NOLINE
/* Radio ports. */
#define LINE_CCA LINE_RADIO_IRQ
#define LINE_ICU LINE_RADIO_GPIO1
//#define LINE_UART4_TX PAL_LINE(GPIOA, 12U)
//#define LINE_UART4_RX PAL_LINE(GPIOA, 11U)
/* The external port can be used for bit bang I2C. */
#define ENABLE_EXTERNAL_I2C FALSE
#if ENABLE_EXTERNAL_I2C == FALSE
#define LINE_USART3_TX LINE_IO_TXD
#define LINE_USART3_RX LINE_IO_RXD
#endif
/* If set to true, the USB interface will be switched on. The tracker is also switched to
* 3V, because USB would not work at 1.8V. Note that the transmission power is increased
* too when operating at 3V. This option will also run the STM32 at 48MHz (AHB) permanently
* because USB needs that speed, otherwise it is running at 6MHz which saves a lot of power.
*/
#define ACTIVATE_USB TRUE
//#define LINE_PWM_MIRROR PAL_LINE(GPIOA, 8U)
//#define LINE_GPIO_PIN PAL_LINE(GPIOA, 8U)
/**
* ICU related definitions.
*/
#define PWM_ICU ICUD4
#define PWM_TIMER_CHANNEL 0
#define PWM_ICU_CLK STM32_TIMCLK1
/* ICU counter frequency. */
/*
* TODO: This should be calculated using timer clock.
* ICU has to run at an integer divide from APBx clock.
*/
#define ICU_COUNT_FREQUENCY 6000000U
#if ((PWM_ICU_CLK % ICU_COUNT_FREQUENCY) != 0)
#error "Invalid ICU frequency for APBx clock setting"
#endif
#define USE_12_BIT_PWM FALSE
/*
* TODO: This will save a lot of system heap as PWM buffers are large
* Stratgey: Allocate PWM buffers from a CCM heap/pool.
* Requires some special handling in PWM and AFSK decoder TBI.
*/
#define USE_HEAP_PWM_BUFFER FALSE
/* Definitions for ICU FIFO implemented using chfactory. */
#define NUMBER_PWM_FIFOS 3U
#define PWM_DATA_SLOTS 6000
/* Number of frame receive buffers. */
#define NUMBER_RX_PKT_BUFFERS 3U
/*
* Number of general AX25/APRS processing & frame send buffers.
* Can configured as being in CCM to save system core memory use.
*/
#define NUMBER_COMMON_PKT_BUFFERS 10U
#define RESERVE_BUFFERS_FOR_INTERNAL 2U
#define MAX_BUFFERS_FOR_BURST_SEND 5U
#if (MAX_BUFFERS_FOR_BURST_SEND > \
(NUMBER_COMMON_PKT_BUFFERS - RESERVE_BUFFERS_FOR_INTERNAL))
#warning "Can not allocate requested buffers for burst send - set to 50%"
#undef MAX_BUFFERS_FOR_BURST_SEND
#define MAX_BUFFERS_FOR_BURST_SEND (NUMBER_COMMON_PKT_BUFFERS / 2)
#endif
/*===========================================================================*/
/* Module pre-compile time settings. */
/*===========================================================================*/
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
/*===========================================================================*/
/* Module data structures and types. */
/*===========================================================================*/
typedef struct radioBand {
radio_freq_t start;
radio_freq_t end;
channel_hz_t step;
radio_freq_t def_aprs;
} radio_band_t;
typedef struct radioParam {
radio_unit_t unit;
radio_type_t type;
radio_band_t *band[NUM_BANDS_PER_RADIO];
} radio_param_t;
/*===========================================================================*/
/* Module macros. */
/*===========================================================================*/
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
//extern const radio_param_t radio_list[NUM_PKT_RADIOS];
#ifdef __cplusplus
extern "C" {
#endif
void pktConfigSerialDiag(void);
void pktConfigSerialPkt(void);
void sysConfigureCoreIO(void);
void pktSetLineModeICU(void);
void pktSerialStart(void);
void dbgWrite(uint8_t level, uint8_t *buf, uint32_t len);
int dbgPrintf(uint8_t level, const char *format, ...);
void pktWrite(uint8_t *buf, uint32_t len);
void pktPowerUpRadio(radio_unit_t radio);
void pktPowerDownRadio(radio_unit_t radio);
radio_freq_t pktCheckAllowedFrequency(radio_unit_t radio, radio_freq_t freq);
uint8_t pktReadIOlines(void);
#ifdef __cplusplus
}
#endif
/*===========================================================================*/
/* Module inline functions. */
/*===========================================================================*/
#endif /* PORTAB_H_ */
/** @} */
/*
Aerospace Decoder - Copyright (C) 2018 Bob Anderson (VK2GJ)
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*/
#ifndef PORTAB_H_
#define PORTAB_H_
/*===========================================================================*/
/* Module constants. */
/*===========================================================================*/
/*
* Serial port definitions
*/
#define SERIAL_CFG_DEBUG_DRIVER &SD3
//#define SERIAL_CFG_PACKET_DRIVER &SD4
#define USE_SPI_ATTACHED_RADIO TRUE
#define DUMP_PACKET_TO_SERIAL FALSE
/*
* TODO: Need to use radio unit ID to set assigned GPIO & SPI.
* Only if there is a multi radio board...
*/
/*
* Radio SPI definitions.
*/
#define PKT_RADIO_SPI &SPID3
/*
* Radio GPIO definitions.
*/
#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_GPIO0 PAL_LINE(GPIOB, 7U)
#define LINE_RADIO_GPIO1 PAL_LINE(GPIOB, 6U)
#define LINE_SPI_SCK PAL_LINE(GPIOB, 3U)
#define LINE_SPI_MISO PAL_LINE(GPIOB, 4U)
#define LINE_SPI_MOSI PAL_LINE(GPIOB, 5U)
#define BAND_MIN_2M_FREQ 144000000 /* Minimum allowed frequency in Hz */
#define BAND_MAX_2M_FREQ 148000000 /* Maximum allowed frequency in Hz */
#define BAND_STEP_2M_HZ 12500
#define BAND_DEF_2M_APRS 144800000 /* Default frequency in Hz. */
#define BAND_MIN_70CM_FREQ 420000000 /* Minimum allowed frequency in Hz */
#define BAND_MAX_70CM_FREQ 450000000 /* Maximum allowed frequency in Hz */
#define BAND_STEP_70CM_HZ 25000
#define BAND_DEF_70CM_APRS 439100000 /* Default frequency in Hz. */
#define DEFAULT_OPERATING_FREQ 144800000
#define Si446x_CLK STM32_HSECLK /* Oscillator frequency in Hz */
#define Si446x_CLK_OFFSET 22 /* Oscillator frequency drift in ppm */
#define Si446x_CLK_TCXO_EN true /* Set this true, if a TCXO is used, false for XTAL */
#define NUM_PKT_RADIOS 1
#define NUM_BANDS_PER_RADIO 2
/* LED status indicators (set to PAL_NOLINE if not available). */
#define LINE_OVERFLOW_LED PAL_NOLINE
#define LINE_DECODER_LED LINE_IO_BLUE
#define LINE_SQUELCH_LED PAL_NOLINE
#define LINE_NO_FIFO_LED PAL_NOLINE
/* Diagnostic PWM mirror port. */
#define LINE_PWM_MIRROR PAL_NOLINE
/* Radio ports. */
#define LINE_CCA LINE_RADIO_IRQ
#define LINE_ICU LINE_RADIO_GPIO1
//#define LINE_UART4_TX PAL_LINE(GPIOA, 12U)
//#define LINE_UART4_RX PAL_LINE(GPIOA, 11U)
/* The external port can be used for bit bang I2C. */
#define ENABLE_EXTERNAL_I2C FALSE
#if ENABLE_EXTERNAL_I2C == FALSE
#define LINE_USART3_TX LINE_IO_TXD
#define LINE_USART3_RX LINE_IO_RXD
#endif
/* If set to true, the USB interface will be switched on. The tracker is also switched to
* 3V, because USB would not work at 1.8V. Note that the transmission power is increased
* too when operating at 3V. This option will also run the STM32 at 48MHz (AHB) permanently
* because USB needs that speed, otherwise it is running at 6MHz which saves a lot of power.
*/
#define ACTIVATE_USB TRUE
//#define LINE_PWM_MIRROR PAL_LINE(GPIOA, 8U)
//#define LINE_GPIO_PIN PAL_LINE(GPIOA, 8U)
/**
* ICU related definitions.
*/
#define PWM_ICU ICUD4
#define PWM_TIMER_CHANNEL 0
#define PWM_ICU_CLK STM32_TIMCLK1
/* ICU counter frequency. */
/*
* TODO: This should be calculated using timer clock.
* ICU has to run at an integer divide from APBx clock.
*/
#define ICU_COUNT_FREQUENCY 6000000U
#if ((PWM_ICU_CLK % ICU_COUNT_FREQUENCY) != 0)
#error "Invalid ICU frequency for APBx clock setting"
#endif
#define USE_12_BIT_PWM FALSE
/*
* TODO: This will save a lot of system heap as PWM buffers are large
* Stratgey: Allocate PWM buffers from a CCM heap/pool.
* Requires some special handling in PWM and AFSK decoder TBI.
*/
#define USE_HEAP_PWM_BUFFER TRUE
/* Definitions for ICU FIFO implemented using chfactory. */
#if USE_HEAP_PWM_BUFFER == TRUE
#define NUMBER_PWM_FIFOS 3U
/* Number of PWM data entries per queue object. */
#define PWM_DATA_SLOTS 200
/* Number of PWM queue objects in total. */
#define PWM_DATA_BUFFERS 10
#else
#define NUMBER_PWM_FIFOS 3U
#define PWM_DATA_SLOTS 6000
#endif
/* Number of frame receive buffers. */
#define NUMBER_RX_PKT_BUFFERS 3U
/*
* Number of general AX25/APRS processing & frame send buffers.
* Can configured as being in CCM to save system core memory use.
*/
#define NUMBER_COMMON_PKT_BUFFERS 10U
#define RESERVE_BUFFERS_FOR_INTERNAL 2U
#define MAX_BUFFERS_FOR_BURST_SEND 5U
#if (MAX_BUFFERS_FOR_BURST_SEND > \
(NUMBER_COMMON_PKT_BUFFERS - RESERVE_BUFFERS_FOR_INTERNAL))
#warning "Can not allocate requested buffers for burst send - set to 50%"
#undef MAX_BUFFERS_FOR_BURST_SEND
#define MAX_BUFFERS_FOR_BURST_SEND (NUMBER_COMMON_PKT_BUFFERS / 2)
#endif
/*===========================================================================*/
/* Module pre-compile time settings. */
/*===========================================================================*/
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
/*===========================================================================*/
/* Module data structures and types. */
/*===========================================================================*/
typedef struct radioBand {
radio_freq_t start;
radio_freq_t end;
channel_hz_t step;
radio_freq_t def_aprs;
} radio_band_t;
typedef struct radioParam {
radio_unit_t unit;
radio_type_t type;
radio_band_t *band[NUM_BANDS_PER_RADIO];
} radio_param_t;
/*===========================================================================*/
/* Module macros. */
/*===========================================================================*/
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
//extern const radio_param_t radio_list[NUM_PKT_RADIOS];
#ifdef __cplusplus
extern "C" {
#endif
void pktConfigSerialDiag(void);
void pktConfigSerialPkt(void);
void sysConfigureCoreIO(void);
void pktSetLineModeICU(void);
void pktSerialStart(void);
void dbgWrite(uint8_t level, uint8_t *buf, uint32_t len);
int dbgPrintf(uint8_t level, const char *format, ...);
void pktWrite(uint8_t *buf, uint32_t len);
void pktPowerUpRadio(radio_unit_t radio);
void pktPowerDownRadio(radio_unit_t radio);
radio_freq_t pktCheckAllowedFrequency(radio_unit_t radio, radio_freq_t freq);
uint8_t pktReadIOlines(void);
#ifdef __cplusplus
}
#endif
/*===========================================================================*/
/* Module inline functions. */
/*===========================================================================*/
#endif /* PORTAB_H_ */
/** @} */

Wyświetl plik

@ -1,199 +1,207 @@
/*
Aerospace Decoder - Copyright (C) 2018 Bob Anderson (VK2GJ)
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*/
#ifndef PORTAB_H_
#define PORTAB_H_
/*===========================================================================*/
/* Module constants. */
/*===========================================================================*/
/*
* Serial port definitions
*/
#define SERIAL_CFG_DEBUG_DRIVER &SD3
//#define SERIAL_CFG_PACKET_DRIVER &SD4
#define USE_SPI_ATTACHED_RADIO TRUE
#define DUMP_PACKET_TO_SERIAL FALSE
/*
* TODO: Need to use radio unit ID to set assigned GPIO & SPI.
* Only if there is a multi radio board...
*/
/*
* Radio SPI definitions.
*/
#define PKT_RADIO_SPI &SPID3
/*
* Radio GPIO definitions.
*/
#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_GPIO0 PAL_LINE(GPIOB, 7U)
#define LINE_RADIO_GPIO1 PAL_LINE(GPIOB, 6U)
#define LINE_SPI_SCK PAL_LINE(GPIOB, 3U)
#define LINE_SPI_MISO PAL_LINE(GPIOB, 4U)
#define LINE_SPI_MOSI PAL_LINE(GPIOB, 5U)
#define BAND_MIN_2M_FREQ 144000000 /* Minimum allowed frequency in Hz */
#define BAND_MAX_2M_FREQ 148000000 /* Maximum allowed frequency in Hz */
#define BAND_STEP_2M_HZ 12500
#define BAND_DEF_2M_APRS 144800000 /* Default frequency in Hz. */
#define BAND_MIN_70CM_FREQ 420000000 /* Minimum allowed frequency in Hz */
#define BAND_MAX_70CM_FREQ 450000000 /* Maximum allowed frequency in Hz */
#define BAND_STEP_70CM_HZ 25000
#define BAND_DEF_70CM_APRS 439100000 /* Default frequency in Hz. */
#define DEFAULT_OPERATING_FREQ 144800000
/* Si446x clock setup. */
#define Si446x_CLK STM32_HSECLK /* Oscillator frequency in Hz */
#define Si446x_CLK_OFFSET 22 /* Oscillator frequency drift in ppm */
#define Si446x_CLK_TCXO_EN true /* Set this true, if a TCXO is used, false for XTAL */
#define NUM_PKT_RADIOS 1
#define NUM_BANDS_PER_RADIO 2
/* LED status indicators (set to PAL_NOLINE if not available). */
#define LINE_OVERFLOW_LED PAL_NOLINE
#define LINE_DECODER_LED LINE_IO_BLUE
#define LINE_SQUELCH_LED PAL_NOLINE
#define LINE_NO_FIFO_LED PAL_NOLINE
/* Diagnostic PWM mirror port. */
#define LINE_PWM_MIRROR PAL_NOLINE
#define LINE_CCA LINE_RADIO_IRQ
#define LINE_ICU LINE_RADIO_GPIO1
//#define LINE_UART4_TX PAL_LINE(GPIOA, 12U)
//#define LINE_UART4_RX PAL_LINE(GPIOA, 11U)
/* The external port can be used for bit bang I2C. */
#define ENABLE_EXTERNAL_I2C FALSE
#if ENABLE_EXTERNAL_I2C == FALSE
#define LINE_USART3_TX LINE_IO_TXD
#define LINE_USART3_RX LINE_IO_RXD
#endif
//#define LINE_PWM_MIRROR PAL_LINE(GPIOA, 8U)
//#define LINE_GPIO_PIN PAL_LINE(GPIOA, 8U)
/**
* ICU related definitions.
*/
#define PWM_ICU ICUD4
#define PWM_TIMER_CHANNEL 0
/* If set to true, the USB interface will be switched on. The tracker is also switched to
* 3V, because USB would not work at 1.8V. Note that the transmission power is increased
* too when operating at 3V. This option will also run the STM32 at 48MHz (AHB) permanently
* because USB needs that speed, otherwise it is running at 6MHz which saves a lot of power.
*/
#define ACTIVATE_USB TRUE
/* ICU counter frequency. */
/*
* TODO: This should be calculated using SYSTEM CLOCK.
* ICU has to run at an integer divide from SYSTEM CLOCK.
*/
#define ICU_COUNT_FREQUENCY 6000000U
#define USE_12_BIT_PWM FALSE
/*
* TODO: This will save a lot of system heap as PWM buffers are large
* Stratgey: Allocate PWM buffers from a CCM heap/pool.
* Requires some special handling in PWM and AFSK decoder.
*/
#define USE_HEAP_PWM_BUFFER FALSE
/* Definitions for ICU FIFO implemented using chfactory. */
#define NUMBER_PWM_FIFOS 3U
#define PWM_DATA_SLOTS 6000
/* Number of frame receive buffers. */
#define NUMBER_RX_PKT_BUFFERS 3U
/* Number of general AX25/APRS processing & frame send buffers. */
#define NUMBER_COMMON_PKT_BUFFERS 10U
#define RESERVE_BUFFERS_FOR_INTERNAL 2U
#define MAX_BUFFERS_FOR_BURST_SEND 3U
#if (MAX_BUFFERS_FOR_BURST_SEND > \
(NUMBER_COMMON_PKT_BUFFERS - RESERVE_BUFFERS_FOR_INTERNAL))
#warning "Can not allocate requested buffers for burst send - set to 50%"
#undef MAX_BUFFERS_FOR_BURST_SEND
#define MAX_BUFFERS_FOR_BURST_SEND (NUMBER_COMMON_PKT_BUFFERS / 2)
#endif
/*===========================================================================*/
/* Module pre-compile time settings. */
/*===========================================================================*/
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
/*===========================================================================*/
/* Module data structures and types. */
/*===========================================================================*/
typedef struct radioBand {
radio_freq_t start;
radio_freq_t end;
channel_hz_t step;
radio_freq_t def_aprs;
} radio_band_t;
typedef struct radioParam {
radio_unit_t unit;
radio_type_t type;
radio_band_t *band[NUM_BANDS_PER_RADIO];
} radio_param_t;
/*===========================================================================*/
/* Module macros. */
/*===========================================================================*/
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#ifdef __cplusplus
extern "C" {
#endif
void pktConfigSerialDiag(void);
void pktConfigSerialPkt(void);
void sysConfigureCoreIO(void);
void pktSetLineModeICU(void);
void pktSerialStart(void);
void dbgWrite(uint8_t level, uint8_t *buf, uint32_t len);
int dbgPrintf(uint8_t level, const char *format, ...);
void pktWrite(uint8_t *buf, uint32_t len);
void pktPowerUpRadio(radio_unit_t radio);
void pktPowerDownRadio(radio_unit_t radio);
radio_freq_t pktCheckAllowedFrequency(radio_unit_t radio, radio_freq_t freq);
uint8_t pktReadIOlines(void);
#ifdef __cplusplus
}
#endif
/*===========================================================================*/
/* Module inline functions. */
/*===========================================================================*/
#endif /* PORTAB_H_ */
/** @} */
/*
Aerospace Decoder - Copyright (C) 2018 Bob Anderson (VK2GJ)
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*/
#ifndef PORTAB_H_
#define PORTAB_H_
/*===========================================================================*/
/* Module constants. */
/*===========================================================================*/
/*
* Serial port definitions
*/
#define SERIAL_CFG_DEBUG_DRIVER &SD3
//#define SERIAL_CFG_PACKET_DRIVER &SD4
#define USE_SPI_ATTACHED_RADIO TRUE
#define DUMP_PACKET_TO_SERIAL FALSE
/*
* TODO: Need to use radio unit ID to set assigned GPIO & SPI.
* Only if there is a multi radio board...
*/
/*
* Radio SPI definitions.
*/
#define PKT_RADIO_SPI &SPID3
/*
* Radio GPIO definitions.
*/
#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_GPIO0 PAL_LINE(GPIOB, 7U)
#define LINE_RADIO_GPIO1 PAL_LINE(GPIOB, 6U)
#define LINE_SPI_SCK PAL_LINE(GPIOB, 3U)
#define LINE_SPI_MISO PAL_LINE(GPIOB, 4U)
#define LINE_SPI_MOSI PAL_LINE(GPIOB, 5U)
#define BAND_MIN_2M_FREQ 144000000 /* Minimum allowed frequency in Hz */
#define BAND_MAX_2M_FREQ 148000000 /* Maximum allowed frequency in Hz */
#define BAND_STEP_2M_HZ 12500
#define BAND_DEF_2M_APRS 144800000 /* Default frequency in Hz. */
#define BAND_MIN_70CM_FREQ 420000000 /* Minimum allowed frequency in Hz */
#define BAND_MAX_70CM_FREQ 450000000 /* Maximum allowed frequency in Hz */
#define BAND_STEP_70CM_HZ 25000
#define BAND_DEF_70CM_APRS 439100000 /* Default frequency in Hz. */
#define DEFAULT_OPERATING_FREQ 144800000
/* Si446x clock setup. */
#define Si446x_CLK STM32_HSECLK /* Oscillator frequency in Hz */
#define Si446x_CLK_OFFSET 22 /* Oscillator frequency drift in ppm */
#define Si446x_CLK_TCXO_EN true /* Set this true, if a TCXO is used, false for XTAL */
#define NUM_PKT_RADIOS 1
#define NUM_BANDS_PER_RADIO 2
/* LED status indicators (set to PAL_NOLINE if not available). */
#define LINE_OVERFLOW_LED PAL_NOLINE
#define LINE_DECODER_LED LINE_IO_BLUE
#define LINE_SQUELCH_LED PAL_NOLINE
#define LINE_NO_FIFO_LED PAL_NOLINE
/* Diagnostic PWM mirror port. */
#define LINE_PWM_MIRROR PAL_NOLINE
#define LINE_CCA LINE_RADIO_IRQ
#define LINE_ICU LINE_RADIO_GPIO1
//#define LINE_UART4_TX PAL_LINE(GPIOA, 12U)
//#define LINE_UART4_RX PAL_LINE(GPIOA, 11U)
/* The external port can be used for bit bang I2C. */
#define ENABLE_EXTERNAL_I2C FALSE
#if ENABLE_EXTERNAL_I2C == FALSE
#define LINE_USART3_TX LINE_IO_TXD
#define LINE_USART3_RX LINE_IO_RXD
#endif
//#define LINE_PWM_MIRROR PAL_LINE(GPIOA, 8U)
//#define LINE_GPIO_PIN PAL_LINE(GPIOA, 8U)
/**
* ICU related definitions.
*/
#define PWM_ICU ICUD4
#define PWM_TIMER_CHANNEL 0
/* If set to true, the USB interface will be switched on. The tracker is also switched to
* 3V, because USB would not work at 1.8V. Note that the transmission power is increased
* too when operating at 3V. This option will also run the STM32 at 48MHz (AHB) permanently
* because USB needs that speed, otherwise it is running at 6MHz which saves a lot of power.
*/
#define ACTIVATE_USB TRUE
/* ICU counter frequency. */
/*
* TODO: This should be calculated using SYSTEM CLOCK.
* ICU has to run at an integer divide from SYSTEM CLOCK.
*/
#define ICU_COUNT_FREQUENCY 6000000U
#define USE_12_BIT_PWM FALSE
/*
* TODO: This will save a lot of system heap as PWM buffers are large
* Stratgey: Allocate PWM buffers from a CCM heap/pool.
* Requires some special handling in PWM and AFSK decoder.
*/
#define USE_HEAP_PWM_BUFFER FALSE
/* Definitions for ICU FIFO implemented using chfactory. */
#if USE_HEAP_PWM_BUFFER == TRUE
#define NUMBER_PWM_FIFOS 3U
/* Number of PWM data entries per queue object. */
#define PWM_DATA_SLOTS 200
/* Number of PWM queue objects in total. */
#define PWM_DATA_BUFFERS 10
#else
#define NUMBER_PWM_FIFOS 3U
#define PWM_DATA_SLOTS 6000
#endif
/* Number of frame receive buffers. */
#define NUMBER_RX_PKT_BUFFERS 3U
/* Number of general AX25/APRS processing & frame send buffers. */
#define NUMBER_COMMON_PKT_BUFFERS 10U
#define RESERVE_BUFFERS_FOR_INTERNAL 2U
#define MAX_BUFFERS_FOR_BURST_SEND 3U
#if (MAX_BUFFERS_FOR_BURST_SEND > \
(NUMBER_COMMON_PKT_BUFFERS - RESERVE_BUFFERS_FOR_INTERNAL))
#warning "Can not allocate requested buffers for burst send - set to 50%"
#undef MAX_BUFFERS_FOR_BURST_SEND
#define MAX_BUFFERS_FOR_BURST_SEND (NUMBER_COMMON_PKT_BUFFERS / 2)
#endif
/*===========================================================================*/
/* Module pre-compile time settings. */
/*===========================================================================*/
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
/*===========================================================================*/
/* Module data structures and types. */
/*===========================================================================*/
typedef struct radioBand {
radio_freq_t start;
radio_freq_t end;
channel_hz_t step;
radio_freq_t def_aprs;
} radio_band_t;
typedef struct radioParam {
radio_unit_t unit;
radio_type_t type;
radio_band_t *band[NUM_BANDS_PER_RADIO];
} radio_param_t;
/*===========================================================================*/
/* Module macros. */
/*===========================================================================*/
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#ifdef __cplusplus
extern "C" {
#endif
void pktConfigSerialDiag(void);
void pktConfigSerialPkt(void);
void sysConfigureCoreIO(void);
void pktSetLineModeICU(void);
void pktSerialStart(void);
void dbgWrite(uint8_t level, uint8_t *buf, uint32_t len);
int dbgPrintf(uint8_t level, const char *format, ...);
void pktWrite(uint8_t *buf, uint32_t len);
void pktPowerUpRadio(radio_unit_t radio);
void pktPowerDownRadio(radio_unit_t radio);
radio_freq_t pktCheckAllowedFrequency(radio_unit_t radio, radio_freq_t freq);
uint8_t pktReadIOlines(void);
#ifdef __cplusplus
}
#endif
/*===========================================================================*/
/* Module inline functions. */
/*===========================================================================*/
#endif /* PORTAB_H_ */
/** @} */

Wyświetl plik

@ -1,240 +1,239 @@
##############################################################################
# Build global options
# NOTE: Can be overridden externally.
#
# Compiler options here.
ifeq ($(USE_OPT),)
USE_OPT = -O2 -ggdb -fomit-frame-pointer -falign-functions=16
endif
# C specific options here (added to USE_OPT).
ifeq ($(USE_COPT),)
USE_COPT = -std=c11
endif
# C++ specific options here (added to USE_OPT).
ifeq ($(USE_CPPOPT),)
USE_CPPOPT = -fno-rtti
endif
# Enable this if you want the linker to remove unused code and data
ifeq ($(USE_LINK_GC),)
USE_LINK_GC = yes
endif
# Linker extra moptions here.
ifeq ($(USE_LDOPT),)
USE_LDOPT =
endif
# Enable this if you want link time optimizations (LTO)
ifeq ($(USE_LTO),)
USE_LTO = yes
endif
# If enabled, this option allows to compile the application in THUMB mode.
ifeq ($(USE_THUMB),)
USE_THUMB = yes
endif
# Enable this if you want to see the full log while compiling.
ifeq ($(USE_VERBOSE_COMPILE),)
USE_VERBOSE_COMPILE = no
endif
# If enabled, this option makes the build process faster by not compiling
# modules not used in the current configuration.
ifeq ($(USE_SMART_BUILD),)
USE_SMART_BUILD = yes
endif
#
# Build global options
##############################################################################
##############################################################################
# Architecture or project specific options
#
# Stack size to be allocated to the Cortex-M process stack. This stack is
# the stack used by the main() thread.
ifeq ($(USE_PROCESS_STACKSIZE),)
USE_PROCESS_STACKSIZE = 0x1000
endif
# Stack size to the allocated to the Cortex-M main/exceptions stack. This
# stack is used for processing interrupts and exceptions.
ifeq ($(USE_EXCEPTIONS_STACKSIZE),)
USE_EXCEPTIONS_STACKSIZE = 0x5000
endif
# Enables the use of FPU (no, softfp, hard).
ifeq ($(USE_FPU),)
USE_FPU = hard
USE_FPU_OPT = -mfloat-abi=$(USE_FPU) \
-mfpu=fpv4-sp-d16 -fsingle-precision-constant
endif
#
# Architecture or project specific options
##############################################################################
##############################################################################
# Project, sources and paths
#
# Define project name here
PROJECT = pp10a
# Imported source files and paths
CHIBIOS = ChibiOS
CONFDIR := ${CURDIR}/cfg/$(PROJECT)
BUILDDIR := ${CURDIR}/build/$(PROJECT)
DEPDIR := ${CURDIR}/.dep/$(PROJECT)
CMSISINC = ${CURDIR}/CMSIS/include
CMSISLIB = ${CURDIR}/CMSIS/Lib/GCC
# Licensing files.
include $(CHIBIOS)/os/license/license.mk
# Startup files.
include $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/mk/startup_stm32f4xx.mk
# HAL-OSAL files (optional).
include $(CHIBIOS)/os/hal/hal.mk
include $(CHIBIOS)/os/hal/ports/STM32/STM32F4xx/platform.mk
include $(CHIBIOS)/os/hal/osal/rt/osal.mk
# BOARD files.
include $(CONFDIR)/board/board.mk
# PORTAB files.
include $(CONFDIR)/portab.mk
# RTOS files (optional).
include $(CHIBIOS)/os/rt/rt.mk
include $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/mk/port_v7m.mk
# Auto-build files in AUTOBUILD_ROOT recursively.
include $(CHIBIOS)/tools/mk/autobuild.mk
# Other files (optional).
include $(CHIBIOS)/test/lib/test.mk
include $(CHIBIOS)/test/rt/rt_test.mk
include $(CHIBIOS)/test/oslib/oslib_test.mk
include $(CHIBIOS)/os/hal/lib/streams/streams.mk
include $(CHIBIOS)/os/various/shell/shell.mk
include $(CHIBIOS)/os/various/fatfs_bindings/fatfs.mk
# Define linker script file here
LDSCRIPT= $(CONFDIR)/STM32F413xH.ld
#$(info $$ALLCSRC is [${ALLCSRC}])
#$(info $$CONFDIR is [${CONFDIR}])
#$(info $$ALLINC is [${ALLINC}])
# C sources that can be compiled in ARM or THUMB mode depending on the global
# setting.
CSRC = $(ALLCSRC) \
$(TESTSRC) \
main.c \
# C++ sources that can be compiled in ARM or THUMB mode depending on the global
# setting.
CPPSRC = $(ALLCPPSRC)
# C sources to be compiled in ARM mode regardless of the global setting.
# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler
# option that results in lower performance and larger code size.
ACSRC =
# C++ sources to be compiled in ARM mode regardless of the global setting.
# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler
# option that results in lower performance and larger code size.
ACPPSRC =
# C sources to be compiled in THUMB mode regardless of the global setting.
# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler
# option that results in lower performance and larger code size.
TCSRC =
# C sources to be compiled in THUMB mode regardless of the global setting.
# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler
# option that results in lower performance and larger code size.
TCPPSRC =
# List ASM source files here
ASMSRC = $(ALLASMSRC)
ASMXSRC = $(ALLXASMSRC)
INCDIR = $(ALLINC) $(TESTINC)
#$(info $$INCDIR is [${INCDIR}])
#
# Project, sources and paths
##############################################################################
##############################################################################
# Compiler settings
#
MCU = cortex-m4
#TRGT = arm-elf-
TRGT = arm-none-eabi-
CC = $(TRGT)gcc
CPPC = $(TRGT)g++
# Enable loading with g++ only if you need C++ runtime support.
# NOTE: You can use C++ even without C++ support if you are careful. C++
# runtime support makes code size explode.
LD = $(TRGT)gcc
#LD = $(TRGT)g++
CP = $(TRGT)objcopy
AS = $(TRGT)gcc -x assembler-with-cpp
AR = $(TRGT)ar
OD = $(TRGT)objdump
SZ = $(TRGT)size
HEX = $(CP) -O ihex
BIN = $(CP) -O binary
# ARM-specific options here
AOPT =
# THUMB-specific options here
TOPT = -mthumb -DTHUMB
# Define C warning options here
CWARN = -Wall -Wextra -Wundef -Wstrict-prototypes
# Define C++ warning options here
CPPWARN = -Wall -Wextra -Wundef
#
# Compiler settings
##############################################################################
##############################################################################
# Start of user section
#
# List all user C define here, like -D_DEBUG=1
UDEFS = -D_GNU_SOURCE -DARM_MATH_CM4 -DSHELL_CMD_TEST_ENABLED=0 \
-DSHELL_CMD_EXIT_ENABLED=1 -DUSB_TRACE_LEVEL=5 \
-DSHELL_CMD_MEM_ENABLED=0
# -DDISABLE_HW_WATCHDOG=1
# Define ASM defines here
UADEFS =
# List all user directories here
UINCDIR = $(CMSISINC)
# List the user directory to look for the libraries here
ULIBDIR = $(CMSISLIB)
# List all user libraries here
ULIBS = -lm $(CMSISLIB)/libarm_cortexM4l_math.a
#
# End of user defines
##############################################################################
RULESPATH = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC
include $(RULESPATH)/rules.mk
burn-$(PROJECT):
st-flash write build/$(PROJECT)/$(PROJECT).bin 0x08000000
##############################################################################
# Build global options
# NOTE: Can be overridden externally.
#
# Compiler options here.
ifeq ($(USE_OPT),)
USE_OPT = -O2 -ggdb -fomit-frame-pointer -falign-functions=16
endif
# C specific options here (added to USE_OPT).
ifeq ($(USE_COPT),)
USE_COPT = -std=c11
endif
# C++ specific options here (added to USE_OPT).
ifeq ($(USE_CPPOPT),)
USE_CPPOPT = -fno-rtti
endif
# Enable this if you want the linker to remove unused code and data
ifeq ($(USE_LINK_GC),)
USE_LINK_GC = yes
endif
# Linker extra moptions here.
ifeq ($(USE_LDOPT),)
USE_LDOPT =
endif
# Enable this if you want link time optimizations (LTO)
ifeq ($(USE_LTO),)
USE_LTO = yes
endif
# If enabled, this option allows to compile the application in THUMB mode.
ifeq ($(USE_THUMB),)
USE_THUMB = yes
endif
# Enable this if you want to see the full log while compiling.
ifeq ($(USE_VERBOSE_COMPILE),)
USE_VERBOSE_COMPILE = no
endif
# If enabled, this option makes the build process faster by not compiling
# modules not used in the current configuration.
ifeq ($(USE_SMART_BUILD),)
USE_SMART_BUILD = yes
endif
#
# Build global options
##############################################################################
##############################################################################
# Architecture or project specific options
#
# Stack size to be allocated to the Cortex-M process stack. This stack is
# the stack used by the main() thread.
ifeq ($(USE_PROCESS_STACKSIZE),)
USE_PROCESS_STACKSIZE = 0x1000
endif
# Stack size to the allocated to the Cortex-M main/exceptions stack. This
# stack is used for processing interrupts and exceptions.
ifeq ($(USE_EXCEPTIONS_STACKSIZE),)
USE_EXCEPTIONS_STACKSIZE = 0x5000
endif
# Enables the use of FPU (no, softfp, hard).
ifeq ($(USE_FPU),)
USE_FPU = hard
USE_FPU_OPT = -mfloat-abi=$(USE_FPU) \
-mfpu=fpv4-sp-d16 -fsingle-precision-constant
endif
#
# Architecture or project specific options
##############################################################################
##############################################################################
# Project, sources and paths
#
# Define project name here
PROJECT = pp10a
# Imported source files and paths
CHIBIOS = ChibiOS
CONFDIR := ${CURDIR}/cfg/$(PROJECT)
BUILDDIR := ${CURDIR}/build/$(PROJECT)
DEPDIR := ${CURDIR}/.dep/$(PROJECT)
CMSISINC = ${CURDIR}/CMSIS/include
CMSISLIB = ${CURDIR}/CMSIS/Lib/GCC
# Licensing files.
include $(CHIBIOS)/os/license/license.mk
# Startup files.
include $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/mk/startup_stm32f4xx.mk
# HAL-OSAL files (optional).
include $(CHIBIOS)/os/hal/hal.mk
include $(CHIBIOS)/os/hal/ports/STM32/STM32F4xx/platform.mk
include $(CHIBIOS)/os/hal/osal/rt/osal.mk
# BOARD files.
include $(CONFDIR)/board/board.mk
# PORTAB files.
include $(CONFDIR)/portab.mk
# RTOS files (optional).
include $(CHIBIOS)/os/rt/rt.mk
include $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/mk/port_v7m.mk
# Auto-build files in AUTOBUILD_ROOT recursively.
include $(CHIBIOS)/tools/mk/autobuild.mk
# Other files (optional).
include $(CHIBIOS)/test/lib/test.mk
include $(CHIBIOS)/test/rt/rt_test.mk
include $(CHIBIOS)/test/oslib/oslib_test.mk
include $(CHIBIOS)/os/hal/lib/streams/streams.mk
include $(CHIBIOS)/os/various/shell/shell.mk
include $(CHIBIOS)/os/various/fatfs_bindings/fatfs.mk
# Define linker script file here
LDSCRIPT= $(CONFDIR)/STM32F413xH.ld
#$(info $$ALLCSRC is [${ALLCSRC}])
#$(info $$CONFDIR is [${CONFDIR}])
#$(info $$ALLINC is [${ALLINC}])
# C sources that can be compiled in ARM or THUMB mode depending on the global
# setting.
CSRC = $(ALLCSRC) \
$(TESTSRC) \
main.c \
# C++ sources that can be compiled in ARM or THUMB mode depending on the global
# setting.
CPPSRC = $(ALLCPPSRC)
# C sources to be compiled in ARM mode regardless of the global setting.
# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler
# option that results in lower performance and larger code size.
ACSRC =
# C++ sources to be compiled in ARM mode regardless of the global setting.
# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler
# option that results in lower performance and larger code size.
ACPPSRC =
# C sources to be compiled in THUMB mode regardless of the global setting.
# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler
# option that results in lower performance and larger code size.
TCSRC =
# C sources to be compiled in THUMB mode regardless of the global setting.
# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler
# option that results in lower performance and larger code size.
TCPPSRC =
# List ASM source files here
ASMSRC = $(ALLASMSRC)
ASMXSRC = $(ALLXASMSRC)
INCDIR = $(ALLINC) $(TESTINC)
#$(info $$INCDIR is [${INCDIR}])
#
# Project, sources and paths
##############################################################################
##############################################################################
# Compiler settings
#
MCU = cortex-m4
#TRGT = arm-elf-
TRGT = arm-none-eabi-
CC = $(TRGT)gcc
CPPC = $(TRGT)g++
# Enable loading with g++ only if you need C++ runtime support.
# NOTE: You can use C++ even without C++ support if you are careful. C++
# runtime support makes code size explode.
LD = $(TRGT)gcc
#LD = $(TRGT)g++
CP = $(TRGT)objcopy
AS = $(TRGT)gcc -x assembler-with-cpp
AR = $(TRGT)ar
OD = $(TRGT)objdump
SZ = $(TRGT)size
HEX = $(CP) -O ihex
BIN = $(CP) -O binary
# ARM-specific options here
AOPT =
# THUMB-specific options here
TOPT = -mthumb -DTHUMB
# Define C warning options here
CWARN = -Wall -Wextra -Wundef -Wstrict-prototypes
# Define C++ warning options here
CPPWARN = -Wall -Wextra -Wundef
#
# Compiler settings
##############################################################################
##############################################################################
# Start of user section
#
# List all user C define here, like -D_DEBUG=1
UDEFS = -D_GNU_SOURCE -DARM_MATH_CM4 -DSHELL_CMD_TEST_ENABLED=0 \
-DSHELL_CMD_EXIT_ENABLED=1 -DUSB_TRACE_LEVEL=5 \
-DSHELL_CMD_MEM_ENABLED=0 -DDISABLE_HW_WATCHDOG=1
# Define ASM defines here
UADEFS =
# List all user directories here
UINCDIR = $(CMSISINC)
# List the user directory to look for the libraries here
ULIBDIR = $(CMSISLIB)
# List all user libraries here
ULIBS = -lm $(CMSISLIB)/libarm_cortexM4l_math.a
#
# End of user defines
##############################################################################
RULESPATH = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC
include $(RULESPATH)/rules.mk
burn-$(PROJECT):
st-flash write build/$(PROJECT)/$(PROJECT).bin 0x08000000

Wyświetl plik

@ -1,207 +1,203 @@
/**
* Put your configuration settings here. See description of all fields in types.h
*/
#include "config.h"
#include "aprs.h"
#include "geofence.h"
conf_t conf_sram;
const conf_t conf_flash_default = {
// Primary position app
.pos_pri = {
.thread_conf = {
.active = false,
.cycle = TIME_S2I(60 * 5),
.init_delay = TIME_S2I(30)
},
.radio_conf = {
.pwr = 0x7F,
.freq = FREQ_APRS_DYNAMIC,
.mod = MOD_AFSK,
.cca = 0x4F,
},
// App identity
.call = "VK2GJ-12",
.path = "WIDE1-1",
.symbol = SYM_ANTENNA,
.aprs_msg = true,
// How often to send telemetry config
.tel_enc_cycle = TIME_S2I(60 * 60)
},
// Secondary position app
.pos_sec = {
.thread_conf = {
.active = false,
.cycle = TIME_S2I(180),
.init_delay = TIME_S2I(60)
},
.radio_conf = {
.pwr = 0x7F,
.freq = 145825000,
.mod = MOD_AFSK,
.cca = 0xFF
},
// App identity
.call = "VK2GJ-15",
.path = "",
.symbol = SYM_BALLOON,
.aprs_msg = true,
.tel_enc_cycle = TIME_S2I(0)
},
// Primary image app
.img_pri = {
.thread_conf = {
.active = false,
.cycle = CYCLE_CONTINUOUSLY,
.init_delay = TIME_S2I(90),
.send_spacing = TIME_S2I(0)
},
.radio_conf = {
.pwr = 0x7F,
.freq = 144800000,
.mod = MOD_2FSK,
.cca = 0x4F
},
// App identity
.call = "VK2GJ-15",
.path = "",
// Image settings
.res = RES_VGA,
.quality = 4,
.buf_size = 40 * 1024,
.redundantTx = false
},
// Secondary image app
.img_sec = {
.thread_conf = {
.active = false,
.cycle = TIME_S2I(60 * 30),
.init_delay = TIME_S2I(60 * 1),
.send_spacing = TIME_S2I(30)
},
.radio_conf = {
.pwr = 0x7F,
.freq = APRS_FREQ_AUSTRALIA,
.mod = MOD_AFSK,
.cca = 0x4F
},
// App identity
.call = "VK2GJ-14",
.path = "",
// Image settings
.res = RES_QVGA,
.quality = 4,
.buf_size = 15 * 1024,
.redundantTx = false
},
// Log app
.log = {
.thread_conf = {
.active = false,
.cycle = TIME_S2I(10),
.init_delay = TIME_S2I(5)
},
.radio_conf = {
.pwr = 0x7F,
.freq = FREQ_APRS_DYNAMIC,
.mod = MOD_AFSK,
.cca = 0x4F
},
// Node identity
.call = "VK2GJ-13",
.path = "WIDE1-1",
.density = 10
},
// APRS app
.aprs = {
.thread_conf = {
// The packet receive service is enabled if true
// Receive is resumed after any transmission
.active = true,
.init_delay = TIME_S2I(20)
},
// The default APRS frequency when geofence is not resolved
.freq = APRS_FREQ_AUSTRALIA,
// The receive identity for APRS
.rx = {
// Receive radio configuration
.radio_conf = {
.freq = FREQ_APRS_DYNAMIC,
.mod = MOD_AFSK,
.rssi = 0x3F
},
// APRS identity used in message responses if digipeat is not enabled
.call = "VK2GJ-4",
.symbol = SYM_ANTENNA
},
// The digipeat transmit identity
.digi = {
.active = true,
// Transmit radio configuration
.radio_conf = {
.freq = FREQ_APRS_RECEIVE,
.pwr = 0x7F,
.mod = MOD_AFSK,
.cca = 0x4F
},
// Digipeat identity
.call = "VK2GJ-5",
.path = "WIDE2-1",
.symbol = SYM_DIGIPEATER,
// Set to have digi beacon position, telemetry & APRSD information.
// This starts a BCN thread specifically for digi
.beacon = true,
.cycle = TIME_S2I(60 * 30), // Beacon interval
// Set true to have digi use GPS for position
// If valid position is not stored then default lat, lon and alt will be used.
// If RTC time is invalid then GPS will be enabled to get time.
// Once RTC is set then GPS is released and can be switched off.
// This will be the case if no other position thread is using it.
.gps = false,
// A set location if GPS not enabled or unable to acquire lock.
//.lat = -337331175, // Degrees (expressed in 1e-7 form)
//.lon = 1511143478, // Degrees (expressed in 1e-7 form)
//.alt = 144, // Altitude in metres
// How often to send telemetry config (TODO: Move out to global level)
.tel_enc_cycle = TIME_S2I(60 * 60 * 2)
},
// The base station identity
.base = {
// Tracker originated messages will be sent to this call sign if enabled
.enabled = true,
.call = "VK2GJ-7",
.path = "WIDE2-1",
},
},
// Global controls
// Power control
.keep_cam_switched_on = false,
.gps_on_vbat = 1000, // mV
.gps_off_vbat = 1000, // mV
.gps_onper_vbat = 1000, // mV
// GPS altitude model control (air pressure determined by on-board BME280)
.gps_pressure = 90000, // Air pressure (Pa) threshold for alt model switch
.gps_low_alt = GPS_STATIONARY,
.gps_high_alt = GPS_AIRBORNE_1G,
// A pre-set location if GPS never enabled or unable to acquire lock.
.lat = -337331175, // Degrees (expressed in 1e-7 form)
.lon = 1511143478, // Degrees (expressed in 1e-7 form)
.alt = 144, // Altitude in metres
.magic = CONFIG_MAGIC_DEFAULT // Do not remove. This is the activation bit.
};
/**
* Put your configuration settings here. See description of all fields in types.h
*/
#include "config.h"
#include "aprs.h"
#include "geofence.h"
conf_t conf_sram;
const conf_t conf_flash_default = {
// Primary position app
.pos_pri = {
.thread_conf = {
.active = false,
.cycle = TIME_S2I(60 * 5),
.init_delay = TIME_S2I(30)
},
.radio_conf = {
.pwr = 0x7F,
.freq = FREQ_APRS_DYNAMIC,
.mod = MOD_AFSK,
.cca = 0x4F,
},
// App identity
.call = "VK2GJ-12",
.path = "WIDE1-1",
.symbol = SYM_ANTENNA,
.aprs_msg = true,
// How often to send telemetry config
.tel_enc_cycle = TIME_S2I(60 * 60)
},
// Secondary position app
.pos_sec = {
.thread_conf = {
.active = false,
.cycle = TIME_S2I(180),
.init_delay = TIME_S2I(60)
},
.radio_conf = {
.pwr = 0x7F,
.freq = 145825000,
.mod = MOD_AFSK,
.cca = 0xFF
},
// App identity
.call = "VK2GJ-15",
.path = "",
.symbol = SYM_BALLOON,
.aprs_msg = true,
.tel_enc_cycle = TIME_S2I(0)
},
// Primary image app
.img_pri = {
.thread_conf = {
.active = false,
.cycle = CYCLE_CONTINUOUSLY,
.init_delay = TIME_S2I(90),
.send_spacing = TIME_S2I(0)
},
.radio_conf = {
.pwr = 0x7F,
.freq = 144800000,
.mod = MOD_2FSK,
.cca = 0x4F
},
// App identity
.call = "VK2GJ-15",
.path = "",
// Image settings
.res = RES_VGA,
.quality = 4,
.buf_size = 40 * 1024,
.redundantTx = false
},
// Secondary image app
.img_sec = {
.thread_conf = {
.active = false,
.cycle = TIME_S2I(60 * 30),
.init_delay = TIME_S2I(60 * 1),
.send_spacing = TIME_S2I(30)
},
.radio_conf = {
.pwr = 0x7F,
.freq = APRS_FREQ_AUSTRALIA,
.mod = MOD_AFSK,
.cca = 0x4F
},
// App identity
.call = "VK2GJ-14",
.path = "",
// Image settings
.res = RES_QVGA,
.quality = 4,
.buf_size = 15 * 1024,
.redundantTx = false
},
// Log app
.log = {
.thread_conf = {
.active = false,
.cycle = TIME_S2I(10),
.init_delay = TIME_S2I(5)
},
.radio_conf = {
.pwr = 0x7F,
.freq = FREQ_APRS_DYNAMIC,
.mod = MOD_AFSK,
.cca = 0x4F
},
// Node identity
.call = "VK2GJ-13",
.path = "WIDE1-1",
.density = 10
},
// APRS app
.aprs = {
.thread_conf = {
// The packet receive service is enabled if true
// Receive is resumed after any transmission
.active = true,
.init_delay = TIME_S2I(20)
},
// The default APRS frequency when geofence is not resolved
.freq = APRS_FREQ_AUSTRALIA,
// The receive identity for APRS
.rx = {
// Receive radio configuration
.radio_conf = {
.freq = FREQ_APRS_DYNAMIC,
.mod = MOD_AFSK,
.rssi = 0x3F
},
// APRS identity used in message responses if digipeat is not enabled
.call = "VK2GJ-4",
.symbol = SYM_ANTENNA
},
// The digipeat transmit identity
.digi = {
.active = true,
// Transmit radio configuration
.radio_conf = {
.freq = FREQ_APRS_RECEIVE,
.pwr = 0x7F,
.mod = MOD_AFSK,
.cca = 0x4F
},
// Digipeat identity
.call = "VK2GJ-5",
.path = "WIDE2-1",
.symbol = SYM_DIGIPEATER,
// Set to have digi beacon position, telemetry & APRSD information.
// This starts a BCN thread specifically for digi
.beacon = true,
.cycle = TIME_S2I(60 * 30), // Beacon interval
// Set true to have digi use GPS for position
// If valid position is not stored then default lat, lon and alt will be used.
// If RTC time is invalid then GPS will be enabled to get time.
// Once RTC is set then GPS is released and can be switched off.
// This will be the case if no other position thread is using GPS.
.gps = false,
// How often to send telemetry config (TODO: Move out to global level)
.tel_enc_cycle = TIME_S2I(60 * 60 * 2)
},
// The base station identity
.base = {
// Tracker originated messages will be sent to this call sign if enabled
.enabled = true,
.call = "VK2GJ-7",
.path = "WIDE2-1",
},
},
// Global controls
// Power control
.keep_cam_switched_on = false,
.gps_on_vbat = 1000, // mV
.gps_off_vbat = 1000, // mV
.gps_onper_vbat = 1000, // mV
// GPS altitude model control (air pressure determined by on-board BME280)
.gps_pressure = 90000, // Air pressure (Pa) threshold for alt model switch
.gps_low_alt = GPS_STATIONARY,
.gps_high_alt = GPS_AIRBORNE_1G,
// A pre-set location if GPS never enabled or unable to acquire lock.
.lat = -337331175, // Degrees (expressed in 1e-7 form)
.lon = 1511143478, // Degrees (expressed in 1e-7 form)
.alt = 144, // Altitude in metres
.magic = CONFIG_MAGIC_DEFAULT // Do not remove. This is the activation bit.
};

Wyświetl plik

@ -1,335 +1,348 @@
/*
Aerospace Decoder - Copyright (C) 2018 Bob Anderson (VK2GJ)
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*/
/**
* @file rxafsk.h
* @brief AFSK decoding definitions.
*
* @addtogroup decoders
* @{
*/
#ifndef CHANNELS_RXAFSK_H_
#define CHANNELS_RXAFSK_H_
/*===========================================================================*/
/* Module constants. */
/*===========================================================================*/
/*
* AFSK decoding definitions.
*/
#define AFSK_BAUD_RATE 1200U
#define AFSK_NUM_TONES 2U
#define AFSK_MARK_INDEX 0U
#define AFSK_MARK_FREQUENCY 1200U
#define AFSK_SPACE_INDEX 1U
#define AFSK_SPACE_FREQUENCY 2200U
/* Thread working area size. */
#define PKT_AFSK_DECODER_WA_SIZE 1024
/* AFSK decoder type selection. */
#define AFSK_NULL_DECODE 0
#define AFSK_DSP_QCORR_DECODE 1
#define AFSK_DSP_FCORR_DECODE 2 /* Currently unimplemented. */
#define AFSK_DECODE_TYPE AFSK_DSP_QCORR_DECODE
/* Debug output type selection. */
#define AFSK_NO_DEBUG 0
#define AFSK_QCORR_FIR_DEBUG 1
#define AFSK_QCORR_DEC_MAG_DEBUG 2
#define AFSK_QCORR_DATA_DEBUG 3
#define AFSK_QCORR_DEC_MS_DEBUG 4
#define AFSK_QCORR_DEC_CS_DEBUG 5
#define AFSK_QCORR_DEC_MFIL_DEBUG 6
#define AFSK_PWM_DATA_CAPTURE_DEBUG 7
#define AFSK_PWM_DATA_REPLAY_DEBUG 8
#define AFSK_DEBUG_TYPE AFSK_NO_DEBUG
/* Error output type selection. */
#define AFSK_NO_ERROR 0
#define AFSK_QSQRT_ERROR 1
#define AFSK_ERROR_TYPE AFSK_NO_ERROR
#define PRE_FILTER_GEN_COEFF TRUE
#define PRE_FILTER_LOW 925
#define PRE_FILTER_HIGH 2475
#define MAG_FILTER_GEN_COEFF TRUE
#define MAG_FILTER_HIGH 1400
#define PRE_FILTER_NUM_TAPS 55U
#define PRE_FILTER_BLOCK_SIZE 1U
#if PRE_FILTER_BLOCK_SIZE != 1
#error "Filter block size must be 1"
#endif
#define USE_QCORR_MAG_LPF TRUE
#define MAG_FILTER_NUM_TAPS 15U
#define MAG_FILTER_BLOCK_SIZE 1U
#if MAG_FILTER_BLOCK_SIZE != 1
#error "Filter block size must be 1"
#endif
#if AFSK_DECODE_TYPE == AFSK_DSP_QCORR_DECODE
/* BPF followed by fixed point IQ correlation decoder.
* Changing decimation changes the filter sample rate.
* Coefficients created dynamically are calculated at run-time.
* Coefficients generated externally in Matlab/Octave need to be re-done.
*/
#define SYMBOL_DECIMATION (12U)
/* Sample rate in Hz. */
#define FILTER_SAMPLE_RATE (SYMBOL_DECIMATION * AFSK_BAUD_RATE)
#define DECODE_FILTER_LENGTH (2U * SYMBOL_DECIMATION)
#elif
/* BPF followed by floating point IQ correlation decoder. */
#define SYMBOL_DECIMATION (24U)
/* Sample rate in Hz. */
#define FILTER_SAMPLE_RATE (SYMBOL_DECIMATION * AFSK_BAUD_RATE)
#define DECODE_FILTER_LENGTH (2U * SYMBOL_DECIMATION)
#else
/* Any other decoder. */
#define SYMBOL_DECIMATION (24U)
/* Sample rate in Hz. */
#define FILTER_SAMPLE_RATE (SYMBOL_DECIMATION * AFSK_BAUD_RATE)
#define DECODE_FILTER_LENGTH (2U * SYMBOL_DECIMATION)
#endif
#define PKT_PWM_QUEUE_PREFIX "pwmx_"
#define PKT_PWM_MBOX_PREFIX "pwmd_"
#define PKT_AFSK_THREAD_NAME_PREFIX "afsk_"
/*===========================================================================*/
/* Module pre-compile time settings. */
/*===========================================================================*/
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
/*===========================================================================*/
/* Module data structures and types. */
/*===========================================================================*/
/**
* @brief This enumeration describes a tone field within the decoder structure.
*/
typedef enum {
TONE_NONE,
TONE_MARK,
TONE_SPACE
} tone_t;
/**
* @brief AFSK demod state machine states.
*/
typedef enum {
DECODER_WAIT = 0,
DECODER_IDLE,
DECODER_POLL,
DECODER_ACTIVE,
DECODER_SUSPEND,
DECODER_RESET,
DECODER_TIMEOUT,
DECODER_ERROR,
DECODER_CLOSE,
DECODER_TERMINATED
} afskdemodstate_t;
typedef float32_t pwm_accum_t;
typedef int16_t dsp_phase_t;
#include "rxpwm.h"
#include "pktservice.h"
/**
* @brief Structure representing an AFSK demod driver.
*/
typedef struct AFSK_data {
char decoder_name[CH_CFG_FACTORY_MAX_NAMES_LENGTH];
/**
* @brief pointer to the packet handler.
*/
packet_svc_t *packet_handler;
/**
* @brief Event source object.
*/
event_source_t event;
/**
* @brief Decoder thread (for events posted to decoder).
*/
thread_t *decoder_thd;
/**
* @brief Frame byte being built.
*/
ax25char_t current_byte;
/**
* @brief HDLC bit count.
*/
uint8_t bit_index;
/**
* @brief AFSK decoder states. TODO: non volatile?
*/
afskdemodstate_t decoder_state;
/**
* @brief Demod decimation timeline accumulator.
*/
pwm_accum_t decimation_accumulator;
/**
* @brief Decimation amount per slice.
*/
pwm_accum_t decimation_size;
/**
* @brief ICU driver being used.
*/
ICUDriver *icudriver;
/**
* @brief ICU driver state.
*/
rx_icu_state_t icustate;
char pwm_fifo_name[CH_CFG_FACTORY_MAX_NAMES_LENGTH];
/**
* @brief ICU guarded FIFO.
*/
dyn_objects_fifo_t *the_pwm_fifo;
/**
* @brief PWM channel FIFO pool.
*/
objects_fifo_t *pwm_fifo_pool;
/**
* @brief Current radio PWM fifo object.
*/
radio_cca_fifo_t *active_radio_object;
/**
* @brief Current demod PWM fifo object.
*/
radio_cca_fifo_t *active_demod_object;
/**
* @brief current symbol frequency.
*/
tone_t tone_freq;
/**
* @brief Prior symbol frequency.
*/
tone_t prior_freq;
/**
* @brief Pointer to a decoder data structure.
* @details This may be Q31 or F32 type.
*/
void *tone_decoder;
/**
* @brief Symbol incoming bit stream.
*/
/* TODO: Should typdef this? */
uint32_t hdlc_bits;
/**
* @brief Opening HDLC flag sequence found.
*/
frame_state_t frame_state;
} AFSKDemodDriver;
/*===========================================================================*/
/* Module macros. */
/*===========================================================================*/
static inline void pktResyncAFSKDecoder(AFSKDemodDriver *myDriver) {
packet_svc_t *myHandler = myDriver->packet_handler;
myDriver->frame_state = FRAME_OPEN;
myHandler->active_packet_object->packet_size = 0;
}
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
extern float32_t pre_filter_coeff_f32[];
extern float32_t mag_filter_coeff_f32[];
extern AFSKDemodDriver AFSKD1;
#ifdef __cplusplus
extern "C" {
#endif
void pktAddAFSKFilterSample(AFSKDemodDriver *myDriver, bit_t binary);
bool pktProcessAFSKFilteredSample(AFSKDemodDriver *myDriver);
bool pktDecodeAFSKSymbol(AFSKDemodDriver *myDriver);
bool pktExtractHDLCfromAFSK(AFSKDemodDriver *myDriver);
bool pktProcessAFSK(AFSKDemodDriver *myDriver, min_pwmcnt_t current_tone[]);
AFSKDemodDriver *pktCreateAFSKDecoder(packet_svc_t *pktDriver);
bool pktCheckAFSKSymbolTime(AFSKDemodDriver *myDriver);
void pktUpdateAFSKSymbolPLL(AFSKDemodDriver *myDriver);
void pktReleaseAFSKDecoder(AFSKDemodDriver *myDriver);
void pktResetAFSKDecoder(AFSKDemodDriver *myDriver);
void pktDisablePWM(AFSKDemodDriver *myDriver);
void pktAFSKDecoder(void *arg);
#ifdef __cplusplus
}
#endif
/*
* Test of flow graph and protocol diagrams.
* TODO: Remove or update.
*/
/**
\dot
digraph G {
main -> parse -> execute;
main -> init;
main -> cleanup;
execute -> make_string;
execute -> printf
init -> make_string;
main -> printf;
execute -> compare;
}
\enddot
*/
/**
\msc
arcgradient = 8;
a [label="Client"],b [label="Server"];
a-xb [label="get accel"];
a=>b [label="get accel"];
a<=b [label="ack"];
a<=b [label="accel data"];
\endmsc
*/
#endif /* CHANNELS_RXAFSK_H_ */
/** @} */
/*
Aerospace Decoder - Copyright (C) 2018 Bob Anderson (VK2GJ)
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*/
/**
* @file rxafsk.h
* @brief AFSK decoding definitions.
*
* @addtogroup decoders
* @{
*/
#ifndef CHANNELS_RXAFSK_H_
#define CHANNELS_RXAFSK_H_
/*===========================================================================*/
/* Module constants. */
/*===========================================================================*/
/*
* AFSK decoding definitions.
*/
#define AFSK_BAUD_RATE 1200U
#define AFSK_NUM_TONES 2U
#define AFSK_MARK_INDEX 0U
#define AFSK_MARK_FREQUENCY 1200U
#define AFSK_SPACE_INDEX 1U
#define AFSK_SPACE_FREQUENCY 2200U
/* Thread working area size. */
#define PKT_AFSK_DECODER_WA_SIZE 1024
/* AFSK decoder type selection. */
#define AFSK_NULL_DECODE 0
#define AFSK_DSP_QCORR_DECODE 1
#define AFSK_DSP_FCORR_DECODE 2 /* Currently unimplemented. */
#define AFSK_DECODE_TYPE AFSK_DSP_QCORR_DECODE
/* Debug output type selection. */
#define AFSK_NO_DEBUG 0
#define AFSK_QCORR_FIR_DEBUG 1
#define AFSK_QCORR_DEC_MAG_DEBUG 2
#define AFSK_QCORR_DATA_DEBUG 3
#define AFSK_QCORR_DEC_MS_DEBUG 4
#define AFSK_QCORR_DEC_CS_DEBUG 5
#define AFSK_QCORR_DEC_MFIL_DEBUG 6
#define AFSK_PWM_DATA_CAPTURE_DEBUG 7
#define AFSK_PWM_DATA_REPLAY_DEBUG 8
#define AFSK_DEBUG_TYPE AFSK_NO_DEBUG
/* Error output type selection. */
#define AFSK_NO_ERROR 0
#define AFSK_QSQRT_ERROR 1
#define AFSK_ERROR_TYPE AFSK_NO_ERROR
#define PRE_FILTER_GEN_COEFF TRUE
#define PRE_FILTER_LOW 925
#define PRE_FILTER_HIGH 2475
#define MAG_FILTER_GEN_COEFF TRUE
#define MAG_FILTER_HIGH 1400
#define PRE_FILTER_NUM_TAPS 55U
#define PRE_FILTER_BLOCK_SIZE 1U
#if PRE_FILTER_BLOCK_SIZE != 1
#error "Filter block size must be 1"
#endif
#define USE_QCORR_MAG_LPF TRUE
#define MAG_FILTER_NUM_TAPS 15U
#define MAG_FILTER_BLOCK_SIZE 1U
#if MAG_FILTER_BLOCK_SIZE != 1
#error "Filter block size must be 1"
#endif
#if AFSK_DECODE_TYPE == AFSK_DSP_QCORR_DECODE
/* BPF followed by fixed point IQ correlation decoder.
* Changing decimation changes the filter sample rate.
* Coefficients created dynamically are calculated at run-time.
* Coefficients generated externally in Matlab/Octave need to be re-done.
*/
#define SYMBOL_DECIMATION (12U)
/* Sample rate in Hz. */
#define FILTER_SAMPLE_RATE (SYMBOL_DECIMATION * AFSK_BAUD_RATE)
#define DECODE_FILTER_LENGTH (2U * SYMBOL_DECIMATION)
#elif
/* BPF followed by floating point IQ correlation decoder. */
#define SYMBOL_DECIMATION (24U)
/* Sample rate in Hz. */
#define FILTER_SAMPLE_RATE (SYMBOL_DECIMATION * AFSK_BAUD_RATE)
#define DECODE_FILTER_LENGTH (2U * SYMBOL_DECIMATION)
#else
/* Any other decoder. */
#define SYMBOL_DECIMATION (24U)
/* Sample rate in Hz. */
#define FILTER_SAMPLE_RATE (SYMBOL_DECIMATION * AFSK_BAUD_RATE)
#define DECODE_FILTER_LENGTH (2U * SYMBOL_DECIMATION)
#endif
#define PKT_PWM_QUEUE_PREFIX "pwmx_"
#define PKT_PWM_MBOX_PREFIX "pwmd_"
#define PKT_AFSK_THREAD_NAME_PREFIX "afsk_"
/*===========================================================================*/
/* Module pre-compile time settings. */
/*===========================================================================*/
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
/*===========================================================================*/
/* Module data structures and types. */
/*===========================================================================*/
/**
* @brief This enumeration describes a tone field within the decoder structure.
*/
typedef enum {
TONE_NONE,
TONE_MARK,
TONE_SPACE
} tone_t;
/**
* @brief AFSK demod state machine states.
*/
typedef enum {
DECODER_WAIT = 0,
DECODER_IDLE,
DECODER_POLL,
DECODER_ACTIVE,
DECODER_SUSPEND,
DECODER_RESET,
DECODER_TIMEOUT,
DECODER_ERROR,
DECODER_CLOSE,
DECODER_TERMINATED
} afskdemodstate_t;
typedef float32_t pwm_accum_t;
typedef int16_t dsp_phase_t;
#include "rxpwm.h"
#include "pktservice.h"
/**
* @brief Structure representing an AFSK demod driver.
*/
typedef struct AFSK_data {
char decoder_name[CH_CFG_FACTORY_MAX_NAMES_LENGTH];
/**
* @brief pointer to the packet handler.
*/
packet_svc_t *packet_handler;
/**
* @brief Event source object.
*/
event_source_t event;
/**
* @brief Decoder thread (for events posted to decoder).
*/
thread_t *decoder_thd;
/**
* @brief Frame byte being built.
*/
ax25char_t current_byte;
/**
* @brief HDLC bit count.
*/
uint8_t bit_index;
/**
* @brief AFSK decoder states. TODO: non volatile?
*/
afskdemodstate_t decoder_state;
/**
* @brief Demod decimation timeline accumulator.
*/
pwm_accum_t decimation_accumulator;
/**
* @brief Decimation amount per slice.
*/
pwm_accum_t decimation_size;
/**
* @brief ICU driver being used.
*/
ICUDriver *icudriver;
/**
* @brief ICU driver state.
*/
rx_icu_state_t icustate;
/**
* @brief PWM queue heap memory.
*/
void *pwm_queue_heap;
/**
* @brief PWM buffer object pool manager.
*/
memory_pool_t pwm_buffer_pool;
/**
* @brief PWM FIFO manager name.
*/
char pwm_fifo_name[CH_CFG_FACTORY_MAX_NAMES_LENGTH];
/**
* @brief ICU guarded FIFO.
*/
dyn_objects_fifo_t *the_pwm_fifo;
/**
* @brief PWM channel FIFO pool.
*/
objects_fifo_t *pwm_fifo_pool;
/**
* @brief Current radio PWM fifo object.
*/
radio_pwm_fifo_t *active_radio_object;
/**
* @brief Current demod PWM fifo object.
*/
radio_pwm_fifo_t *active_demod_object;
/**
* @brief current symbol frequency.
*/
tone_t tone_freq;
/**
* @brief Prior symbol frequency.
*/
tone_t prior_freq;
/**
* @brief Pointer to a decoder data structure.
* @details This may be Q31 or F32 type.
*/
void *tone_decoder;
/**
* @brief Symbol incoming bit stream.
*/
/* TODO: Should typdef this? */
uint32_t hdlc_bits;
/**
* @brief Opening HDLC flag sequence found.
*/
frame_state_t frame_state;
} AFSKDemodDriver;
/*===========================================================================*/
/* Module macros. */
/*===========================================================================*/
static inline void pktResyncAFSKDecoder(AFSKDemodDriver *myDriver) {
packet_svc_t *myHandler = myDriver->packet_handler;
myDriver->frame_state = FRAME_OPEN;
myHandler->active_packet_object->packet_size = 0;
}
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
extern float32_t pre_filter_coeff_f32[];
extern float32_t mag_filter_coeff_f32[];
extern AFSKDemodDriver AFSKD1;
#ifdef __cplusplus
extern "C" {
#endif
void pktAddAFSKFilterSample(AFSKDemodDriver *myDriver, bit_t binary);
bool pktProcessAFSKFilteredSample(AFSKDemodDriver *myDriver);
bool pktDecodeAFSKSymbol(AFSKDemodDriver *myDriver);
bool pktExtractHDLCfromAFSK(AFSKDemodDriver *myDriver);
bool pktProcessAFSK(AFSKDemodDriver *myDriver, min_pwmcnt_t current_tone[]);
AFSKDemodDriver *pktCreateAFSKDecoder(packet_svc_t *pktDriver);
bool pktCheckAFSKSymbolTime(AFSKDemodDriver *myDriver);
void pktUpdateAFSKSymbolPLL(AFSKDemodDriver *myDriver);
void pktReleaseAFSKDecoder(AFSKDemodDriver *myDriver);
void pktResetAFSKDecoder(AFSKDemodDriver *myDriver);
void pktDisablePWM(AFSKDemodDriver *myDriver);
void pktAFSKDecoder(void *arg);
#ifdef __cplusplus
}
#endif
/*
* Test of flow graph and protocol diagrams.
* TODO: Remove or update.
*/
/**
\dot
digraph G {
main -> parse -> execute;
main -> init;
main -> cleanup;
execute -> make_string;
execute -> printf
init -> make_string;
main -> printf;
execute -> compare;
}
\enddot
*/
/**
\msc
arcgradient = 8;
a [label="Client"],b [label="Server"];
a-xb [label="get accel"];
a=>b [label="get accel"];
a<=b [label="ack"];
a<=b [label="accel data"];
\endmsc
*/
#endif /* CHANNELS_RXAFSK_H_ */
/** @} */

Wyświetl plik

@ -1,251 +1,295 @@
/*
Aerospace Decoder - Copyright (C) 2018 Bob Anderson (VK2GJ)
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*/
/**
* @file rxpwm.h
* @brief ICU user macros and structures.
*
* @addtogroup channels
* @{
*/
#ifndef PKT_CHANNELS_RXPWM_H_
#define PKT_CHANNELS_RXPWM_H_
#include "pktconf.h"
/*===========================================================================*/
/* Module constants. */
/*===========================================================================*/
/* Limit of ICU and PWM count for packed format. */
#if USE_12_BIT_PWM == TRUE
#define PWM_MAX_COUNT 0xFFF
#define MAX_PWM_BITS 12
#else
#define PWM_MAX_COUNT 0xFFFF
#define MAX_PWM_BITS 16
#endif
/* PWM stream in-band prefix. */
#define PWM_IN_BAND_PREFIX 0
/* PWM stream terminate in-band reason codes. */
#define PWM_TERM_CCA_CLOSE 0
#define PWM_TERM_QUEUE_FULL 1
#define PWM_TERM_ICU_OVERFLOW 2
#define PWM_TERM_NO_QUEUE 3
#define PWM_TERM_DECODE_ENDED 4
#define PWM_TERM_DECODE_STOP 5
/* ICU will be stopped if no activity for this number of seconds. */
#define ICU_INACTIVITY_TIMEOUT 60
/*===========================================================================*/
/* Module data structures and types. */
/*===========================================================================*/
typedef uint8_t pwm_code_t;
typedef enum ICUStates {
PKT_PWM_INIT = 0,
PKT_PWM_READY,
PKT_PWM_ACTIVE,
PKT_PWM_STOP
} rx_icu_state_t;
/* Types for ICU and PWM data. */
typedef uint16_t min_icucnt_t;
typedef uint16_t min_pwmcnt_t;
typedef uint8_t packed_pwm_data_t;
#if USE_12_BIT_PWM == TRUE
typedef packed_pwm_data_t packed_pwmcnt_t;
typedef packed_pwm_data_t packed_pwmxtn_t;
/* Structure containing packed PWM results. */
typedef struct {
packed_pwmcnt_t impulse;
packed_pwmcnt_t valley;
packed_pwmxtn_t xtn;
} packed_pwm_counts_t;
#else
typedef min_pwmcnt_t packed_pwmcnt_t;
/* Structure containing packed PWM results. */
typedef struct {
packed_pwmcnt_t impulse;
packed_pwmcnt_t valley;
} packed_pwm_counts_t;
#endif
/* Union of packed PWM results and byte array representation. */
typedef union {
packed_pwm_counts_t pwm;
packed_pwm_data_t bytes[sizeof(packed_pwm_counts_t)];
} byte_packed_pwm_t;
/* Structure holding PWM entries created from ICU results. */
typedef struct {
min_pwmcnt_t impulse;
min_pwmcnt_t valley;
} min_pwm_counts_t;
/* Union of PWM results and byte array representation. */
typedef union {
min_pwm_counts_t pwm;
min_pwmcnt_t array[sizeof(min_pwm_counts_t)
/ sizeof(min_pwmcnt_t)];
} array_min_pwm_counts_t;
/* Union of packed PWM data buffer and byte array representation. */
typedef union {
byte_packed_pwm_t pwm_buffer[PWM_DATA_SLOTS];
packed_pwm_data_t pwm_bytes[sizeof(byte_packed_pwm_t)
* PWM_DATA_SLOTS];
} radio_pwm_buffer_t;
/* PWM FIFO object with embedded queue shared between ICU and decoder. */
typedef struct {
/* For safety keep clear - where pool stores its free link. */
struct pool_header link;
/* TODO: The next becomes a pointer to a buffer obtained from the heap. */
#if USE_HEAP_PWM_BUFFER == TRUE
radio_pwm_buffer_t *packed_buffer;
#else
/* Allocate a buffer in the queue object. */
radio_pwm_buffer_t packed_buffer;
#endif
input_queue_t radio_pwm_queue;
binary_semaphore_t sem;
volatile eventflags_t status;
} radio_cca_fifo_t;
/*===========================================================================*/
/* Module inline functions. */
/*===========================================================================*/
/**
* @brief Convert ICU data to PWM data and pack into minimized buffer.
* @note This function deals with ICU data packed into 12 bits or 16 bits.
*
* @param[in] icup pointer to ICU driver.
* @param[in] dest pointer to the object for PWM data.
*
* @api
*/
static inline void pktConvertICUtoPWM(ICUDriver *icup,
byte_packed_pwm_t *dest) {
icucnt_t impulse = icuGetWidthX(icup);
icucnt_t valley = icuGetPeriodX(icup) - impulse;
#if USE_12_BIT_PWM == TRUE
dest->pwm.impulse = (packed_pwmcnt_t)impulse & 0xFFU;
dest->pwm.valley = (packed_pwmcnt_t)valley & 0xFFU;
/*
* Pack extension bits 8-11 of impulse and valley into a byte.
* Impulse goes into low nibble and valley into high nibble.
*/
valley >>= 4;
impulse >>= 8;
dest->pwm.xtn = ((packed_pwmxtn_t)(impulse) & 0x000FU);
dest->pwm.xtn |= ((packed_pwmxtn_t)(valley) & 0x00F0U);
#else
dest->pwm.impulse = (packed_pwmcnt_t)impulse & 0xFFFFU;
dest->pwm.valley = (packed_pwmcnt_t)valley & 0xFFFFU;
#endif
}
/**
* @brief Unpack PWM data into PWM structure.
* @note This function deals with ICU data up to 12 bits.
*
* @param[in] src Buffer containing packed impulse and valley data.
* @param[in] dest pointer to the destination object for PWM data.
*
* @api
*/
static inline void pktUnpackPWMData(byte_packed_pwm_t src,
array_min_pwm_counts_t *dest) {
#if USE_12_BIT_PWM == TRUE
min_icucnt_t duration = src.pwm.impulse;
duration |= ((min_icucnt_t)(src.pwm.xtn & 0x0FU) << 8);
dest->pwm.impulse = duration;
duration = src.pwm.valley;
duration |= ((min_icucnt_t)(src.pwm.xtn & 0xF0U) << 4);
dest->pwm.valley = duration;
#else
min_icucnt_t duration = src.pwm.impulse;
dest->pwm.impulse = duration;
duration = src.pwm.valley;
dest->pwm.valley = duration;
#endif
}
/**
* @brief Write PWM data into input queue.
* @note This function deals with PWM data packed in sequential bytes.
*
* @param[in] queue pointer to an input queue object.
* @param[in] pack PWM packed data object.
*
* @return The operation status.
* @retval MSG_OK The PWM entry has been queued.
* @retval MSG_TIMEOUT The queue is full.
* @retval MSG_RESET The last queue slot is reserved for in-band signaling.
* The data is not an in-band signal.
*
* @api
*/
static inline msg_t pktWritePWMQueueI(input_queue_t *queue,
byte_packed_pwm_t pack) {
/* Check if there is only one slot left. */
if(iqGetEmptyI(queue) == sizeof(byte_packed_pwm_t)) {
if(pack.bytes[0] != PWM_IN_BAND_PREFIX)
return MSG_RESET;
}
/* Data is normal PWM or an in-band. */
for(uint8_t b = 0; b < sizeof(pack.bytes); b++) {
if(MSG_TIMEOUT == iqPutI(queue, pack.bytes[b]))
return MSG_TIMEOUT;
}
return MSG_OK;
}
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#ifdef __cplusplus
extern "C" {
#endif
ICUDriver *pktAttachICU(radio_unit_t radio_id);
void pktDetachICU(ICUDriver *myICU);
void pktICUStart(ICUDriver *myICU);
void pktRadioICUWidth(ICUDriver *myICU);
void pktRadioICUPeriod(ICUDriver *myICU);
void PktRadioICUOverflow(ICUDriver *myICU);
void pktRadioCCAInput(ICUDriver *myICU);
void pktStopAllICUTimersI(ICUDriver *myICU);
void pktSleepICUI(ICUDriver *myICU);
msg_t pktQueuePWMDataI(ICUDriver *myICU);
void pktClosePWMChannelI(ICUDriver *myICU, eventflags_t evt,
pwm_code_t reason);
void pktICUInactivityTimeout(ICUDriver *myICU);
void pktPWMInactivityTimeout(ICUDriver *myICU);
#ifdef __cplusplus
}
#endif
#endif /* PKT_CHANNELS_RXPWM_H_ */
/** @} */
/*
Aerospace Decoder - Copyright (C) 2018 Bob Anderson (VK2GJ)
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*/
/**
* @file rxpwm.h
* @brief ICU user macros and structures.
*
* @addtogroup channels
* @{
*/
#ifndef PKT_CHANNELS_RXPWM_H_
#define PKT_CHANNELS_RXPWM_H_
#include "pktconf.h"
/*===========================================================================*/
/* Module constants. */
/*===========================================================================*/
/* Limit of ICU and PWM count for packed format. */
#if USE_12_BIT_PWM == TRUE
#define PWM_MAX_COUNT 0xFFF
#define MAX_PWM_BITS 12
#else
#define PWM_MAX_COUNT 0xFFFF
#define MAX_PWM_BITS 16
#endif
/* PWM stream in-band prefix. */
#define PWM_IN_BAND_PREFIX 0
/* PWM stream terminate in-band reason codes. */
#define PWM_TERM_CCA_CLOSE 0
#define PWM_TERM_QUEUE_FULL 1
#define PWM_TERM_ICU_OVERFLOW 2
#define PWM_TERM_NO_QUEUE 3
#define PWM_TERM_DECODE_ENDED 4
#define PWM_TERM_DECODE_STOP 5
#define PWM_TERM_NO_DATA 6
#define PWM_TERM_QUEUE_LOCK 7
#define PWM_INFO_QUEUE_SWAP 8
/* ICU will be stopped if no activity for this number of seconds. */
#define ICU_INACTIVITY_TIMEOUT 60
/*===========================================================================*/
/* Module data structures and types. */
/*===========================================================================*/
typedef uint8_t pwm_code_t;
typedef enum ICUStates {
PKT_PWM_INIT = 0,
PKT_PWM_READY,
PKT_PWM_ACTIVE,
PKT_PWM_STOP
} rx_icu_state_t;
/* Types for ICU and PWM data. */
typedef uint16_t min_icucnt_t;
typedef uint16_t min_pwmcnt_t;
typedef uint8_t packed_pwm_data_t;
#if USE_12_BIT_PWM == TRUE
typedef packed_pwm_data_t packed_pwmcnt_t;
typedef packed_pwm_data_t packed_pwmxtn_t;
/* Structure containing packed PWM results. */
typedef struct {
packed_pwmcnt_t impulse;
packed_pwmcnt_t valley;
packed_pwmxtn_t xtn;
} packed_pwm_counts_t;
#else
typedef min_pwmcnt_t packed_pwmcnt_t;
/* Structure containing packed PWM results. */
typedef struct {
packed_pwmcnt_t impulse;
packed_pwmcnt_t valley;
} packed_pwm_counts_t;
#endif
/* Union of packed PWM results and byte array representation. */
typedef union {
packed_pwm_counts_t pwm;
packed_pwm_data_t bytes[sizeof(packed_pwm_counts_t)];
} byte_packed_pwm_t;
/* Structure holding PWM entries created from ICU results. */
typedef struct {
min_pwmcnt_t impulse;
min_pwmcnt_t valley;
} min_pwm_counts_t;
/* Union of PWM results and byte array representation. */
typedef union {
min_pwm_counts_t pwm;
min_pwmcnt_t array[sizeof(min_pwm_counts_t)
/ sizeof(min_pwmcnt_t)];
} array_min_pwm_counts_t;
/* Union of packed PWM data buffer and byte array representation. */
typedef union {
byte_packed_pwm_t pwm_buffer[PWM_DATA_SLOTS];
packed_pwm_data_t pwm_bytes[sizeof(byte_packed_pwm_t)
* PWM_DATA_SLOTS];
} radio_pwm_buffer_t;
#if USE_HEAP_PWM_BUFFER == TRUE
/* Forward declare struct. */
typedef struct PWMobject radio_pwm_object_t;
typedef struct PWMobject {
radio_pwm_buffer_t buffer;
/* In linked mode the reference to the next PWM queue is saved here.
* The decoder will continue to process linked PWM queues until completion.
*/
input_queue_t queue;
radio_pwm_object_t *next;
} radio_pwm_object_t;
#endif
/*
* PWM FIFO object. Path between ICU and decoder during an AFSK decode.
*/
typedef struct {
/* For safety keep clear - where FIFO pool stores its free link. */
struct pool_header link;
#if USE_HEAP_PWM_BUFFER == TRUE
/*
* There are two PWM object pointers.
* One for the radio (producer) side.
* And one for the decoder (consumer) side.
*/
radio_pwm_object_t *radio_pwm_queue;
radio_pwm_object_t *decode_pwm_queue;
#else
/* Allocate a PWM buffer in the queue object. */
radio_pwm_buffer_t packed_buffer;
/*
* This is the current radio queue object.
* In single queue mode PWM is written to a single queue only.
* The queue has a single large buffer and used for the entire PWM session.
*
* In linked buffer mode PWM can chain multiple smaller input buffers.
* After getting a new PWM buffer object the queue is re-initialized.
* The queue fill with further PWM then continues.
* As PWM buffers are consumed by the decoder they are recycled back to the pool.
* The radio PWM can then re-use those buffers which in theory reduces memory utilisation.
*/
input_queue_t radio_pwm_queue;
#endif
/*
* The semaphore controls the release of the PWM buffer and FIFO resources.
* In non-linked mode the buffer is enclosed within the FIFO object.
* In linked mode the last PWM buffer is protected along with the FIFO.
* The semaphore prevents any release during trailing PWM buffering.
* Trailing PWM is not used but the object(s) are still in use by the radio.
*/
binary_semaphore_t sem;
volatile eventflags_t status;
} radio_pwm_fifo_t;
/*===========================================================================*/
/* Module inline functions. */
/*===========================================================================*/
/**
* @brief Convert ICU data to PWM data and pack into minimized buffer.
* @note This function deals with ICU data packed into 12 bits or 16 bits.
*
* @param[in] icup pointer to ICU driver.
* @param[in] dest pointer to the object for PWM data.
*
* @api
*/
static inline void pktConvertICUtoPWM(ICUDriver *icup,
byte_packed_pwm_t *dest) {
icucnt_t impulse = icuGetWidthX(icup);
icucnt_t valley = icuGetPeriodX(icup) - impulse;
#if USE_12_BIT_PWM == TRUE
dest->pwm.impulse = (packed_pwmcnt_t)impulse & 0xFFU;
dest->pwm.valley = (packed_pwmcnt_t)valley & 0xFFU;
/*
* Pack extension bits 8-11 of impulse and valley into a byte.
* Impulse goes into low nibble and valley into high nibble.
*/
valley >>= 4;
impulse >>= 8;
dest->pwm.xtn = ((packed_pwmxtn_t)(impulse) & 0x000FU);
dest->pwm.xtn |= ((packed_pwmxtn_t)(valley) & 0x00F0U);
#else
dest->pwm.impulse = (packed_pwmcnt_t)impulse & 0xFFFFU;
dest->pwm.valley = (packed_pwmcnt_t)valley & 0xFFFFU;
#endif
}
/**
* @brief Unpack PWM data into PWM structure.
* @note This function deals with ICU data up to 12 bits.
*
* @param[in] src Buffer containing packed impulse and valley data.
* @param[in] dest pointer to the destination object for PWM data.
*
* @api
*/
static inline void pktUnpackPWMData(byte_packed_pwm_t src,
array_min_pwm_counts_t *dest) {
#if USE_12_BIT_PWM == TRUE
min_icucnt_t duration = src.pwm.impulse;
duration |= ((min_icucnt_t)(src.pwm.xtn & 0x0FU) << 8);
dest->pwm.impulse = duration;
duration = src.pwm.valley;
duration |= ((min_icucnt_t)(src.pwm.xtn & 0xF0U) << 4);
dest->pwm.valley = duration;
#else
min_icucnt_t duration = src.pwm.impulse;
dest->pwm.impulse = duration;
duration = src.pwm.valley;
dest->pwm.valley = duration;
#endif
}
/**
* @brief Write PWM data into input queue.
* @note This function deals with PWM data packed in sequential bytes.
*
* @param[in] queue pointer to an input queue object.
* @param[in] pack PWM packed data object.
*
* @return The operation status.
* @retval MSG_OK The PWM entry has been queued.
* @retval MSG_TIMEOUT The queue is full.
* @retval MSG_RESET The last queue slot is reserved for in-band signaling.
* The data is not an in-band signal.
*
* @api
*/
static inline msg_t pktWritePWMQueueI(input_queue_t *queue,
byte_packed_pwm_t pack) {
/* Check if there is only one slot left. */
if(iqGetEmptyI(queue) == sizeof(byte_packed_pwm_t)) {
if(pack.bytes[0] != PWM_IN_BAND_PREFIX)
return MSG_RESET;
}
/* Data is normal PWM or an in-band. */
for(uint8_t b = 0; b < sizeof(pack.bytes); b++) {
if(MSG_TIMEOUT == iqPutI(queue, pack.bytes[b]))
return MSG_TIMEOUT;
}
return MSG_OK;
}
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#ifdef __cplusplus
extern "C" {
#endif
ICUDriver *pktAttachICU(radio_unit_t radio_id);
void pktDetachICU(ICUDriver *myICU);
void pktICUStart(ICUDriver *myICU);
void pktRadioICUWidth(ICUDriver *myICU);
void pktRadioICUPeriod(ICUDriver *myICU);
void PktRadioICUOverflow(ICUDriver *myICU);
void pktRadioCCAInput(ICUDriver *myICU);
void pktStopAllICUTimersI(ICUDriver *myICU);
void pktSleepICUI(ICUDriver *myICU);
msg_t pktQueuePWMDataI(ICUDriver *myICU);
void pktClosePWMChannelI(ICUDriver *myICU, eventflags_t evt,
pwm_code_t reason);
void pktICUInactivityTimeout(ICUDriver *myICU);
void pktPWMInactivityTimeout(ICUDriver *myICU);
#ifdef __cplusplus
}
#endif
#endif /* PKT_CHANNELS_RXPWM_H_ */
/** @} */

Wyświetl plik

@ -1,255 +1,257 @@
#ifndef __si446x__H__
#define __si446x__H__
/*===========================================================================*/
/* Module constants. */
/*===========================================================================*/
#define Si446x_LOCK_BY_SEMAPHORE TRUE
#ifndef Si446x_CLK
#error "Si446x_CLK is not defined which is needed for Si446x."
#endif
#ifndef Si446x_CLK_OFFSET
#define Si446x_CLK_OFFSET 0
#endif
// Various macros
#define Si446x_getGPIO0() palReadLine(LINE_RADIO_GPIO0)
#define Si446x_getGPIO1() palReadLine(LINE_RADIO_GPIO1)
#define Si446x_getCCA() palReadLine(LINE_RADIO_IRQ)
/* Frequency offset corrected oscillator frequency */
#define Si446x_CCLK ((Si446x_CLK) + (Si446x_CLK_OFFSET) \
* (Si446x_CLK) / 1000000)
// Si4464 States
#define Si446x_STATE_NOCHANGE 0
#define Si446x_STATE_SLEEP 1
#define Si446x_STATE_SPI_ACTIVE 2
#define Si446x_STATE_READY 3
#define Si446x_STATE_READY2 4
#define Si446x_STATE_TX_TUNE 5
#define Si446x_STATE_RX_TUNE 6
#define Si446x_STATE_TX 7
#define Si446x_STATE_RX 8
/*
* Commands.
*/
#define Si446x_READ_CMD_BUFF 0x44
#define Si446x_START_TX 0x31
#define Si446x_START_RX 0x32
#define Si446x_REQUEST_DEVICE_STATE 0x33
#define Si446x_RX_HOP 0x36
#define Si446x_FIFO_INFO 0x15
/* Defined response values. */
#define Si446x_COMMAND_CTS 0xFF
/*
* Property group commands.
* Format is 0xGGNN (GG = group, NN = number).
*/
#define Si446x_GLOBAL_XO_TUNE 0x0000
#define Si446x_GLOBAL_CLK_CFG 0x0001
#define Si446x_GLOBAL_CONFIG 0x0003
#define Si446x_INT_CTL_ENABLE 0x0100
#define Si446x_INT_CTL_MODEM_ENABLE 0x0102
#define Si446x_FRR_CTL_A_MODE 0x0200
#define Si446x_FRR_CTL_B_MODE 0x0201
#define Si446x_FRR_CTL_C_MODE 0x0202
#define Si446x_FRR_CTL_D_MODE 0x0203
#define Si446x_PREAMBLE_TX_LENGTH 0x1000
#define Si446x_PREAMBLE_CONFIG_STD_1 0x1001
#define Si446x_PREAMBLE_CONFIG_NSTD 0x1002
#define Si446x_PREAMBLE_CONFIG_STD_2 0x1003
#define Si446x_PREAMBLE_CONFIG 0x1004
#define Si446x_PREAMBLE_PATTERN 0x1005
#define Si446x_SYNC_CONFIG 0x1100
#define Si446x_PKT_CONFIG1 0x1206
#define Si446x_MODEM_MOD_TYPE 0x2000
#define Si446x_MODEM_MAP_CONTROL 0x2001
#define Si446x_MODEM_DSM_CTRL 0x2002
#define Si446x_MODEM_DATA_RATE 0x2003
#define Si446x_MODEM_TX_NCO_MODE 0x2006
#define Si446x_MODEM_FREQ_DEV 0x200A
#define Si446x_MODEM_TX_RAMP_DELAY 0x2018
#define Si446x_MODEM_MDM_CTRL 0x2019
#define Si446x_MODEM_IF_CONTROL 0x201A
#define Si446x_MODEM_IF_FREQ 0x201B
#define Si446x_MODEM_DECIMATION_CFG1 0x201E
#define Si446x_MODEM_DECIMATION_CFG0 0x201F
#define Si446x_MODEM_BCR_OSR 0x2022
#define Si446x_MODEM_BCR_NCO_OFFSET 0x2024
#define Si446x_MODEM_BCR_GAIN 0x2027
#define Si446x_MODEM_BCR_GEAR 0x2029
#define Si446x_MODEM_BCR_MISC1 0x202A
#define Si446x_MODEM_AFC_GEAR 0x202C
#define Si446x_MODEM_AFC_WAIT 0x202D
#define Si446x_MODEM_AFC_GAIN 0x202E
#define Si446x_MODEM_AFC_LIMITER 0x2030
#define Si446x_MODEM_AFC_MISC 0x2032
#define Si446x_MODEM_AGC_CONTROL 0x2035
#define Si446x_MODEM_AGC_WINDOW_SIZE 0x2038
#define Si446x_MODEM_AGC_RFPD_DECAY 0x2039
#define Si446x_MODEM_AGC_IFPD_DECAY 0x203A
#define Si446x_MODEM_FSK4_GAIN1 0x203B
#define Si446x_MODEM_FSK4_GAIN0 0x203C
#define Si446x_MODEM_FSK4_TH 0x203D
#define Si446x_MODEM_FSK4_MAP 0x203F
#define Si446x_MODEM_OOK_PDTC 0x2040
#define Si446x_MODEM_OOK_CNT1 0x2042
#define Si446x_MODEM_OOK_MISC 0x2043
#define Si446x_MODEM_RAW_SEARCH 0x2044
#define Si446x_MODEM_RAW_CONTROL 0x2045
#define Si446x_MODEM_RAW_EYE 0x2046
#define Si446x_MODEM_ANT_DIV_MODE 0x2048
#define Si446x_MODEM_ANT_DIV_CONTROL 0x2049
#define Si446x_MODEM_RSSI_THRESH 0x204A
#define Si446x_MODEM_RSSI_JUMP_THRESH 0x204B
#define Si446x_MODEM_RSSI_CONTROL 0x204C
#define Si446x_MODEM_RSSI_CONTROL2 0x204D
#define Si446x_MODEM_RSSI_COMP 0x204E
#define Si446x_MODEM_CLKGEN_BAND 0x2051
#define Si446x_MODEM_CHFLT_RX1_CHFLT_COE13_7_0 0x2100
#define Si446x_MODEM_CHFLT_RX1_CHFLT_COE12_7_0 0x2101
#define Si446x_MODEM_CHFLT_RX1_CHFLT_COE11_7_0 0x2102
#define Si446x_MODEM_CHFLT_RX1_CHFLT_COE10_7_0 0x2103
#define Si446x_MODEM_CHFLT_RX1_CHFLT_COE9_7_0 0x2104
#define Si446x_MODEM_CHFLT_RX1_CHFLT_COE8_7_0 0x2105
#define Si446x_MODEM_CHFLT_RX1_CHFLT_COE7_7_0 0x2106
#define Si446x_MODEM_CHFLT_RX1_CHFLT_COE6_7_0 0x2107
#define Si446x_MODEM_CHFLT_RX1_CHFLT_COE5_7_0 0x2108
#define Si446x_MODEM_CHFLT_RX1_CHFLT_COE4_7_0 0x2109
#define Si446x_MODEM_CHFLT_RX1_CHFLT_COE3_7_0 0x210A
#define Si446x_MODEM_CHFLT_RX1_CHFLT_COE2_7_0 0x210B
#define Si446x_MODEM_CHFLT_RX1_CHFLT_COE1_7_0 0x210C
#define Si446x_MODEM_CHFLT_RX1_CHFLT_COE0_7_0 0x210D
#define Si446x_MODEM_CHFLT_RX1_CHFLT_COEM0 0x210E
#define Si446x_MODEM_CHFLT_RX1_CHFLT_COEM1 0x210F
#define Si446x_MODEM_CHFLT_RX1_CHFLT_COEM2 0x2110
#define Si446x_MODEM_CHFLT_RX1_CHFLT_COEM3 0x2111
#define Si446x_MODEM_CHFLT_RX2_CHFLT_COE13_7_0 0x2112
#define Si446x_MODEM_CHFLT_RX2_CHFLT_COE12_7_0 0x2113
#define Si446x_MODEM_CHFLT_RX2_CHFLT_COE11_7_0 0x2114
#define Si446x_MODEM_CHFLT_RX2_CHFLT_COE10_7_0 0x2115
#define Si446x_MODEM_CHFLT_RX2_CHFLT_COE9_7_0 0x2116
#define Si446x_MODEM_CHFLT_RX2_CHFLT_COE8_7_0 0x2117
#define Si446x_MODEM_CHFLT_RX2_CHFLT_COE7_7_0 0x2118
#define Si446x_MODEM_CHFLT_RX2_CHFLT_COE6_7_0 0x2119
#define Si446x_MODEM_CHFLT_RX2_CHFLT_COE5_7_0 0x211A
#define Si446x_MODEM_CHFLT_RX2_CHFLT_COE4_7_0 0x211B
#define Si446x_MODEM_CHFLT_RX2_CHFLT_COE3_7_0 0x211C
#define Si446x_MODEM_CHFLT_RX2_CHFLT_COE2_7_0 0x211D
#define Si446x_MODEM_CHFLT_RX2_CHFLT_COE1_7_0 0x211E
#define Si446x_MODEM_CHFLT_RX2_CHFLT_COE0_7_0 0x211F
#define Si446x_MODEM_CHFLT_RX2_CHFLT_COEM0 0x2120
#define Si446x_MODEM_CHFLT_RX2_CHFLT_COEM1 0x2121
#define Si446x_MODEM_CHFLT_RX2_CHFLT_COEM2 0x2122
#define Si446x_MODEM_CHFLT_RX2_CHFLT_COEM3 0x2123
#define Si446x_PA_PWR_LVL 0x2201
#define Si446x_PA_TC 0x2203
#define Si446x_SYNTH_PFDCP_CPFF 0x2300
#define Si446x_SYNTH_PFDCP_CPINT 0x2301
#define Si446x_SYNTH_VCO_KV 0x2302
#define Si446x_SYNTH_LPFILT3 0x2303
#define Si446x_SYNTH_LPFILT2 0x2304
#define Si446x_SYNTH_LPFILT1 0x2305
#define Si446x_SYNTH_LPFILT0 0x2306
#define Si446x_FREQ_CONTROL_INTE 0x4000
#define Si446x_FREQ_CONTROL_FRAC 0x4001
#define Si446x_FREQ_CONTROL_CHANNEL_STEP_SIZE 0x4004
#define Si446x_FREQ_CONTROL_W_SIZE 0x4006
#define Si446x_FREQ_CONTROL_VCOCNT_RX_ADJ 0x4007
#define PKT_SI446X_APRS_CHANNEL 94
#define PKT_SI446X_SQUELCH_LEVEL 0x4F
#define PKT_SI446X_NO_CCA_RSSI 0xFF
#define Si446x_FIFO_SEPARATE_SIZE 64
#define Si446x_FIFO_COMBINED_SIZE 129
#define SI_AFSK_FIFO_MIN_FEEDER_WA_SIZE 1024
#define SI_FSK_FIFO_FEEDER_WA_SIZE 1024
/* AFSK NRZI up-sampler definitions. */
#define PLAYBACK_RATE 13200
#define BAUD_RATE 1200 /* APRS AFSK baudrate */
#define SAMPLES_PER_BAUD (PLAYBACK_RATE / BAUD_RATE) /* Samples per baud (13200Hz / 1200baud = 11samp/baud) */
#define PHASE_DELTA_1200 (((2 * 1200) << 16) / PLAYBACK_RATE) /* Delta-phase per sample for 1200Hz tone */
#define PHASE_DELTA_2200 (((2 * 2200) << 16) / PLAYBACK_RATE) /* Delta-phase per sample for 2200Hz tone */
/*===========================================================================*/
/* Module data structures and types. */
/*===========================================================================*/
typedef struct {
uint32_t phase_delta; // 1200/2200 for standard AX.25
uint32_t phase; // Fixed point 9.7 (2PI = TABLE_SIZE)
uint32_t packet_pos; // Next bit to be sent out
uint32_t current_sample_in_baud; // 1 bit = SAMPLES_PER_BAUD samples
uint8_t current_byte;
} up_iterator_t;
typedef struct radioTask radio_task_object_t;
// Public methods
int16_t Si446x_getLastTemperature(radio_unit_t radio);
void Si446x_shutdown(radio_unit_t radio);
void Si446x_sendAFSK(packet_t pp);
bool Si446x_blocSendAFSK(radio_task_object_t *rto);
void Si446x_send2FSK(packet_t pp);
bool Si446x_blocSend2FSK(radio_task_object_t *rto);
void Si446x_disableReceive(radio_unit_t radio);
void Si446x_stopDecoder(void);
bool Si4464_resumeReceive(radio_unit_t radio,
radio_freq_t rx_frequency,
channel_hz_t rx_step,
radio_ch_t rx_chan,
radio_squelch_t rx_rssi,
mod_t rx_mod);
bool Si446x_receiveNoLock(radio_unit_t radio,
radio_freq_t rx_frequency,
channel_hz_t rx_step,
radio_ch_t chan,
radio_squelch_t rssi,
mod_t mod);
void Si446x_lockRadio(radio_mode_t mode);
void Si446x_unlockRadio(radio_mode_t mode);
void Si446x_lockRadioByCamera(void);
void Si446x_unlockRadioByCamera(void);
void Si446x_conditional_init(radio_unit_t radio);
bool Si446x_setBandParameters(radio_unit_t radio,
radio_freq_t freq,
channel_hz_t step);
extern void pktReleasePacketBuffer(packet_t pp);
static inline void Si446x_releaseSendObject(packet_t pp) {
pktReleasePacketBuffer(pp);
}
#endif /* __si446x__H__ */
#ifndef __si446x__H__
#define __si446x__H__
/*===========================================================================*/
/* Module constants. */
/*===========================================================================*/
#define Si446x_LOCK_BY_SEMAPHORE TRUE
#ifndef Si446x_CLK
#error "Si446x_CLK is not defined which is needed for Si446x."
#endif
#ifndef Si446x_CLK_OFFSET
#define Si446x_CLK_OFFSET 0
#endif
// Various macros
#define Si446x_getGPIO0() palReadLine(LINE_RADIO_GPIO0)
#define Si446x_getGPIO1() palReadLine(LINE_RADIO_GPIO1)
#define Si446x_getCCA() palReadLine(LINE_RADIO_IRQ)
/* Frequency offset corrected oscillator frequency */
#define Si446x_CCLK ((Si446x_CLK) + (Si446x_CLK_OFFSET) \
* (Si446x_CLK) / 1000000)
// Si4464 States
#define Si446x_STATE_NOCHANGE 0
#define Si446x_STATE_SLEEP 1
#define Si446x_STATE_SPI_ACTIVE 2
#define Si446x_STATE_READY 3
#define Si446x_STATE_READY2 4
#define Si446x_STATE_TX_TUNE 5
#define Si446x_STATE_RX_TUNE 6
#define Si446x_STATE_TX 7
#define Si446x_STATE_RX 8
/*
* Commands.
*/
#define Si446x_GET_ADC_READING 0x14
#define Si446x_FIFO_INFO 0x15
#define Si446x_GET_MODEM_STATUS 0x22
#define Si446x_START_TX 0x31
#define Si446x_START_RX 0x32
#define Si446x_REQUEST_DEVICE_STATE 0x33
#define Si446x_RX_HOP 0x36
#define Si446x_READ_CMD_BUFF 0x44
#define Si446x_WRITE_TX_FIFO 0x66
/* Defined response values. */
#define Si446x_COMMAND_CTS 0xFF
/*
* Property group commands.
* Format is 0xGGNN (GG = group, NN = number).
*/
#define Si446x_GLOBAL_XO_TUNE 0x0000
#define Si446x_GLOBAL_CLK_CFG 0x0001
#define Si446x_GLOBAL_CONFIG 0x0003
#define Si446x_INT_CTL_ENABLE 0x0100
#define Si446x_INT_CTL_MODEM_ENABLE 0x0102
#define Si446x_FRR_CTL_A_MODE 0x0200
#define Si446x_FRR_CTL_B_MODE 0x0201
#define Si446x_FRR_CTL_C_MODE 0x0202
#define Si446x_FRR_CTL_D_MODE 0x0203
#define Si446x_PREAMBLE_TX_LENGTH 0x1000
#define Si446x_PREAMBLE_CONFIG_STD_1 0x1001
#define Si446x_PREAMBLE_CONFIG_NSTD 0x1002
#define Si446x_PREAMBLE_CONFIG_STD_2 0x1003
#define Si446x_PREAMBLE_CONFIG 0x1004
#define Si446x_PREAMBLE_PATTERN 0x1005
#define Si446x_SYNC_CONFIG 0x1100
#define Si446x_PKT_CONFIG1 0x1206
#define Si446x_MODEM_MOD_TYPE 0x2000
#define Si446x_MODEM_MAP_CONTROL 0x2001
#define Si446x_MODEM_DSM_CTRL 0x2002
#define Si446x_MODEM_DATA_RATE 0x2003
#define Si446x_MODEM_TX_NCO_MODE 0x2006
#define Si446x_MODEM_FREQ_DEV 0x200A
#define Si446x_MODEM_TX_RAMP_DELAY 0x2018
#define Si446x_MODEM_MDM_CTRL 0x2019
#define Si446x_MODEM_IF_CONTROL 0x201A
#define Si446x_MODEM_IF_FREQ 0x201B
#define Si446x_MODEM_DECIMATION_CFG1 0x201E
#define Si446x_MODEM_DECIMATION_CFG0 0x201F
#define Si446x_MODEM_BCR_OSR 0x2022
#define Si446x_MODEM_BCR_NCO_OFFSET 0x2024
#define Si446x_MODEM_BCR_GAIN 0x2027
#define Si446x_MODEM_BCR_GEAR 0x2029
#define Si446x_MODEM_BCR_MISC1 0x202A
#define Si446x_MODEM_AFC_GEAR 0x202C
#define Si446x_MODEM_AFC_WAIT 0x202D
#define Si446x_MODEM_AFC_GAIN 0x202E
#define Si446x_MODEM_AFC_LIMITER 0x2030
#define Si446x_MODEM_AFC_MISC 0x2032
#define Si446x_MODEM_AGC_CONTROL 0x2035
#define Si446x_MODEM_AGC_WINDOW_SIZE 0x2038
#define Si446x_MODEM_AGC_RFPD_DECAY 0x2039
#define Si446x_MODEM_AGC_IFPD_DECAY 0x203A
#define Si446x_MODEM_FSK4_GAIN1 0x203B
#define Si446x_MODEM_FSK4_GAIN0 0x203C
#define Si446x_MODEM_FSK4_TH 0x203D
#define Si446x_MODEM_FSK4_MAP 0x203F
#define Si446x_MODEM_OOK_PDTC 0x2040
#define Si446x_MODEM_OOK_CNT1 0x2042
#define Si446x_MODEM_OOK_MISC 0x2043
#define Si446x_MODEM_RAW_SEARCH 0x2044
#define Si446x_MODEM_RAW_CONTROL 0x2045
#define Si446x_MODEM_RAW_EYE 0x2046
#define Si446x_MODEM_ANT_DIV_MODE 0x2048
#define Si446x_MODEM_ANT_DIV_CONTROL 0x2049
#define Si446x_MODEM_RSSI_THRESH 0x204A
#define Si446x_MODEM_RSSI_JUMP_THRESH 0x204B
#define Si446x_MODEM_RSSI_CONTROL 0x204C
#define Si446x_MODEM_RSSI_CONTROL2 0x204D
#define Si446x_MODEM_RSSI_COMP 0x204E
#define Si446x_MODEM_CLKGEN_BAND 0x2051
#define Si446x_MODEM_CHFLT_RX1_CHFLT_COE13_7_0 0x2100
#define Si446x_MODEM_CHFLT_RX1_CHFLT_COE12_7_0 0x2101
#define Si446x_MODEM_CHFLT_RX1_CHFLT_COE11_7_0 0x2102
#define Si446x_MODEM_CHFLT_RX1_CHFLT_COE10_7_0 0x2103
#define Si446x_MODEM_CHFLT_RX1_CHFLT_COE9_7_0 0x2104
#define Si446x_MODEM_CHFLT_RX1_CHFLT_COE8_7_0 0x2105
#define Si446x_MODEM_CHFLT_RX1_CHFLT_COE7_7_0 0x2106
#define Si446x_MODEM_CHFLT_RX1_CHFLT_COE6_7_0 0x2107
#define Si446x_MODEM_CHFLT_RX1_CHFLT_COE5_7_0 0x2108
#define Si446x_MODEM_CHFLT_RX1_CHFLT_COE4_7_0 0x2109
#define Si446x_MODEM_CHFLT_RX1_CHFLT_COE3_7_0 0x210A
#define Si446x_MODEM_CHFLT_RX1_CHFLT_COE2_7_0 0x210B
#define Si446x_MODEM_CHFLT_RX1_CHFLT_COE1_7_0 0x210C
#define Si446x_MODEM_CHFLT_RX1_CHFLT_COE0_7_0 0x210D
#define Si446x_MODEM_CHFLT_RX1_CHFLT_COEM0 0x210E
#define Si446x_MODEM_CHFLT_RX1_CHFLT_COEM1 0x210F
#define Si446x_MODEM_CHFLT_RX1_CHFLT_COEM2 0x2110
#define Si446x_MODEM_CHFLT_RX1_CHFLT_COEM3 0x2111
#define Si446x_MODEM_CHFLT_RX2_CHFLT_COE13_7_0 0x2112
#define Si446x_MODEM_CHFLT_RX2_CHFLT_COE12_7_0 0x2113
#define Si446x_MODEM_CHFLT_RX2_CHFLT_COE11_7_0 0x2114
#define Si446x_MODEM_CHFLT_RX2_CHFLT_COE10_7_0 0x2115
#define Si446x_MODEM_CHFLT_RX2_CHFLT_COE9_7_0 0x2116
#define Si446x_MODEM_CHFLT_RX2_CHFLT_COE8_7_0 0x2117
#define Si446x_MODEM_CHFLT_RX2_CHFLT_COE7_7_0 0x2118
#define Si446x_MODEM_CHFLT_RX2_CHFLT_COE6_7_0 0x2119
#define Si446x_MODEM_CHFLT_RX2_CHFLT_COE5_7_0 0x211A
#define Si446x_MODEM_CHFLT_RX2_CHFLT_COE4_7_0 0x211B
#define Si446x_MODEM_CHFLT_RX2_CHFLT_COE3_7_0 0x211C
#define Si446x_MODEM_CHFLT_RX2_CHFLT_COE2_7_0 0x211D
#define Si446x_MODEM_CHFLT_RX2_CHFLT_COE1_7_0 0x211E
#define Si446x_MODEM_CHFLT_RX2_CHFLT_COE0_7_0 0x211F
#define Si446x_MODEM_CHFLT_RX2_CHFLT_COEM0 0x2120
#define Si446x_MODEM_CHFLT_RX2_CHFLT_COEM1 0x2121
#define Si446x_MODEM_CHFLT_RX2_CHFLT_COEM2 0x2122
#define Si446x_MODEM_CHFLT_RX2_CHFLT_COEM3 0x2123
#define Si446x_PA_PWR_LVL 0x2201
#define Si446x_PA_TC 0x2203
#define Si446x_SYNTH_PFDCP_CPFF 0x2300
#define Si446x_SYNTH_PFDCP_CPINT 0x2301
#define Si446x_SYNTH_VCO_KV 0x2302
#define Si446x_SYNTH_LPFILT3 0x2303
#define Si446x_SYNTH_LPFILT2 0x2304
#define Si446x_SYNTH_LPFILT1 0x2305
#define Si446x_SYNTH_LPFILT0 0x2306
#define Si446x_FREQ_CONTROL_INTE 0x4000
#define Si446x_FREQ_CONTROL_FRAC 0x4001
#define Si446x_FREQ_CONTROL_CHANNEL_STEP_SIZE 0x4004
#define Si446x_FREQ_CONTROL_W_SIZE 0x4006
#define Si446x_FREQ_CONTROL_VCOCNT_RX_ADJ 0x4007
#define PKT_SI446X_APRS_CHANNEL 94
#define PKT_SI446X_SQUELCH_LEVEL 0x4F
#define PKT_SI446X_NO_CCA_RSSI 0xFF
#define Si446x_FIFO_SEPARATE_SIZE 64
#define Si446x_FIFO_COMBINED_SIZE 129
#define SI_AFSK_FIFO_MIN_FEEDER_WA_SIZE 1024
#define SI_FSK_FIFO_FEEDER_WA_SIZE 1024
/* AFSK NRZI up-sampler definitions. */
#define PLAYBACK_RATE 13200
#define BAUD_RATE 1200 /* APRS AFSK baudrate */
#define SAMPLES_PER_BAUD (PLAYBACK_RATE / BAUD_RATE) /* Samples per baud (13200Hz / 1200baud = 11samp/baud) */
#define PHASE_DELTA_1200 (((2 * 1200) << 16) / PLAYBACK_RATE) /* Delta-phase per sample for 1200Hz tone */
#define PHASE_DELTA_2200 (((2 * 2200) << 16) / PLAYBACK_RATE) /* Delta-phase per sample for 2200Hz tone */
/*===========================================================================*/
/* Module data structures and types. */
/*===========================================================================*/
typedef struct {
uint32_t phase_delta; // 1200/2200 for standard AX.25
uint32_t phase; // Fixed point 9.7 (2PI = TABLE_SIZE)
uint32_t packet_pos; // Next bit to be sent out
uint32_t current_sample_in_baud; // 1 bit = SAMPLES_PER_BAUD samples
uint8_t current_byte;
} up_iterator_t;
typedef struct radioTask radio_task_object_t;
// Public methods
int16_t Si446x_getLastTemperature(const radio_unit_t radio);
void Si446x_shutdown(const radio_unit_t radio);
void Si446x_sendAFSK(packet_t pp);
bool Si446x_blocSendAFSK(radio_task_object_t *rto);
void Si446x_send2FSK(packet_t pp);
bool Si446x_blocSend2FSK(radio_task_object_t *rto);
void Si446x_disableReceive(radio_unit_t radio);
void Si446x_stopDecoder(void);
bool Si4464_resumeReceive(const radio_unit_t radio,
radio_freq_t rx_frequency,
channel_hz_t rx_step,
radio_ch_t rx_chan,
radio_squelch_t rx_rssi,
mod_t rx_mod);
bool Si446x_receiveNoLock(const radio_unit_t radio,
radio_freq_t rx_frequency,
channel_hz_t rx_step,
radio_ch_t chan,
radio_squelch_t rssi,
mod_t mod);
void Si446x_lockRadio(const radio_mode_t mode);
void Si446x_unlockRadio(const radio_mode_t mode);
void Si446x_lockRadioByCamera(void);
void Si446x_unlockRadioByCamera(void);
void Si446x_conditional_init(radio_unit_t radio);
bool Si446x_setBandParameters(const radio_unit_t radio,
radio_freq_t freq,
channel_hz_t step);
radio_signal_t Si446x_getCurrentRSSI(const radio_unit_t radio);
extern void pktReleasePacketBuffer(packet_t pp);
static inline void Si446x_releaseSendObject(packet_t pp) {
pktReleasePacketBuffer(pp);
}
#endif /* __si446x__H__ */

Wyświetl plik

@ -1,154 +1,155 @@
/*
Aerospace Decoder - Copyright (C) 2018 Bob Anderson (VK2GJ)
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*/
/**
* @file pktradio.h
* @brief Generic radio definitions.
*
* @addtogroup managers
* @{
*/
#ifndef PKT_MANAGERS_PKTRADIO_H_
#define PKT_MANAGERS_PKTRADIO_H_
/*===========================================================================*/
/* Module constants. */
/*===========================================================================*/
/* Thread working area size. */
#define PKT_RADIO_MANAGER_WA_SIZE 4096
#define PKT_RADIO_TASK_QUEUE_PREFIX "radm_"
/* The number of radio task object the FIFO has. */
#define RADIO_TASK_QUEUE_MAX 10
#define NUM_BANDS_PER_RADIO 2
/*===========================================================================*/
/* Module data structures and types. */
/*===========================================================================*/
#include "pkttypes.h"
/**
* @brief Radio manager control commands.
* @details Radio task requests execute these commands.
*/
typedef enum radioCommand {
PKT_RADIO_RX_OPEN,
PKT_RADIO_RX_START,
PKT_RADIO_RX_STOP,
PKT_RADIO_TX_SEND,
PKT_RADIO_RX_CLOSE,
PKT_RADIO_TX_THREAD
} radio_command_t;
/**
* Forward declare structure types.
*/
typedef struct radioTask radio_task_object_t;
typedef struct packetHandlerData packet_svc_t;
typedef struct radioParam radio_param_t;
/**
* @brief Radio task notification callback type.
*
* @param[in] rcob pointer to a @p radio task object
*/
typedef void (*radio_task_cb_t)(radio_task_object_t *task_object);
#include "ax25_pad.h"
/**
* @brief Radio task object.
* @details queue object submitted via FIFO or radio task requests.
*/
struct radioTask {
/* For safety keep clear - where pool stores its free link. */
struct pool_header link;
radio_command_t command;
mod_t type;
radio_freq_t base_frequency;
channel_hz_t step_hz;
radio_ch_t channel;
radio_squelch_t squelch;
radio_task_cb_t callback;
msg_t result;
thread_t *thread;
char tx_thd_name[16];
packet_svc_t *handler;
packet_t packet_out;
uint8_t tx_power;
uint32_t tx_speed;
uint8_t tx_seq_num;
};
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
//extern const radio_param_t radio_list[NUM_PKT_RADIOS];
#ifdef __cplusplus
extern "C" {
#endif
thread_t *pktRadioManagerCreate(const radio_unit_t radio);
void pktRadioManagerRelease(const radio_unit_t radio);
void pktRadioManager(void *arg);
msg_t pktGetRadioTaskObject(const radio_unit_t radio,
const sysinterval_t timeout,
radio_task_object_t **rt);
void pktSubmitRadioTask(const radio_unit_t radio,
radio_task_object_t *object,
radio_task_cb_t cb);
void pktScheduleThreadRelease(radio_unit_t radio,
thread_t *thread);
msg_t pktAcquireRadio(radio_unit_t radio, sysinterval_t timeout);
void pktReleaseRadio(radio_unit_t radio);
radio_freq_t pktComputeOperatingFrequency(const radio_unit_t radio,
radio_freq_t base_freq,
channel_hz_t step,
radio_ch_t chan,
const radio_mode_t mode);
bool pktLLDresumeReceive(const radio_unit_t radio);
bool pktLLDsendPacket(radio_task_object_t *rto);
void pktScheduleSendComplete(radio_task_object_t *rto,
thread_t *thread);
void pktStartDecoder(const radio_unit_t radio);
void pktStopDecoder(const radio_unit_t radio);
int pktDisplayFrequencyCode(radio_freq_t code, char *buf, size_t size);
#ifdef __cplusplus
}
#endif
/*===========================================================================*/
/* Module inline functions. */
/*===========================================================================*/
/**
* @brief Alias for convenience of pktStopDecoder.
*
* @param[in] radio radio unit ID
*
* @api
*/
#define pktPauseDecoding(radio) pktStopDecoder(radio)
/**
* @brief Alias for convenience of pktStartDecoder.
*
* @param[in] radio radio unit ID
*
* @api
*/
#define pktResumeDecoding(radio) pktStartDecoder(radio)
#endif /* PKT_MANAGERS_PKTRADIO_H_ */
/** @} */
/*
Aerospace Decoder - Copyright (C) 2018 Bob Anderson (VK2GJ)
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*/
/**
* @file pktradio.h
* @brief Generic radio definitions.
*
* @addtogroup managers
* @{
*/
#ifndef PKT_MANAGERS_PKTRADIO_H_
#define PKT_MANAGERS_PKTRADIO_H_
/*===========================================================================*/
/* Module constants. */
/*===========================================================================*/
/* Thread working area size. */
#define PKT_RADIO_MANAGER_WA_SIZE 4096
#define PKT_RADIO_TASK_QUEUE_PREFIX "radm_"
/* The number of radio task object the FIFO has. */
#define RADIO_TASK_QUEUE_MAX 10
#define NUM_BANDS_PER_RADIO 2
/*===========================================================================*/
/* Module data structures and types. */
/*===========================================================================*/
#include "pkttypes.h"
/**
* @brief Radio manager control commands.
* @details Radio task requests execute these commands.
*/
typedef enum radioCommand {
PKT_RADIO_RX_OPEN,
PKT_RADIO_RX_START,
PKT_RADIO_RX_STOP,
PKT_RADIO_TX_SEND,
PKT_RADIO_RX_CLOSE,
PKT_RADIO_TX_THREAD
} radio_command_t;
/**
* Forward declare structure types.
*/
typedef struct radioTask radio_task_object_t;
typedef struct packetHandlerData packet_svc_t;
typedef struct radioParam radio_param_t;
/**
* @brief Radio task notification callback type.
*
* @param[in] rcob pointer to a @p radio task object
*/
typedef void (*radio_task_cb_t)(radio_task_object_t *task_object);
#include "ax25_pad.h"
/**
* @brief Radio task object.
* @details queue object submitted via FIFO or radio task requests.
*/
struct radioTask {
/* For safety keep clear - where pool stores its free link. */
struct pool_header link;
radio_command_t command;
mod_t type;
radio_freq_t base_frequency;
channel_hz_t step_hz;
radio_ch_t channel;
radio_squelch_t squelch;
radio_task_cb_t callback;
msg_t result;
thread_t *thread;
char tx_thd_name[16];
packet_svc_t *handler;
packet_t packet_out;
uint8_t tx_power;
uint32_t tx_speed;
uint8_t tx_seq_num;
};
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
//extern const radio_param_t radio_list[NUM_PKT_RADIOS];
#ifdef __cplusplus
extern "C" {
#endif
thread_t *pktRadioManagerCreate(const radio_unit_t radio);
void pktRadioManagerRelease(const radio_unit_t radio);
void pktRadioManager(void *arg);
msg_t pktGetRadioTaskObject(const radio_unit_t radio,
const sysinterval_t timeout,
radio_task_object_t **rt);
void pktSubmitRadioTask(const radio_unit_t radio,
radio_task_object_t *object,
radio_task_cb_t cb);
void pktScheduleThreadRelease(radio_unit_t radio,
thread_t *thread);
msg_t pktAcquireRadio(radio_unit_t radio, sysinterval_t timeout);
void pktReleaseRadio(radio_unit_t radio);
radio_freq_t pktComputeOperatingFrequency(const radio_unit_t radio,
radio_freq_t base_freq,
channel_hz_t step,
radio_ch_t chan,
const radio_mode_t mode);
bool pktLLDresumeReceive(const radio_unit_t radio);
bool pktLLDsendPacket(radio_task_object_t *rto);
void pktLLDcaptureReceiveStrength(packet_svc_t *handler);
void pktScheduleSendComplete(radio_task_object_t *rto,
thread_t *thread);
void pktStartDecoder(const radio_unit_t radio);
void pktStopDecoder(const radio_unit_t radio);
int pktDisplayFrequencyCode(radio_freq_t code, char *buf, size_t size);
#ifdef __cplusplus
}
#endif
/*===========================================================================*/
/* Module inline functions. */
/*===========================================================================*/
/**
* @brief Alias for convenience of pktStopDecoder.
*
* @param[in] radio radio unit ID
*
* @api
*/
#define pktPauseDecoding(radio) pktStopDecoder(radio)
/**
* @brief Alias for convenience of pktStartDecoder.
*
* @param[in] radio radio unit ID
*
* @api
*/
#define pktResumeDecoding(radio) pktStartDecoder(radio)
#endif /* PKT_MANAGERS_PKTRADIO_H_ */
/** @} */

Wyświetl plik

@ -1,27 +1,27 @@
/*
Aerospace Decoder - Copyright (C) 2018 Bob Anderson (VK2GJ)
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*/
/**
* @file pktconf.c
* @brief Configuration data.
*
* @addtogroup pktconfig
* @details Decoder related settings and configuration.
* @{
*/
#include "pktconf.h"
/*===========================================================================*/
/* Module exported variables. */
/*===========================================================================*/
packet_svc_t RPKTD1;
binary_semaphore_t diag_out_sem;
/*
Aerospace Decoder - Copyright (C) 2018 Bob Anderson (VK2GJ)
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*/
/**
* @file pktconf.c
* @brief Configuration data.
*
* @addtogroup pktconfig
* @details Decoder related settings and configuration.
* @{
*/
#include "pktconf.h"
/*===========================================================================*/
/* Module exported variables. */
/*===========================================================================*/
packet_svc_t RPKTD1;
binary_semaphore_t diag_out_sem;

Wyświetl plik

@ -1,88 +1,90 @@
/*
Aerospace Decoder - Copyright (C) 2018 Bob Anderson (VK2GJ)
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*/
/**
* @file pkttypes.h
* @brief Types definitions.
* @details Include this file as required in a source code module.
*
* @addtogroup pktconfig
* @details Decoder type definitions.
* @{
*/
#ifndef PKT_PKTTYPES_H_
#define PKT_PKTTYPES_H_
#ifdef PKT_IS_TEST_PROJECT
/* Modulation type. */
typedef enum {
MOD_NONE,
MOD_AFSK,
MOD_2FSK
} mod_t;
#endif
#ifdef PKT_IS_TEST_PROJECT
inline const char *getModulation(uint8_t key) {
const char *val[] = {"NONE", "AFSK", "2FSK"};
return val[key];
};
#endif
/* Radio parameters. */
/* Radio frequency in Hz. */
typedef uint32_t radio_freq_t;
/* Channel step in Hz. */
typedef uint16_t channel_hz_t;
/* Channel selector for radio frequency. */
typedef uint8_t radio_ch_t;
/* Radio squelch setting. */
typedef uint8_t radio_squelch_t;
typedef int8_t radio_pwr_t;
/**
* @brief Definition of radio unit ID.
* @details Defines the radio unit used in configuring and enabling a radio.
*
*/
typedef enum radioUnit {
PKT_RADIO_1
} radio_unit_t;
typedef enum radioTypes {
SI4464,
SI4463
} radio_type_t;
typedef enum radioMode {
RADIO_OFF,
RADIO_RX,
RADIO_TX
} radio_mode_t;
typedef uint8_t ax25char_t;
typedef int32_t gps_coord_t;
typedef int32_t gps_alt_t;
typedef uint16_t aprs_sym_t;
typedef uint32_t link_speed_t;
typedef uint16_t volt_level_t;
#endif /* PKT_PKTTYPES_H_ */
/*
Aerospace Decoder - Copyright (C) 2018 Bob Anderson (VK2GJ)
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*/
/**
* @file pkttypes.h
* @brief Types definitions.
* @details Include this file as required in a source code module.
*
* @addtogroup pktconfig
* @details Decoder type definitions.
* @{
*/
#ifndef PKT_PKTTYPES_H_
#define PKT_PKTTYPES_H_
#ifdef PKT_IS_TEST_PROJECT
/* Modulation type. */
typedef enum {
MOD_NONE,
MOD_AFSK,
MOD_2FSK
} mod_t;
#endif
#ifdef PKT_IS_TEST_PROJECT
inline const char *getModulation(uint8_t key) {
const char *val[] = {"NONE", "AFSK", "2FSK"};
return val[key];
};
#endif
/* Radio parameters. */
/* Radio frequency in Hz. */
typedef uint32_t radio_freq_t;
/* Channel step in Hz. */
typedef uint16_t channel_hz_t;
/* Channel selector for radio frequency. */
typedef uint8_t radio_ch_t;
/* Radio squelch setting. */
typedef uint8_t radio_squelch_t;
typedef int8_t radio_pwr_t;
typedef int8_t radio_signal_t;
/**
* @brief Definition of radio unit ID.
* @details Defines the radio unit used in configuring and enabling a radio.
*
*/
typedef enum radioUnit {
PKT_RADIO_1
} radio_unit_t;
typedef enum radioTypes {
SI4464,
SI4463
} radio_type_t;
typedef enum radioMode {
RADIO_OFF,
RADIO_RX,
RADIO_TX
} radio_mode_t;
typedef uint8_t ax25char_t;
typedef int32_t gps_coord_t;
typedef int32_t gps_alt_t;
typedef uint16_t aprs_sym_t;
typedef uint32_t link_speed_t;
typedef uint16_t volt_level_t;
#endif /* PKT_PKTTYPES_H_ */