Sven Steudte 2018-07-29 22:38:32 +02:00
commit 5b89260c12
46 zmienionych plików z 4413 dodań i 3951 usunięć

Wyświetl plik

@ -98,7 +98,7 @@
#define STM32_HAS_RCC_I2SPLLSRC FALSE
#define STM32_HAS_RCC_CK48MSEL TRUE
#define STM32_RCC_CK48MSEL_USES_I2S FALSE
#define STM32_TIMPRE_PRESCALE4 FALSE
#define STM32_TIMPRE_PRESCALE4 TRUE
/* ADC attributes.*/
#define STM32_ADC_HANDLER Vector88
@ -480,7 +480,7 @@
#define STM32_HAS_RCC_I2SPLLSRC FALSE
#define STM32_HAS_RCC_CK48MSEL TRUE
#define STM32_RCC_CK48MSEL_USES_I2S FALSE
#define STM32_TIMPRE_PRESCALE4 FALSE
#define STM32_TIMPRE_PRESCALE4 TRUE
/* ADC attributes.*/
#define STM32_ADC_HANDLER Vector88
@ -839,7 +839,7 @@
#define STM32_HAS_RCC_I2SPLLSRC FALSE
#define STM32_HAS_RCC_CK48MSEL FALSE
#define STM32_RCC_CK48MSEL_USES_I2S FALSE
#define STM32_TIMPRE_PRESCALE4 FALSE
#define STM32_TIMPRE_PRESCALE4 TRUE
/* ADC attributes.*/
#define STM32_ADC_HANDLER Vector88
@ -1217,7 +1217,7 @@
#define STM32_HAS_RCC_I2SPLLSRC TRUE
#define STM32_HAS_RCC_CK48MSEL TRUE
#define STM32_RCC_CK48MSEL_USES_I2S TRUE
#define STM32_TIMPRE_PRESCALE4 TRUE
#define STM32_TIMPRE_PRESCALE4 FALSE
/* ADC attributes.*/
#define STM32_ADC_HANDLER Vector88
@ -1607,7 +1607,7 @@
#define STM32_HAS_RCC_I2SPLLSRC TRUE
#define STM32_HAS_RCC_CK48MSEL TRUE
#define STM32_RCC_CK48MSEL_USES_I2S TRUE
#define STM32_TIMPRE_PRESCALE4 TRUE
#define STM32_TIMPRE_PRESCALE4 FALSE
/* ADC attributes.*/
#define STM32_ADC_HANDLER Vector88
@ -1942,7 +1942,7 @@
#define STM32_HAS_RCC_I2SPLLSRC FALSE
#define STM32_HAS_RCC_CK48MSEL FALSE
#define STM32_RCC_CK48MSEL_USES_I2S FALSE
#define STM32_TIMPRE_PRESCALE4 TRUE
#define STM32_TIMPRE_PRESCALE4 FALSE
/* ADC attributes.*/
#define STM32_ADC_HANDLER Vector88
@ -2253,7 +2253,7 @@
#define STM32_HAS_RCC_I2SPLLSRC FALSE
#define STM32_HAS_RCC_CK48MSEL FALSE
#define STM32_RCC_CK48MSEL_USES_I2S FALSE
#define STM32_TIMPRE_PRESCALE4 TRUE
#define STM32_TIMPRE_PRESCALE4 FALSE
/* ADC attributes.*/
#define STM32_ADC_HANDLER Vector88
@ -2534,7 +2534,7 @@
#define STM32_HAS_RCC_I2SPLLSRC FALSE
#define STM32_HAS_RCC_CK48MSEL FALSE
#define STM32_RCC_CK48MSEL_USES_I2S FALSE
#define STM32_TIMPRE_PRESCALE4 FALSE
#define STM32_TIMPRE_PRESCALE4 TRUE
/* ADC attributes.*/
#define STM32_ADC_HANDLER Vector88
@ -2888,7 +2888,7 @@
#define STM32_HAS_RCC_I2SPLLSRC FALSE
#define STM32_HAS_RCC_CK48MSEL FALSE
#define STM32_RCC_CK48MSEL_USES_I2S FALSE
#define STM32_TIMPRE_PRESCALE4 TRUE
#define STM32_TIMPRE_PRESCALE4 FALSE
/* ADC attributes.*/
#define STM32_ADC_HANDLER Vector88

Wyświetl plik

@ -103,8 +103,6 @@ void spiStart(SPIDriver *spip, const SPIConfig *config) {
/**
* @brief Deactivates the SPI peripheral.
* @note Deactivating the peripheral also enforces a release of the slave
* select line.
*
* @param[in] spip pointer to the @p SPIDriver object
*

Wyświetl plik

@ -239,114 +239,9 @@
#define GPIOK_PIN14 14U
#define GPIOK_PIN15 15U
/*
* IO lines assignments.
*/
// IO
/*
#define LINE_GPIO_PIN PAL_LINE(GPIOA, 8U)
#define LINE_IO_TXD PAL_LINE(GPIOB, 10U)
#define LINE_IO_RXD PAL_LINE(GPIOC, 11U)
*/
// APRS IO lines
/*
#define LINE_IO1 LINE_GPIO_PIN
#define LINE_IO2 LINE_IO_TXD
#define LINE_IO3 LINE_IO_RXD
#define LINE_IO4 PAL_NOLINE
#define LINE_IO5 PAL_NOLINE
#define LINE_IO6 PAL_NOLINE
#define LINE_IO7 PAL_NOLINE
#define LINE_IO8 PAL_NOLINE
*/
// LED
/*
#define LINE_IO_BLUE PAL_LINE(GPIOC, 1U)
#define LINE_IO_GREEN PAL_LINE(GPIOC, 3U)
*/
// GPS
/*
#define LINE_GPS_EN PAL_LINE(GPIOA, 15U)
#define LINE_GPS_RESET PAL_LINE(GPIOB, 14U)
#define LINE_GPS_TXD PAL_LINE(GPIOB, 13U)
#define LINE_GPS_RXD PAL_LINE(GPIOB, 12U)
#define LINE_GPS_TIMEPULSE PAL_LINE(GPIOB, 15U)
*/
// I2C
/*
#define LINE_I2C_SCL PAL_LINE(GPIOB, 8U)
#define LINE_I2C_SDA PAL_LINE(GPIOB, 9U)
*/
// SPI
/*
#define LINE_SPI_SCK PAL_LINE(GPIOB, 3U)
#define LINE_SPI_MISO PAL_LINE(GPIOB, 4U)
#define LINE_SPI_MOSI PAL_LINE(GPIOB, 5U)
*/
// Camera pins
/*
#define LINE_CAM_XCLK PAL_LINE(GPIOC, 9U)
#define LINE_CAM_PCLK PAL_LINE(GPIOC, 6U)
#define LINE_CAM_VSYNC PAL_LINE(GPIOC, 5U)
#define LINE_CAM_D2 PAL_LINE(GPIOA, 0U)
#define LINE_CAM_D3 PAL_LINE(GPIOA, 1U)
#define LINE_CAM_D4 PAL_LINE(GPIOA, 2U)
#define LINE_CAM_D5 PAL_LINE(GPIOA, 3U)
#define LINE_CAM_D6 PAL_LINE(GPIOA, 4U)
#define LINE_CAM_D7 PAL_LINE(GPIOA, 5U)
#define LINE_CAM_D8 PAL_LINE(GPIOA, 6U)
#define LINE_CAM_D9 PAL_LINE(GPIOA, 7U)
#define LINE_CAM_EN PAL_LINE(GPIOC, 7U)
#define LINE_CAM_RESET PAL_LINE(GPIOB, 0U)
*/
// Radio pins
/*
#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)
*/
// SD Card pins
/*
#define LINE_SD_CS PAL_LINE(GPIOC, 0U)
#define LINE_SD_DET PAL_LINE(GPIOC, 8U)
*/
// ADC
/*
#define LINE_ADC_VSOL PAL_LINE(GPIOC, 2U)
#define LINE_ADC_VBAT PAL_LINE(GPIOB, 1U)
#define LINE_ADC_VUSB PAL_LINE(GPIOC, 4U)
*/
// USB
/*
#define LINE_USB_ID PAL_LINE(GPIOA, 10U)
#define LINE_USB_VBUS PAL_LINE(GPIOA, 9U)
#define LINE_USB_DM PAL_LINE(GPIOA, 11U)
#define LINE_USB_DP PAL_LINE(GPIOA, 12U)
*/
// Misc
/* For enabling TCXO. Done in early_init. */
#define LINE_TCXO_EN PAL_LINE(GPIOC, 13U)
// Hardware dependent settings
//#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 */
/*
* I/O ports initial setup, this configuration is established soon after reset
* in the initialization code.

Wyświetl plik

@ -1,401 +1,418 @@
/*
ChibiOS - Copyright (C) 2006..2016 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
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.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file templates/halconf.h
* @brief HAL configuration header.
* @details HAL configuration file, this file allows to enable or disable the
* various device drivers from your application. You may also use
* this file in order to override the device drivers default settings.
*
* @addtogroup HAL_CONF
* @{
*/
#ifndef HALCONF_H
#define HALCONF_H
#include "mcuconf.h"
/**
* @brief Enables the PAL subsystem.
*/
#if !defined(HAL_USE_PAL) || defined(__DOXYGEN__)
#define HAL_USE_PAL TRUE
#endif
/**
* @brief Enables the ADC subsystem.
*/
#if !defined(HAL_USE_ADC) || defined(__DOXYGEN__)
#define HAL_USE_ADC TRUE
#endif
/**
* @brief Enables the CAN subsystem.
*/
#if !defined(HAL_USE_CAN) || defined(__DOXYGEN__)
#define HAL_USE_CAN FALSE
#endif
/**
* @brief Enables the DAC subsystem.
*/
#if !defined(HAL_USE_DAC) || defined(__DOXYGEN__)
#define HAL_USE_DAC FALSE
#endif
/**
* @brief Enables the EXT subsystem.
*/
#if !defined(HAL_USE_EXT) || defined(__DOXYGEN__)
#define HAL_USE_EXT FALSE
#endif
/**
* @brief Enables the GPT subsystem.
*/
#if !defined(HAL_USE_GPT) || defined(__DOXYGEN__)
#define HAL_USE_GPT FALSE
#endif
/**
* @brief Enables the I2C subsystem.
*/
#if !defined(HAL_USE_I2C) || defined(__DOXYGEN__)
#define HAL_USE_I2C TRUE
#endif
/**
* @brief Enables the I2S subsystem.
*/
#if !defined(HAL_USE_I2S) || defined(__DOXYGEN__)
#define HAL_USE_I2S FALSE
#endif
/**
* @brief Enables the ICU subsystem.
*/
#if !defined(HAL_USE_ICU) || defined(__DOXYGEN__)
#define HAL_USE_ICU TRUE
/* Driver extension to add user fields. */
#define ICU_DRIVER_EXT_FIELDS \
void *link; \
virtual_timer_t cca_timer; \
virtual_timer_t icu_timer; \
virtual_timer_t pwm_timer;
#endif
/**
* @brief Enables the MAC subsystem.
*/
#if !defined(HAL_USE_MAC) || defined(__DOXYGEN__)
#define HAL_USE_MAC FALSE
#endif
/**
* @brief Enables the MMC_SPI subsystem.
*/
#if !defined(HAL_USE_MMC_SPI) || defined(__DOXYGEN__)
#define HAL_USE_MMC_SPI TRUE
#endif
/**
* @brief Enables the PWM subsystem.
*/
#if !defined(HAL_USE_PWM) || defined(__DOXYGEN__)
#define HAL_USE_PWM FALSE
#endif
/**
* @brief Enables the QSPI subsystem.
*/
#if !defined(HAL_USE_QSPI) || defined(__DOXYGEN__)
#define HAL_USE_QSPI FALSE
#endif
/**
* @brief Enables the RTC subsystem.
*/
#if !defined(HAL_USE_RTC) || defined(__DOXYGEN__)
#define HAL_USE_RTC TRUE
#endif
/**
* @brief Enables the SDC subsystem.
*/
#if !defined(HAL_USE_SDC) || defined(__DOXYGEN__)
#define HAL_USE_SDC FALSE
#endif
/**
* @brief Enables the SERIAL subsystem.
*/
#if !defined(HAL_USE_SERIAL) || defined(__DOXYGEN__)
#define HAL_USE_SERIAL TRUE
#endif
/**
* @brief Enables the SERIAL over USB subsystem.
*/
#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__)
#define HAL_USE_SERIAL_USB TRUE
#endif
/**
* @brief Enables the SPI subsystem.
*/
#if !defined(HAL_USE_SPI) || defined(__DOXYGEN__)
#define HAL_USE_SPI TRUE
#endif
/**
* @brief Enables the UART subsystem.
*/
#if !defined(HAL_USE_UART) || defined(__DOXYGEN__)
#define HAL_USE_UART FALSE
#endif
/**
* @brief Enables the USB subsystem.
*/
#if !defined(HAL_USE_USB) || defined(__DOXYGEN__)
#define HAL_USE_USB TRUE
#endif
/**
* @brief Enables the WDG subsystem.
*/
#if !defined(HAL_USE_WDG) || defined(__DOXYGEN__)
#define HAL_USE_WDG TRUE
#endif
/*===========================================================================*/
/* ADC driver related settings. */
/*===========================================================================*/
/**
* @brief Enables synchronous APIs.
* @note Disabling this option saves both code and data space.
*/
#if !defined(ADC_USE_WAIT) || defined(__DOXYGEN__)
#define ADC_USE_WAIT TRUE
#endif
/**
* @brief Enables the @p adcAcquireBus() and @p adcReleaseBus() APIs.
* @note Disabling this option saves both code and data space.
*/
#if !defined(ADC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
#define ADC_USE_MUTUAL_EXCLUSION TRUE
#endif
/*===========================================================================*/
/* CAN driver related settings. */
/*===========================================================================*/
/**
* @brief Sleep mode related APIs inclusion switch.
*/
#if !defined(CAN_USE_SLEEP_MODE) || defined(__DOXYGEN__)
#define CAN_USE_SLEEP_MODE TRUE
#endif
/*===========================================================================*/
/* I2C driver related settings. */
/*===========================================================================*/
/**
* @brief Enables the mutual exclusion APIs on the I2C bus.
*/
#if !defined(I2C_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
#define I2C_USE_MUTUAL_EXCLUSION TRUE
#endif
/*===========================================================================*/
/* MAC driver related settings. */
/*===========================================================================*/
/**
* @brief Enables an event sources for incoming packets.
*/
#if !defined(MAC_USE_ZERO_COPY) || defined(__DOXYGEN__)
#define MAC_USE_ZERO_COPY FALSE
#endif
/**
* @brief Enables an event sources for incoming packets.
*/
#if !defined(MAC_USE_EVENTS) || defined(__DOXYGEN__)
#define MAC_USE_EVENTS TRUE
#endif
/*===========================================================================*/
/* MMC_SPI driver related settings. */
/*===========================================================================*/
/**
* @brief Delays insertions.
* @details If enabled this options inserts delays into the MMC waiting
* routines releasing some extra CPU time for the threads with
* lower priority, this may slow down the driver a bit however.
* This option is recommended also if the SPI driver does not
* use a DMA channel and heavily loads the CPU.
*/
#if !defined(MMC_NICE_WAITING) || defined(__DOXYGEN__)
#define MMC_NICE_WAITING TRUE
#endif
/*===========================================================================*/
/* SDC driver related settings. */
/*===========================================================================*/
/**
* @brief Number of initialization attempts before rejecting the card.
* @note Attempts are performed at 10mS intervals.
*/
#if !defined(SDC_INIT_RETRY) || defined(__DOXYGEN__)
#define SDC_INIT_RETRY 100
#endif
/**
* @brief Include support for MMC cards.
* @note MMC support is not yet implemented so this option must be kept
* at @p FALSE.
*/
#if !defined(SDC_MMC_SUPPORT) || defined(__DOXYGEN__)
#define SDC_MMC_SUPPORT FALSE
#endif
/**
* @brief Delays insertions.
* @details If enabled this options inserts delays into the MMC waiting
* routines releasing some extra CPU time for the threads with
* lower priority, this may slow down the driver a bit however.
*/
#if !defined(SDC_NICE_WAITING) || defined(__DOXYGEN__)
#define SDC_NICE_WAITING TRUE
#endif
/*===========================================================================*/
/* SERIAL driver related settings. */
/*===========================================================================*/
/**
* @brief Default bit rate.
* @details Configuration parameter, this is the baud rate selected for the
* default configuration.
*/
#if !defined(SERIAL_DEFAULT_BITRATE) || defined(__DOXYGEN__)
#define SERIAL_DEFAULT_BITRATE 38400
#endif
/**
* @brief Serial buffers size.
* @details Configuration parameter, you can change the depth of the queue
* buffers depending on the requirements of your application.
* @note The default is 16 bytes for both the transmission and receive
* buffers.
*/
#if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__)
#define SERIAL_BUFFERS_SIZE 16
#endif
/*===========================================================================*/
/* SERIAL_USB driver related setting. */
/*===========================================================================*/
/**
* @brief Serial over USB buffers size.
* @details Configuration parameter, the buffer size must be a multiple of
* the USB data endpoint maximum packet size.
* @note The default is 256 bytes for both the transmission and receive
* buffers.
*/
#if !defined(SERIAL_USB_BUFFERS_SIZE) || defined(__DOXYGEN__)
#define SERIAL_USB_BUFFERS_SIZE 256
#endif
/**
* @brief Serial over USB number of buffers.
* @note The default is 2 buffers.
*/
#if !defined(SERIAL_USB_BUFFERS_NUMBER) || defined(__DOXYGEN__)
#define SERIAL_USB_BUFFERS_NUMBER 2
#endif
/*===========================================================================*/
/* SPI driver related settings. */
/*===========================================================================*/
/**
* @brief Enables synchronous APIs.
* @note Disabling this option saves both code and data space.
*/
#if !defined(SPI_USE_WAIT) || defined(__DOXYGEN__)
#define SPI_USE_WAIT TRUE
#endif
/**
* @brief Enables the @p spiAcquireBus() and @p spiReleaseBus() APIs.
* @note Disabling this option saves both code and data space.
*/
#if !defined(SPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
#define SPI_USE_MUTUAL_EXCLUSION TRUE
#endif
/*===========================================================================*/
/* UART driver related settings. */
/*===========================================================================*/
/**
* @brief Enables synchronous APIs.
* @note Disabling this option saves both code and data space.
*/
#if !defined(UART_USE_WAIT) || defined(__DOXYGEN__)
#define UART_USE_WAIT FALSE
#endif
/**
* @brief Enables the @p uartAcquireBus() and @p uartReleaseBus() APIs.
* @note Disabling this option saves both code and data space.
*/
#if !defined(UART_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
#define UART_USE_MUTUAL_EXCLUSION FALSE
#endif
/*===========================================================================*/
/* USB driver related settings. */
/*===========================================================================*/
/**
* @brief Enables synchronous APIs.
* @note Disabling this option saves both code and data space.
*/
#if !defined(USB_USE_WAIT) || defined(__DOXYGEN__)
#define USB_USE_WAIT TRUE
#endif
/**
* @brief Set host wakeup duration.
*/
#if !defined(USB_HOST_WAKEUP_DURATION) || defined(__DOXYGEN__)
#define USB_HOST_WAKEUP_DURATION 15
#endif
#endif /* HALCONF_H */
/** @} */
/*
ChibiOS - Copyright (C) 2006..2016 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
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.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file templates/halconf.h
* @brief HAL configuration header.
* @details HAL configuration file, this file allows to enable or disable the
* various device drivers from your application. You may also use
* this file in order to override the device drivers default settings.
*
* @addtogroup HAL_CONF
* @{
*/
#ifndef HALCONF_H
#define HALCONF_H
#include "mcuconf.h"
/**
* @brief Enables the PAL subsystem.
*/
#if !defined(HAL_USE_PAL) || defined(__DOXYGEN__)
#define HAL_USE_PAL TRUE
#endif
/**
* @brief Enables the ADC subsystem.
*/
#if !defined(HAL_USE_ADC) || defined(__DOXYGEN__)
#define HAL_USE_ADC TRUE
#endif
/**
* @brief Enables the CAN subsystem.
*/
#if !defined(HAL_USE_CAN) || defined(__DOXYGEN__)
#define HAL_USE_CAN FALSE
#endif
/**
* @brief Enables the DAC subsystem.
*/
#if !defined(HAL_USE_DAC) || defined(__DOXYGEN__)
#define HAL_USE_DAC FALSE
#endif
/**
* @brief Enables the EXT subsystem.
*/
#if !defined(HAL_USE_EXT) || defined(__DOXYGEN__)
#define HAL_USE_EXT FALSE
#endif
/**
* @brief Enables the GPT subsystem.
*/
#if !defined(HAL_USE_GPT) || defined(__DOXYGEN__)
#define HAL_USE_GPT FALSE
#endif
/**
* @brief Enables the I2C subsystem.
*/
#if !defined(HAL_USE_I2C) || defined(__DOXYGEN__)
#define HAL_USE_I2C TRUE
#endif
/**
* @brief Enables the I2S subsystem.
*/
#if !defined(HAL_USE_I2S) || defined(__DOXYGEN__)
#define HAL_USE_I2S FALSE
#endif
/**
* @brief Enables the ICU subsystem.
*/
#if !defined(HAL_USE_ICU) || defined(__DOXYGEN__)
#define HAL_USE_ICU TRUE
/* Driver extension to add user fields. */
#define ICU_DRIVER_EXT_FIELDS \
void *link; \
virtual_timer_t cca_timer; \
virtual_timer_t icu_timer; \
virtual_timer_t pwm_timer;
#endif
/**
* @brief Enables the MAC subsystem.
*/
#if !defined(HAL_USE_MAC) || defined(__DOXYGEN__)
#define HAL_USE_MAC FALSE
#endif
/**
* @brief Enables the MMC_SPI subsystem.
*/
#if !defined(HAL_USE_MMC_SPI) || defined(__DOXYGEN__)
#define HAL_USE_MMC_SPI TRUE
#endif
/**
* @brief Enables the PWM subsystem.
*/
#if !defined(HAL_USE_PWM) || defined(__DOXYGEN__)
#define HAL_USE_PWM FALSE
#endif
/**
* @brief Enables the QSPI subsystem.
*/
#if !defined(HAL_USE_QSPI) || defined(__DOXYGEN__)
#define HAL_USE_QSPI FALSE
#endif
/**
* @brief Enables the RTC subsystem.
*/
#if !defined(HAL_USE_RTC) || defined(__DOXYGEN__)
#define HAL_USE_RTC TRUE
#endif
/**
* @brief Enables the SDC subsystem.
*/
#if !defined(HAL_USE_SDC) || defined(__DOXYGEN__)
#define HAL_USE_SDC FALSE
#endif
/**
* @brief Enables the SERIAL subsystem.
*/
#if !defined(HAL_USE_SERIAL) || defined(__DOXYGEN__)
#define HAL_USE_SERIAL TRUE
#endif
/**
* @brief Enables the SERIAL over USB subsystem.
*/
#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__)
#define HAL_USE_SERIAL_USB TRUE
#endif
/**
* @brief Enables the SPI subsystem.
*/
#if !defined(HAL_USE_SPI) || defined(__DOXYGEN__)
#define HAL_USE_SPI TRUE
#endif
/**
* @brief Enables the UART subsystem.
*/
#if !defined(HAL_USE_UART) || defined(__DOXYGEN__)
#define HAL_USE_UART FALSE
#endif
/**
* @brief Enables the USB subsystem.
*/
#if !defined(HAL_USE_USB) || defined(__DOXYGEN__)
#define HAL_USE_USB TRUE
#endif
/**
* @brief Enables the WDG subsystem.
*/
#if !defined(HAL_USE_WDG) || defined(__DOXYGEN__)
#define HAL_USE_WDG TRUE
#endif
/*===========================================================================*/
/* ADC driver related settings. */
/*===========================================================================*/
/**
* @brief Enables synchronous APIs.
* @note Disabling this option saves both code and data space.
*/
#if !defined(ADC_USE_WAIT) || defined(__DOXYGEN__)
#define ADC_USE_WAIT TRUE
#endif
/**
* @brief Enables the @p adcAcquireBus() and @p adcReleaseBus() APIs.
* @note Disabling this option saves both code and data space.
*/
#if !defined(ADC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
#define ADC_USE_MUTUAL_EXCLUSION TRUE
#endif
/*===========================================================================*/
/* CAN driver related settings. */
/*===========================================================================*/
/**
* @brief Sleep mode related APIs inclusion switch.
*/
#if !defined(CAN_USE_SLEEP_MODE) || defined(__DOXYGEN__)
#define CAN_USE_SLEEP_MODE TRUE
#endif
/*===========================================================================*/
/* I2C driver related settings. */
/*===========================================================================*/
/**
* @brief Enables the mutual exclusion APIs on the I2C bus.
*/
#if !defined(I2C_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
#define I2C_USE_MUTUAL_EXCLUSION TRUE
#endif
/*===========================================================================*/
/* MAC driver related settings. */
/*===========================================================================*/
/**
* @brief Enables an event sources for incoming packets.
*/
#if !defined(MAC_USE_ZERO_COPY) || defined(__DOXYGEN__)
#define MAC_USE_ZERO_COPY FALSE
#endif
/**
* @brief Enables an event sources for incoming packets.
*/
#if !defined(MAC_USE_EVENTS) || defined(__DOXYGEN__)
#define MAC_USE_EVENTS TRUE
#endif
/*===========================================================================*/
/* MMC_SPI driver related settings. */
/*===========================================================================*/
/**
* @brief Delays insertions.
* @details If enabled this options inserts delays into the MMC waiting
* routines releasing some extra CPU time for the threads with
* lower priority, this may slow down the driver a bit however.
* This option is recommended also if the SPI driver does not
* use a DMA channel and heavily loads the CPU.
*/
#if !defined(MMC_NICE_WAITING) || defined(__DOXYGEN__)
#define MMC_NICE_WAITING TRUE
#endif
/*===========================================================================*/
/* SDC driver related settings. */
/*===========================================================================*/
/**
* @brief Number of initialization attempts before rejecting the card.
* @note Attempts are performed at 10mS intervals.
*/
#if !defined(SDC_INIT_RETRY) || defined(__DOXYGEN__)
#define SDC_INIT_RETRY 100
#endif
/**
* @brief Include support for MMC cards.
* @note MMC support is not yet implemented so this option must be kept
* at @p FALSE.
*/
#if !defined(SDC_MMC_SUPPORT) || defined(__DOXYGEN__)
#define SDC_MMC_SUPPORT FALSE
#endif
/**
* @brief Delays insertions.
* @details If enabled this options inserts delays into the MMC waiting
* routines releasing some extra CPU time for the threads with
* lower priority, this may slow down the driver a bit however.
*/
#if !defined(SDC_NICE_WAITING) || defined(__DOXYGEN__)
#define SDC_NICE_WAITING TRUE
#endif
/*===========================================================================*/
/* SERIAL driver related settings. */
/*===========================================================================*/
/**
* @brief Default bit rate.
* @details Configuration parameter, this is the baud rate selected for the
* default configuration.
*/
#if !defined(SERIAL_DEFAULT_BITRATE) || defined(__DOXYGEN__)
#define SERIAL_DEFAULT_BITRATE 38400
#endif
/**
* @brief Serial buffers size.
* @details Configuration parameter, you can change the depth of the queue
* buffers depending on the requirements of your application.
* @note The default is 16 bytes for both the transmission and receive
* buffers.
*/
#if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__)
#define SERIAL_BUFFERS_SIZE 16
#endif
/*===========================================================================*/
/* SERIAL_USB driver related setting. */
/*===========================================================================*/
/**
* @brief Serial over USB buffers size.
* @details Configuration parameter, the buffer size must be a multiple of
* the USB data endpoint maximum packet size.
* @note The default is 256 bytes for both the transmission and receive
* buffers.
*/
#if !defined(SERIAL_USB_BUFFERS_SIZE) || defined(__DOXYGEN__)
#define SERIAL_USB_BUFFERS_SIZE 256
#endif
/**
* @brief Serial over USB number of buffers.
* @note The default is 2 buffers.
*/
#if !defined(SERIAL_USB_BUFFERS_NUMBER) || defined(__DOXYGEN__)
#define SERIAL_USB_BUFFERS_NUMBER 2
#endif
/*===========================================================================*/
/* SPI driver related settings. */
/*===========================================================================*/
/**
* @brief Enables synchronous APIs.
* @note Disabling this option saves both code and data space.
*/
#if !defined(SPI_USE_WAIT) || defined(__DOXYGEN__)
#define SPI_USE_WAIT TRUE
#endif
/**
* @brief Enables circular transfers APIs.
* @note Disabling this option saves both code and data space.
*/
#if !defined(SPI_USE_CIRCULAR) || defined(__DOXYGEN__)
#define SPI_USE_CIRCULAR FALSE
#endif
/**
* @brief Enables the @p spiAcquireBus() and @p spiReleaseBus() APIs.
* @note Disabling this option saves both code and data space.
*/
#if !defined(SPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
#define SPI_USE_MUTUAL_EXCLUSION TRUE
#endif
/**
* @brief Handling method for SPI CS line.
* @note Disabling this option saves both code and data space.
*/
#if !defined(SPI_SELECT_MODE) || defined(__DOXYGEN__)
#define SPI_SELECT_MODE SPI_SELECT_MODE_PAD
#endif
/*===========================================================================*/
/* UART driver related settings. */
/*===========================================================================*/
/**
* @brief Enables synchronous APIs.
* @note Disabling this option saves both code and data space.
*/
#if !defined(UART_USE_WAIT) || defined(__DOXYGEN__)
#define UART_USE_WAIT FALSE
#endif
/**
* @brief Enables the @p uartAcquireBus() and @p uartReleaseBus() APIs.
* @note Disabling this option saves both code and data space.
*/
#if !defined(UART_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
#define UART_USE_MUTUAL_EXCLUSION FALSE
#endif
/*===========================================================================*/
/* USB driver related settings. */
/*===========================================================================*/
/**
* @brief Enables synchronous APIs.
* @note Disabling this option saves both code and data space.
*/
#if !defined(USB_USE_WAIT) || defined(__DOXYGEN__)
#define USB_USE_WAIT TRUE
#endif
/**
* @brief Set host wakeup duration.
*/
#if !defined(USB_HOST_WAKEUP_DURATION) || defined(__DOXYGEN__)
#define USB_HOST_WAKEUP_DURATION 15
#endif
#endif /* HALCONF_H */
/** @} */

Wyświetl plik

@ -52,7 +52,7 @@ typedef struct SysProviders {
const radio_config_t radio_list[] = {
{ /* Radio #1 */
.unit = PKT_RADIO_1,
.type = SI4464,
.type = SI446X,
.band = {
(radio_band_t * const)&band_2m,
NULL
@ -111,16 +111,35 @@ void pktConfigSerialDiag(void) {
#endif
}
void pktConfigSerialPkt(void) {
/**
* TODO: Move this into pktradio.c or make it an Si446x function in si446x.c
* The GPIO assignments per radio should be in the radio record.
*/
ioline_t pktSetLineModeICU(const radio_unit_t radio) {
(void)radio;
palSetLineMode(LINE_ICU, PAL_MODE_INPUT | PAL_MODE_ALTERNATE(2));
return LINE_ICU;
}
/**
* TODO: Move this into pktconf.h and use general GPIO to setup.
* TODO: Move this into pktradio.c or make it an Si446x function in si446x.c
* The GPIO assignments per radio should be in the radio record.
*/
void pktSetLineModeICU(void) {
palSetLineMode(LINE_ICU, PAL_MODE_INPUT | PAL_MODE_ALTERNATE(2));
}
/*ioline_t pktSetLineModeRadioGPIO1(const radio_unit_t radio) {
(void)radio;
palSetLineMode(LINE_RADIO_GPIO1, PAL_MODE_INPUT_PULLDOWN);
return LINE_RADIO_GPIO1;
}*/
/**
* TODO: Move this into pktradio.c or make it an Si446x function in si446x.c
* The GPIO assignments per radio should be in the radio record.
*/
/*ioline_t pktSetLineModeRadioGPIO0(const radio_unit_t radio) {
(void)radio;
palSetLineMode(LINE_RADIO_GPIO0, PAL_MODE_INPUT_PULLDOWN);
return LINE_RADIO_GPIO0;
}*/
/*
* Read GPIO that are used for:
@ -136,19 +155,18 @@ uint8_t pktReadIOlines() {
}
void pktSerialStart(void) {
#if ENABLE_EXTERNAL_I2C == FALSE
#if ENABLE_SERIAL_DEBUG == TRUE
pktConfigSerialDiag();
pktConfigSerialPkt();
sdStart(SERIAL_CFG_DEBUG_DRIVER, &debug_config);
#endif
/* Setup diagnostic resource access semaphore. */
extern binary_semaphore_t diag_out_sem;
chBSemObjectInit(&diag_out_sem, false);
extern binary_semaphore_t debug_out_sem;
chBSemObjectInit(&debug_out_sem, false);
}
void dbgWrite(uint8_t level, uint8_t *buf, uint32_t len) {
(void)level;
#if ENABLE_EXTERNAL_I2C == FALSE
#if ENABLE_SERIAL_DEBUG == TRUE
chnWrite((BaseSequentialStream*)SERIAL_CFG_DEBUG_DRIVER, buf, len);
#else
(void)buf;
@ -158,7 +176,7 @@ void dbgWrite(uint8_t level, uint8_t *buf, uint32_t len) {
int dbgPrintf(uint8_t level, const char *format, ...) {
(void)level;
#if ENABLE_EXTERNAL_I2C == FALSE
#if ENABLE_SERIAL_DEBUG == TRUE
va_list arg;
int done;
@ -174,7 +192,12 @@ int dbgPrintf(uint8_t level, const char *format, ...) {
}
void pktWrite(uint8_t *buf, uint32_t len) {
#if ENABLE_SERIAL_DEBUG == TRUE
chnWrite((BaseSequentialStream*)SERIAL_CFG_DEBUG_DRIVER, buf, len);
#else
(void)buf;
(void)len;
#endif
}
void pktConfigureCoreIO(void) {
@ -194,9 +217,6 @@ void pktConfigureCoreIO(void) {
| PAL_STM32_OSPEED_HIGHEST
| PAL_STM32_OTYPE_OPENDRAIN); // SCL
#if ACTIVATE_USB
startUSB();
#endif
}
/** @} */

Wyświetl plik

@ -17,11 +17,8 @@
* 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
//#define USE_SPI_ATTACHED_RADIO TRUE
/*
* TODO: Need to use radio unit ID to set assigned GPIO & SPI.
@ -63,11 +60,6 @@
#define LINE_USB_DM PAL_LINE(GPIOA, 11U)
#define LINE_USB_DP PAL_LINE(GPIOA, 12U)
// IO
#define LINE_GPIO_PIN PAL_LINE(GPIOA, 8U)
#define LINE_IO_TXD PAL_LINE(GPIOB, 10U)
#define LINE_IO_RXD PAL_LINE(GPIOC, 11U)
// LED
#define LINE_IO_BLUE PAL_LINE(GPIOC, 1U)
#define LINE_IO_GREEN PAL_LINE(GPIOC, 3U)
@ -83,6 +75,11 @@
#define LINE_GPS_RXD PAL_LINE(GPIOB, 12U)
#define LINE_GPS_TIMEPULSE PAL_LINE(GPIOB, 15U)
// IO
#define LINE_GPIO_PIN PAL_LINE(GPIOA, 8U)
#define LINE_IO_TXD PAL_LINE(GPIOB, 10U)
#define LINE_IO_RXD PAL_LINE(GPIOC, 11U)
// APRS IO lines
#define LINE_IO1 LINE_GPIO_PIN
#define LINE_IO2 LINE_IO_TXD
@ -93,7 +90,7 @@
#define LINE_IO7 PAL_NOLINE
#define LINE_IO8 PAL_NOLINE
// Hardware dependent settings
/* 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 */
@ -107,6 +104,7 @@
#define LINE_RADIO_GPIO0 PAL_LINE(GPIOB, 7U)
#define LINE_RADIO_GPIO1 PAL_LINE(GPIOB, 6U)
// SPI
#define LINE_SPI_SCK PAL_LINE(GPIOB, 3U)
#define LINE_SPI_MISO PAL_LINE(GPIOB, 4U)
#define LINE_SPI_MOSI PAL_LINE(GPIOB, 5U)
@ -149,17 +147,26 @@
/* The external port can be used for bit bang I2C. */
#define ENABLE_EXTERNAL_I2C TRUE
#if ENABLE_EXTERNAL_I2C == FALSE
#define EI2C_SCL LINE_IO_TXD /* SCL */
#define EI2C_SDA LINE_IO_RXD /* SDA */
/* To use IO_TXD/IO_RXD for UART debug channel. */
#define ENABLE_SERIAL_DEBUG FALSE
#if ENABLE_EXTERNAL_I2C == TRUE && ENABLE_SERIAL_DEBUG == TRUE
#error "Cannot enable serial debug and external I2C together"
#elif ENABLE_EXTERNAL_I2C == FALSE && ENABLE_SERIAL_DEBUG == TRUE
#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.
/* If set to true, the console using 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.
* USB needs 48MHz speed to operate.
*/
#define ACTIVATE_USB TRUE
#define ACTIVATE_CONSOLE TRUE
/**
* ICU related definitions.
@ -196,22 +203,22 @@
/* Definitions for ICU FIFO implemented using chfactory. */
#if USE_HEAP_PWM_BUFFER == TRUE
/* Use factory FIFO as stream control with separate chained PWM buffers. */
#define NUMBER_PWM_FIFOS 3U
#define NUMBER_PWM_FIFOS 5U
/* Number of PWM data entries per queue object. */
#define PWM_DATA_SLOTS 200
/* Number of PWM queue objects in total. */
#define PWM_DATA_BUFFERS 30
#else
#else /* USE_HEAP_PWM_BUFFER != TRUE */
/* Use factory FIFO as stream control with integrated PWM buffer. */
#define NUMBER_PWM_FIFOS 3U
#define PWM_DATA_SLOTS 6000
#endif
#endif /* USE_HEAP_PWM_BUFFER == TRUE */
/* Number of frame receive buffers. */
#define NUMBER_RX_PKT_BUFFERS 3U
#define USE_CCM_HEAP_RX_BUFFERS TRUE
#define NUMBER_RX_PKT_BUFFERS 3U
#define USE_CCM_HEAP_RX_BUFFERS TRUE
#define PKT_RX_RLS_USE_NO_FIFO TRUE
#define PKT_RX_RLS_USE_NO_FIFO TRUE
/*
* Number of general AX25/APRS processing & frame send buffers.
@ -239,13 +246,6 @@
/* 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 radioConfig {
radio_unit_t unit;
radio_type_t type;
@ -266,13 +266,15 @@ extern "C" {
void pktConfigSerialDiag(void);
void pktConfigSerialPkt(void);
void pktConfigureCoreIO(void);
void pktSetLineModeICU(void);
ioline_t pktSetLineModeICU(const radio_unit_t radio);
ioline_t pktSetLineModeRadioGPIO1(const radio_unit_t radio);
ioline_t pktSetLineModeRadioGPIO0(const radio_unit_t radio);
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);
//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);
uint8_t pktGetNumRadios(void);
@ -285,6 +287,7 @@ extern "C" {
/* Module inline functions. */
/*===========================================================================*/
#endif /* PORTAB_H_ */
/** @} */

Wyświetl plik

@ -18,14 +18,14 @@
#define _BOARD_H_
/*
* Setup for Pecan Pico 10a board.
* Setup for Pecan Pico 10b board.
*/
/*
* Board identifier.
*/
#define BOARD_PECANPICO10A
#define BOARD_NAME "Pecan Pico 10a"
#define BOARD_PECANPICO10B
#define BOARD_NAME "Pecan Pico 10b"
/*
* No LSE available
@ -243,116 +243,9 @@
* IO lines assignments.
*/
// IO
/*
#define LINE_GPIO_PIN1 PAL_LINE(GPIOA, 8U)
#define LINE_GPIO_PIN2 PAL_LINE(GPIOC, 15U)
#define LINE_IO_TXD PAL_LINE(GPIOB, 10U)
#define LINE_IO_RXD PAL_LINE(GPIOC, 11U)
*/
//APRS IO lines
/*
#define LINE_IO1 LINE_GPIO_PIN1
#define LINE_IO2 LINE_IO_TXD
#define LINE_IO3 LINE_IO_RXD
#define LINE_IO4 LINE_GPIO_PIN2
#define LINE_IO5 PAL_NOLINE
#define LINE_IO6 PAL_NOLINE
#define LINE_IO7 PAL_NOLINE
#define LINE_IO8 PAL_NOLINE
*/
// LED
/*
#define LINE_IO_BLUE PAL_LINE(GPIOC, 1U)
#define LINE_IO_GREEN PAL_LINE(GPIOC, 3U)
*/
// GPS
/*
#define LINE_GPS_EN PAL_LINE(GPIOC, 5U)
#define LINE_GPS_RESET PAL_LINE(GPIOA, 15U)
#define LINE_GPS_TXD PAL_LINE(GPIOB, 13U)
#define LINE_GPS_RXD PAL_LINE(GPIOB, 12U)
#define LINE_GPS_TIMEPULSE PAL_LINE(GPIOB, 15U)
*/
// I2C
/*
#define LINE_I2C_SCL PAL_LINE(GPIOB, 8U)
#define LINE_I2C_SDA PAL_LINE(GPIOB, 9U)
*/
// SPI
/*
#define LINE_SPI_SCK PAL_LINE(GPIOB, 3U)
#define LINE_SPI_MISO PAL_LINE(GPIOB, 4U)
#define LINE_SPI_MOSI PAL_LINE(GPIOB, 5U)
*/
// Camera pins
/*
#define LINE_CAM_XCLK PAL_LINE(GPIOC, 9U)
#define LINE_CAM_PCLK PAL_LINE(GPIOC, 6U)
#define LINE_CAM_VSYNC PAL_LINE(GPIOB, 14U)
#define LINE_CAM_D2 PAL_LINE(GPIOA, 0U)
#define LINE_CAM_D3 PAL_LINE(GPIOA, 1U)
#define LINE_CAM_D4 PAL_LINE(GPIOA, 2U)
#define LINE_CAM_D5 PAL_LINE(GPIOA, 3U)
#define LINE_CAM_D6 PAL_LINE(GPIOA, 4U)
#define LINE_CAM_D7 PAL_LINE(GPIOA, 5U)
#define LINE_CAM_D8 PAL_LINE(GPIOA, 6U)
#define LINE_CAM_D9 PAL_LINE(GPIOA, 7U)
#define LINE_CAM_EN PAL_LINE(GPIOC, 7U)
#define LINE_CAM_RESET PAL_LINE(GPIOB, 0U)
*/
// Radio pins
/*
#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)
*/
// SD Card pins
/*
#define LINE_SD_CS PAL_LINE(GPIOC, 0U)
#define LINE_SD_DET PAL_LINE(GPIOC, 8U)
*/
// ADC
/*
#define LINE_ADC_VSOL PAL_LINE(GPIOC, 2U)
#define LINE_ADC_VBAT PAL_LINE(GPIOB, 1U)
#define LINE_ADC_VUSB PAL_LINE(GPIOC, 4U)
*/
// USB
/*
#define LINE_USB_ID PAL_LINE(GPIOA, 10U)
#define LINE_USB_VBUS PAL_LINE(GPIOA, 9U)
#define LINE_USB_DM PAL_LINE(GPIOA, 11U)
#define LINE_USB_DP PAL_LINE(GPIOA, 12U)
*/
// Misc
/* For enabling TCXO. Done in early_init. */
#define LINE_TCXO_EN PAL_LINE(GPIOC, 13U)
// Hardware dependent settings
//#define Si446x_MIN_FREQ 144000000 /* Minimum allowed frequency in Hz */
//#define Si446x_MAX_FREQ 148000000 /* Maximum allowed frequency in Hz */
//#define Si446x_BASE_FREQ Si446x_MIN_FREQ
//#define Si446x_STEP_HZ 12500
//#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 */
/*
* I/O ports initial setup, this configuration is established soon after reset
* in the initialization code.

Wyświetl plik

@ -1,394 +1,411 @@
/*
ChibiOS - Copyright (C) 2006..2016 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
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.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file templates/halconf.h
* @brief HAL configuration header.
* @details HAL configuration file, this file allows to enable or disable the
* various device drivers from your application. You may also use
* this file in order to override the device drivers default settings.
*
* @addtogroup HAL_CONF
* @{
*/
#ifndef HALCONF_H
#define HALCONF_H
#include "mcuconf.h"
/**
* @brief Enables the PAL subsystem.
*/
#if !defined(HAL_USE_PAL) || defined(__DOXYGEN__)
#define HAL_USE_PAL TRUE
#endif
/**
* @brief Enables the ADC subsystem.
*/
#if !defined(HAL_USE_ADC) || defined(__DOXYGEN__)
#define HAL_USE_ADC TRUE
#endif
/**
* @brief Enables the CAN subsystem.
*/
#if !defined(HAL_USE_CAN) || defined(__DOXYGEN__)
#define HAL_USE_CAN FALSE
#endif
/**
* @brief Enables the DAC subsystem.
*/
#if !defined(HAL_USE_DAC) || defined(__DOXYGEN__)
#define HAL_USE_DAC FALSE
#endif
/**
* @brief Enables the EXT subsystem.
*/
#if !defined(HAL_USE_EXT) || defined(__DOXYGEN__)
#define HAL_USE_EXT FALSE
#endif
/**
* @brief Enables the GPT subsystem.
*/
#if !defined(HAL_USE_GPT) || defined(__DOXYGEN__)
#define HAL_USE_GPT FALSE
#endif
/**
* @brief Enables the I2C subsystem.
*/
#if !defined(HAL_USE_I2C) || defined(__DOXYGEN__)
#define HAL_USE_I2C TRUE
#endif
/**
* @brief Enables the I2S subsystem.
*/
#if !defined(HAL_USE_I2S) || defined(__DOXYGEN__)
#define HAL_USE_I2S FALSE
#endif
/**
* @brief Enables the ICU subsystem.
*/
#if !defined(HAL_USE_ICU) || defined(__DOXYGEN__)
#define HAL_USE_ICU TRUE
/* Driver extension to add user fields. */
#define ICU_DRIVER_EXT_FIELDS \
void *link; \
virtual_timer_t cca_timer; \
virtual_timer_t icu_timer; \
virtual_timer_t pwm_timer;
#endif
/**
* @brief Enables the MAC subsystem.
*/
#if !defined(HAL_USE_MAC) || defined(__DOXYGEN__)
#define HAL_USE_MAC FALSE
#endif
/**
* @brief Enables the MMC_SPI subsystem.
*/
#if !defined(HAL_USE_MMC_SPI) || defined(__DOXYGEN__)
#define HAL_USE_MMC_SPI TRUE
#endif
/**
* @brief Enables the PWM subsystem.
*/
#if !defined(HAL_USE_PWM) || defined(__DOXYGEN__)
#define HAL_USE_PWM FALSE
#endif
/**
* @brief Enables the QSPI subsystem.
*/
#if !defined(HAL_USE_QSPI) || defined(__DOXYGEN__)
#define HAL_USE_QSPI FALSE
#endif
/**
* @brief Enables the RTC subsystem.
*/
#if !defined(HAL_USE_RTC) || defined(__DOXYGEN__)
#define HAL_USE_RTC TRUE
#endif
/**
* @brief Enables the SDC subsystem.
*/
#if !defined(HAL_USE_SDC) || defined(__DOXYGEN__)
#define HAL_USE_SDC FALSE
#endif
/**
* @brief Enables the SERIAL subsystem.
*/
#if !defined(HAL_USE_SERIAL) || defined(__DOXYGEN__)
#define HAL_USE_SERIAL TRUE
#endif
/**
* @brief Enables the SERIAL over USB subsystem.
*/
#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__)
#define HAL_USE_SERIAL_USB TRUE
#endif
/**
* @brief Enables the SPI subsystem.
*/
#if !defined(HAL_USE_SPI) || defined(__DOXYGEN__)
#define HAL_USE_SPI TRUE
#endif
/**
* @brief Enables the UART subsystem.
*/
#if !defined(HAL_USE_UART) || defined(__DOXYGEN__)
#define HAL_USE_UART FALSE
#endif
/**
* @brief Enables the USB subsystem.
*/
#if !defined(HAL_USE_USB) || defined(__DOXYGEN__)
#define HAL_USE_USB TRUE
#endif
/**
* @brief Enables the WDG subsystem.
*/
#if !defined(HAL_USE_WDG) || defined(__DOXYGEN__)
#define HAL_USE_WDG TRUE
#endif
/*===========================================================================*/
/* ADC driver related settings. */
/*===========================================================================*/
/**
* @brief Enables synchronous APIs.
* @note Disabling this option saves both code and data space.
*/
#if !defined(ADC_USE_WAIT) || defined(__DOXYGEN__)
#define ADC_USE_WAIT TRUE
#endif
/**
* @brief Enables the @p adcAcquireBus() and @p adcReleaseBus() APIs.
* @note Disabling this option saves both code and data space.
*/
#if !defined(ADC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
#define ADC_USE_MUTUAL_EXCLUSION TRUE
#endif
/*===========================================================================*/
/* CAN driver related settings. */
/*===========================================================================*/
/**
* @brief Sleep mode related APIs inclusion switch.
*/
#if !defined(CAN_USE_SLEEP_MODE) || defined(__DOXYGEN__)
#define CAN_USE_SLEEP_MODE TRUE
#endif
/*===========================================================================*/
/* I2C driver related settings. */
/*===========================================================================*/
/**
* @brief Enables the mutual exclusion APIs on the I2C bus.
*/
#if !defined(I2C_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
#define I2C_USE_MUTUAL_EXCLUSION TRUE
#endif
/*===========================================================================*/
/* MAC driver related settings. */
/*===========================================================================*/
/**
* @brief Enables an event sources for incoming packets.
*/
#if !defined(MAC_USE_ZERO_COPY) || defined(__DOXYGEN__)
#define MAC_USE_ZERO_COPY FALSE
#endif
/**
* @brief Enables an event sources for incoming packets.
*/
#if !defined(MAC_USE_EVENTS) || defined(__DOXYGEN__)
#define MAC_USE_EVENTS TRUE
#endif
/*===========================================================================*/
/* MMC_SPI driver related settings. */
/*===========================================================================*/
/**
* @brief Delays insertions.
* @details If enabled this options inserts delays into the MMC waiting
* routines releasing some extra CPU time for the threads with
* lower priority, this may slow down the driver a bit however.
* This option is recommended also if the SPI driver does not
* use a DMA channel and heavily loads the CPU.
*/
#if !defined(MMC_NICE_WAITING) || defined(__DOXYGEN__)
#define MMC_NICE_WAITING TRUE
#endif
/*===========================================================================*/
/* SDC driver related settings. */
/*===========================================================================*/
/**
* @brief Number of initialization attempts before rejecting the card.
* @note Attempts are performed at 10mS intervals.
*/
#if !defined(SDC_INIT_RETRY) || defined(__DOXYGEN__)
#define SDC_INIT_RETRY 100
#endif
/**
* @brief Include support for MMC cards.
* @note MMC support is not yet implemented so this option must be kept
* at @p FALSE.
*/
#if !defined(SDC_MMC_SUPPORT) || defined(__DOXYGEN__)
#define SDC_MMC_SUPPORT FALSE
#endif
/**
* @brief Delays insertions.
* @details If enabled this options inserts delays into the MMC waiting
* routines releasing some extra CPU time for the threads with
* lower priority, this may slow down the driver a bit however.
*/
#if !defined(SDC_NICE_WAITING) || defined(__DOXYGEN__)
#define SDC_NICE_WAITING TRUE
#endif
/*===========================================================================*/
/* SERIAL driver related settings. */
/*===========================================================================*/
/**
* @brief Default bit rate.
* @details Configuration parameter, this is the baud rate selected for the
* default configuration.
*/
#if !defined(SERIAL_DEFAULT_BITRATE) || defined(__DOXYGEN__)
#define SERIAL_DEFAULT_BITRATE 38400
#endif
/**
* @brief Serial buffers size.
* @details Configuration parameter, you can change the depth of the queue
* buffers depending on the requirements of your application.
* @note The default is 16 bytes for both the transmission and receive
* buffers.
*/
#if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__)
#define SERIAL_BUFFERS_SIZE 16
#endif
/*===========================================================================*/
/* SERIAL_USB driver related setting. */
/*===========================================================================*/
/**
* @brief Serial over USB buffers size.
* @details Configuration parameter, the buffer size must be a multiple of
* the USB data endpoint maximum packet size.
* @note The default is 256 bytes for both the transmission and receive
* buffers.
*/
#if !defined(SERIAL_USB_BUFFERS_SIZE) || defined(__DOXYGEN__)
#define SERIAL_USB_BUFFERS_SIZE 256
#endif
/**
* @brief Serial over USB number of buffers.
* @note The default is 2 buffers.
*/
#if !defined(SERIAL_USB_BUFFERS_NUMBER) || defined(__DOXYGEN__)
#define SERIAL_USB_BUFFERS_NUMBER 2
#endif
/*===========================================================================*/
/* SPI driver related settings. */
/*===========================================================================*/
/**
* @brief Enables synchronous APIs.
* @note Disabling this option saves both code and data space.
*/
#if !defined(SPI_USE_WAIT) || defined(__DOXYGEN__)
#define SPI_USE_WAIT TRUE
#endif
/**
* @brief Enables the @p spiAcquireBus() and @p spiReleaseBus() APIs.
* @note Disabling this option saves both code and data space.
*/
#if !defined(SPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
#define SPI_USE_MUTUAL_EXCLUSION TRUE
#endif
/*===========================================================================*/
/* UART driver related settings. */
/*===========================================================================*/
/**
* @brief Enables synchronous APIs.
* @note Disabling this option saves both code and data space.
*/
#if !defined(UART_USE_WAIT) || defined(__DOXYGEN__)
#define UART_USE_WAIT FALSE
#endif
/**
* @brief Enables the @p uartAcquireBus() and @p uartReleaseBus() APIs.
* @note Disabling this option saves both code and data space.
*/
#if !defined(UART_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
#define UART_USE_MUTUAL_EXCLUSION FALSE
#endif
/*===========================================================================*/
/* USB driver related settings. */
/*===========================================================================*/
/**
* @brief Enables synchronous APIs.
* @note Disabling this option saves both code and data space.
*/
#if !defined(USB_USE_WAIT) || defined(__DOXYGEN__)
#define USB_USE_WAIT FALSE
#endif
#endif /* HALCONF_H */
/** @} */
/*
ChibiOS - Copyright (C) 2006..2016 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
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.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file templates/halconf.h
* @brief HAL configuration header.
* @details HAL configuration file, this file allows to enable or disable the
* various device drivers from your application. You may also use
* this file in order to override the device drivers default settings.
*
* @addtogroup HAL_CONF
* @{
*/
#ifndef HALCONF_H
#define HALCONF_H
#include "mcuconf.h"
/**
* @brief Enables the PAL subsystem.
*/
#if !defined(HAL_USE_PAL) || defined(__DOXYGEN__)
#define HAL_USE_PAL TRUE
#endif
/**
* @brief Enables the ADC subsystem.
*/
#if !defined(HAL_USE_ADC) || defined(__DOXYGEN__)
#define HAL_USE_ADC TRUE
#endif
/**
* @brief Enables the CAN subsystem.
*/
#if !defined(HAL_USE_CAN) || defined(__DOXYGEN__)
#define HAL_USE_CAN FALSE
#endif
/**
* @brief Enables the DAC subsystem.
*/
#if !defined(HAL_USE_DAC) || defined(__DOXYGEN__)
#define HAL_USE_DAC FALSE
#endif
/**
* @brief Enables the EXT subsystem.
*/
#if !defined(HAL_USE_EXT) || defined(__DOXYGEN__)
#define HAL_USE_EXT FALSE
#endif
/**
* @brief Enables the GPT subsystem.
*/
#if !defined(HAL_USE_GPT) || defined(__DOXYGEN__)
#define HAL_USE_GPT FALSE
#endif
/**
* @brief Enables the I2C subsystem.
*/
#if !defined(HAL_USE_I2C) || defined(__DOXYGEN__)
#define HAL_USE_I2C TRUE
#endif
/**
* @brief Enables the I2S subsystem.
*/
#if !defined(HAL_USE_I2S) || defined(__DOXYGEN__)
#define HAL_USE_I2S FALSE
#endif
/**
* @brief Enables the ICU subsystem.
*/
#if !defined(HAL_USE_ICU) || defined(__DOXYGEN__)
#define HAL_USE_ICU TRUE
/* Driver extension to add user fields. */
#define ICU_DRIVER_EXT_FIELDS \
void *link; \
virtual_timer_t cca_timer; \
virtual_timer_t icu_timer; \
virtual_timer_t pwm_timer;
#endif
/**
* @brief Enables the MAC subsystem.
*/
#if !defined(HAL_USE_MAC) || defined(__DOXYGEN__)
#define HAL_USE_MAC FALSE
#endif
/**
* @brief Enables the MMC_SPI subsystem.
*/
#if !defined(HAL_USE_MMC_SPI) || defined(__DOXYGEN__)
#define HAL_USE_MMC_SPI TRUE
#endif
/**
* @brief Enables the PWM subsystem.
*/
#if !defined(HAL_USE_PWM) || defined(__DOXYGEN__)
#define HAL_USE_PWM FALSE
#endif
/**
* @brief Enables the QSPI subsystem.
*/
#if !defined(HAL_USE_QSPI) || defined(__DOXYGEN__)
#define HAL_USE_QSPI FALSE
#endif
/**
* @brief Enables the RTC subsystem.
*/
#if !defined(HAL_USE_RTC) || defined(__DOXYGEN__)
#define HAL_USE_RTC TRUE
#endif
/**
* @brief Enables the SDC subsystem.
*/
#if !defined(HAL_USE_SDC) || defined(__DOXYGEN__)
#define HAL_USE_SDC FALSE
#endif
/**
* @brief Enables the SERIAL subsystem.
*/
#if !defined(HAL_USE_SERIAL) || defined(__DOXYGEN__)
#define HAL_USE_SERIAL TRUE
#endif
/**
* @brief Enables the SERIAL over USB subsystem.
*/
#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__)
#define HAL_USE_SERIAL_USB TRUE
#endif
/**
* @brief Enables the SPI subsystem.
*/
#if !defined(HAL_USE_SPI) || defined(__DOXYGEN__)
#define HAL_USE_SPI TRUE
#endif
/**
* @brief Enables the UART subsystem.
*/
#if !defined(HAL_USE_UART) || defined(__DOXYGEN__)
#define HAL_USE_UART FALSE
#endif
/**
* @brief Enables the USB subsystem.
*/
#if !defined(HAL_USE_USB) || defined(__DOXYGEN__)
#define HAL_USE_USB TRUE
#endif
/**
* @brief Enables the WDG subsystem.
*/
#if !defined(HAL_USE_WDG) || defined(__DOXYGEN__)
#define HAL_USE_WDG TRUE
#endif
/*===========================================================================*/
/* ADC driver related settings. */
/*===========================================================================*/
/**
* @brief Enables synchronous APIs.
* @note Disabling this option saves both code and data space.
*/
#if !defined(ADC_USE_WAIT) || defined(__DOXYGEN__)
#define ADC_USE_WAIT TRUE
#endif
/**
* @brief Enables the @p adcAcquireBus() and @p adcReleaseBus() APIs.
* @note Disabling this option saves both code and data space.
*/
#if !defined(ADC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
#define ADC_USE_MUTUAL_EXCLUSION TRUE
#endif
/*===========================================================================*/
/* CAN driver related settings. */
/*===========================================================================*/
/**
* @brief Sleep mode related APIs inclusion switch.
*/
#if !defined(CAN_USE_SLEEP_MODE) || defined(__DOXYGEN__)
#define CAN_USE_SLEEP_MODE TRUE
#endif
/*===========================================================================*/
/* I2C driver related settings. */
/*===========================================================================*/
/**
* @brief Enables the mutual exclusion APIs on the I2C bus.
*/
#if !defined(I2C_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
#define I2C_USE_MUTUAL_EXCLUSION TRUE
#endif
/*===========================================================================*/
/* MAC driver related settings. */
/*===========================================================================*/
/**
* @brief Enables an event sources for incoming packets.
*/
#if !defined(MAC_USE_ZERO_COPY) || defined(__DOXYGEN__)
#define MAC_USE_ZERO_COPY FALSE
#endif
/**
* @brief Enables an event sources for incoming packets.
*/
#if !defined(MAC_USE_EVENTS) || defined(__DOXYGEN__)
#define MAC_USE_EVENTS TRUE
#endif
/*===========================================================================*/
/* MMC_SPI driver related settings. */
/*===========================================================================*/
/**
* @brief Delays insertions.
* @details If enabled this options inserts delays into the MMC waiting
* routines releasing some extra CPU time for the threads with
* lower priority, this may slow down the driver a bit however.
* This option is recommended also if the SPI driver does not
* use a DMA channel and heavily loads the CPU.
*/
#if !defined(MMC_NICE_WAITING) || defined(__DOXYGEN__)
#define MMC_NICE_WAITING TRUE
#endif
/*===========================================================================*/
/* SDC driver related settings. */
/*===========================================================================*/
/**
* @brief Number of initialization attempts before rejecting the card.
* @note Attempts are performed at 10mS intervals.
*/
#if !defined(SDC_INIT_RETRY) || defined(__DOXYGEN__)
#define SDC_INIT_RETRY 100
#endif
/**
* @brief Include support for MMC cards.
* @note MMC support is not yet implemented so this option must be kept
* at @p FALSE.
*/
#if !defined(SDC_MMC_SUPPORT) || defined(__DOXYGEN__)
#define SDC_MMC_SUPPORT FALSE
#endif
/**
* @brief Delays insertions.
* @details If enabled this options inserts delays into the MMC waiting
* routines releasing some extra CPU time for the threads with
* lower priority, this may slow down the driver a bit however.
*/
#if !defined(SDC_NICE_WAITING) || defined(__DOXYGEN__)
#define SDC_NICE_WAITING TRUE
#endif
/*===========================================================================*/
/* SERIAL driver related settings. */
/*===========================================================================*/
/**
* @brief Default bit rate.
* @details Configuration parameter, this is the baud rate selected for the
* default configuration.
*/
#if !defined(SERIAL_DEFAULT_BITRATE) || defined(__DOXYGEN__)
#define SERIAL_DEFAULT_BITRATE 38400
#endif
/**
* @brief Serial buffers size.
* @details Configuration parameter, you can change the depth of the queue
* buffers depending on the requirements of your application.
* @note The default is 16 bytes for both the transmission and receive
* buffers.
*/
#if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__)
#define SERIAL_BUFFERS_SIZE 16
#endif
/*===========================================================================*/
/* SERIAL_USB driver related setting. */
/*===========================================================================*/
/**
* @brief Serial over USB buffers size.
* @details Configuration parameter, the buffer size must be a multiple of
* the USB data endpoint maximum packet size.
* @note The default is 256 bytes for both the transmission and receive
* buffers.
*/
#if !defined(SERIAL_USB_BUFFERS_SIZE) || defined(__DOXYGEN__)
#define SERIAL_USB_BUFFERS_SIZE 256
#endif
/**
* @brief Serial over USB number of buffers.
* @note The default is 2 buffers.
*/
#if !defined(SERIAL_USB_BUFFERS_NUMBER) || defined(__DOXYGEN__)
#define SERIAL_USB_BUFFERS_NUMBER 2
#endif
/*===========================================================================*/
/* SPI driver related settings. */
/*===========================================================================*/
/**
* @brief Enables synchronous APIs.
* @note Disabling this option saves both code and data space.
*/
#if !defined(SPI_USE_WAIT) || defined(__DOXYGEN__)
#define SPI_USE_WAIT TRUE
#endif
/**
* @brief Enables circular transfers APIs.
* @note Disabling this option saves both code and data space.
*/
#if !defined(SPI_USE_CIRCULAR) || defined(__DOXYGEN__)
#define SPI_USE_CIRCULAR FALSE
#endif
/**
* @brief Enables the @p spiAcquireBus() and @p spiReleaseBus() APIs.
* @note Disabling this option saves both code and data space.
*/
#if !defined(SPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
#define SPI_USE_MUTUAL_EXCLUSION TRUE
#endif
/**
* @brief Handling method for SPI CS line.
* @note Disabling this option saves both code and data space.
*/
#if !defined(SPI_SELECT_MODE) || defined(__DOXYGEN__)
#define SPI_SELECT_MODE SPI_SELECT_MODE_PAD
#endif
/*===========================================================================*/
/* UART driver related settings. */
/*===========================================================================*/
/**
* @brief Enables synchronous APIs.
* @note Disabling this option saves both code and data space.
*/
#if !defined(UART_USE_WAIT) || defined(__DOXYGEN__)
#define UART_USE_WAIT FALSE
#endif
/**
* @brief Enables the @p uartAcquireBus() and @p uartReleaseBus() APIs.
* @note Disabling this option saves both code and data space.
*/
#if !defined(UART_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
#define UART_USE_MUTUAL_EXCLUSION FALSE
#endif
/*===========================================================================*/
/* USB driver related settings. */
/*===========================================================================*/
/**
* @brief Enables synchronous APIs.
* @note Disabling this option saves both code and data space.
*/
#if !defined(USB_USE_WAIT) || defined(__DOXYGEN__)
#define USB_USE_WAIT FALSE
#endif
#endif /* HALCONF_H */
/** @} */

Wyświetl plik

@ -52,7 +52,7 @@ typedef struct SysProviders {
const radio_config_t radio_list[] = {
{ /* Radio #1 */
.unit = PKT_RADIO_1,
.type = SI4464,
.type = SI446X,
.band = {
(radio_band_t * const)&band_2m,
NULL
@ -109,16 +109,35 @@ void pktConfigSerialDiag(void) {
palSetLineMode(LINE_USART3_RX, PAL_MODE_ALTERNATE(7));
}
void pktConfigSerialPkt(void) {
/**
* TODO: Move this into pktradio.c or make it an Si446x function in si446x.c
* The GPIO assignments per radio should be in the radio record.
*/
ioline_t pktSetLineModeICU(const radio_unit_t radio) {
(void)radio;
palSetLineMode(LINE_ICU, PAL_MODE_INPUT | PAL_MODE_ALTERNATE(2));
return LINE_ICU;
}
/**
* TODO: Move this into pktconf.h and use general GPIO to setup.
* TODO: Move this into pktradio.c or make it an Si446x function in si446x.c
* The GPIO assignments per radio should be in the radio record.
*/
void pktSetLineModeICU(void) {
palSetLineMode(LINE_ICU, PAL_MODE_INPUT | PAL_MODE_ALTERNATE(2));
}
/*ioline_t pktSetLineModeRadioGPIO1(const radio_unit_t radio) {
(void)radio;
palSetLineMode(LINE_RADIO_GPIO1, PAL_MODE_INPUT_PULLDOWN);
return LINE_RADIO_GPIO1;
}*/
/**
* TODO: Move this into pktradio.c or make it an Si446x function in si446x.c
* The GPIO assignments per radio should be in the radio record.
*/
/*ioline_t pktSetLineModeRadioGPIO0(const radio_unit_t radio) {
(void)radio;
palSetLineMode(LINE_RADIO_GPIO0, PAL_MODE_INPUT_PULLDOWN);
return LINE_RADIO_GPIO0;
}*/
/*
* Read GPIO that are used for:
@ -135,19 +154,19 @@ uint8_t pktReadIOlines() {
}
void pktSerialStart(void) {
#if ENABLE_EXTERNAL_I2C == FALSE
#if ENABLE_SERIAL_DEBUG == TRUE
pktConfigSerialDiag();
pktConfigSerialPkt();
//pktConfigSerialPkt();
sdStart(SERIAL_CFG_DEBUG_DRIVER, &debug_config);
#endif
/* Setup diagnostic resource access semaphore. */
extern binary_semaphore_t diag_out_sem;
chBSemObjectInit(&diag_out_sem, false);
extern binary_semaphore_t debug_out_sem;
chBSemObjectInit(&debug_out_sem, false);
}
void dbgWrite(uint8_t level, uint8_t *buf, uint32_t len) {
(void)level;
#if ENABLE_EXTERNAL_I2C == FALSE
#if ENABLE_SERIAL_DEBUG == TRUE
chnWrite((BaseSequentialStream*)SERIAL_CFG_DEBUG_DRIVER, buf, len);
#else
(void)buf;
@ -157,7 +176,7 @@ void dbgWrite(uint8_t level, uint8_t *buf, uint32_t len) {
int dbgPrintf(uint8_t level, const char *format, ...) {
(void)level;
#if ENABLE_EXTERNAL_I2C == FALSE
#if ENABLE_SERIAL_DEBUG == TRUE
va_list arg;
int done;
@ -173,7 +192,12 @@ int dbgPrintf(uint8_t level, const char *format, ...) {
}
void pktWrite(uint8_t *buf, uint32_t len) {
#if ENABLE_SERIAL_DEBUG == TRUE
chnWrite((BaseSequentialStream*)SERIAL_CFG_DEBUG_DRIVER, buf, len);
#else
(void)buf;
(void)len;
#endif
}
void pktConfigureCoreIO(void) {
@ -193,9 +217,6 @@ void pktConfigureCoreIO(void) {
| PAL_STM32_OSPEED_HIGHEST
| PAL_STM32_OTYPE_OPENDRAIN); // SCL
#if ACTIVATE_USB
startUSB();
#endif
}
/** @} */

Wyświetl plik

@ -17,11 +17,6 @@
* 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.
@ -107,9 +102,6 @@
#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)
// SPI
#define LINE_SPI_SCK PAL_LINE(GPIOB, 3U)
@ -152,19 +144,26 @@
//#define LINE_UART4_RX PAL_LINE(GPIOA, 11U)
/* The external port can be used for bit bang I2C. */
#define ENABLE_EXTERNAL_I2C FALSE
#define ENABLE_EXTERNAL_I2C TRUE
#if ENABLE_EXTERNAL_I2C == FALSE
#define EI2C_SCL LINE_GPIO_PIN1 /* SCL */
#define EI2C_SDA LINE_GPIO_PIN2 /* SDA */
/* To use IO_TXD/IO_RXD for UART debug channel. */
#define ENABLE_SERIAL_DEBUG TRUE
#if ENABLE_SERIAL_DEBUG == TRUE
#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.
/* If set to true, the console using 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.
* USB needs 48MHz speed to operate.
*/
#define ACTIVATE_USB TRUE
#define ACTIVATE_CONSOLE TRUE
/**
* ICU related definitions.
@ -175,8 +174,8 @@
/* ICU counter frequency. */
/*
* TODO: This should be calculated using SYSTEM CLOCK.
* ICU has to run at an integer divide from SYSTEM CLOCK.
* TODO: This should be calculated using timer clock.
* ICU has to run at an integer divide from APBx clock.
*/
#define ICU_COUNT_FREQUENCY 6000000U
@ -201,28 +200,28 @@
/* Definitions for ICU FIFO implemented using chfactory. */
#if USE_HEAP_PWM_BUFFER == TRUE
/* Use factory FIFO as stream control with separate chained PWM buffers. */
#define NUMBER_PWM_FIFOS 3U
#define NUMBER_PWM_FIFOS 5U
/* Number of PWM data entries per queue object. */
#define PWM_DATA_SLOTS 200
/* Number of PWM queue objects in total. */
#define PWM_DATA_BUFFERS 30
#else
#else /* USE_HEAP_PWM_BUFFER != TRUE */
/* Use factory FIFO as stream control with integrated PWM buffer. */
#define NUMBER_PWM_FIFOS 3U
#define PWM_DATA_SLOTS 6000
#endif
#endif /* USE_HEAP_PWM_BUFFER == TRUE */
/* Number of frame receive buffers. */
#define NUMBER_RX_PKT_BUFFERS 3U
#define USE_CCM_HEAP_RX_BUFFERS FALSE
#define USE_CCM_HEAP_RX_BUFFERS TRUE
#define PKT_RX_RLS_USE_NO_FIFO FALSE
#define PKT_RX_RLS_USE_NO_FIFO TRUE
/*
* 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 NUMBER_COMMON_PKT_BUFFERS 10U
#define RESERVE_BUFFERS_FOR_INTERNAL 2U
#define MAX_BUFFERS_FOR_BURST_SEND 5U
#if (MAX_BUFFERS_FOR_BURST_SEND > \
@ -244,13 +243,6 @@
/* 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 radioConfig {
radio_unit_t unit;
radio_type_t type;
@ -271,7 +263,9 @@ extern "C" {
void pktConfigSerialDiag(void);
void pktConfigSerialPkt(void);
void pktConfigureCoreIO(void);
void pktSetLineModeICU(void);
ioline_t pktSetLineModeICU(const radio_unit_t radio);
ioline_t pktSetLineModeRadioGPIO1(const radio_unit_t radio);
ioline_t pktSetLineModeRadioGPIO0(const radio_unit_t radio);
void pktSerialStart(void);
void dbgWrite(uint8_t level, uint8_t *buf, uint32_t len);
int dbgPrintf(uint8_t level, const char *format, ...);
@ -290,6 +284,7 @@ extern "C" {
/* Module inline functions. */
/*===========================================================================*/
#endif /* PORTAB_H_ */
/** @} */

Wyświetl plik

@ -15,18 +15,13 @@ int main(void) {
/* Setup core IO peripherals. */
pktConfigureCoreIO();
// Init debugging (Serial debug port, LEDs)
DEBUG_INIT();
/* Setup the mutex for trace output. */
//DEBUG_INIT();
#if ACTIVATE_USB
/*
* TODO: Defer configure of USB mode.
* Set D+ (LINE_USB_DP) as pushpull out and low in board.h.
* Then delay here before ALT 10 for USB.
*/
/* Start Serial Over USB. */
startSDU();
TRACE_INFO("MAIN > USB startup");
#if ACTIVATE_CONSOLE
/* Start console. */
pktStartConsole();
TRACE_INFO("MAIN > Console startup");
#endif
/*
@ -37,29 +32,33 @@ int main(void) {
chDbgAssert(pkt == true, "failed to init packet system");
/* Start serial diagnostic channels if selected. */
/* Start serial debug channel(s) if selected. */
pktSerialStart();
/* Create packet radio service. */
if(!pktServiceCreate(PKT_RADIO_1)) {
TRACE_ERROR("PKT > Unable to create packet services");
} else {
pktEnableEventTrace();
/*
* Create a packet radio service.
* For now there is just one radio.
*/
while(!pktServiceCreate(PKT_RADIO_1)) {
TRACE_ERROR("MAIN > Unable to create packet radio %d services",
PKT_RADIO_1);
chThdSleep(TIME_S2I(10));
}
TRACE_INFO("MAIN > Starting threads");
pktEnableEventTrace(PKT_RADIO_1);
TRACE_INFO("MAIN > Started packet radio service for radio %d",
PKT_RADIO_1);
TRACE_INFO("MAIN > Starting application and ancillary threads");
// Startup threads
start_essential_threads(); // Startup required modules (tracking manager, watchdog)
start_user_threads(); // Startup optional modules (eg. POSITION, LOG, ...)
TRACE_INFO("MAIN > Active");
TRACE_INFO("MAIN > Active");
while(true) {
#if ACTIVATE_USB
manageTraceAndShell();
pktTraceEvents();
#endif /* ACTIVATE_USB */
/* Wait in a loop if nothing to do. */
/* Trace events from packet decoder system. */
pktTraceEvents();
chThdSleep(TIME_MS2I(200));
}
}

Wyświetl plik

@ -95,6 +95,9 @@ DEPDIR := ${CURDIR}/.dep/$(PROJECT)
CMSISINC = ${CURDIR}/CMSIS/include
CMSISLIB = ${CURDIR}/CMSIS/Lib/GCC
# ChibiOS versions of system calls
ALLSRC := $(CHIBIOS)/os/various/syscalls.c
# Licensing files.
include $(CHIBIOS)/os/license/license.mk
# Startup files.

Wyświetl plik

@ -1,240 +1,243 @@
##############################################################################
# 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 = pp10b
# 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 = pp10b
# 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
# ChibiOS versions of system calls
ALLSRC := $(CHIBIOS)/os/various/syscalls.c
# 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

@ -13,7 +13,7 @@ const conf_t conf_flash_default = {
// Primary position app
.pos_pri = {
.beacon = {
.active = true,
.active = false,
.cycle = TIME_S2I(60 * 5),
.init_delay = TIME_S2I(60),
.fixed = false // Add lat, lon alt fields if enabling fixed
@ -28,7 +28,7 @@ const conf_t conf_flash_default = {
.call = "VK2GJ-12",
.path = "WIDE1-1",
.symbol = SYM_ANTENNA,
.aprs_msg = true, // Set true to enable APRS messages to be accepted on this call sign
.aprs_msg = true, // Enable APRS message reception on this call sign
},
// Secondary position app
@ -49,7 +49,7 @@ const conf_t conf_flash_default = {
.call = "VK2GJ-15",
.path = "",
.symbol = SYM_BALLOON,
.aprs_msg = true,// Set true to enable APRS messages to be accepted on this call sign
.aprs_msg = true, // Enable APRS message reception on this call sign
},
// Primary image app
@ -81,13 +81,13 @@ const conf_t conf_flash_default = {
// Secondary image app
.img_sec = {
.svc_conf = {
.active = true,
.active = false,
.cycle = TIME_S2I(60 * 30),
.init_delay = TIME_S2I(60 * 1),
.send_spacing = TIME_S2I(30)
},
.radio_conf = {
.pwr = 0x1F,
.pwr = 0x7F,
.freq = APRS_FREQ_AUSTRALIA,
.mod = MOD_AFSK,
.cca = 0x4F
@ -175,7 +175,7 @@ const conf_t conf_flash_default = {
// Power control
.keep_cam_switched_on = false,
.gps_on_vbat = 3600, // mV
.gps_off_vbat = 3000, // mV
.gps_off_vbat = 3400, // mV
.gps_onper_vbat = 4000, // mV
// GPS altitude model control (air pressure controlled using on-board BME280)
@ -192,7 +192,7 @@ const conf_t conf_flash_default = {
// The base station identity.
.base = {
// If enabled APRS messages are addressed to this call sign
// If enabled tracker initiated APRS messages are addressed to this call sign
.enabled = true,
.call = "VK2GJ-7",
.path = "WIDE2-1",

Wyświetl plik

@ -989,8 +989,8 @@ msg_t OV5640_LockResourcesForCapture(void) {
pktLLDradioPauseDecoding(PKT_RADIO_1);
//pktPauseDecoding(PKT_RADIO_1);
/* Hold TRACE output on USB. */
if(isUSBactive())
chMtxLock(&trace_mtx);
/* if(isUSBactive())
chMtxLock(&trace_mtx);*/
return MSG_OK;
}
@ -999,8 +999,8 @@ msg_t OV5640_LockResourcesForCapture(void) {
*/
void OV5640_UnlockResourcesForCapture(void) {
/* Re-enable TRACE output on USB. */
if(isUSBactive())
chMtxUnlock(&trace_mtx);
/* if(isUSBactive())
chMtxUnlock(&trace_mtx);*/
I2C_Unlock();
/* TODO: have to make this a loop which would handle multiple receivers. */
pktLLDradioResumeDecoding(PKT_RADIO_1);

Wyświetl plik

@ -14,12 +14,35 @@
#endif
#include "geofence.h"
#include "si446x_patch.h"
/*===========================================================================*/
/* Module local variables. */
/*===========================================================================*/
// Si446x variables
static int16_t lastTemp = 0x7FFF;
/*===========================================================================*/
/* Module constants. */
/*===========================================================================*/
/* =================================================================== SPI communication ==================================================================== */
/*===========================================================================*/
/* Module exported variables. */
/*===========================================================================*/
si446x_part_t part_info;
si446x_func_t func_info;
/*===========================================================================*/
/* Module local definitions. */
/*===========================================================================*/
static const uint8_t Radio_Patch_Data_Array[] = {
SI446X_PATCH_CMDS,
0x00
};
static const SPIConfig ls_spicfg = {
.ssport = PAL_PORT(LINE_RADIO_CS),
@ -27,6 +50,48 @@ static const SPIConfig ls_spicfg = {
.cr1 = SPI_CR1_MSTR
};
/**
* SPI write which uses CTS on GPIO1.
* Used when starting the radio up from shutdown state.
* @pre The MCU GPIO pin connected to 446x GPIO1 must be pre-configured.
*/
static bool Si446x_writeBoot(const uint8_t* txData, uint32_t len) {
/* Write data via SPI with CTS checked via GPIO1. */
/* TODO: Add radio unit ID and get specific radio SPI driver. */
//uint8_t null_spi[len];
/* Acquire bus and then start SPI. */
spiAcquireBus(PKT_RADIO_SPI);
spiStart(PKT_RADIO_SPI, &ls_spicfg);
/* Poll for CTS. */
uint8_t timeout = 100;
do {
if(timeout != 100)
chThdSleep(TIME_MS2I(1));
} while(palReadLine(LINE_RADIO_GPIO1) != PAL_HIGH && timeout--);
if(!timeout) {
TRACE_ERROR("SI > CTS not received");
/* Stop SPI and relinquish bus. */
spiStop(PKT_RADIO_SPI);
spiReleaseBus(PKT_RADIO_SPI);
return false;
}
/* Transfer data. No need to check CTS.*/
spiSelect(PKT_RADIO_SPI);
spiSend(PKT_RADIO_SPI, len, txData);
spiUnselect(PKT_RADIO_SPI);
/* Stop SPI and relinquish bus. */
spiStop(PKT_RADIO_SPI);
spiReleaseBus(PKT_RADIO_SPI);
return true;
}
static bool Si446x_write(const uint8_t* txData, uint32_t len) {
// Transmit data by SPI
/* TODO: Add radio unit ID and get specific radio SPI driver. */
@ -55,7 +120,7 @@ static bool Si446x_write(const uint8_t* txData, uint32_t len) {
return false;
}
/* Transfer data. Discard read back. */
/* Transfer data. */
spiSelect(PKT_RADIO_SPI);
spiExchange(PKT_RADIO_SPI, len, txData, null_spi);
spiUnselect(PKT_RADIO_SPI);
@ -67,15 +132,74 @@ static bool Si446x_write(const uint8_t* txData, uint32_t len) {
return true;
}
/**
* SPI read which uses CTS on GPIO1.
* Use this when first taking radio out of shutdown.
* The MCU GPIO pin connected to 446x GPIO1 must be already configured.
*/
static bool Si446x_readBoot(const uint8_t* txData, uint32_t txlen,
uint8_t* rxData, uint32_t rxlen) {
/* TODO: Add radio unit ID and get SPI configuration accordingly. */
/* Acquire bus. */
spiAcquireBus(PKT_RADIO_SPI);
/* Poll for CTS on GPIO1 from radio. */
uint8_t timeout = 100;
while(palReadLine(LINE_RADIO_GPIO1) != PAL_HIGH && timeout--) {
chThdSleep(TIME_MS2I(1));
}
if(!timeout) {
/* Relinquish bus. */
spiReleaseBus(PKT_RADIO_SPI);
TRACE_ERROR("SI > CTS not received");
return false;
}
/*
* Now write command and any data.
*/
spiStart(PKT_RADIO_SPI, &ls_spicfg);
spiSelect(PKT_RADIO_SPI);
spiSend(PKT_RADIO_SPI, txlen, txData);
spiUnselect(PKT_RADIO_SPI);
/* Poll for CTS from command. */
timeout = 100;
while(palReadLine(LINE_RADIO_GPIO1) != PAL_HIGH && timeout--) {
chThdSleep(TIME_MS2I(1));
}
if(!timeout) {
/* Stop SPI and relinquish bus. */
spiStop(PKT_RADIO_SPI);
spiReleaseBus(PKT_RADIO_SPI);
TRACE_ERROR("SI > CTS not received");
return false;
}
/* Read the response. */
uint8_t rx_ready[] = {Si446x_READ_CMD_BUFF, 0x00};
spiSelect(PKT_RADIO_SPI);
spiExchange(PKT_RADIO_SPI, rxlen, rx_ready, rxData);
spiUnselect(PKT_RADIO_SPI);
/* Stop SPI and relinquish bus. */
spiStop(PKT_RADIO_SPI);
spiReleaseBus(PKT_RADIO_SPI);
return true;
}
/**
* Read data from Si446x.
*/
static bool Si446x_read(const uint8_t* txData, uint32_t txlen,
uint8_t* rxData, uint32_t rxlen) {
// Transmit data by SPI
/* TODO: Add radio unit ID and get SPI configuration accordingly. */
/* Command readback to be discarded here. */
uint8_t null_spi[txlen];
/* Acquire bus and then start SPI. */
spiAcquireBus(PKT_RADIO_SPI);
@ -89,27 +213,28 @@ static bool Si446x_read(const uint8_t* txData, uint32_t txlen,
uint8_t timeout = 100;
uint8_t rx_ready[] = {Si446x_READ_CMD_BUFF, 0x00};
do {
if(timeout != 100)
chThdSleep(TIME_MS2I(1));
spiSelect(PKT_RADIO_SPI);
spiExchange(PKT_RADIO_SPI, 1, rx_ready, &rx_ready[1]);
spiUnselect(PKT_RADIO_SPI);
if(timeout != 100)
chThdSleep(TIME_MS2I(1));
} while(rx_ready[1] != Si446x_COMMAND_CTS && timeout--);
if(!timeout) {
TRACE_ERROR("SI > CTS not received");
/* Stop SPI (de-asserts select as well) and relinquish bus. */
/* Stop SPI and relinquish bus. */
spiStop(PKT_RADIO_SPI);
spiReleaseBus(PKT_RADIO_SPI);
return false;
}
/*
* Now write command and data. Discard the read back.
* Now write command and data.
*/
spiSelect(PKT_RADIO_SPI);
spiExchange(PKT_RADIO_SPI, txlen, txData, null_spi);
spiSend(PKT_RADIO_SPI, txlen, txData);
spiUnselect(PKT_RADIO_SPI);
/*
* Poll waiting for CTS again using the READ_CMD_BUFF command.
* Once CTS is received the response data is ready in the rx data buffer.
@ -117,14 +242,14 @@ static bool Si446x_read(const uint8_t* txData, uint32_t txlen,
*/
timeout = 100;
do {
spiUnselect(PKT_RADIO_SPI);
if(timeout != 100)
chThdSleep(TIME_MS2I(1));
spiSelect(PKT_RADIO_SPI);
spiExchange(PKT_RADIO_SPI, rxlen, rx_ready, rxData);
spiUnselect(PKT_RADIO_SPI);
} while(rxData[1] != Si446x_COMMAND_CTS && timeout--);
/* Stop SPI (de-asserts select as well) and relinquish bus. */
/* Stop SPI and relinquish bus. */
spiStop(PKT_RADIO_SPI);
spiReleaseBus(PKT_RADIO_SPI);
@ -135,171 +260,273 @@ static bool Si446x_read(const uint8_t* txData, uint32_t txlen,
return true;
}
/* TODO: Make set property a single func with size parameter. */
static void Si446x_setProperty8(uint16_t reg, uint8_t val) {
uint8_t msg[] = {0x11, (reg >> 8) & 0xFF, 0x01, reg & 0xFF, val};
Si446x_write(msg, 5);
uint8_t msg[] = {Si446x_SET_PROPERTY,
(reg >> 8) & 0xFF, 0x01, reg & 0xFF, val};
Si446x_write(msg, sizeof(msg));
}
static void Si446x_setProperty16(uint16_t reg, uint8_t val1, uint8_t val2) {
uint8_t msg[] = {0x11, (reg >> 8) & 0xFF, 0x02, reg & 0xFF, val1, val2};
Si446x_write(msg, 6);
uint8_t msg[] = {Si446x_SET_PROPERTY,
(reg >> 8) & 0xFF, 0x02, reg & 0xFF, val1, val2};
Si446x_write(msg, sizeof(msg));
}
static void Si446x_setProperty24(uint16_t reg, uint8_t val1, uint8_t val2, uint8_t val3) {
uint8_t msg[] = {0x11, (reg >> 8) & 0xFF, 0x03, reg & 0xFF, val1, val2, val3};
Si446x_write(msg, 7);
static void Si446x_setProperty24(uint16_t reg, uint8_t val1,
uint8_t val2, uint8_t val3) {
uint8_t msg[] = {Si446x_SET_PROPERTY,
(reg >> 8) & 0xFF, 0x03, reg & 0xFF, val1, val2, val3};
Si446x_write(msg, sizeof(msg));
}
static void Si446x_setProperty32(uint16_t reg, uint8_t val1, uint8_t val2, uint8_t val3, uint8_t val4) {
uint8_t msg[] = {0x11, (reg >> 8) & 0xFF, 0x04, reg & 0xFF, val1, val2, val3, val4};
Si446x_write(msg, 8);
static void Si446x_setProperty32(uint16_t reg, uint8_t val1,
uint8_t val2, uint8_t val3, uint8_t val4) {
uint8_t msg[] = {Si446x_SET_PROPERTY,
(reg >> 8) & 0xFF, 0x04, reg & 0xFF,
val1, val2, val3, val4};
Si446x_write(msg, sizeof(msg));
}
/**
* Initializes Si446x transceiver chip. Adjusts the frequency which is shifted by variable
* oscillator voltage.
* @param mv Oscillator voltage in mv
* Initializes Si446x transceiver chip.
*/
static void Si446x_init(const radio_unit_t radio) {
static bool Si446x_init(const radio_unit_t radio) {
TRACE_INFO("SI > Init radio");
TRACE_INFO("SI > Start up and initialize radio %d", radio);
packet_svc_t *handler = pktGetServiceObject(radio);
chDbgAssert(handler != NULL, "invalid radio ID");
//chDbgAssert(handler != NULL, "invalid radio ID");
//pktPowerUpRadio(radio);
Si446x_powerup(radio);
//palClearLine(LINE_RADIO_SDN); // Radio SDN low (power up transceiver)
//chThdSleep(TIME_MS2I(10)); // Wait for transceiver to power up
/*
* Set MCU GPIO for radio GPIO1 (CTS).
* Execute radio startup sequence.
*/
if(!Si446x_radioStartup(radio)) {
TRACE_ERROR("SI > Start up of radio %d failed", radio);
return false;
}
// Power up (send oscillator type)
const uint8_t x3 = (Si446x_CCLK >> 24) & 0x0FF;
const uint8_t x2 = (Si446x_CCLK >> 16) & 0x0FF;
const uint8_t x1 = (Si446x_CCLK >> 8) & 0x0FF;
const uint8_t x0 = (Si446x_CCLK >> 0) & 0x0FF;
const uint8_t init_command[] = {0x02, 0x01, (Si446x_CLK_TCXO_EN & 0x1), x3, x2, x1, x0};
Si446x_write(init_command, 7);
chThdSleep(TIME_MS2I(25));
/* Calculate clock source parameters. */
const uint8_t x3 = (Si446x_CCLK >> 24) & 0x0FF;
const uint8_t x2 = (Si446x_CCLK >> 16) & 0x0FF;
const uint8_t x1 = (Si446x_CCLK >> 8) & 0x0FF;
const uint8_t x0 = (Si446x_CCLK >> 0) & 0x0FF;
// Set transceiver GPIOs
uint8_t gpio_pin_cfg_command[] = {
0x13, // Command type = GPIO settings
0x00, // GPIO0 GPIO_MODE = DONOTHING
0x15, // GPIO1 GPIO_MODE = RAW_RX_DATA
0x21, // GPIO2 GPIO_MODE = RX_STATE
0x20, // GPIO3 GPIO_MODE = TX_STATE
0x1B, // NIRQ NIRQ_MODE = CCA
0x0B, // SDO SDO_MODE = SDO
0x00 // GEN_CONFIG
};
Si446x_write(gpio_pin_cfg_command, 8);
chThdSleep(TIME_MS2I(25));
/*
* Start the chip API with the POWER_UP command.
* A second POWER_UP will take place if a patch needs to be applied.
* The PART_INFO command is used to determine if this is a 4464 or 4463.
*/
#if !Si446x_CLK_TCXO_EN
Si446x_setProperty8(Si446x_GLOBAL_XO_TUNE, 0x00);
#endif
const uint8_t init_command[] = {Si446x_POWER_UP, 0x01,
(Si446x_CLK_TCXO_EN & 0x1),
x3, x2, x1, x0};
/*
* Use of writeBoot() enables SPI write without using OS delays.
* The Si446x GPIO1 is set to CTS at start up.
*
* The Si446x SDO pin is configured to SDO data by the POWER_UP command.
*/
Si446x_writeBoot(init_command, sizeof(init_command));
Si446x_setProperty8(Si446x_FRR_CTL_A_MODE, 0x00);
Si446x_setProperty8(Si446x_FRR_CTL_B_MODE, 0x00);
Si446x_setProperty8(Si446x_FRR_CTL_C_MODE, 0x00);
Si446x_setProperty8(Si446x_FRR_CTL_D_MODE, 0x00);
Si446x_setProperty8(Si446x_INT_CTL_ENABLE, 0x00);
/* Set combined FIFO mode = 0x70. */
//Si446x_setProperty8(Si446x_GLOBAL_CONFIG, 0x60);
Si446x_setProperty8(Si446x_GLOBAL_CONFIG, 0x70);
/*
* Next get the PART_INFO.
* Store details for reference.
* If the part requires a patch then reset and delay (TBD).
* Output the patch and re-execute the POWER_UP command.
*/
/* Clear FIFO. */
const uint8_t reset_fifo[] = {0x15, 0x01};
Si446x_write(reset_fifo, 2);
/* No need to unset bits... see si docs. */
const uint8_t get_part[] = {Si446x_GET_PART_INFO};
Si446x_readBoot(get_part, sizeof(get_part), (uint8_t *)&part_info,
sizeof(part_info));
/* Save the part number and ROM revision. */
handler->radio_part = (part_info.info[3] << 8) + part_info.info[4];
handler->radio_rom_rev = part_info.info[9];
/*
* Check this radio requires a patch installed.
* TODO: Probably should be in a table...
*/
if(is_Si4463_patch_required(handler->radio_part, handler->radio_rom_rev)) {
/* Power cycle radio and apply patch. */
Si446x_radioShutdown(radio);
chThdSleep(TIME_MS2I(10));
Si446x_radioStartup(radio);
uint16_t i = 0;
while(Radio_Patch_Data_Array[i] != 0) {
Si446x_writeBoot(&Radio_Patch_Data_Array[i + 1], Radio_Patch_Data_Array[i]);
i += Radio_Patch_Data_Array[i] + 1;
}
const uint8_t init_command[] = {Si446x_POWER_UP, 0x81,
(Si446x_CLK_TCXO_EN & 0x1),
x3, x2, x1, x0};
Si446x_writeBoot(init_command, sizeof(init_command));
}
/* Get and save the patch ID from FUNC_INFO for reference. */
const uint8_t get_func[] = {Si446x_GET_FUNC_INFO};
Si446x_readBoot(get_func, sizeof(get_func), (uint8_t *)&func_info,
sizeof(func_info));
handler->radio_patch = (func_info.info[5] << 8) + func_info.info[6];
/*
* Set transceiver GPIOs.
* GPIO0, 1 and NIRQ can now be reconfigured as required by TX or RX modes.
* In that case each needs to setup GPIOs as required.
*/
uint8_t gpio_pin_cfg_command2[] = {
Si446x_GPIO_PIN_CFG, // Command type = GPIO settings
0x00, // GPIO0 GPIO_MODE = DONOTHING
0x15, // GPIO1 GPIO_MODE = RAW_RX_DATA
0x21, // GPIO2 GPIO_MODE = RX_STATE
0x20, // GPIO3 GPIO_MODE = TX_STATE
0x1B, // NIRQ NIRQ_MODE = CCA
0x0B, // SDO SDO_MODE = SDO
0x00 // GEN_CONFIG
};
Si446x_write(gpio_pin_cfg_command2, sizeof(gpio_pin_cfg_command2));
/* TODO: We should clear interrupts here with a GET_INT_STATUS. */
/*
* TODO: Move the TX and RX settings out into the respective functions.
* This would split up into AFSK and FSK for RX & TX.
* Leave only common setup and init in here for selected base band frequency.
*/
Si446x_setProperty8(Si446x_PREAMBLE_TX_LENGTH, 0x00);
/* TODO: Use PREAMBLE_CONFIG_NSTD, etc. to send flags?
* To do this with AFSK up-sampling requires a preamble pattern of 88 bits.
* The 446x only has up to 32 pattern bits.
* Why 88 bits? Due to the oversampling used to create AFSK at 13.2ksps.
* Each HDLC bit takes 11 TX bit times.
*
* The alternative is to use TX_FIELDS.
* Send preamble (HDLC flags) using FIELD_1 in a loop with fixed data 0x7E.
* Field length can be 4096 bytes so up to 372 flags could be sent.
* The flag bit stream uses 11 bytes per flag.
* Using 200 flags would be 11 * 200 = 2200 bytes (17,600 stream bits).
* Set FIELD_1 as 2,200 bytes and feed 200 x the bit pattern to the FIFO.
* The transition to FIELD_2 is handled in the 446x packet handler.
* Then FIELD_2 FIFO data is fed from the layer0 (bit stream) data buffer.
*/
Si446x_setProperty8(Si446x_SYNC_CONFIG, 0x80);
Si446x_setProperty8(Si446x_GLOBAL_CLK_CFG, 0x00);
Si446x_setProperty8(Si446x_MODEM_RSSI_CONTROL, 0x00);
/* TODO: Don't need this setting? */
Si446x_setProperty8(Si446x_PREAMBLE_CONFIG_STD_1, 0x14);
Si446x_setProperty8(Si446x_PKT_CONFIG1, 0x41);
Si446x_setProperty8(Si446x_MODEM_MAP_CONTROL, 0x00);
Si446x_setProperty8(Si446x_MODEM_DSM_CTRL, 0x07);
Si446x_setProperty8(Si446x_MODEM_CLKGEN_BAND, 0x0D);
/* If Si446x is using its own xtal set the trim capacitor value. */
#if !Si446x_CLK_TCXO_EN
Si446x_setProperty8(Si446x_GLOBAL_XO_TUNE, 0x40);
#endif
Si446x_setProperty24(Si446x_MODEM_FREQ_DEV, 0x00, 0x00, 0x79);
Si446x_setProperty8(Si446x_MODEM_TX_RAMP_DELAY, 0x01);
Si446x_setProperty8(Si446x_PA_TC, 0x3D);
Si446x_setProperty8(Si446x_FREQ_CONTROL_INTE, 0x41);
Si446x_setProperty24(Si446x_FREQ_CONTROL_FRAC, 0x0B, 0xB1, 0x3B);
Si446x_setProperty16(Si446x_FREQ_CONTROL_CHANNEL_STEP_SIZE, 0x0B, 0xD1);
Si446x_setProperty8(Si446x_FREQ_CONTROL_W_SIZE, 0x20);
Si446x_setProperty8(Si446x_FREQ_CONTROL_VCOCNT_RX_ADJ, 0xFA);
Si446x_setProperty8(Si446x_MODEM_MDM_CTRL, 0x80);
Si446x_setProperty8(Si446x_MODEM_IF_CONTROL, 0x08);
Si446x_setProperty24(Si446x_MODEM_IF_FREQ, 0x02, 0x80, 0x00);
Si446x_setProperty8(Si446x_MODEM_DECIMATION_CFG1, 0x70);
Si446x_setProperty8(Si446x_MODEM_DECIMATION_CFG0, 0x10);
Si446x_setProperty16(Si446x_MODEM_BCR_OSR, 0x01, 0xC3);
Si446x_setProperty24(Si446x_MODEM_BCR_NCO_OFFSET, 0x01, 0x22, 0x60);
Si446x_setProperty16(Si446x_MODEM_BCR_GAIN, 0x00, 0x91);
Si446x_setProperty8(Si446x_MODEM_BCR_GEAR, 0x00);
Si446x_setProperty8(Si446x_MODEM_BCR_MISC1, 0xC2);
Si446x_setProperty8(Si446x_MODEM_AFC_GEAR, 0x54);
/* Fast response registers - not used at this time. */
Si446x_setProperty8(Si446x_FRR_CTL_A_MODE, 0x00);
Si446x_setProperty8(Si446x_FRR_CTL_B_MODE, 0x00);
Si446x_setProperty8(Si446x_FRR_CTL_C_MODE, 0x00);
Si446x_setProperty8(Si446x_FRR_CTL_D_MODE, 0x00);
Si446x_setProperty8(Si446x_INT_CTL_ENABLE, 0x00);
/* Set combined FIFO mode = 0x70. */
Si446x_setProperty8(Si446x_GLOBAL_CONFIG, 0x70);
/* Clear TX & RX FIFO. */
const uint8_t reset_fifo[] = {Si446x_FIFO_INFO, 0x03};
Si446x_write(reset_fifo, sizeof(reset_fifo));
/* No need to unset bits... see si docs. */
/*
* TODO: Move the TX and RX settings out into the respective functions.
* This would split up into AFSK and FSK for RX & TX.
* Leave only common setup and init here.
*/
Si446x_setProperty8(Si446x_PREAMBLE_TX_LENGTH, 0x00);
Si446x_setProperty8(Si446x_SYNC_CONFIG, 0x80);
/* 32K clock disabled. Divided clock disabled. */
Si446x_setProperty8(Si446x_GLOBAL_CLK_CFG, 0x00);
Si446x_setProperty8(Si446x_MODEM_RSSI_CONTROL, 0x00);
/* TODO: Don't need this setting? */
Si446x_setProperty8(Si446x_PREAMBLE_CONFIG_STD_1, 0x14);
Si446x_setProperty8(Si446x_PKT_CONFIG1, 0x41);
Si446x_setProperty8(Si446x_MODEM_MAP_CONTROL, 0x00);
Si446x_setProperty8(Si446x_MODEM_DSM_CTRL, 0x07);
Si446x_setProperty8(Si446x_MODEM_CLKGEN_BAND, 0x0D);
Si446x_setProperty24(Si446x_MODEM_FREQ_DEV, 0x00, 0x00, 0x79);
Si446x_setProperty8(Si446x_MODEM_TX_RAMP_DELAY, 0x01);
Si446x_setProperty8(Si446x_PA_TC, 0x3D);
Si446x_setProperty8(Si446x_FREQ_CONTROL_INTE, 0x41);
Si446x_setProperty24(Si446x_FREQ_CONTROL_FRAC, 0x0B, 0xB1, 0x3B);
Si446x_setProperty16(Si446x_FREQ_CONTROL_CHANNEL_STEP_SIZE, 0x0B, 0xD1);
Si446x_setProperty8(Si446x_FREQ_CONTROL_W_SIZE, 0x20);
Si446x_setProperty8(Si446x_FREQ_CONTROL_VCOCNT_RX_ADJ, 0xFA);
Si446x_setProperty8(Si446x_MODEM_MDM_CTRL, 0x80);
Si446x_setProperty8(Si446x_MODEM_IF_CONTROL, 0x08);
Si446x_setProperty24(Si446x_MODEM_IF_FREQ, 0x02, 0x80, 0x00);
Si446x_setProperty8(Si446x_MODEM_DECIMATION_CFG1, 0x70);
Si446x_setProperty8(Si446x_MODEM_DECIMATION_CFG0, 0x10);
Si446x_setProperty16(Si446x_MODEM_BCR_OSR, 0x01, 0xC3);
Si446x_setProperty24(Si446x_MODEM_BCR_NCO_OFFSET, 0x01, 0x22, 0x60);
Si446x_setProperty16(Si446x_MODEM_BCR_GAIN, 0x00, 0x91);
Si446x_setProperty8(Si446x_MODEM_BCR_GEAR, 0x00);
Si446x_setProperty8(Si446x_MODEM_BCR_MISC1, 0xC2);
Si446x_setProperty8(Si446x_MODEM_AFC_GEAR, 0x54);
if(is_part_Si4463(handler->radio_part))
Si446x_setProperty8(Si446x_MODEM_AFC_WAIT, 0x23);
else
Si446x_setProperty8(Si446x_MODEM_AFC_WAIT, 0x36);
Si446x_setProperty16(Si446x_MODEM_AFC_GAIN, 0x80, 0xAB);
Si446x_setProperty16(Si446x_MODEM_AFC_LIMITER, 0x02, 0x50);
Si446x_setProperty8(Si446x_MODEM_AFC_MISC, 0x80);
Si446x_setProperty8(Si446x_MODEM_AGC_CONTROL, 0xE2);
Si446x_setProperty8(Si446x_MODEM_AGC_WINDOW_SIZE, 0x11);
Si446x_setProperty8(Si446x_MODEM_AGC_RFPD_DECAY, 0x63);
Si446x_setProperty8(Si446x_MODEM_AGC_IFPD_DECAY, 0x63);
Si446x_setProperty8(Si446x_MODEM_FSK4_GAIN1, 0x00);
Si446x_setProperty8(Si446x_MODEM_FSK4_GAIN0, 0x02);
Si446x_setProperty16(Si446x_MODEM_FSK4_TH, 0x35, 0x55);
Si446x_setProperty8(Si446x_MODEM_FSK4_MAP, 0x00);
Si446x_setProperty8(Si446x_MODEM_OOK_PDTC, 0x2A);
Si446x_setProperty8(Si446x_MODEM_OOK_CNT1, 0x85);
Si446x_setProperty8(Si446x_MODEM_OOK_MISC, 0x23);
Si446x_setProperty8(Si446x_MODEM_RAW_SEARCH, 0xD6);
Si446x_setProperty8(Si446x_MODEM_RAW_CONTROL, 0x8F);
Si446x_setProperty16(Si446x_MODEM_RAW_EYE, 0x00, 0x3B);
Si446x_setProperty8(Si446x_MODEM_ANT_DIV_MODE, 0x01);
Si446x_setProperty8(Si446x_MODEM_ANT_DIV_CONTROL, 0x80);
Si446x_setProperty8(Si446x_MODEM_RSSI_COMP, 0x40);
handler->radio_init = true;
Si446x_setProperty16(Si446x_MODEM_AFC_GAIN, 0x80, 0xAB);
Si446x_setProperty16(Si446x_MODEM_AFC_LIMITER, 0x02, 0x50);
Si446x_setProperty8(Si446x_MODEM_AFC_MISC, 0x80);
if(is_part_Si4463(handler->radio_part))
Si446x_setProperty8(Si446x_MODEM_AGC_CONTROL, 0xE0);
else
Si446x_setProperty8(Si446x_MODEM_AGC_CONTROL, 0xE2);
Si446x_setProperty8(Si446x_MODEM_AGC_WINDOW_SIZE, 0x11);
Si446x_setProperty8(Si446x_MODEM_AGC_RFPD_DECAY, 0x63);
Si446x_setProperty8(Si446x_MODEM_AGC_IFPD_DECAY, 0x63);
if(is_part_Si4463(handler->radio_part))
Si446x_setProperty8(Si446x_MODEM_FSK4_GAIN1, 0x80);
else
Si446x_setProperty8(Si446x_MODEM_FSK4_GAIN1, 0x00);
Si446x_setProperty8(Si446x_MODEM_FSK4_GAIN0, 0x02);
Si446x_setProperty16(Si446x_MODEM_FSK4_TH, 0x35, 0x55);
Si446x_setProperty8(Si446x_MODEM_FSK4_MAP, 0x00);
Si446x_setProperty8(Si446x_MODEM_OOK_PDTC, 0x2A);
Si446x_setProperty8(Si446x_MODEM_OOK_CNT1, 0x85);
Si446x_setProperty8(Si446x_MODEM_OOK_MISC, 0x23);
if(is_part_Si4463(handler->radio_part))
Si446x_setProperty8(Si446x_MODEM_RAW_SEARCH2, 0xBC);
else
Si446x_setProperty8(Si446x_MODEM_RAW_SEARCH, 0xD6);
Si446x_setProperty8(Si446x_MODEM_RAW_CONTROL, 0x8F);
Si446x_setProperty16(Si446x_MODEM_RAW_EYE, 0x00, 0x3B);
Si446x_setProperty8(Si446x_MODEM_ANT_DIV_MODE, 0x01);
Si446x_setProperty8(Si446x_MODEM_ANT_DIV_CONTROL, 0x80);
Si446x_setProperty8(Si446x_MODEM_RSSI_COMP, 0x40);
if(is_part_Si4463(handler->radio_part)) {
Si446x_setProperty8(Si446x_MODEM_SPIKE_DET, 0x03);
Si446x_setProperty8(Si446x_MODEM_DSA_CTRL1, 0xA0);
Si446x_setProperty8(Si446x_MODEM_DSA_CTRL2, 0x04);
Si446x_setProperty8(Si446x_MODEM_ONE_SHOT_AFC, 0x07);
Si446x_setProperty8(Si446x_MODEM_DSA_QUAL, 0x06);
Si446x_setProperty8(Si446x_MODEM_DSA_RSSI, 0x78);
Si446x_setProperty8(Si446x_MODEM_DECIMATION_CFG2, 0x0C);
Si446x_setProperty8(Si446x_MODEM_RSSI_MUTE, 0x00);
Si446x_setProperty8(Si446x_MODEM_DSA_MISC, 0x20);
Si446x_setProperty8(Si446x_PREAMBLE_CONFIG, 0x21);
}
handler->radio_init = true;
return true;
}
void Si446x_conditional_init(const radio_unit_t radio) {
// Initialize radio
/**
* Intialize radio only if if it has been shutdown.
*/
bool Si446x_conditional_init(const radio_unit_t radio) {
packet_svc_t *handler = pktGetServiceObject(radio);
chDbgAssert(handler != NULL, "invalid radio ID");
//chDbgAssert(handler != NULL, "invalid radio ID");
if(!handler->radio_init)
Si446x_init(radio);
return Si446x_init(radio);
return true;
}
/*
@ -332,8 +559,9 @@ bool Si446x_setBandParameters(const radio_unit_t radio,
/* Set the band parameter. */
uint32_t sy_sel = 8;
uint8_t set_band_property_command[] = {0x11, 0x20, 0x01, 0x51, (band + sy_sel)};
Si446x_write(set_band_property_command, 5);
uint8_t set_band_property_command[] = {Si446x_SET_PROPERTY,
0x20, 0x01, 0x51, (band + sy_sel)};
Si446x_write(set_band_property_command, sizeof(set_band_property_command));
/* Set the PLL parameters. */
uint32_t f_pfd = 2 * Si446x_CCLK / outdiv;
@ -350,15 +578,18 @@ bool Si446x_setBandParameters(const radio_unit_t radio,
uint8_t c1 = channel_increment / 0x100;
uint8_t c0 = channel_increment - (0x100 * c1);
uint8_t set_frequency_property_command[] = {0x11, 0x40, 0x04, 0x00, n, m2, m1, m0, c1, c0};
Si446x_write(set_frequency_property_command, 10);
uint8_t set_frequency_property_command[] = {Si446x_SET_PROPERTY,
0x40, 0x04, 0x00, n,
m2, m1, m0, c1, c0};
Si446x_write(set_frequency_property_command,
sizeof(set_frequency_property_command));
uint32_t x = ((((uint32_t)1 << 19) * outdiv * 1300.0)/(2*Si446x_CCLK))*2;
uint8_t x2 = (x >> 16) & 0xFF;
uint8_t x1 = (x >> 8) & 0xFF;
uint8_t x0 = (x >> 0) & 0xFF;
uint8_t set_deviation[] = {0x11, 0x20, 0x03, 0x0a, x2, x1, x0};
Si446x_write(set_deviation, 7);
uint8_t set_deviation[] = {Si446x_SET_PROPERTY, 0x20, 0x03, 0x0a, x2, x1, x0};
Si446x_write(set_deviation, sizeof(set_deviation));
return true;
}
@ -382,13 +613,17 @@ bool Si446x_setBandParameters(const radio_unit_t radio,
static void Si446x_setPowerLevel(const radio_pwr_t level)
{
// Set the Power
uint8_t set_pa_pwr_lvl_property_command[] = {0x11, 0x22, 0x01, 0x01, level};
Si446x_write(set_pa_pwr_lvl_property_command, 5);
uint8_t set_pa_pwr_lvl_property_command[] = {Si446x_SET_PROPERTY,
0x22, 0x01, 0x01, level};
Si446x_write(set_pa_pwr_lvl_property_command,
sizeof(set_pa_pwr_lvl_property_command));
}
/* =========================================================== Radio specific modulation settings =========================================================== */
/*
* Radio modulation settings
*/
static void Si446x_setModemAFSK_TX(const radio_unit_t radio) {
/* TODO: Hardware mapping. */
@ -498,7 +733,9 @@ static void Si446x_setModem2FSK_TX(const uint32_t speed)
}
/* ====================================================================== Radio Settings ====================================================================== */
/*
* Radio Settings
*/
static uint8_t __attribute__((unused)) Si446x_getChannel(const radio_unit_t radio) {
/* TODO: add hardware mapping. */
@ -509,7 +746,9 @@ static uint8_t __attribute__((unused)) Si446x_getChannel(const radio_unit_t radi
return rxData[3];
}
/* ======================================================================= Radio FIFO ======================================================================= */
/*
* Radio FIFO
*/
static void Si446x_writeFIFO(uint8_t *msg, uint8_t size) {
/* TODO: add hardware mapping. */
@ -528,7 +767,9 @@ static uint8_t Si446x_getTXfreeFIFO(const radio_unit_t radio) {
return rxData[3];
}
/* ====================================================================== Radio States ====================================================================== */
/*
* Radio States
*/
radio_signal_t Si446x_getCurrentRSSI(const radio_unit_t radio) {
/* TODO: add hardware mapping. */
@ -540,15 +781,6 @@ radio_signal_t Si446x_getCurrentRSSI(const radio_unit_t radio) {
return rxData[4];
}
void Si446x_getPartInfo(const radio_unit_t radio, si446x_info_t *info) {
/* TODO: add hardware mapping. */
(void)radio;
/* Get status. Leave any pending interrupts intact. */
const uint8_t status_info[] = {Si446x_GET_PART_INFO};
Si446x_read(status_info, sizeof(status_info), (uint8_t *)info,
sizeof(si446x_info_t));
}
static uint8_t Si446x_getState(const radio_unit_t radio) {
/* TODO: add hardware mapping. */
(void)radio;
@ -561,7 +793,7 @@ static uint8_t Si446x_getState(const radio_unit_t radio) {
static void Si446x_setTXState(const radio_unit_t radio, uint8_t chan, uint16_t size){
/* TODO: add hardware mapping. */
(void)radio;
uint8_t change_state_command[] = {0x31, chan,
uint8_t change_state_command[] = {Si446x_START_TX, chan,
(Si446x_STATE_READY << 4),
(size >> 8) & 0x1F, size & 0xFF};
Si446x_write(change_state_command, sizeof(change_state_command));
@ -570,42 +802,83 @@ static void Si446x_setTXState(const radio_unit_t radio, uint8_t chan, uint16_t s
static void Si446x_setReadyState(const radio_unit_t radio) {
/* TODO: add hardware mapping. */
(void)radio;
const uint8_t change_state_command[] = {0x34, 0x03};
const uint8_t change_state_command[] = {Si446x_CHANGE_STATE,
Si446x_STATE_READY};
Si446x_write(change_state_command, sizeof(change_state_command));
}
static void Si446x_setRXState(const radio_unit_t radio, uint8_t chan){
/* TODO: add hardware mapping. */
(void)radio;
const uint8_t change_state_command[] = {0x32, chan, 0x00, 0x00,
const uint8_t change_state_command[] = {Si446x_START_RX, chan, 0x00, 0x00,
0x00, 0x00, 0x08, 0x08};
Si446x_write(change_state_command, sizeof(change_state_command));
}
static void Si446x_setStandbyState(const radio_unit_t radio) {
/* TODO: add hardware mapping. */
(void)radio;
const uint8_t change_state_command[] = {Si446x_CHANGE_STATE,
Si446x_STATE_STANDBY};
Si446x_write(change_state_command, sizeof(change_state_command));
}
/**
*
*/
void Si446x_powerup(const radio_unit_t radio) {
TRACE_INFO("SI > Power up radio %i", radio);
packet_svc_t *handler = pktGetServiceObject(radio);
chDbgAssert(handler != NULL, "invalid radio ID");
palClearLine(LINE_RADIO_SDN); // Radio SDN low (power up transceiver)
chThdSleep(TIME_MS2I(10)); // Wait for transceiver to power up
void Si446x_radioStandby(const radio_unit_t radio) {
Si446x_setStandbyState(radio);
}
/**
* The GPIO LINE_RADIO_SDN is set high in board initialization.
* Thus the radio is in shutdown following board initialization.
* Si446x GPIO1 is configured to output CTS (option 8) during POR.
* We use the MCU GPIO connected to radio GPIO1 to check CTS here.
*
* Radio init is performed in the radio manager thread init stage.
* The radio GPIOs can be reconfigured after radio init is complete.
*/
void Si446x_shutdown(const radio_unit_t radio) {
TRACE_INFO("SI > Shutdown radio %i", radio);
bool Si446x_radioStartup(const radio_unit_t radio) {
TRACE_INFO("SI > Enable radio %i", radio);
/* Assert SDN low to perform POR wakeup. */
palClearLine(LINE_RADIO_SDN);
/*
* Set MCU GPIO input for POR and CTS of radio from GPIO0 and GPIO1.
* TODO: Add function to get radio_list record for this radio number.
* Then get LINE_GPIO_XXX from the radio record.
* Should these setups go into coreIO function?
*/
palSetLineMode(LINE_RADIO_GPIO0, PAL_MODE_INPUT_PULLDOWN);
palSetLineMode(LINE_RADIO_GPIO1, PAL_MODE_INPUT_PULLDOWN);
ioline_t cts = LINE_RADIO_GPIO1;
//return LINE_RADIO_GPIO1;
//ioline_t cts = pktSetLineModeRadioGPIO1(radio);
//pktSetLineModeRadioGPIO0(radio);
/* Wait for transceiver to wake up (maximum wakeup time is 6mS).
* During start up the POR state is on GPIO0.
* This goes from zero to one when POR completes.
* We could test this but for now just use a delay.
*/
chThdSleep(TIME_MS2I(10));
/* Return state of CTS after delay. */
return pktReadGPIOline(cts) == PAL_HIGH;
}
/**
* The radio is shutdown by setting LINE_RADIO_SDN high.
*/
void Si446x_radioShutdown(const radio_unit_t radio) {
TRACE_INFO("SI > Disable radio %i", radio);
packet_svc_t *handler = pktGetServiceObject(radio);
chDbgAssert(handler != NULL, "invalid radio ID");
//chDbgAssert(handler != NULL, "invalid radio ID");
//pktPowerDownRadio(radio);
palSetLine(LINE_RADIO_SDN);
handler->radio_init = false;
chThdSleep(TIME_MS2I(1));
}
/* ====================================================================== Radio TX/RX ======================================================================= */
@ -619,8 +892,6 @@ static bool Si446x_checkCCAthreshold(const radio_unit_t radio, uint8_t ms) {
/* TODO: Hardware mapping of radio. */
(void)radio;
uint16_t cca = 0;
/* Tick per millisecond. */
//sysinterval_t uslice = TIME_MS2I(1);
/* Measure sliced CCA instances in period. */
for(uint16_t i = 0; i < (ms * TIME_MS2I(1)); i++) {
cca += Si446x_getCCA();
@ -809,7 +1080,7 @@ void Si446x_disableReceive(const radio_unit_t radio) {
/* FIXME: */
if(Si446x_getState(radio) == Si446x_STATE_RX) {
//rx_frequency = 0;
Si446x_shutdown(radio);
Si446x_radioShutdown(radio);
}
}
@ -1374,7 +1645,7 @@ int16_t Si446x_getLastTemperature(const radio_unit_t radio) {
if(lastTemp == 0x7FFF) { // Temperature was never measured => measure it now
packet_svc_t *handler = pktGetServiceObject(radio);
chDbgAssert(handler != NULL, "invalid radio ID");
//chDbgAssert(handler != NULL, "invalid radio ID");
if(handler->radio_init) {
pktAcquireRadio(radio, TIME_INFINITE);

Wyświetl plik

@ -15,47 +15,49 @@
/* Module constants. */
/*===========================================================================*/
#define SI446X_EVT_TX_TIMEOUT EVENT_MASK(0)
#define SI446X_EVT_TX_TIMEOUT EVENT_MASK(0)
#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
*/
#define Si446x_LOCK_BY_SEMAPHORE TRUE
/* 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
#define Si446x_STATE_NOCHANGE 0
#define Si446x_STATE_SLEEP 1
#define Si446x_STATE_STANDBY 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_PART_INFO 0x01
#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
#define Si446x_NOP 0x00
#define Si446x_GET_PART_INFO 0x01
#define Si446x_POWER_UP 0x02
#define Si446x_GET_FUNC_INFO 0x10
#define Si446x_SET_PROPERTY 0x11
#define Si446x_GET_PROPERTY 0x12
#define Si446x_GPIO_PIN_CFG 0x13
#define Si446x_GET_ADC_READING 0x14
#define Si446x_FIFO_INFO 0x15
#define Si446x_PACKET_INFO 0x16
#define Si446x_GET_INT_STATUS 0x20
#define Si446x_GET_PH_STATUS 0x21
#define Si446x_GET_MODEM_STATUS 0x22
#define Si446x_GET_CHIP_STATUS 0x23
#define Si446x_START_TX 0x31
#define Si446x_START_RX 0x32
#define Si446x_REQUEST_DEVICE_STATE 0x33
#define Si446x_CHANGE_STATE 0x34
#define Si446x_RX_HOP 0x36
#define Si446x_TX_HOP 0x37
#define Si446x_READ_CMD_BUFF 0x44
#define Si446x_WRITE_TX_FIFO 0x66
#define Si446x_READ_RX_FIFO 0x77
/* Defined response values. */
#define Si446x_COMMAND_CTS 0xFF
#define Si446x_COMMAND_CTS 0xFF
/*
* Property group commands.
@ -97,6 +99,8 @@
#define Si446x_MODEM_IF_FREQ 0x201B
#define Si446x_MODEM_DECIMATION_CFG1 0x201E
#define Si446x_MODEM_DECIMATION_CFG0 0x201F
#define Si446x_MODEM_DECIMATION_CFG2 0x2020
#define Si446x_MODEM_IFPKD_THRESHOLDS 0x2021
#define Si446x_MODEM_BCR_OSR 0x2022
#define Si446x_MODEM_BCR_NCO_OFFSET 0x2024
#define Si446x_MODEM_BCR_GAIN 0x2027
@ -129,7 +133,16 @@
#define Si446x_MODEM_RSSI_CONTROL 0x204C
#define Si446x_MODEM_RSSI_CONTROL2 0x204D
#define Si446x_MODEM_RSSI_COMP 0x204E
#define Si446x_MODEM_RAW_SEARCH2 0x2050
#define Si446x_MODEM_CLKGEN_BAND 0x2051
#define Si446x_MODEM_SPIKE_DET 0x2054
#define Si446x_MODEM_ONE_SHOT_AFC 0x2055
#define Si446x_MODEM_RSSI_MUTE 0x2057
#define Si446x_MODEM_DSA_CTRL1 0x205B
#define Si446x_MODEM_DSA_CTRL2 0x205C
#define Si446x_MODEM_DSA_QUAL 0x205D
#define Si446x_MODEM_DSA_RSSI 0x205E
#define Si446x_MODEM_DSA_MISC 0x205F
#define Si446x_MODEM_CHFLT_RX1_CHFLT_COE13_7_0 0x2100
#define Si446x_MODEM_CHFLT_RX1_CHFLT_COE12_7_0 0x2101
@ -213,6 +226,10 @@
#define Si446x_CCLK ((Si446x_CLK) + (Si446x_CLK_OFFSET) \
* (Si446x_CLK) / 1000000)
#define is_part_Si4463(part) (part == 0x4463)
#define is_Si4463_patch_required(part, rom) (is_part_Si4463(part) && rom == 0x6)
/*===========================================================================*/
/* Module data structures and types. */
/*===========================================================================*/
@ -227,16 +244,15 @@ typedef struct {
/* Si446x part info. */
typedef struct {
uint8_t cmd;
uint8_t cts;
uint8_t chiprev;
uint16_t part;
uint8_t pbuild;
uint16_t id;
uint8_t customer;
uint8_t romid;
} si446x_info_t;
uint8_t info[10];
} si446x_part_t;
/* Si446x func info. */
typedef struct {
uint8_t info[10];
} si446x_func_t;
/* External. */
typedef struct radioTask radio_task_object_t;
/*===========================================================================*/
@ -249,8 +265,9 @@ extern void pktReleasePacketBuffer(packet_t pp);
extern "C" {
#endif
int16_t Si446x_getLastTemperature(const radio_unit_t radio);
void Si446x_powerup(const radio_unit_t radio);
void Si446x_shutdown(const radio_unit_t radio);
bool Si446x_radioStartup(const radio_unit_t radio);
void Si446x_radioShutdown(const radio_unit_t radio);
void Si446x_radioStandby(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);
@ -273,12 +290,11 @@ extern "C" {
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_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);
void Si446x_getPartInfo(const radio_unit_t radio, si446x_info_t *info);
#ifdef __cplusplus
}
#endif

Wyświetl plik

@ -0,0 +1,80 @@
// COPYRIGHT=2015 Silicon Laboratories, Inc.
// GENERATED=09:13 October 20 2015
// ROMID=0x06
// FUNCTION=TEST
// MAJOR=0
// MINOR=0
// BUILD=0
// PATCHID=0xCA90
// REQUIRES=NONE
// SIZE=512
// CRCT=0x714b
#define SI446X_PATCH_ROMID 00
#define SI446X_PATCH_ID 00
#define SI446X_PATCH_CMDS \
0x08,0x04,0x21,0x71,0x4B,0x00,0x00,0xDC,0x95, \
0x08,0x05,0xA6,0x22,0x21,0xF0,0x41,0x5B,0x26, \
0x08,0xE2,0x2F,0x1C,0xBB,0x0A,0xA8,0x94,0x28, \
0x08,0x05,0x87,0x67,0xE2,0x58,0x1A,0x07,0x5B, \
0x08,0xE1,0xD0,0x72,0xD8,0x8A,0xB8,0x5B,0x7D, \
0x08,0x05,0x11,0xEC,0x9E,0x28,0x23,0x1B,0x6D, \
0x08,0xE2,0x4F,0x8A,0xB2,0xA9,0x29,0x14,0x13, \
0x08,0x05,0xD1,0x2E,0x71,0x6A,0x51,0x4C,0x2C, \
0x08,0xE5,0x80,0x27,0x42,0xA4,0x69,0xB0,0x7F, \
0x08,0x05,0xAA,0x81,0x2A,0xBD,0x45,0xE8,0xA8, \
0x08,0xEA,0xE4,0xF0,0x24,0xC9,0x9F,0xCC,0x3C, \
0x08,0x05,0x08,0xF5,0x05,0x04,0x27,0x62,0x98, \
0x08,0xEA,0x6B,0x62,0x84,0xA1,0xF9,0x4A,0xE2, \
0x08,0x05,0xE9,0x77,0x05,0x4F,0x84,0xEE,0x35, \
0x08,0xE2,0x43,0xC3,0x8D,0xFB,0xAD,0x54,0x25, \
0x08,0x05,0x14,0x06,0x5E,0x39,0x36,0x2F,0x45, \
0x08,0xEA,0x0C,0x1C,0x74,0xD0,0x11,0xFC,0x32, \
0x08,0x05,0xDA,0x38,0xBA,0x0E,0x3C,0xE7,0x8B, \
0x08,0xEA,0xB0,0x09,0xE6,0xFF,0x94,0xBB,0xA9, \
0x08,0x05,0xD7,0x11,0x29,0xFE,0xDC,0x71,0xD5, \
0x08,0xEA,0x7F,0x83,0xA7,0x60,0x90,0x62,0x18, \
0x08,0x05,0x84,0x7F,0x6A,0xD1,0x91,0xC6,0x52, \
0x08,0xEA,0x2A,0xD8,0x7B,0x8E,0x4A,0x9F,0x91, \
0x08,0x05,0xBD,0xAA,0x9D,0x16,0x18,0x06,0x15, \
0x08,0xE2,0x55,0xAD,0x2D,0x0A,0x14,0x1F,0x5D, \
0x08,0x05,0xD3,0xE0,0x7C,0x39,0xCF,0x01,0xF0, \
0x08,0xEF,0x3A,0x91,0x72,0x6A,0x03,0xBB,0x96, \
0x08,0xE7,0x83,0x6D,0xA4,0x92,0xFC,0x13,0xA7, \
0x08,0xEF,0xF8,0xFD,0xCF,0x62,0x07,0x6F,0x1E, \
0x08,0xE7,0x4C,0xEA,0x4A,0x75,0x4F,0xD6,0xCF, \
0x08,0xE2,0xF6,0x11,0xE4,0x26,0x0D,0x4D,0xC6, \
0x08,0x05,0xFB,0xBF,0xE8,0x07,0x89,0xC3,0x51, \
0x08,0xEF,0x82,0x27,0x04,0x3F,0x96,0xA8,0x58, \
0x08,0xE7,0x41,0x29,0x3C,0x75,0x2A,0x03,0x1C, \
0x08,0xEF,0xAF,0x59,0x98,0x36,0xAA,0x0F,0x06, \
0x08,0xE6,0xF6,0x93,0x41,0x2D,0xEC,0x0E,0x99, \
0x08,0x05,0x29,0x19,0x90,0xE5,0xAA,0x36,0x40, \
0x08,0xE7,0xFB,0x68,0x10,0x7D,0x77,0x5D,0xC0, \
0x08,0xE7,0xCB,0xB4,0xDD,0xCE,0x90,0x54,0xBE, \
0x08,0xE7,0x72,0x8A,0xD6,0x02,0xF4,0xDD,0xCC, \
0x08,0xE7,0x6A,0x21,0x0B,0x02,0x86,0xEC,0x15, \
0x08,0xE7,0x7B,0x7C,0x3D,0x6B,0x81,0x03,0xD0, \
0x08,0xEF,0x7D,0x61,0x36,0x94,0x7C,0xA0,0xDF, \
0x08,0xEF,0xCC,0x85,0x3B,0xDA,0xE0,0x5C,0x1C, \
0x08,0xE7,0xE3,0x75,0xBB,0x39,0x22,0x4B,0xA8, \
0x08,0xEF,0xF9,0xCE,0xE0,0x5E,0xEB,0x1D,0xCB, \
0x08,0xE7,0xBD,0xE2,0x70,0xD5,0xAB,0x4E,0x3F, \
0x08,0xE7,0xB7,0x8D,0x20,0x68,0x6B,0x09,0x52, \
0x08,0xEF,0xA1,0x1B,0x90,0xCD,0x98,0x00,0x63, \
0x08,0xEF,0x54,0x67,0x5D,0x9C,0x11,0xFC,0x45, \
0x08,0xE7,0xD4,0x9B,0xC8,0x97,0xBE,0x8A,0x07, \
0x08,0xEF,0x52,0x8D,0x90,0x63,0x73,0xD5,0x2A, \
0x08,0xEF,0x03,0xBC,0x6E,0x1C,0x76,0xBE,0x4A, \
0x08,0xE7,0xC2,0xED,0x67,0xBA,0x5E,0x66,0x21, \
0x08,0xEF,0xE7,0x3F,0x87,0xBE,0xE0,0x7A,0x6D, \
0x08,0xE7,0xC9,0x70,0x93,0x1D,0x64,0xF5,0x6C, \
0x08,0xEF,0xF5,0x28,0x08,0x34,0xB3,0xB6,0x2C, \
0x08,0xEF,0x3A,0x0A,0xEC,0x0F,0xDB,0x56,0xCA, \
0x08,0xEF,0x39,0xA0,0x6E,0xED,0x79,0xD0,0x24, \
0x08,0xE7,0x6C,0x0B,0xAF,0xA9,0x4E,0x40,0xB5, \
0x08,0xE9,0xB9,0xAF,0xBF,0x25,0x50,0xD1,0x37, \
0x08,0x05,0x9E,0xDB,0xDE,0x3F,0x94,0xE9,0x6B, \
0x08,0xEC,0xC5,0x05,0xAA,0x57,0xDC,0x8A,0x5E, \
0x08,0x05,0x70,0xDA,0x84,0x84,0xDD,0xCA,0x90

Wyświetl plik

@ -11,6 +11,7 @@
#include "pflash.h"
#include "ublox.h"
#include <string.h>
#include <time.h>
static uint8_t usb_buffer[16*1024] __attribute__((aligned(32))); // USB image buffer
@ -28,10 +29,12 @@ const ShellCommand commands[] = {
#endif
{"sats", usb_cmd_get_gps_sat_info},
{"error_list", usb_cmd_get_error_list},
{"time", usb_cmd_time},
{"radio", usb_cmd_radio},
{NULL, NULL}
};
/*
/**
*
*/
void usb_cmd_get_gps_sat_info(BaseSequentialStream *chp, int argc, char *argv[]) {
@ -312,3 +315,81 @@ void usb_cmd_get_error_list(BaseSequentialStream *chp, int argc, char *argv[])
}
}
/**
*
*/
void usb_cmd_time(BaseSequentialStream *chp, int argc, char *argv[]) {
(void)argv;
if(argc > 0 && argc != 2) {
shellUsage(chp, "time [YYYY-MM-DD HH:MM:SS]");
return;
}
/* Read time from RTC. */
ptime_t time;
getTime(&time);
if(argc == 0) {
chprintf(chp, "RTC time %04d-%02d-%02d %02d:%02d:%02d\r\n",
time.year, time.month, time.day,
time.hour, time.minute, time.day);
chprintf(chp, "\r\nTo set time: time [YYYY-MM-DD HH:MM:SS]\r\n");
return;
}
/*
* TODO:
* - add error checking of values.
* - allow just date or time as parameter?
*/
struct tm cdate;
struct tm ctime;
strptime(argv[0], "%Y-%m-%d", &cdate);
strptime(argv[1], "%T", &ctime);
time.year = cdate.tm_year + 1900;
time.month = cdate.tm_mon + 1;
time.day = cdate.tm_mday;
time.hour = ctime.tm_hour;
time.minute = ctime.tm_min;
time.second = ctime.tm_sec;
setTime(&time);
/* struct tm {
int tm_sec; Seconds (0-60)
int tm_min; Minutes (0-59)
int tm_hour; Hours (0-23)
int tm_mday; Day of the month (1-31)
int tm_mon; Month (0-11)
int tm_year; Year - 1900
int tm_wday; Day of the week (0-6, Sunday = 0)
int tm_yday; Day in the year (0-365, 1 Jan = 0)
int tm_isdst; Daylight saving time
};*/
}
/**
* List type, part ROM rev and patch for radio.
*/
void usb_cmd_radio(BaseSequentialStream *chp, int argc, char *argv[]) {
(void)argv;
if(argc > 1) {
shellUsage(chp, "radio [number]");
return;
}
radio_unit_t radio;
if(argc == 0)
radio = PKT_RADIO_1;
else
radio = atoi(argv[0]);
int8_t num = pktGetNumRadios();
if(radio == 0 || radio > num) {
chprintf(chp, "Invalid radio number %d\r\n", radio);
return;
}
packet_svc_t *handler = pktGetServiceObject(radio);
chprintf(chp, "Radio %d info: part number %04x, rom revision %02x, "
"patch ID %04x\r\n",
radio, handler->radio_part,
handler->radio_rom_rev, handler->radio_patch);
}

Wyświetl plik

@ -14,6 +14,9 @@ void usb_cmd_set_test_gps(BaseSequentialStream *chp, int argc, char *argv[]);
void usb_cmd_ccm_heap(BaseSequentialStream *chp, int argc, char *argv[]);
void usb_cmd_get_gps_sat_info(BaseSequentialStream *chp, int argc, char *argv[]);
void usb_cmd_get_error_list(BaseSequentialStream *chp, int argc, char *argv[]);
void usb_cmd_time(BaseSequentialStream *chp, int argc, char *argv[]);
void usb_cmd_radio(BaseSequentialStream *chp, int argc, char *argv[]);
extern const ShellCommand commands[];
#endif

Wyświetl plik

@ -2,7 +2,7 @@
#include "hal.h"
#include "debug.h"
mutex_t trace_mtx; // Used internal to synchronize multiple chprintf in debug.h
//mutex_t trace_mtx; // Used internal to synchronize multiple chprintf in debug.h
char error_list[ERROR_LIST_SIZE][ERROR_LIST_LENGTH];
uint8_t error_counter;

Wyświetl plik

@ -22,12 +22,14 @@ extern const SerialConfig uart_config;
extern uint8_t usb_trace_level;
// Initializer for serial debug and LEDs
/*
#define DEBUG_INIT() { \
chMtxObjectInit(&trace_mtx); \
}
*/
#define TRACE_BASE(format, type, args...) { \
if(isSDUAvailable()) { \
if(isConsoleOutputAvailable()) { \
if(TRACE_TIME) { \
chprintf((BaseSequentialStream*)&SDU1, "[%8d.%03d]", chVTGetSystemTime()/CH_CFG_ST_FREQUENCY, (chVTGetSystemTime()*1000/CH_CFG_ST_FREQUENCY)%1000); \
} \
@ -66,6 +68,7 @@ extern uint8_t usb_trace_level;
#define TRACE_TAB " "
#endif
/*
#define TRACE_BIN(data, len) { \
chMtxLock(&trace_mtx); \
chprintf((BaseSequentialStream*)&SD3, "[%8d.%03d][DEBUG] ", chVTGetSystemTime()/CH_CFG_ST_FREQUENCY, (chVTGetSystemTime()*1000/CH_CFG_ST_FREQUENCY)%1000); \
@ -85,6 +88,7 @@ extern uint8_t usb_trace_level;
TRACE_TAB, i, (data)[i], (data)[i+1], (data)[i+2], (data)[i+3], (data)[i+4], (data)[i+5], (data)[i+6], (data)[i+7]); \
chMtxUnlock(&trace_mtx); \
}
*/
/*

Wyświetl plik

@ -1,156 +1,187 @@
#include "ch.h"
#include "hal.h"
#include "usbcfg.h"
#include "shell.h"
#include "commands.h"
#include "pktconf.h"
static thread_t *shelltp;
sdu_term_t sdu_chn_state;
event_listener_t sdu1_el;
static const ShellConfig shell_cfg = {
(BaseSequentialStream*)&SDU1,
commands
};
/*
*
*/
void startUSB(void) {
usbObjectInit(&USBD1);
usbStart(&USBD1, &usbcfg);
/* Currently does nothing. */
usbDisconnectBus(&USBD1);
chThdSleep(TIME_MS2I(100));
/* Currently does nothing. */
usbConnectBus(&USBD1);
sdu_chn_state = TERM_SDU_INIT;
}
/**
* @brief Manage trace output and shell on Serial Over USB.
*
*/
void startSDU(void) {
if(sdu_chn_state != TERM_SDU_INIT)
return;
sduObjectInit(&SDU1);
chEvtRegister(chnGetEventSource(&SDU1), &sdu1_el, USB_SDU1_EVT);
sduStart(&SDU1, &serusbcfg);
sdu_chn_state = TERM_SDU_START;
}
/**
* @brief Manage trace output and shell on Serial Over USB.
* @notes TRACE output is sent to USB serial.
* @notes TRACE output is suspended when any key is pressed on terminal.
* @notes A new shell is invoked and remains active until logout.
* @notes TRACE output is then resumed.
*
* @api
*/
void manageTraceAndShell(void) {
if(chEvtGetAndClearEvents(EVENT_MASK(USB_SDU1_EVT)) == 0)
return;
BaseSequentialStream *chp = (BaseSequentialStream *)&SDU1;
eventflags_t evtf = chEvtGetAndClearFlags(&sdu1_el);
switch(sdu_chn_state) {
case TERM_SDU_INIT:
break;
case TERM_SDU_START:
if(evtf & CHN_CONNECTED) {
sdu_chn_state = TERM_SDU_OUT;
chprintf(chp, "\r\n*** Terminal connected ***\r\n");
break;
}
if(evtf & CHN_DISCONNECTED) {
sdu_chn_state = TERM_SDU_IDLE;
break;
}
break;
case TERM_SDU_IDLE: {
/* if(evtf == 0)
break;*/
if(evtf & CHN_CONNECTED) {
sdu_chn_state = TERM_SDU_OUT;
chprintf(chp, "\r\n*** Trace output enabled ***\r\n");
//break;
}
break;
} /* End case TERM_SDU_IDLE */
case TERM_SDU_OUT: {
if(evtf & CHN_DISCONNECTED) {
sdu_chn_state = TERM_SDU_START;
break;
}
if(evtf & CHN_INPUT_AVAILABLE) {
/* Flush the input queue. */
while(chnGetTimeout((SerialUSBDriver *)chp,
TIME_MS2I(100)) != STM_TIMEOUT);
chprintf(chp, "\r\n*** Trace suspended - type ^D or use the "
"'exit' command to resume trace ***\r\n");
shellInit();
shelltp = chThdCreateFromHeap(NULL,
THD_WORKING_AREA_SIZE(4*1024),
"shell", NORMALPRIO + 1,
shellThread,
(void*)&shell_cfg);
if(shelltp == NULL) {
chprintf(chp, "\r\n*** Failed to open shell ***\r\n");
break;
}
sdu_chn_state = TERM_SDU_SHELL;
}
break;
} /* End case TERM_SDU_OUT */
case TERM_SDU_SHELL: {
/* USB disconnect. */
if(evtf & CHN_DISCONNECTED) {
chThdTerminate(shelltp);
sdu_chn_state = TERM_SDU_EXIT;
break;
}
/* Was shell terminated from CLI? */
if(chThdTerminatedX(shelltp)) {
chThdWait(shelltp);
shelltp = NULL;
sdu_chn_state = TERM_SDU_OUT;
chprintf(chp, "\r\n*** Trace resumed by user ***\r\n");
}
break;
} /* End case TERM_SDU_SHELL */
case TERM_SDU_EXIT: {
chThdWait(shelltp);
shelltp = NULL;
sdu_chn_state = TERM_SDU_START;
break;
} /* End case TERM_SDU_EXIT */
default:
break;
} /* End switch. */
}
/*
*
*/
bool isSDUAvailable(void) {
/* Return channel connection status of SDU. */
return (bool)(sdu_chn_state == TERM_SDU_OUT);
}
#include "ch.h"
#include "hal.h"
#include "usbcfg.h"
#include "shell.h"
#include "commands.h"
#include "pktconf.h"
static const ShellConfig shell_cfg = {
(BaseSequentialStream*)&SDU1,
commands
};
static con_chn_state_t console_state;
/**
* @brief Manage trace output and shell on Serial Over USB.
* @notes TRACE output is sent to USB serial.
* @notes TRACE output is suspended when any key is pressed on terminal.
* @notes A new shell is invoked and remains active until logout.
* @notes TRACE output is then resumed.
*
* @thread
*/
THD_FUNCTION(pktConsole, arg) {
BaseAsynchronousChannel *driver = (BaseAsynchronousChannel *)arg;
event_listener_t con_el;
thread_t *shelltp;
chEvtRegisterMaskWithFlags(chnGetEventSource(driver),
&con_el,
CONSOLE_CHANNEL_EVT,
CHN_CONNECTED | CHN_DISCONNECTED | CHN_INPUT_AVAILABLE);
console_state = CON_CHN_READY;
/* Next run the handshake protocol to start the control thread. */
/*Wait for start from initiator. */
thread_t *initiator = chMsgWait();
(void)chMsgGet(initiator);
/* Release the initiator which next enables the channel. */
chMsgRelease(initiator, MSG_OK);
/* Wait for channel to be started. */
initiator = chMsgWait();
(void)chMsgGet(initiator);
/* Release the initiator which then completes. */
chMsgRelease(initiator, MSG_OK);
while(true) {
chEvtWaitAny(CONSOLE_CHANNEL_EVT);
BaseSequentialStream *chp = (BaseSequentialStream *)driver;
eventflags_t evtf = chEvtGetAndClearFlags(&con_el);
switch(console_state) {
case CON_CHN_READY:
if(evtf & CHN_CONNECTED) {
console_state = CON_CHN_OUT;
chprintf(chp, "\r\n*** Terminal connected ***\r\n");
break;
}
if(evtf & CHN_DISCONNECTED) {
console_state = CON_CHN_IDLE;
break;
}
break;
case CON_CHN_IDLE: {
if(evtf & CHN_CONNECTED) {
console_state = CON_CHN_OUT;
chprintf(chp, "\r\n*** Trace output enabled ***\r\n");
}
break;
} /* End case TERM_SDU_IDLE */
case CON_CHN_OUT: {
if(evtf & CHN_DISCONNECTED) {
console_state = CON_CHN_READY;
break;
}
if(evtf & CHN_INPUT_AVAILABLE) {
/* Flush the input queue. */
while(chnGetTimeout((SerialUSBDriver *)chp,
TIME_MS2I(100)) != STM_TIMEOUT);
chprintf(chp, "\r\n*** Trace suspended - type ^D or use the "
"'exit' command to resume trace ***\r\n");
shellInit();
shelltp = chThdCreateFromHeap(NULL,
THD_WORKING_AREA_SIZE(4*1024),
"shell", NORMALPRIO + 1,
shellThread,
(void*)&shell_cfg);
if(shelltp == NULL) {
chprintf(chp, "\r\n*** Failed to open shell ***\r\n");
break;
}
console_state = CON_CHN_SHELL;
}
break;
} /* End case TERM_SDU_OUT */
case CON_CHN_SHELL: {
/* USB disconnect. */
if(evtf & CHN_DISCONNECTED) {
chThdTerminate(shelltp);
console_state = CON_CHN_EXIT;
break;
}
/* Was shell terminated from CLI? */
if(chThdTerminatedX(shelltp)) {
chThdWait(shelltp);
shelltp = NULL;
console_state = CON_CHN_OUT;
chprintf(chp, "\r\n*** Trace resumed by user ***\r\n");
}
break;
} /* End case TERM_SDU_SHELL */
case CON_CHN_EXIT: {
chThdWait(shelltp);
shelltp = NULL;
console_state = CON_CHN_READY;
break;
} /* End case TERM_SDU_EXIT */
default:
break;
} /* End switch. */
}
}
/*
* TODO: Defer configure of GPIO USB so a disconnect can be signaled on D+.
* Set D+ (LINE_USB_DP) as pushpull out and low in board.h.
* Then delay here before setting alternate mode to enable USB IO.
* Rename this function to pktStartConsole.
*/
msg_t pktStartConsole(void) {
/* Init and start USB. */
usbObjectInit(&USBD1);
usbStart(&USBD1, &usbcfg);
/* Set SDIS in USB controller. */
usbDisconnectBus(&USBD1);
chThdSleep(TIME_MS2I(1000));
/* Remove SDIS. */
usbConnectBus(&USBD1);
/* Init serial over USB. */
sduObjectInit(&SDU1);
/* Start the console handler. */
thread_t *console = chThdCreateFromHeap(NULL,
THD_WORKING_AREA_SIZE(1024),
"CON",
LOWPRIO + 10,
pktConsole,
&SDU1);
if(console == NULL)
return MSG_TIMEOUT;
/* Wait for thread to start. */
msg_t smsg = chMsgSend(console, MSG_OK);
/* Start serial over USB. */
sduStart(&SDU1, &serusbcfg);
/* Signal thread to enter event monitoring. */
smsg = chMsgSend(console, MSG_OK);
return smsg;
}
/**
*
*/
bool isConsoleOutputAvailable(void) {
/* Return channel connection status of SDU. */
return (bool)(console_state == CON_CHN_OUT);
}

Wyświetl plik

@ -1,24 +1,24 @@
#ifndef __USB_H__
#define __USB_H__
#include "ch.h"
#include "hal.h"
typedef enum sduTermStates {
TERM_SDU_INIT = 0,
TERM_SDU_START,
TERM_SDU_IDLE,
TERM_SDU_OUT,
TERM_SDU_SHELL,
TERM_SDU_EXIT
} sdu_term_t;
#define isUSBactive() (SDU1.config->usbp->state == USB_ACTIVE)
void startUSB(void);
void startSDU(void);
void manageTraceAndShell(void);
bool isSDUAvailable(void);
#endif
#ifndef __USB_H__
#define __USB_H__
#include "ch.h"
#include "hal.h"
typedef enum consoleStates {
CON_CHN_INIT = 0,
CON_CHN_READY,
CON_CHN_IDLE,
CON_CHN_OUT,
CON_CHN_SHELL,
CON_CHN_EXIT
} con_chn_state_t;
#define isUSBactive() (SDU1.config->usbp->state == USB_ACTIVE)
msg_t pktStartConsole(void);
void startSDU(void);
void manageTraceAndShell(void);
bool isConsoleOutputAvailable(void);
#endif

Wyświetl plik

@ -3,8 +3,9 @@
* pins of the Pecan. The I2C bus is bitbanged and operates at 45 kHz if the
* STM32 is operated at SYSCLK=48MHz.
*
* TXD pin: SCL
* RXD pin: SDA
* GPIO pins...
* EI2C_SCL
* EI2C_SDA
*
* @see https://en.wikipedia.org/wiki/I%C2%B2C
*/
@ -14,32 +15,29 @@
#include "debug.h"
#include "portab.h"
#define SCL LINE_IO_TXD /* SCL is connected to the TXD labeled line */
#define SDA LINE_IO_RXD /* SDA is connected to the RXD labeled line */
static bool started = false;
static inline bool read_SCL(void) { // Return current level of SCL line, 0 or 1
palSetLineMode(SCL, PAL_MODE_INPUT_PULLUP | PAL_STM32_OSPEED_HIGHEST);
return palReadLine(SCL);
palSetLineMode(EI2C_SCL, PAL_MODE_INPUT_PULLUP | PAL_STM32_OSPEED_HIGHEST);
return palReadLine(EI2C_SCL);
}
static inline bool read_SDA(void) { // Return current level of SDA line, 0 or 1
palSetLineMode(SDA, PAL_MODE_INPUT_PULLUP | PAL_STM32_OSPEED_HIGHEST);
return palReadLine(SDA);
palSetLineMode(EI2C_SDA, PAL_MODE_INPUT_PULLUP | PAL_STM32_OSPEED_HIGHEST);
return palReadLine(EI2C_SDA);
}
static inline void set_SCL(void) { // Do not drive SCL(set pin high-impedance)
palSetLineMode(SCL, PAL_MODE_INPUT_PULLUP | PAL_STM32_OSPEED_HIGHEST);
palSetLineMode(EI2C_SCL, PAL_MODE_INPUT_PULLUP | PAL_STM32_OSPEED_HIGHEST);
}
static inline void clear_SCL(void) { // Actively drive SCL signal low
palSetLineMode(SCL, PAL_MODE_OUTPUT_PUSHPULL | PAL_STM32_OSPEED_HIGHEST);
palClearLine(SCL);
palSetLineMode(EI2C_SCL, PAL_MODE_OUTPUT_PUSHPULL | PAL_STM32_OSPEED_HIGHEST);
palClearLine(EI2C_SCL);
}
static inline void set_SDA(void) { // Do not drive SDA(set pin high-impedance)
palSetLineMode(SDA, PAL_MODE_INPUT_PULLUP | PAL_STM32_OSPEED_HIGHEST);
palSetLineMode(EI2C_SDA, PAL_MODE_INPUT_PULLUP | PAL_STM32_OSPEED_HIGHEST);
}
static inline void clear_SDA(void) { // Actively drive SDA signal low
palSetLineMode(SDA, PAL_MODE_OUTPUT_PUSHPULL | PAL_STM32_OSPEED_HIGHEST);
palClearLine(SDA);
palSetLineMode(EI2C_SDA, PAL_MODE_OUTPUT_PUSHPULL | PAL_STM32_OSPEED_HIGHEST);
palClearLine(EI2C_SDA);
}
static inline void arbitration_lost(void) {
TRACE_ERROR("arbitration_lost");
@ -53,7 +51,6 @@ static void i2c_start_cond(void) {
set_SCL();
sysinterval_t t0 = chVTGetSystemTime();
while(read_SCL() == 0 && TIME_I2MS(chVTGetSystemTime()-t0) < 10) { // Clock stretching
// You should add timeout to this loop
}
}
if(read_SDA() == 0)
@ -71,7 +68,6 @@ static void i2c_stop_cond(void) {
// Clock stretching
sysinterval_t t0 = chVTGetSystemTime();
while(read_SCL() == 0 && TIME_I2MS(chVTGetSystemTime()-t0) < 10) { // Clock stretching
// add timeout to this loop.
}
// SCL is high, set SDA from 0 to 1
@ -95,7 +91,6 @@ static void i2c_write_bit(bool bit) {
// Wait for SDA value to be read by slave, minimum of 4us for standard mode
sysinterval_t t0 = chVTGetSystemTime();
while(read_SCL() == 0 && TIME_I2MS(chVTGetSystemTime()-t0) < 10) { // Clock stretching
// You should add timeout to this loop
}
// SCL is high, now data is valid
@ -118,7 +113,6 @@ static bool i2c_read_bit(void) {
sysinterval_t t0 = chVTGetSystemTime();
while(read_SCL() == 0 && TIME_I2MS(chVTGetSystemTime()-t0) < 10) { // Clock stretching
// You should add timeout to this loop
}
// SCL is high, read out bit

Wyświetl plik

@ -15,6 +15,7 @@
*/
#include "pktconf.h"
#include "portab.h"
/*===========================================================================*/
/* Driver exported variables. */
@ -198,7 +199,7 @@ void pktDisablePWM(AFSKDemodDriver *myDriver) {
chSysLock();
/* Close the PWM stream. */
pktClosePWMChannelI(myDriver->icudriver, 0, PWM_TERM_DECODE_STOP);
pktClosePWMChannelI(myDriver->icudriver, EVT_NONE, PWM_TERM_DECODE_STOP);
/* Stop ICU capture. */
icuStopCaptureI(myDriver->icudriver);
@ -593,7 +594,7 @@ AFSKDemodDriver *pktCreateAFSKDecoder(packet_svc_t *pktHandler) {
/* Create the AFSK decoder thread. */
extern memory_heap_t *ccm_heap;
myDriver->decoder_thd = chThdCreateFromHeap(ccm_heap,
myDriver->decoder_thd = chThdCreateFromHeap(NULL,
THD_WORKING_AREA_SIZE(PKT_AFSK_DECODER_WA_SIZE),
myDriver->decoder_name,
NORMALPRIO - 10,
@ -831,24 +832,24 @@ THD_FUNCTION(pktAFSKDecoder, arg) {
pkt_data_object_t *myPktBuffer = pktTakeDataBuffer(myHandler,
pkt_buffer_pool,
TIME_MS2I(100));
#if AFSK_DEBUG_TYPE == AFSK_PWM_DATA_CAPTURE_DEBUG
char buf[80];
int out = chsnprintf(buf, sizeof(buf),
"\r\n======= START ===========\r\n");
pktWrite( (uint8_t *)buf, out);
#endif
/* If no buffer is available the handler pointer is also set to NULL. */
if(myPktBuffer == NULL) {
/* Decrease ref count on AX25 FIFO. */
chFactoryReleaseObjectsFIFO(pkt_fifo);
pktAddEventFlags(myHandler, EVT_AX25_NO_BUFFER);
myDriver->active_demod_object->status |=
EVT_AX25_NO_BUFFER;
pktAddEventFlags(myHandler, EVT_PKT_NO_BUFFER);
//myDriver->active_demod_object->status |= EVT_AX25_NO_BUFFER;
myDriver->decoder_state = DECODER_RESET;
break;
}
#if AFSK_DEBUG_TYPE == AFSK_PWM_DATA_CAPTURE_DEBUG
char buf[80];
int out = chsnprintf(buf, sizeof(buf),
"\r\n======= START ===========\r\n");
chnWrite(pkt_out, (uint8_t *)buf, out);
#endif
/* Increase thread priority. */
(void)chThdSetPriority(DECODER_RUN_PRIORITY);
/* Turn on the decoder LED. */
@ -884,7 +885,7 @@ THD_FUNCTION(pktAFSKDecoder, arg) {
if(n != sizeof(packed_pwm_counts_t)) {
/* PWM stream wait timeout. */
pktAddEventFlags(myHandler, EVT_PWM_STREAM_TIMEOUT);
myDriver->active_demod_object->status |= EVT_PWM_STREAM_TIMEOUT;
//myDriver->active_demod_object->status |= EVT_PWM_STREAM_TIMEOUT;
myDriver->decoder_state = DECODER_RESET;
break;
}
@ -895,7 +896,7 @@ THD_FUNCTION(pktAFSKDecoder, arg) {
char buf[80];
int out = chsnprintf(buf, sizeof(buf), "%i, %i\r\n",
radio.pwm.impulse, radio.pwm.valley);
chnWrite(pkt_out, (uint8_t *)buf, out);
pktWrite( (uint8_t *)buf, out);
#endif
/* Look for "in band" message in radio data. */
@ -931,6 +932,11 @@ THD_FUNCTION(pktAFSKDecoder, arg) {
continue; /* Decoder state switch. */
} /* End case. */
/* If PWM reports a zero impulse or valley.
* The PWM side has already posted a PWM_STREAM_CLOSE event.
*/
case PWM_TERM_ICU_ZERO:
/* If CCA ends and the decoder has not validated any frame.
* The PWM side has already posted a PWM_STREAM_CLOSE event.
*/
@ -1044,6 +1050,19 @@ THD_FUNCTION(pktAFSKDecoder, arg) {
*/
case DECODER_RESET: {
if(myHandler->active_packet_object != NULL) {
#if AFSK_DEBUG_TYPE == AFSK_PWM_DATA_CAPTURE_DEBUG
char buf[80];
int out = chsnprintf(buf, sizeof(buf),
"\r\n======= STOP ===========\r\n");
pktWrite( (uint8_t *)buf, out);
#endif
#if AFSK_DEBUG_TYPE == AFSK_AX25_RAW_PACKET_DUMP \
|| AFSK_DEBUG_TYPE == AFSK_PWM_DATA_CAPTURE_DEBUG
pktDumpAX25Frame(myHandler->active_packet_object->buffer,
myHandler->active_packet_object->packet_size,
AX25_DUMP_RAW);
#endif
#if USE_CCM_HEAP_RX_BUFFERS == TRUE
/* Free the packet buffer in the heap now. */
chHeapFree(myHandler->active_packet_object->buffer);
@ -1068,13 +1087,10 @@ THD_FUNCTION(pktAFSKDecoder, arg) {
/*
* Lock the PWM queue to stop any further radio data being written.
*/
myDriver->active_demod_object->status |= EVT_AFSK_DECODE_RESET;
myDriver->active_demod_object->status |= STA_AFSK_DECODE_RESET;
/*
* Wait for FIFO stream control object to be free from the radio.
* Normally this semaphore will not suspend as decoding is slow.
* If can be a forced release by semaphore reset.
* TODO: This may happen if the watchdog system forces reset.
* TBD.
*/
(void)chBSemWait(&myFIFO->sem);
@ -1135,22 +1151,23 @@ THD_FUNCTION(pktAFSKDecoder, arg) {
* Indicate AFSK decode done.
* If PWM is still being captured for this stream capture will cease.
*/
eventflags_t evtf = EVT_AFSK_DECODE_DONE;
myDriver->active_demod_object->status |= evtf;
//eventflags_t evtf = EVT_NONE;
myDriver->active_demod_object->status |= STA_AFSK_DECODE_DONE;
/* Copy latest status into packet buffer object. */
myHandler->active_packet_object->status =
myDriver->active_demod_object->status;
/* Dispatch the packet buffer object and get AX25 events. */
evtf |= pktDispatchReceivedBuffer(myHandler->active_packet_object);
myHandler->active_packet_object->status |=
pktDispatchReceivedBuffer(myHandler->active_packet_object);
/* Forget the packet object. */
/* Remove the packet object reference. */
myHandler->active_packet_object = NULL;
/* Send events then update demod object status. */
pktAddEventFlags(myHandler, evtf);
myDriver->active_demod_object->status |= evtf;
//pktAddEventFlags(myHandler, evtf);
//myDriver->active_demod_object->status |= evtf;
} /* Active packet object != NULL. */
myDriver->decoder_state = DECODER_RESET;
break;

Wyświetl plik

@ -51,7 +51,7 @@
#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_AX25_RAW_PACKET_DUMP 8
#define AFSK_DEBUG_TYPE AFSK_NO_DEBUG
@ -77,7 +77,7 @@
#define USE_QCORR_MAG_LPF TRUE
#define MAG_FILTER_NUM_TAPS 15U
#define MAG_FILTER_BLOCK_SIZE 1U
#define MAG_FILTER_BLOCK_SIZE 1U
#if MAG_FILTER_BLOCK_SIZE != 1
#error "Filter block size must be 1"
#endif
@ -162,7 +162,7 @@ typedef struct AFSK_data {
/**
* @brief pointer to the packet handler.
*/
packet_svc_t *packet_handler;
packet_svc_t *packet_handler;
/**
* @brief Event source object.

Wyświetl plik

@ -96,11 +96,11 @@ THD_FUNCTION(pktPWMispatcher, arg) {
*
* @api
*/
ICUDriver *pktAttachICU(radio_unit_t radio_id) {
ICUDriver *pktAttachICU(radio_unit_t radio) {
/* For now there is only one radio and a fixed ICU association.
* TODO: Implement Radio <-> ICU association code and data structure.
*/
(void)radio_id;
//(void)radio_id;
/*
* Initialize the RX_DATA capture ICU.
@ -113,7 +113,7 @@ ICUDriver *pktAttachICU(radio_unit_t radio_id) {
/* The RX_DATA input is routed to ICU timer.
* Set in portab.c
*/
pktSetLineModeICU();
(void)pktSetLineModeICU(radio);
/* If using PWM mirror to output to a diagnostic port. */
pktSetGPIOlineMode(LINE_PWM_MIRROR, PAL_MODE_OUTPUT_PUSHPULL);
@ -214,7 +214,7 @@ void pktClosePWMChannelI(ICUDriver *myICU, eventflags_t evt, pwm_code_t reason)
/* Stop the ICU notification (callback). */
icuDisableNotificationsI(myICU);
if(myDemod->active_radio_object != NULL) {
myDemod->active_radio_object->status |= (EVT_PWM_STREAM_CLOSED | evt);
myDemod->active_radio_object->status |= (STA_PWM_STREAM_CLOSED | evt);
pktAddEventFlagsI(myHandler, evt);
#if USE_HEAP_PWM_BUFFER == TRUE
input_queue_t *myQueue =
@ -236,7 +236,7 @@ void pktClosePWMChannelI(ICUDriver *myICU, eventflags_t evt, pwm_code_t reason)
* In any case flag the error.
*/
pktWriteGPIOline(LINE_OVERFLOW_LED, PAL_HIGH);
myDemod->active_radio_object->status |= EVT_PWM_QUEUE_OVERRUN;
//myDemod->active_radio_object->status |= EVT_PWM_QUEUE_OVERRUN;
pktAddEventFlagsI(myHandler, EVT_PWM_QUEUE_OVERRUN);
}
/* Allow the decoder thread to release the stream FIFO object. */
@ -527,10 +527,10 @@ void pktRadioCCATrailTimer(ICUDriver *myICU) {
* Hence the decoder is responsible for releasing the PWM FIFO object.
* Prior to releasing the FIFO the decoder waits on the FIFO semaphore.
* Closing PWM from here sets the FIFO management semaphore.
* This caters for the case where the decoder terminates stram processing first.
* This caters for the case where the decoder terminates stream processing first.
* This may happen if noise produces a long string of data.
*/
pktClosePWMChannelI(myICU, EVT_PWM_STREAM_CLOSE, PWM_TERM_CCA_CLOSE);
pktClosePWMChannelI(myICU, EVT_NONE, PWM_TERM_CCA_CLOSE);
break;
}
@ -649,7 +649,7 @@ void pktRadioICUPeriod(ICUDriver *myICU) {
* flag may cause trailing PWM activity.
*
*/
if((myDemod->active_radio_object->status & EVT_AFSK_DECODE_DONE) != 0) {
if((myDemod->active_radio_object->status & STA_AFSK_DECODE_DONE) != 0) {
pktClosePWMChannelI(myICU, EVT_NONE, PWM_ACK_DECODE_END);
chSysUnlockFromISR();
return;
@ -660,11 +660,21 @@ void pktRadioICUPeriod(ICUDriver *myICU) {
* This will happen when no AX25 buffer is available or overflows.
* Close the PWM stream and wait for next radio CCA.
*/
if((myDemod->active_radio_object->status & EVT_AFSK_DECODE_RESET) != 0) {
if((myDemod->active_radio_object->status & STA_AFSK_DECODE_RESET) != 0) {
pktClosePWMChannelI(myICU, EVT_NONE, PWM_ACK_DECODE_ERROR);
chSysUnlockFromISR();
return;
}
/*
* Check if impulse ICU value is zero and thus invalid.
*/
if(icuGetWidthX(myICU) == 0) {
pktClosePWMChannelI(myICU, EVT_NONE, PWM_TERM_ICU_ZERO);
chSysUnlockFromISR();
return;
}
/* Write ICU data to PWM queue. */
msg_t qs = pktQueuePWMDataI(myICU);

Wyświetl plik

@ -45,7 +45,7 @@
#define PWM_ACK_DECODE_END 4
#define PWM_TERM_DECODE_STOP 5
#define PWM_TERM_NO_DATA 6
//#define PWM_TERM_QUEUE_LOCK 7
#define PWM_TERM_ICU_ZERO 7
#define PWM_INFO_QUEUE_SWAP 8
#define PWM_ACK_DECODE_ERROR 9

Wyświetl plik

@ -207,7 +207,7 @@ q31_t push_qcorr_sample(AFSKDemodDriver *myDriver, bit_t sample) {
#if AFSK_DEBUG_TYPE == AFSK_QCORR_FIR_DEBUG
char buf[80];
int out = chsnprintf(buf, sizeof(buf), "%X\r\n", scaledOut);
chnWrite(pkt_out, (uint8_t *)buf, out);
pktWrite( (uint8_t *)buf, out);
#endif
/*
@ -261,7 +261,7 @@ bool process_qcorr_output(AFSKDemodDriver *myDriver) {
int out = chsnprintf(buf, sizeof(buf), "%i, %i\r\n",
myBin->cos_out, myBin->sin_out);
}
chnWrite(pkt_out, (uint8_t *)buf, out);
pktWrite( (uint8_t *)buf, out);
#endif
}
@ -294,7 +294,7 @@ bool process_qcorr_output(AFSKDemodDriver *myDriver) {
i, decoder->filter_bins[i].mag,
decoder->current_n,
decoder->current_n % decoder->decode_length);
chnWrite(pkt_out, (uint8_t *)buf, out);
pktWrite( (uint8_t *)buf, out);
}
#endif
@ -508,7 +508,7 @@ void calc_qcorr_magnitude(AFSKDemodDriver *myDriver) {
int out = chsnprintf(buf, sizeof(buf), \
"MAG SQRT failed bin %i, cosQ %X, sinQ %X, cos %f, sin %f, mag2 %f, mag %X, index %i\r\n", \
i, myBin->cos_out, myBin->sin_out, cos, sin, mag2, raw_mag, decoder->current_n);
chnWrite(pkt_out, (uint8_t *)buf, out);
pktWrite( (uint8_t *)buf, out);
#endif /* AFSK_ERROR_TYPE == AFSK_SQRT_ERROR */
#else
@ -528,7 +528,7 @@ void calc_qcorr_magnitude(AFSKDemodDriver *myDriver) {
"mag2 %X, mag %X, index %i\r\n",
i, myBin->cos_out, myBin->sin_out, cos, sin, mag2,
decoder->filter_bins[i].raw_mag, decoder->current_n);
chnWrite(pkt_out, (uint8_t *)buf, out);
pktWrite( (uint8_t *)buf, out);
#endif /* AFSK_ERROR_TYPE == AFSK_SQRT_ERROR */
#endif /* QCORR_MAG_USE_FLOAT */
}
@ -540,7 +540,7 @@ void calc_qcorr_magnitude(AFSKDemodDriver *myDriver) {
} else {
out = chsnprintf(buf, sizeof(buf), "%i\r\n", raw_mag);
}
chnWrite(pkt_out, (uint8_t *)buf, out);
pktWrite( (uint8_t *)buf, out);
#endif
}
}
@ -576,7 +576,7 @@ void filter_qcorr_magnitude(AFSKDemodDriver *myDriver) {
decoder->filter_bins[i].raw_mag,
decoder->filter_bins[i].filtered_mag);
}
chnWrite(pkt_out, (uint8_t *)buf, out);
pktWrite( (uint8_t *)buf, out);
#endif
}
}
@ -619,7 +619,7 @@ void evaluate_qcorr_tone(AFSKDemodDriver *myDriver) {
char buf[200];
int out = chsnprintf(buf, sizeof(buf), "%i, %i\r\n",
mark, space);
chnWrite(pkt_out, (uint8_t *)buf, out);
pktWrite( (uint8_t *)buf, out);
#endif
}
@ -660,7 +660,7 @@ static void setup_qcorr_prefilter(qcorr_decoder_t *decoder) {
char buf[80];
int out = chsnprintf(buf, sizeof(buf),
"PRE FILTER COEFF %f %x\r\n", coeff_total_f32, coeff_total_q31);
chnWrite(pkt_out, (uint8_t *)buf, out);
pktWrite( (uint8_t *)buf, out);
#endif
}
@ -791,7 +791,7 @@ static void setup_qcorr_magfilter(qcorr_decoder_t *decoder) {
char buf[80];
int out = chsnprintf(buf, sizeof(buf),
"MAG FILTER COEFF %f %x\r\n", bin_coeff_total_f32, bin_coeff_total_q31);
chnWrite(pkt_out, (uint8_t *)buf, out);
pktWrite( (uint8_t *)buf, out);
#endif
}
#endif

Wyświetl plik

@ -1,25 +1,28 @@
/*
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.
*/
/*===========================================================================*/
/* Aerospace Decoder configuration definition and ChibiOS system includes. */
/*===========================================================================*/
#include "pktconf.h"
/**
* @file dbguart.c
* @brief Serial channels for debug.
*
* @addtogroup IODevices
* @{
*/
/** @} */
/*
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.
*/
/*===========================================================================*/
/* Aerospace Decoder configuration definition and ChibiOS system includes. */
/*===========================================================================*/
#include "pktconf.h"
#include "dbguart.h"
/**
* @file dbguart.c
* @brief Serial channels for debug.
*
* @addtogroup IODevices
* @{
*/
binary_semaphore_t debug_out_sem;
//BaseSequentialStream* pkt_out = (BaseSequentialStream*)SERIAL_CFG_DEBUG_DRIVER;
/** @} */

Wyświetl plik

@ -1,42 +1,43 @@
/*
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 dbguart.h
* @brief Definitions for UART4.
*
* @addtogroup IODevices
* @{
*/
#ifndef DEVICES_DBGUART_H_
#define DEVICES_DBGUART_H_
#include "portab.h"
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#define DBG_ERROR 1
#define DBG_WARN 2
#define DBG_INFO 3
#define DBG_DEBUG 4
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif /* DEVICES_DBGUART_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 dbguart.h
* @brief Definitions for UART4.
*
* @addtogroup IODevices
* @{
*/
#ifndef DEVICES_DBGUART_H_
#define DEVICES_DBGUART_H_
#include "portab.h"
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#define DBG_ERROR 1
#define DBG_WARN 2
#define DBG_INFO 3
#define DBG_DEBUG 4
#ifdef __cplusplus
extern "C" {
#endif
extern BaseSequentialStream* pkt_out;
#ifdef __cplusplus
}
#endif
#endif /* DEVICES_DBGUART_H_ */
/** @} */

Wyświetl plik

@ -1,145 +1,145 @@
/*
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 ax25_dump.c
* @brief Packet dump utility.
*
* @addtogroup DSP
* @{
*/
#include "pktconf.h"
/* Buffer and size params for serial terminal output. */
char serial_buf[1024];
int serial_out;
/* Access control semaphore. */
extern binary_semaphore_t diag_out_sem;
void pktDumpAX25Frame(ax25char_t *frame_buffer,
ax25size_t frame_size, ax25_select_t which) {
if(which == AX25_DUMP_ALL || which == AX25_DUMP_RAW) {
ax25size_t bufpos;
ax25size_t bufpos_a = 0;
/* Write out a buffer line as hex first. */
for(bufpos = 0; bufpos < frame_size; bufpos++) {
if((bufpos + 1) % DUMP_LINE_LENGTH == 0) {
serial_out = chsnprintf(serial_buf, sizeof(serial_buf),
"%02x\r\n", frame_buffer[bufpos]);
pktWrite((uint8_t *)serial_buf, serial_out);
/* Write out full line of converted ASCII under hex.*/
bufpos_a = (bufpos + 1) - DUMP_LINE_LENGTH;
do {
char asciichar = frame_buffer[bufpos_a];
if(asciichar == 0x7e) {
asciichar = '^';
} else {
asciichar >>= 1;
if(!((asciichar >= 0x70 && asciichar < 0x7a)
|| (asciichar > 0x2f && asciichar < 0x3a)
|| (asciichar > 0x40 && asciichar < 0x5b))) {
asciichar = 0x20;
} else if(asciichar >= 0x70 && asciichar < 0x7a) {
asciichar &= 0x3f;
}
}
if((bufpos_a + 1) % DUMP_LINE_LENGTH == 0) {
serial_out = chsnprintf(serial_buf,
sizeof(serial_buf),
" %c\r\n", asciichar);
} else {
serial_out = chsnprintf(serial_buf,
sizeof(serial_buf),
" %c ", asciichar);
}
pktWrite((uint8_t *)serial_buf, serial_out);
} while(bufpos_a++ < bufpos);
} else {
serial_out = chsnprintf(serial_buf, sizeof(serial_buf),
"%02x ", frame_buffer[bufpos]);
pktWrite((uint8_t *)serial_buf, serial_out);
}
} /* End for(bufpos = 0; bufpos < frame_size; bufpos++). */
serial_out = chsnprintf(serial_buf, sizeof(serial_buf), "\r\n");
pktWrite((uint8_t *)serial_buf, serial_out);
/* Write out remaining partial line of converted ASCII under hex. */
do {
char asciichar = frame_buffer[bufpos_a];
if(asciichar == 0x7e) {
asciichar = '^';
} else {
asciichar >>= 1;
if(!((asciichar >= 0x70 && asciichar < 0x7a)
|| (asciichar > 0x2f && asciichar < 0x3a)
|| (asciichar > 0x40 && asciichar < 0x5b))) {
asciichar = 0x20;
} else if(asciichar >= 0x70 && asciichar < 0x7a) {
asciichar &= 0x3f;
}
}
serial_out = chsnprintf(serial_buf, sizeof(serial_buf),
" %c ", asciichar);
pktWrite((uint8_t *)serial_buf, serial_out);
} while(++bufpos_a < bufpos);
serial_out = chsnprintf(serial_buf, sizeof(serial_buf), "\r\n");
pktWrite((uint8_t *)serial_buf, serial_out);
} /* End raw dump. */
}
void pktDiagnosticOutput(packet_svc_t *packetHandler,
pkt_data_object_t *myPktFIFO) {
chBSemWait(&diag_out_sem);
/* Buffer and size params for serial terminal output. */
char serial_buf[1024];
int serial_out;
/* Packet buffer. */
ax25char_t *frame_buffer = myPktFIFO->buffer;
uint16_t frame_size = myPktFIFO->packet_size;
if(pktIsBufferValidAX25Frame(myPktFIFO)) {
uint16_t magicCRC = calc_crc16(frame_buffer, 0, frame_size);
float32_t good = (float32_t)packetHandler->good_count
/ (float32_t)packetHandler->valid_count;
serial_out = chsnprintf(serial_buf, sizeof(serial_buf),
"AFSK... mode: %s, factory: %s, status: %x"
", packet count: %u sync count: %u"
" valid frames: %u"
" good frames: %u (%.2f%%), bytes: %u"
", CRCm: %04x\r\n",
((packetHandler->usr_callback == NULL) ? "polling" : "callback"),
packetHandler->pbuff_name,
myPktFIFO->status,
packetHandler->sync_count,
packetHandler->frame_count,
packetHandler->valid_count,
packetHandler->good_count,
(good * 100),
frame_size,
magicCRC
);
dbgWrite(DBG_INFO, (uint8_t *)serial_buf, serial_out);
/* Dump the frame contents out. */
pktDumpAX25Frame(frame_buffer, frame_size, AX25_DUMP_RAW);
} else { /* End if valid frame. */
serial_out = chsnprintf(serial_buf, sizeof(serial_buf),
"Invalid frame, status %x, bytes %u\r\n",
myPktFIFO->status, myPktFIFO->packet_size);
dbgWrite(DBG_INFO, (uint8_t *)serial_buf, serial_out);
}
chBSemSignal(&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 ax25_dump.c
* @brief Packet dump utility.
*
* @addtogroup DSP
* @{
*/
#include "pktconf.h"
/* Buffer and size params for serial terminal output. */
char serial_buf[1024];
int serial_out;
/* Access control semaphore. */
extern binary_semaphore_t debug_out_sem;
void pktDumpAX25Frame(ax25char_t *frame_buffer,
ax25size_t frame_size, ax25_select_t which) {
if(which == AX25_DUMP_ALL || which == AX25_DUMP_RAW) {
ax25size_t bufpos;
ax25size_t bufpos_a = 0;
/* Write out a buffer line as hex first. */
for(bufpos = 0; bufpos < frame_size; bufpos++) {
if((bufpos + 1) % DUMP_LINE_LENGTH == 0) {
serial_out = chsnprintf(serial_buf, sizeof(serial_buf),
"%02x\r\n", frame_buffer[bufpos]);
pktWrite((uint8_t *)serial_buf, serial_out);
/* Write out full line of converted ASCII under hex.*/
bufpos_a = (bufpos + 1) - DUMP_LINE_LENGTH;
do {
char asciichar = frame_buffer[bufpos_a];
if(asciichar == 0x7e) {
asciichar = '^';
} else {
asciichar >>= 1;
if(!((asciichar >= 0x70 && asciichar < 0x7a)
|| (asciichar > 0x2f && asciichar < 0x3a)
|| (asciichar > 0x40 && asciichar < 0x5b))) {
asciichar = 0x20;
} else if(asciichar >= 0x70 && asciichar < 0x7a) {
asciichar &= 0x3f;
}
}
if((bufpos_a + 1) % DUMP_LINE_LENGTH == 0) {
serial_out = chsnprintf(serial_buf,
sizeof(serial_buf),
" %c\r\n", asciichar);
} else {
serial_out = chsnprintf(serial_buf,
sizeof(serial_buf),
" %c ", asciichar);
}
pktWrite((uint8_t *)serial_buf, serial_out);
} while(bufpos_a++ < bufpos);
} else {
serial_out = chsnprintf(serial_buf, sizeof(serial_buf),
"%02x ", frame_buffer[bufpos]);
pktWrite((uint8_t *)serial_buf, serial_out);
}
} /* End for(bufpos = 0; bufpos < frame_size; bufpos++). */
serial_out = chsnprintf(serial_buf, sizeof(serial_buf), "\r\n");
pktWrite((uint8_t *)serial_buf, serial_out);
/* Write out remaining partial line of converted ASCII under hex. */
do {
char asciichar = frame_buffer[bufpos_a];
if(asciichar == 0x7e) {
asciichar = '^';
} else {
asciichar >>= 1;
if(!((asciichar >= 0x70 && asciichar < 0x7a)
|| (asciichar > 0x2f && asciichar < 0x3a)
|| (asciichar > 0x40 && asciichar < 0x5b))) {
asciichar = 0x20;
} else if(asciichar >= 0x70 && asciichar < 0x7a) {
asciichar &= 0x3f;
}
}
serial_out = chsnprintf(serial_buf, sizeof(serial_buf),
" %c ", asciichar);
pktWrite((uint8_t *)serial_buf, serial_out);
} while(++bufpos_a < bufpos);
serial_out = chsnprintf(serial_buf, sizeof(serial_buf), "\r\n");
pktWrite((uint8_t *)serial_buf, serial_out);
} /* End raw dump. */
}
void pktDiagnosticOutput(packet_svc_t *packetHandler,
pkt_data_object_t *myPktFIFO) {
chBSemWait(&debug_out_sem);
/* Buffer and size params for serial terminal output. */
char serial_buf[1024];
int serial_out;
/* Packet buffer. */
ax25char_t *frame_buffer = myPktFIFO->buffer;
uint16_t frame_size = myPktFIFO->packet_size;
if(pktIsBufferValidAX25Frame(myPktFIFO)) {
uint16_t magicCRC = calc_crc16(frame_buffer, 0, frame_size);
float32_t good = (float32_t)packetHandler->good_count
/ (float32_t)packetHandler->valid_count;
serial_out = chsnprintf(serial_buf, sizeof(serial_buf),
"AFSK... mode: %s, factory: %s, status: %x"
", packet count: %u sync count: %u"
" valid frames: %u"
" good frames: %u (%.2f%%), bytes: %u"
", CRCm: %04x\r\n",
((packetHandler->usr_callback == NULL) ? "polling" : "callback"),
packetHandler->pbuff_name,
myPktFIFO->status,
packetHandler->sync_count,
packetHandler->frame_count,
packetHandler->valid_count,
packetHandler->good_count,
(good * 100),
frame_size,
magicCRC
);
dbgWrite(DBG_INFO, (uint8_t *)serial_buf, serial_out);
/* Dump the frame contents out. */
pktDumpAX25Frame(frame_buffer, frame_size, AX25_DUMP_RAW);
} else { /* End if valid frame. */
serial_out = chsnprintf(serial_buf, sizeof(serial_buf),
"Invalid frame, status %x, bytes %u\r\n",
myPktFIFO->status, myPktFIFO->packet_size);
dbgWrite(DBG_INFO, (uint8_t *)serial_buf, serial_out);
}
chBSemSignal(&debug_out_sem);
}
/** @} */

Wyświetl plik

@ -12,18 +12,22 @@ event_listener_t pkt_el;
static bool trace_enabled = false;
void pktEnableEventTrace() {
chEvtRegister(pktGetEventSource(&RPKTD1), &pkt_el, 1);
void pktEnableEventTrace(radio_unit_t radio) {
packet_svc_t *handler = pktGetServiceObject(radio);
chEvtRegister(pktGetEventSource(handler), &pkt_el, 1);
trace_enabled = true;
}
void pktDisableEventTrace() {
void pktDisableEventTrace(radio_unit_t radio) {
packet_svc_t *handler = pktGetServiceObject(radio);
trace_enabled = false;
chEvtUnregister(pktGetEventSource(&RPKTD1), &pkt_el);
chEvtUnregister(pktGetEventSource(handler), &pkt_el);
}
/*
* TODO: Refactor and add severity categories filtering
* TODO:
* - Refactor and add severity categories filtering
* - Add packet service listener object per radio.
*/
void pktTraceEvents() {
if(!trace_enabled)
@ -37,20 +41,26 @@ eventmask_t evt = chEvtGetAndClearEvents(EVENT_MASK(1));
if(flags & EVT_PWM_FIFO_EMPTY) {
TRACE_WARN("PKT > PWM FIFO exhausted");
}
if(flags & EVT_AX25_NO_BUFFER) {
if(flags & EVT_PKT_NO_BUFFER) {
TRACE_WARN("PKT > AX25 FIFO exhausted");
}
if(flags & EVT_ICU_SLEEP_TIMEOUT) {
TRACE_INFO("PKT > PWM ICU has entered sleep");
}
if(flags & EVT_AX25_BUFFER_FULL) {
if(flags & EVT_PKT_BUFFER_FULL) {
TRACE_WARN("PKT > AX25 receive buffer full");
}
if(flags & EVT_PWM_QUEUE_OVERRUN) {
TRACE_ERROR("PKT > PWM queue overrun");
}
if(flags & EVT_PWM_INVALID_INBAND) {
TRACE_ERROR("PKT > Invalid PWM in-band flag");
TRACE_ERROR("PKT > Invalid PWM in-band message");
}
if(flags & EVT_PWM_NO_DATA) {
TRACE_ERROR("PKT > No PWM data from radio");
}
if(flags & EVT_PKT_FAILED_CB_THD) {
TRACE_ERROR("PKT > Failed to create RX callback thread");
}
/* if(flags & EVT_ICU_OVERFLOW) {
TRACE_DEBUG("PKT > PWM ICU overflow");
@ -59,7 +69,7 @@ eventmask_t evt = chEvtGetAndClearEvents(EVENT_MASK(1));
TRACE_WARN("PKT > PWM stream timeout");
}
if(flags & EVT_PWM_NO_DATA) {
TRACE_WARN("PKT > PWM data not started from radio");
TRACE_WARN("PKT > No PWM data from radio");
}
if(flags & EVT_AFSK_START_FAIL) {
TRACE_ERROR("PKT > AFSK decoder failed to start");

Wyświetl plik

@ -1,36 +1,36 @@
/*
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 pktevt.h
* @brief Packet event tracing.
*
* @addtogroup pktdiag
* @{
*/
#ifndef PKT_DIAGNOSTICS_PKTEVT_H_
#define PKT_DIAGNOSTICS_PKTEVT_H_
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#ifdef __cplusplus
extern "C" {
#endif
void pktTraceEvents(void);
void pktEnableEventTrace(void);
void pktDisableEventTrace(void);
#ifdef __cplusplus
}
#endif
#endif /* PKT_DIAGNOSTICS_PKTEVT_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 pktevt.h
* @brief Packet event tracing.
*
* @addtogroup pktdiag
* @{
*/
#ifndef PKT_DIAGNOSTICS_PKTEVT_H_
#define PKT_DIAGNOSTICS_PKTEVT_H_
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#ifdef __cplusplus
extern "C" {
#endif
void pktTraceEvents(void);
void pktEnableEventTrace(radio_unit_t radio);
void pktDisableEventTrace(radio_unit_t radio);
#ifdef __cplusplus
}
#endif
#endif /* PKT_DIAGNOSTICS_PKTEVT_H_ */
/** @} */

Wyświetl plik

@ -29,7 +29,7 @@
* @notes Receive tasks start the receive/decode system which are threads.
* @notes Transmit tasks should be handled in threads (and are in 446x).
*
* @param[in] arg pointer to a @p radio task queue for this thread.
* @param[in] arg pointer to a @p packet service object for this radio.
*
* @return status (MSG_OK) on exit.
*
@ -37,7 +37,7 @@
*/
THD_FUNCTION(pktRadioManager, arg) {
/* When waiting for TX tasks to complete. */
#define PKT_RADIO_TASK_MANAGER_WAIT_RATE_MS 100
#define PKT_RADIO_TX_TASK_RECHECK_WAIT_MS 100
packet_svc_t *handler = arg;
@ -49,8 +49,19 @@ THD_FUNCTION(pktRadioManager, arg) {
chDbgAssert(radio_queue != NULL, "no queue in radio manager FIFO");
/* Run until terminate request and no outstanding TX tasks. */
const radio_unit_t radio = handler->radio;
/* Take radio out of shutdown and initialize base registers. */
bool init = pktLLDradioInit(radio);
thread_t *initiator = chMsgWait();
chMsgGet(initiator);
if(!init) {
chMsgRelease(initiator, MSG_ERROR);
chThdExit(MSG_OK);
}
chMsgRelease(initiator, MSG_OK);
/* Run until close request and no outstanding TX tasks. */
while(true) {
/* Check for task requests. */
radio_task_object_t *task_object;
@ -58,26 +69,25 @@ THD_FUNCTION(pktRadioManager, arg) {
(void *)&task_object, TIME_INFINITE);
/* Something to do. */
const radio_unit_t radio = handler->radio;
/* Process command. */
switch(task_object->command) {
case PKT_RADIO_MGR_CLOSE: {
/*
* Radio manager terminate is sent as a task object.
* Radio manager close is sent as a task object.
* When no TX tasks are outstanding release the FIFO and terminate.
* The task initiator waits with chThdWait(...).
*/
if(handler->tx_count == 0) {
pktLLDradioShutdown(radio);
chFactoryReleaseObjectsFIFO(handler->the_radio_fifo);
chThdExit(MSG_OK);
/* We never arrive here. */
return;
}
/*
* There are still TX sessions running.
* Wait, repost task, let the FIFO be processed and check again.
*/
chThdSleep(TIME_MS2I(PKT_RADIO_TASK_MANAGER_WAIT_RATE_MS));
chThdSleep(TIME_MS2I(PKT_RADIO_TX_TASK_RECHECK_WAIT_MS));
pktSubmitRadioTask(radio, task_object, NULL);
continue;
}
@ -129,8 +139,6 @@ THD_FUNCTION(pktRadioManager, arg) {
break;
} /* End switch on modulation type. */
/* Initialise the radio. */
pktLLDradioInit(radio);
break;
} /* End case PKT_RADIO_OPEN. */
@ -144,7 +152,6 @@ THD_FUNCTION(pktRadioManager, arg) {
/* Enable receive. */
if(pktLLDradioEnableReceive(radio, task_object))
pktLLDradioStartDecoder(radio);
//pktStartDecoder(radio);
/* Unlock radio and allow transmit requests. */
pktReleaseRadio(radio);
@ -165,7 +172,6 @@ THD_FUNCTION(pktRadioManager, arg) {
/* TODO: Abstract acquire and release in LLD. */
pktAcquireRadio(radio, TIME_INFINITE);
pktLLDradioStopDecoder(radio);
//pktStopDecoder(handler->radio);
pktReleaseRadio(radio);
break;
} /* End case. */
@ -183,7 +189,6 @@ THD_FUNCTION(pktRadioManager, arg) {
++handler->radio_tx_config.tx_seq_num;
/* Pause the decoder. */
pktLLDradioPauseDecoding(radio);
//pktPauseDecoding(radio);
if(pktLLDradioSendPacket(task_object)) {
/*
* Keep count of active sends.
@ -203,7 +208,8 @@ THD_FUNCTION(pktRadioManager, arg) {
pktReleaseBufferChain(pp);
if(pktIsReceivePaused(radio)) {
if(!pktLLDradioResumeReceive(radio)) {
TRACE_ERROR("RAD > Receive failed to resume after transmit");
TRACE_ERROR("RAD > Receive on radio %d failed to "
"resume after transmit", radio);
break;
}
pktLLDradioResumeDecoding(radio);
@ -217,8 +223,7 @@ THD_FUNCTION(pktRadioManager, arg) {
thread_t *decoder = NULL;
switch(task_object->type) {
case MOD_AFSK: {
/* TODO: Implement LLD abstraction closing decoder. */
//Si446x_disableReceive(radio);
/* Stop receive. */
pktLLDradioDisableReceive(radio);
/* TODO: This should be a function back in pktservice or rxafsk. */
esp = pktGetEventSource((AFSKDemodDriver *)handler->link_controller);
@ -278,25 +283,26 @@ THD_FUNCTION(pktRadioManager, arg) {
msg_t send_msg = chThdWait(task_object->thread);
if(send_msg == MSG_TIMEOUT) {
TRACE_ERROR("RAD > Transmit timeout");
TRACE_ERROR("RAD > Transmit timeout on radio %d", radio);
}
if(send_msg == MSG_RESET) {
TRACE_ERROR("RAD > Transmit failed to start");
TRACE_ERROR("RAD > Transmit failed to start on radio %d", radio);
}
/* If no transmissions pending then enable RX or power down. */
if(--handler->tx_count == 0) {
/* Check at handler level is OK. No LLD required. */
if(pktIsReceivePaused(radio)) {
if(!pktLLDradioResumeReceive(radio)) {
TRACE_ERROR("RAD > Receive failed to resume after transmit");
TRACE_ERROR("RAD > Receive on radio %d failed to "
"resume after transmit", radio);
break;
}
/* TODO: Implement LLD since resume depends on radio and mod type. */
pktLLDradioResumeDecoding(radio);
//pktResumeDecoding(radio);
} else {
/* Power down radio. */
pktLLDradioPowerDown(radio);
/* Enter standby state (low power). */
TRACE_INFO("RAD > Radio %d entering standby", radio);
pktLLDradioStandby(radio);
}
} /* Else more TX tasks outstanding so let those complete. */
break;
@ -325,7 +331,7 @@ thread_t *pktRadioManagerCreate(const radio_unit_t radio) {
packet_svc_t *handler = pktGetServiceObject(radio);
chDbgAssert(handler != NULL, "invalid radio ID");
//chDbgAssert(handler != NULL, "invalid radio ID");
/* Create the radio manager name. */
chsnprintf(handler->rtask_name, sizeof(handler->rtask_name),
@ -343,7 +349,7 @@ thread_t *pktRadioManagerCreate(const radio_unit_t radio) {
handler->the_radio_fifo = the_radio_fifo;
dbgPrintf(DBG_INFO, "PKT > radio manager thread created. FIFO @ 0x%x\r\n",
TRACE_INFO("PKT > radio manager thread created. FIFO @ 0x%x",
the_radio_fifo);
/* Start the task dispatcher thread. */
@ -359,9 +365,22 @@ thread_t *pktRadioManagerCreate(const radio_unit_t radio) {
if(handler->radio_manager == NULL) {
chFactoryReleaseObjectsFIFO(the_radio_fifo);
handler->the_packet_fifo = NULL;
return NULL;
}
return handler->radio_manager;
msg_t init = chMsgSend(handler->radio_manager, MSG_OK);
if(init == MSG_OK)
return handler->radio_manager;
/* Radio init failed so clean up. */
chFactoryReleaseObjectsFIFO(the_radio_fifo);
handler->the_packet_fifo = NULL;
chThdTerminate(handler->radio_manager);
handler->radio_manager = NULL;
return NULL;
}
/**
@ -408,7 +427,7 @@ msg_t pktGetRadioTaskObjectI(const radio_unit_t radio,
packet_svc_t *handler = pktGetServiceObject(radio);
chDbgAssert(handler != NULL, "invalid radio ID");
//chDbgAssert(handler != NULL, "invalid radio ID");
dyn_objects_fifo_t *task_fifo = handler->the_radio_fifo;
chDbgAssert(task_fifo != NULL, "no radio task fifo");
@ -441,7 +460,7 @@ void pktSubmitRadioTaskI(const radio_unit_t radio,
const radio_task_cb_t cb) {
packet_svc_t *handler = pktGetServiceObject(radio);
chDbgAssert(handler != NULL, "invalid radio ID");
//chDbgAssert(handler != NULL, "invalid radio ID");
dyn_objects_fifo_t *task_fifo = handler->the_radio_fifo;
chDbgAssert(task_fifo != NULL, "no radio task fifo");
@ -483,7 +502,7 @@ msg_t pktGetRadioTaskObject(const radio_unit_t radio,
packet_svc_t *handler = pktGetServiceObject(radio);
chDbgAssert(handler != NULL, "invalid radio ID");
//chDbgAssert(handler != NULL, "invalid radio ID");
dyn_objects_fifo_t *task_fifo =
chFactoryFindObjectsFIFO(handler->rtask_name);
@ -519,7 +538,7 @@ void pktSubmitRadioTask(const radio_unit_t radio,
const radio_task_cb_t cb) {
packet_svc_t *handler = pktGetServiceObject(radio);
chDbgAssert(handler != NULL, "invalid radio ID");
//chDbgAssert(handler != NULL, "invalid radio ID");
dyn_objects_fifo_t *task_fifo = handler->the_radio_fifo;
chDbgAssert(task_fifo != NULL, "no radio task fifo");
@ -597,7 +616,7 @@ void pktReleaseRadio(const radio_unit_t radio) {
}
/*
*
* TODO: Refactor this to use an array of strings.
*/
int pktDisplayFrequencyCode(const radio_freq_t code, char *buf, size_t size) {
char* str = NULL;
@ -619,11 +638,11 @@ int pktDisplayFrequencyCode(const radio_freq_t code, char *buf, size_t size) {
break;
case FREQ_CMDC_RECEIVE:
str = "CNC Receivefrequency";
str = "CNC Receive frequency";
break;
case FREQ_APRS_DEFAULT:
str = "APRS Defaultfrequency";
str = "APRS Default frequency";
break;
case FREQ_CODES_END:
@ -688,7 +707,7 @@ radio_freq_t pktGetReceiveOperatingFrequency(const radio_unit_t radio) {
}
/*
*
* TODO: Rework to use max radio and start and PKT_RADIO_1 in loop.
*/
radio_freq_t pktCheckAllowedFrequency(const radio_unit_t radio,
radio_freq_t freq) {
@ -710,6 +729,20 @@ radio_freq_t pktCheckAllowedFrequency(const radio_unit_t radio,
return FREQ_RADIO_INVALID;
}
/**
* Get radio data.
*/
const radio_config_t *pktGetRadioData(radio_unit_t radio) {
const radio_config_t *radio_list = pktGetRadioList();
uint8_t i = 0;
while(radio_list[i].unit != PKT_RADIO_NONE) {
if(radio_list[i].unit == radio)
return &radio_list[i];
i++;
}
return NULL;
}
/**
* @brief Compute an operating frequency.
* @notes All special frequency codes are resolved to an actual frequency.
@ -770,30 +803,20 @@ radio_freq_t pktComputeOperatingFrequency(const radio_unit_t radio,
/**
*
*/
void pktLLDradioInit(const radio_unit_t radio) {
bool pktLLDradioInit(const radio_unit_t radio) {
/* TODO: Implement hardware mapping. */
Si446x_conditional_init(radio);
}
/**
*
*/
void pktLLDradioPowerUp(const radio_unit_t radio) {
/* TODO: Implement hardware mapping. */
(void)radio;
/*
* NOTE: RADIO_CS and RADIO_SDN pins are configured in board.h
* RADIO_SDN is configured to open drain as it is pulled up on PCB by 100K.
* RADIO_SDN is configured to open drain pullup.
* It is also pulled up on PCB by 100K.
* The radio powers up in SDN mode.
*
* CS is set as push-pull and initialized to HIGH.
*/
// Power up transceiver
Si446x_powerup(radio);
return Si446x_conditional_init(radio);
}
void pktLLDradioPowerDown(const radio_unit_t radio) {
void pktLLDradioShutdown(const radio_unit_t radio) {
/* TODO: Implement hardware mapping. */
(void)radio;
@ -801,8 +824,18 @@ void pktLLDradioPowerDown(const radio_unit_t radio) {
* Put radio in shutdown mode.
* All registers are lost.
*/
//palSetLine(LINE_RADIO_SDN);
Si446x_shutdown(radio);
Si446x_radioShutdown(radio);
}
void pktLLDradioStandby(const radio_unit_t radio) {
/* TODO: Implement hardware mapping. */
(void)radio;
/*
* Put radio in standby (low power) mode.
* All registers are retained.
*/
Si446x_radioStandby(radio);
}
/**
@ -852,7 +885,7 @@ bool pktLLDradioEnableReceive(const radio_unit_t radio,
radio_task_object_t *rto) {
packet_svc_t *handler = pktGetServiceObject(radio);
chDbgAssert(handler != NULL, "invalid radio ID");
//chDbgAssert(handler != NULL, "invalid radio ID");
if(handler == NULL)
return false;
@ -896,7 +929,7 @@ void pktLLDradioDisableReceive(const radio_unit_t radio) {
bool pktLLDradioResumeReceive(const radio_unit_t radio) {
packet_svc_t *handler = pktGetServiceObject(radio);
chDbgAssert(handler != NULL, "invalid radio ID");
//chDbgAssert(handler != NULL, "invalid radio ID");
radio_freq_t freq = handler->radio_rx_config.base_frequency;
channel_hz_t step = handler->radio_rx_config.step_hz;
@ -921,7 +954,7 @@ bool pktLLDradioResumeReceive(const radio_unit_t radio) {
*/
void pktLLDradioCaptureRSSI(const radio_unit_t radio) {
packet_svc_t *handler = pktGetServiceObject(radio);
chDbgAssert(handler != NULL, "invalid radio ID");
//chDbgAssert(handler != NULL, "invalid radio ID");
handler->rx_stength = Si446x_getCurrentRSSI(radio);
}

Wyświetl plik

@ -29,7 +29,7 @@
/* The number of radio task object the FIFO has. */
#define RADIO_TASK_QUEUE_MAX 10
#define NUM_BANDS_PER_RADIO 2
//#define NUM_BANDS_PER_RADIO 2
#define PKT_RADIO_MANAGER_TASK_KILL TRUE
@ -124,50 +124,49 @@ struct radioTask {
/* External declarations. */
/*===========================================================================*/
extern const radio_config_t *radio_list;
#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,
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,
void pktSubmitRadioTask(const radio_unit_t radio,
radio_task_object_t *object,
radio_task_cb_t cb);
void pktScheduleThreadRelease(const radio_unit_t radio,
void pktScheduleThreadRelease(const radio_unit_t radio,
thread_t *thread);
msg_t pktAcquireRadio(const radio_unit_t radio, sysinterval_t timeout);
void pktReleaseRadio(const radio_unit_t radio);
radio_freq_t pktCheckAllowedFrequency(const radio_unit_t radio,
msg_t pktAcquireRadio(const radio_unit_t radio, sysinterval_t timeout);
void pktReleaseRadio(const radio_unit_t radio);
radio_freq_t pktCheckAllowedFrequency(const radio_unit_t radio,
radio_freq_t freq);
radio_freq_t pktComputeOperatingFrequency(const 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 pktLLDradioEnableReceive(const radio_unit_t radio,
bool pktLLDradioEnableReceive(const radio_unit_t radio,
radio_task_object_t *rto);
void pktLLDradioDisableReceive(const radio_unit_t radio);
bool pktLLDradioResumeReceive(const radio_unit_t radio);
bool pktLLDradioSendPacket(radio_task_object_t *rto);
void pktLLDradioCaptureRSSI(const radio_unit_t radio);
void pktLLDradioPowerUp(const radio_unit_t radio);
void pktLLDradioInit(const radio_unit_t radio);
void pktLLDradioPowerDown(const radio_unit_t radio);
void pktLLDradioPauseDecoding(const radio_unit_t radio);
void pktLLDradioResumeDecoding(const radio_unit_t radio);
void pktLLDradioStartDecoder(const radio_unit_t radio);
void pktLLDradioStopDecoder(const radio_unit_t radio);
void pktLLDradioSendComplete(radio_task_object_t *rto,
void pktLLDradioDisableReceive(const radio_unit_t radio);
bool pktLLDradioResumeReceive(const radio_unit_t radio);
bool pktLLDradioSendPacket(radio_task_object_t *rto);
void pktLLDradioCaptureRSSI(const radio_unit_t radio);
//bool pktLLDradioExitShutdown(const radio_unit_t radio);
bool pktLLDradioInit(const radio_unit_t radio);
void pktLLDradioStandby(const radio_unit_t radio);
void pktLLDradioShutdown(const radio_unit_t radio);
void pktLLDradioPauseDecoding(const radio_unit_t radio);
void pktLLDradioResumeDecoding(const radio_unit_t radio);
void pktLLDradioStartDecoder(const radio_unit_t radio);
void pktLLDradioStopDecoder(const radio_unit_t radio);
void pktLLDradioSendComplete(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);
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);
const radio_config_t *pktGetRadioData(radio_unit_t radio);
#ifdef __cplusplus
}
#endif
@ -177,7 +176,7 @@ extern "C" {
/*===========================================================================*/
/**
* @brief Alias for convenience of pktStopDecoder.
* @brief Alias of pktStopDecoder for convenience.
*
* @param[in] radio radio unit ID
*

Wyświetl plik

@ -366,7 +366,7 @@ void pktStartDecoder(const radio_unit_t radio) {
packet_svc_t *handler = pktGetServiceObject(radio);
chDbgAssert(handler != NULL, "invalid radio ID");
//chDbgAssert(handler != NULL, "invalid radio ID");
if(!pktIsReceivePaused(radio))
/* Wrong state. */
@ -465,8 +465,8 @@ void pktStopDecoder(radio_unit_t radio) {
packet_svc_t *handler = pktGetServiceObject(radio);
if(handler == NULL)
chDbgAssert(false, "invalid radio ID");
/* if(handler == NULL)
chDbgAssert(false, "invalid radio ID");*/
if(!pktIsReceiveActive(radio))
return;
@ -609,10 +609,10 @@ eventflags_t pktDispatchReceivedBuffer(pkt_data_object_t *pkt_buffer) {
if(magicCRC == CRC_INCLUSIVE_CONSTANT)
handler->good_count++;
flags |= (magicCRC == CRC_INCLUSIVE_CONSTANT)
? EVT_AX25_FRAME_RDY
: EVT_AX25_CRC_ERROR;
? STA_PKT_FRAME_RDY
: STA_PKT_CRC_ERROR;
} else {
flags |= EVT_PKT_INVALID_FRAME;
flags |= STA_PKT_INVALID_FRAME;
}
/* Update status in packet buffer object. */
@ -633,9 +633,10 @@ eventflags_t pktDispatchReceivedBuffer(pkt_data_object_t *pkt_buffer) {
chDbgAssert(cb_thd != NULL, "failed to create callback thread");
if(cb_thd == NULL) {
/* Failed to create CB thread. Release buffer. Flag event. */
/* Failed to create CB thread. Release buffer. Broadcast event. */
chFifoReturnObject(pkt_fifo, pkt_buffer);
flags |= EVT_PKT_FAILED_CB_THD;
pktAddEventFlags(handler, EVT_PKT_FAILED_CB_THD);
//flags |= EVT_PKT_FAILED_CB_THD;
} else {
/* Increase outstanding callback count. */
@ -807,7 +808,7 @@ void pktCallbackManagerOpen(radio_unit_t radio) {
packet_svc_t *handler = pktGetServiceObject(radio);
chDbgAssert(handler != NULL, "invalid radio ID");
//chDbgAssert(handler != NULL, "invalid radio ID");
/* Create the callback handler thread name. */
chsnprintf(handler->cbend_name, sizeof(handler->cbend_name),
@ -832,7 +833,7 @@ dyn_objects_fifo_t *pktIncomingBufferPoolCreate(radio_unit_t radio) {
packet_svc_t *handler = pktGetServiceObject(radio);
chDbgAssert(handler != NULL, "invalid radio ID");
//chDbgAssert(handler != NULL, "invalid radio ID");
/* Create the packet buffer name for this radio. */
chsnprintf(handler->pbuff_name, sizeof(handler->pbuff_name),
@ -1010,7 +1011,7 @@ thread_t *pktCallbackManagerCreate(radio_unit_t radio) {
packet_svc_t *handler = pktGetServiceObject(radio);
chDbgAssert(handler != NULL, "invalid radio ID");
//chDbgAssert(handler != NULL, "invalid radio ID");
/* Create the callback termination thread name. */
chsnprintf(handler->cbend_name, sizeof(handler->cbend_name),

Wyświetl plik

@ -92,6 +92,21 @@ typedef struct packetHandlerData {
*/
radio_unit_t radio;
/**
* @brief Radio part number.
*/
radio_part_t radio_part;
/**
* @brief Radio revision level.
*/
radio_rev_t radio_rom_rev;
/**
* @brief Radio patch ID.
*/
radio_patch_t radio_patch;
/**
* @brief Radio initialization flag.
*/
@ -512,7 +527,7 @@ static inline msg_t pktReceiveDataBufferTimeout(packet_svc_t *handler,
static inline bool pktIsBufferValidAX25Frame(pkt_data_object_t *object) {
chDbgAssert(object != NULL, "no pointer to packet object buffer");
uint16_t frame_size = object->packet_size;
return ((object->status & EVT_AFSK_DECODE_DONE)
return ((object->status & STA_AFSK_DECODE_DONE)
&& (frame_size >= PKT_MIN_FRAME));
}
@ -525,13 +540,13 @@ static inline bool pktIsBufferValidAX25Frame(pkt_data_object_t *object) {
*
* @return The operation status.
* @retval true if the frame is valid and has good CRC.
* @retval false if the frame is valid and has bad CRC.
* @retval false if the frame is invalid or has bad CRC.
*
* @api
*/
static inline bool pktGetAX25FrameStatus(pkt_data_object_t *object) {
chDbgAssert(object != NULL, "no pointer to packet object buffer");
return !(object->status & (EVT_PKT_INVALID_FRAME | EVT_AX25_CRC_ERROR));
return !(object->status & (STA_PKT_INVALID_FRAME | STA_PKT_CRC_ERROR));
}
/**
@ -552,6 +567,9 @@ inline packet_svc_t *pktGetServiceObject(radio_unit_t radio) {
if(radio == PKT_RADIO_1) {
handler = &RPKTD1;
}
chDbgAssert(handler != NULL, "invalid radio ID");
return handler;
}
@ -571,7 +589,7 @@ static inline packet_state_t pktGetServiceState(radio_unit_t radio) {
*/
packet_svc_t *handler = pktGetServiceObject(radio);
chDbgAssert(handler != NULL, "invalid radio ID");
//chDbgAssert(handler != NULL, "invalid radio ID");
return handler->state;
}

Wyświetl plik

@ -24,4 +24,3 @@
packet_svc_t RPKTD1;
binary_semaphore_t diag_out_sem;

Wyświetl plik

@ -57,30 +57,31 @@
* The packet channel object holds the global events.
* Events are broadcast to any listeners.
*/
#define EVT_AX25_FRAME_RDY EVENT_MASK(EVT_PRIORITY_BASE + 0)
#define EVT_AX25_BUFFER_FULL EVENT_MASK(EVT_PRIORITY_BASE + 1)
#define EVT_AX25_CRC_ERROR EVENT_MASK(EVT_PRIORITY_BASE + 2)
#define EVT_AX25_NO_BUFFER EVENT_MASK(EVT_PRIORITY_BASE + 3)
//#define STA_AX25_FRAME_RDY EVENT_MASK(EVT_PRIORITY_BASE + 0)
#define EVT_PKT_BUFFER_FULL EVENT_MASK(EVT_PRIORITY_BASE + 1)
//#define STA_AX25_CRC_ERROR EVENT_MASK(EVT_PRIORITY_BASE + 2)
#define EVT_PKT_NO_BUFFER EVENT_MASK(EVT_PRIORITY_BASE + 3)
#define EVT_AFSK_TERMINATED EVENT_MASK(EVT_PRIORITY_BASE + 4)
//#define EVT_AFSK_TERMINATED EVENT_MASK(EVT_PRIORITY_BASE + 4)
#define EVT_AFSK_START_FAIL EVENT_MASK(EVT_PRIORITY_BASE + 5)
#define EVT_AFSK_DECODE_RESET EVENT_MASK(EVT_PRIORITY_BASE + 6)
#define EVT_AFSK_DECODE_DONE EVENT_MASK(EVT_PRIORITY_BASE + 7)
//#define STA_AFSK_DECODE_RESET EVENT_MASK(EVT_PRIORITY_BASE + 6)
//#define STA_AFSK_DECODE_DONE EVENT_MASK(EVT_PRIORITY_BASE + 7)
/* TODO: Create an AKSK event field in decoder for the PWM & radio events. */
#define EVT_PWM_NO_DATA EVENT_MASK(EVT_PRIORITY_BASE + 8)
#define EVT_PWM_INVALID_INBAND EVENT_MASK(EVT_PRIORITY_BASE + 9)
#define EVT_PWM_FIFO_EMPTY EVENT_MASK(EVT_PRIORITY_BASE + 10)
#define EVT_PWM_QUEUE_FULL EVENT_MASK(EVT_PRIORITY_BASE + 11)
#define EVT_PWM_STREAM_CLOSED EVENT_MASK(EVT_PRIORITY_BASE + 12)
//#define STA_PWM_STREAM_CLOSED EVENT_MASK(EVT_PRIORITY_BASE + 12)
#define EVT_PWM_STREAM_TIMEOUT EVENT_MASK(EVT_PRIORITY_BASE + 13)
#define EVT_PWM_QUEUE_OVERRUN EVENT_MASK(EVT_PRIORITY_BASE + 14)
#define EVT_PWM_BUFFER_FAIL EVENT_MASK(EVT_PRIORITY_BASE + 15)
#define EVT_PWM_STREAM_OPEN EVENT_MASK(EVT_PRIORITY_BASE + 16)
#define EVT_PWM_FIFO_REMNANT EVENT_MASK(EVT_PRIORITY_BASE + 17)
#define EVT_PWM_STREAM_CLOSE EVENT_MASK(EVT_PRIORITY_BASE + 18)
#define EVT_PKT_INVALID_FRAME EVENT_MASK(EVT_PRIORITY_BASE + 19)
//#define EVT_PWM_STREAM_CLOSE EVENT_MASK(EVT_PRIORITY_BASE + 18)
//#define STA_PKT_INVALID_FRAME EVENT_MASK(EVT_PRIORITY_BASE + 19)
#define EVT_PKT_FAILED_CB_THD EVENT_MASK(EVT_PRIORITY_BASE + 20)
#define EVT_PKT_BUFFER_MGR_FAIL EVENT_MASK(EVT_PRIORITY_BASE + 21)
@ -104,9 +105,8 @@
#define DEC_COMMAND_CLOSE EVENT_MASK(EVT_PRIORITY_BASE + 2)
#define DEC_DIAG_OUT_END EVENT_MASK(EVT_PRIORITY_BASE + 3)
/* Reserved system event broadcast IDs (set mask in user threads level). */
#define USB_SHELL_EVT EVT_PRIORITY_BASE + 0
#define USB_SDU1_EVT EVT_PRIORITY_BASE + 16
/* Console thread event masks. */
#define CONSOLE_CHANNEL_EVT EVENT_MASK(EVT_PRIORITY_BASE + 0)
/* Response thread event masks (from decoder to initiator). */
#define DEC_OPEN_EXEC EVENT_MASK(EVT_PRIORITY_BASE + 15)
@ -115,12 +115,27 @@
#define DEC_CLOSE_EXEC EVENT_MASK(EVT_PRIORITY_BASE + 18)
#define USR_COMMAND_ACK EVENT_MASK(EVT_PRIORITY_BASE + 19)
/* Diagnostic event masks. */
#define EVT_DIAG_OUT_END EVENT_MASK(EVT_PRIORITY_BASE + 20)
#define EVT_PKT_OUT_END EVENT_MASK(EVT_PRIORITY_BASE + 21)
#define EVT_STATUS_CLEAR EVT_NONE
/**
* PWM stream status bits.
*/
typedef uint32_t statusmask_t; /**< Mask of status identifiers. */
/**
* @brief Returns an event mask from an event identifier.
*/
#define STATUS_MASK(sid) ((statusmask_t)1 << (statusmask_t)(sid))
/* TODO: Classify status by PKT, AFSK and 2FSK types. */
#define STA_PKT_FRAME_RDY STATUS_MASK(0)
#define STA_PKT_CRC_ERROR STATUS_MASK(1)
#define STA_PKT_INVALID_FRAME STATUS_MASK(2)
#define STA_AFSK_DECODE_RESET STATUS_MASK(3)
#define STA_AFSK_DECODE_DONE STATUS_MASK(4)
#define STA_PWM_STREAM_CLOSED STATUS_MASK(5)
#define useCCM __attribute__((section(".ram4")))
#ifdef PKT_IS_TEST_PROJECT
@ -227,7 +242,6 @@ static inline int8_t pktReadGPIOline(ioline_t line) {
static inline msg_t pktSendRadioCommand(radio_unit_t radio,
radio_task_object_t *task,
radio_task_cb_t cb) {
#if USE_SPI_ATTACHED_RADIO == TRUE
radio_task_object_t *rt = NULL;
msg_t msg = pktGetRadioTaskObject(radio, TIME_MS2I(3000), &rt);
if(msg != MSG_OK)
@ -235,11 +249,6 @@ static inline msg_t pktSendRadioCommand(radio_unit_t radio,
*rt = *task;
pktSubmitRadioTask(radio, rt, cb);
return msg;
#else
(void)task;
(void)handler;
return MSG_OK;
#endif
}
/**
@ -251,12 +260,8 @@ static inline msg_t pktSendRadioCommand(radio_unit_t radio,
* @api
*/
static inline void pktReleaseBufferObject(packet_t pp) {
#if USE_SPI_ATTACHED_RADIO == TRUE
chDbgAssert(pp != NULL, "no packet pointer");
pktReleasePacketBuffer(pp);
#else
(void)pp;
#endif
}
/**
@ -269,8 +274,6 @@ static inline void pktReleaseBufferObject(packet_t pp) {
* @api
*/
static inline void pktReleaseBufferChain(packet_t pp) {
#if USE_SPI_ATTACHED_RADIO == TRUE
chDbgAssert(pp != NULL, "no packet pointer");
/* Release all packets in linked list. */
do {
@ -278,9 +281,6 @@ static inline void pktReleaseBufferChain(packet_t pp) {
pktReleasePacketBuffer(pp);
pp = np;
} while(pp != NULL);
#else
(void)pp;
#endif
}
#endif /* _PKTCONF_H_ */

Wyświetl plik

@ -65,9 +65,18 @@ typedef enum radioUnit {
PKT_RADIO_1
} radio_unit_t;
typedef uint16_t radio_part_t;
typedef uint8_t radio_rev_t;
typedef uint16_t radio_patch_t;
/*
* Specify radio family.
* Specific radio in family is identified dynamically.
*/
typedef enum radioTypes {
SI4464,
SI4463
SI446X
} radio_type_t;
typedef enum radioMode {
@ -76,6 +85,13 @@ typedef enum radioMode {
RADIO_TX
} radio_mode_t;
typedef struct radioBand {
radio_freq_t start;
radio_freq_t end;
channel_hz_t step;
radio_freq_t def_aprs;
} radio_band_t;
typedef uint8_t ax25char_t;
typedef int32_t gps_coord_t;

Wyświetl plik

@ -1,160 +1,157 @@
/*
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.
*/
#include "pktconf.h"
/**
* @brief Extract HDLC from AFSK.
* @post The HDLC state will be updated.
* @notes In the case of an HDLC_RESET HDLC sync can be restarted.
* @notes This is done where the AX25 payload is below minimum size.
* @notes If the payload is above minimum size state HDLC_RESET is set.
* @notes In that case it is left to the decoder to determine an action.
*
* @param[in] myDriver pointer to an @p AFSKDemodDriver structure.
*
* @return status of operation
* @retval true character processed and HDLC state updated on flags.
* @retval false frame buffer full.
*
* @api
*/
bool pktExtractHDLCfromAFSK(AFSKDemodDriver *myDriver) {
packet_svc_t *myHandler = myDriver->packet_handler;
/* Shift prior HDLC bits up before adding new bit. */
myDriver->hdlc_bits <<= 1;
myDriver->hdlc_bits &= 0xFE;
/* Same tone indicates a 1. */
if(myDriver->tone_freq == myDriver->prior_freq) {
myDriver->hdlc_bits |= 1;
}
/* Update the prior frequency. */
myDriver->prior_freq = myDriver->tone_freq;
/*
* Check if we are in AX25 data capture mode.
* If so check and act on HDLC codes otherwise just store data.
*/
switch(myDriver->frame_state) {
case FRAME_OPEN: {
switch(myDriver->hdlc_bits & HDLC_CODE_MASK) {
case HDLC_FLAG: {
/*
* An HDLC flag after minimum packet size terminates the AX25 frame.
*/
if(myHandler->active_packet_object->packet_size >= PKT_MIN_FRAME) {
/*
* Frame size is valid.
* Dump any bits already put into the AX25 byte.
*/
myDriver->bit_index = 0;
/* Inform decoder thread of end of frame. */
myDriver->frame_state = FRAME_CLOSE;
return true;
} /* End AX25 frame size check. */
/*
* Frame size is not valid.
* HDLC sync still in progress.
* Reset AX25 counts and wait for next HDLC bit.
*/
pktResetDataCount(myHandler->active_packet_object);
myDriver->bit_index = 0;
return true;
} /* End case. */
case HDLC_RESET: {
/*
* Can be a real HDLC reset or most likely incorrect bit sync.
* TODO: Figure out correct handling.
* Make a macro to test if no data stored?
*/
myDriver->active_demod_object->status |= EVT_HDLC_RESET_RCVD;
pktAddEventFlags(myHandler, EVT_HDLC_RESET_RCVD);
if(myHandler->active_packet_object->packet_size < PKT_MIN_FRAME) {
/* No data payload stored yet so go back to sync search. */
myHandler->active_packet_object->packet_size = 0;
myDriver->frame_state = FRAME_SEARCH;
myHandler->sync_count--;
break;
}
/* Else let the decoder determine what to do. */
myDriver->frame_state = FRAME_RESET;
return true;
} /* End case. */
default: {
/* Check for RLL encoding inserted ("stuffed") bit in the bit stream. */
if((myDriver->hdlc_bits & HDLC_RLL_MASK) == HDLC_RLL_BIT) {
/*
* The stuffed bit is discarded.
* We just wait for next HDLC bit.
*/
return true;
}
/*
* Else we have a non-special pattern.
* Just put the bit into the AX25 data.
* AX25 data bits arrive MSB -> LSB.
*/
myDriver->current_byte &= 0x7F;
if((myDriver->hdlc_bits & 0x01) == 1) {
myDriver->current_byte |= 0x80;
}
/* Check if we have a byte accumulated. */
if(++myDriver->bit_index == 8U) {
myDriver->bit_index = 0;
if(pktStoreBufferData(myHandler->active_packet_object,
myDriver->current_byte)) {
return true;
}
pktAddEventFlags(myHandler, EVT_AX25_BUFFER_FULL);
myDriver->active_demod_object->status |= EVT_AX25_BUFFER_FULL;
return false;
}
/* Else shift the prior bit to make space for next bit. */
myDriver->current_byte >>= 1;
return true;
} /* End case default. */
} /* End switch. */
} /* Else not frame_open... */
case FRAME_SEARCH: {
/*
* Frame start not yet detected.
* Check for opening HDLC flag sequence.
*/
if(
((myDriver->hdlc_bits & HDLC_FRAME_MASK_A) == HDLC_FRAME_OPEN_A)
||
((myDriver->hdlc_bits & HDLC_FRAME_MASK_B) == HDLC_FRAME_OPEN_B)
) {
myDriver->frame_state = FRAME_OPEN;
myHandler->sync_count++;
/* Reset AX25 data indexes. */
myHandler->active_packet_object->packet_size = 0;
myDriver->bit_index = 0;
/*
* AX25 data buffering is now enabled.
* Data bytes will be written to the AX25 buffer.
*/
}
return true;
}
default:
return true;
} /* End switch on frame state. */
} /* End function. */
/** @} */
/*
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.
*/
#include "pktconf.h"
/**
* @brief Extract HDLC from AFSK.
* @post The HDLC state will be updated.
* @notes In the case of an HDLC_RESET HDLC sync can be restarted.
* @notes This is done where the AX25 payload is below minimum size.
* @notes If the payload is above minimum size state HDLC_RESET is set.
* @notes In that case it is left to the decoder to determine an action.
*
* @param[in] myDriver pointer to an @p AFSKDemodDriver structure.
*
* @return status of operation
* @retval true character processed and HDLC state updated on flags.
* @retval false frame buffer full.
*
* @api
*/
bool pktExtractHDLCfromAFSK(AFSKDemodDriver *myDriver) {
packet_svc_t *myHandler = myDriver->packet_handler;
/* Shift prior HDLC bits up before adding new bit. */
myDriver->hdlc_bits <<= 1;
myDriver->hdlc_bits &= 0xFE;
/* Same tone indicates a 1. */
if(myDriver->tone_freq == myDriver->prior_freq) {
myDriver->hdlc_bits |= 1;
}
/* Update the prior frequency. */
myDriver->prior_freq = myDriver->tone_freq;
/*
* Check if we are in AX25 data capture mode.
* If so check and act on HDLC codes otherwise just store data.
*/
switch(myDriver->frame_state) {
case FRAME_OPEN: {
switch(myDriver->hdlc_bits & HDLC_CODE_MASK) {
case HDLC_FLAG: {
/*
* An HDLC flag after minimum packet size terminates the AX25 frame.
*/
if(myHandler->active_packet_object->packet_size >= PKT_MIN_FRAME) {
/*
* Frame size is valid.
* Dump any bits already put into the AX25 byte.
*/
myDriver->bit_index = 0;
/* Inform decoder thread of end of frame. */
myDriver->frame_state = FRAME_CLOSE;
return true;
} /* End AX25 frame size check. */
/*
* Frame size is not valid.
* HDLC sync still in progress.
* Reset AX25 counts and wait for next HDLC bit.
*/
pktResetDataCount(myHandler->active_packet_object);
myDriver->bit_index = 0;
return true;
} /* End case. */
case HDLC_RESET: {
/*
* Can be a real HDLC reset or most likely incorrect bit sync.
*/
//myDriver->active_demod_object->status |= STA_HDLC_RESET_RCVD;
pktAddEventFlags(myHandler, EVT_HDLC_RESET_RCVD);
if(myHandler->active_packet_object->packet_size < PKT_MIN_FRAME) {
/* No data payload stored yet so go back to sync search. */
myHandler->active_packet_object->packet_size = 0;
myDriver->frame_state = FRAME_SEARCH;
myHandler->sync_count--;
break;
}
/* Else let the decoder determine what to do. */
myDriver->frame_state = FRAME_RESET;
return true;
} /* End case. */
default: {
/* Check for RLL encoding inserted ("stuffed") bit in the bit stream. */
if((myDriver->hdlc_bits & HDLC_RLL_MASK) == HDLC_RLL_BIT) {
/*
* The stuffed bit is discarded.
* We just wait for next HDLC bit.
*/
return true;
}
/*
* Else we have a non-special pattern.
* Just put the bit into the AX25 data.
* AX25 data bits arrive MSB -> LSB.
*/
myDriver->current_byte &= 0x7F;
if((myDriver->hdlc_bits & 0x01) == 1) {
myDriver->current_byte |= 0x80;
}
/* Check if we have a byte accumulated. */
if(++myDriver->bit_index == 8U) {
myDriver->bit_index = 0;
if(pktStoreBufferData(myHandler->active_packet_object,
myDriver->current_byte)) {
return true;
}
pktAddEventFlags(myHandler, EVT_PKT_BUFFER_FULL);
return false;
}
/* Else shift the prior bit to make space for next bit. */
myDriver->current_byte >>= 1;
return true;
} /* End case default. */
} /* End switch. */
} /* Else not frame_open... */
case FRAME_SEARCH: {
/*
* Frame start not yet detected.
* Check for opening HDLC flag sequence.
*/
if(
((myDriver->hdlc_bits & HDLC_FRAME_MASK_A) == HDLC_FRAME_OPEN_A)
||
((myDriver->hdlc_bits & HDLC_FRAME_MASK_B) == HDLC_FRAME_OPEN_B)
) {
myDriver->frame_state = FRAME_OPEN;
myHandler->sync_count++;
/* Reset AX25 data indexes. */
myHandler->active_packet_object->packet_size = 0;
myDriver->bit_index = 0;
/*
* AX25 data buffering is now enabled.
* Data bytes will be written to the AX25 buffer.
*/
}
return true;
}
default:
return true;
} /* End switch on frame state. */
} /* End function. */
/** @} */

Wyświetl plik

@ -502,13 +502,20 @@ THD_FUNCTION(collectorThread, arg) {
setSystemStatus(tp);
getTime(&time);
/* Set timeout based on cycle or minimum 1 minute. */
sysinterval_t gps_wait_time;
if(config->beacon.cycle < TIME_S2I(60))
gps_wait_time = TIME_S2I(60);
else
gps_wait_time = config->beacon.cycle;
if(time.year == RTC_BASE_YEAR) {
/*
* The RTC is not set.
* Enable the GPS and attempt a lock which results in setting the RTC.
*/
TRACE_INFO("COLL > Acquire time using GPS");
if(aquirePosition(tp, ltp, TIME_S2I(600))) {
if(aquirePosition(tp, ltp, gps_wait_time)) {
/* Acquisition succeeded. */
TRACE_INFO("COLL > Time update acquired from GPS");
} else {
@ -538,15 +545,10 @@ THD_FUNCTION(collectorThread, arg) {
/*
* Try GPS lock to get data.
* If lock not attained fallback data is set.
* Timeout will be remainder of time if RTC set was done.
*/
TRACE_INFO("COLL > Acquire position using GPS");
// Determine timeout waiting for lock.
sysinterval_t gps_wait_time;
if(config->beacon.gps_wait > TIME_S2I(63)) // Minimum 1M + 3S
gps_wait_time = config->beacon.gps_wait;
else
gps_wait_time = TIME_S2I(600); // Default 10 minutes.
if(aquirePosition(tp, ltp, gps_wait_time - TIME_S2I(3))) {
if(aquirePosition(tp, ltp, gps_wait_time)) {
TRACE_INFO("COLL > Acquired fresh GPS data");
} else {
/* Historical data has been carried forward. */
@ -558,7 +560,7 @@ THD_FUNCTION(collectorThread, arg) {
extern uint8_t gps_model;
// Trace data
unixTimestamp2Date(&time, tp->gps_time);
TRACE_INFO( "COLL > GPS status: state=%s model=%s)",
TRACE_INFO( "COLL > GPS status: state=%s model=%s",
get_gps_state_name(tp->gps_state),
gps_get_model_name(gps_model));
TRACE_INFO( "COLL > New data point (ID=%d)\r\n"

Wyświetl plik

@ -41,32 +41,44 @@ THD_FUNCTION(bcnThread, arg) {
pktDisplayFrequencyCode(conf->radio_conf.freq, code_s, sizeof(code_s));
TRACE_INFO("POS > Do module BEACON cycle for %s on %s%s",
conf->call, code_s, conf->run_once ? " (?aprsp response)" : "");
extern thread_t *collector_thd;
/* TODO: Add a while loop here that checks remaining time in cycle.
* When within time then keep trying for GPS lock.
* The collector will keep the GPS on if battery is OK.
*/
if(chVTIsSystemTimeWithinX(time, time + conf->beacon.cycle)) {
}
/*
* Pass pointer to beacon config to the collector thread.
*/
dataPoint_t *dataPoint =
(dataPoint_t *)chMsgSend(collector_thd, (msg_t)conf);
extern thread_t *collector_thd;
msg_t dpmsg = chMsgSend(collector_thd, (msg_t)conf);
if(dpmsg == MSG_TIMEOUT) {
}
/* If not a timeout then this is a datapoint. */
dataPoint_t *dataPoint = (dataPoint_t *)dpmsg;
/* Continue here when collector responds. */
if(!p_sleep(&conf->beacon.sleep_conf)) {
if(!isPositionValid(dataPoint) || dataPoint == NULL) {
TRACE_INFO("BCN > Waiting for position data for"
" %s (GPS state=%d)", conf->call, dataPoint->gps_state);
if(conf->run_once) {
//if(!isPositionValid(dataPoint) || dataPoint == NULL) {
/* TRACE_INFO("BCN > Waiting for position data for"
" %s (GPS state=%d)", conf->call, dataPoint->gps_state);*/
//if(conf->run_once) {
/* If this is run once so don't retry. */
chHeapFree(conf);
pktThdTerminateSelf();
}
if(isGPSbatteryOperable(dataPoint)) {
//chHeapFree(conf);
//pktThdTerminateSelf();
//}
//if(isGPSbatteryOperable(dataPoint)) {
/* If the battery is good retry quickly.
* TODO: Rework and involve the p_sleep setting?
* Limit to a number of retries? */
chThdSleep(TIME_S2I(60));
continue;
}
//chThdSleep(TIME_S2I(60));
//continue;
//}
/* Else battery weak so beacon fallback data (TX may fail). */
}
//}
// Telemetry encoding parameter transmissions
if(conf_sram.tel_enc_cycle != 0