Changes in event codes and radio manager

- Refactor event codes (more to be done to...)
- Refactor radio manager (change loop handling)
pull/4/head
bob 2018-06-19 08:47:50 +10:00
rodzic a08d3d9aba
commit aff37ba24c
11 zmienionych plików z 1802 dodań i 1662 usunięć

Wyświetl plik

@ -1,244 +1,244 @@
/*
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 portab.c
* @brief Application portability module code.
*
* @addtogroup application_portability
* @{
*/
#include "hal.h"
#include "chprintf.h"
#include "pkttypes.h"
#include "portab.h"
#include "usb.h"
#include "types.h"
#include <stdarg.h>
/*===========================================================================*/
/* Module local definitions. */
/*===========================================================================*/
const radio_band_t band_2m = {
.start = BAND_MIN_2M_FREQ,
.end = BAND_MAX_2M_FREQ,
.step = BAND_STEP_2M_HZ,
.def_aprs = BAND_DEF_2M_APRS
};
const radio_band_t band_70cm = {
.start = BAND_MIN_70CM_FREQ,
.end = BAND_MAX_70CM_FREQ,
.step = BAND_STEP_70CM_HZ,
.def_aprs = BAND_DEF_70CM_APRS
};
/*===========================================================================*/
/* Module exported variables. */
/*===========================================================================*/
typedef struct SysProviders {
} providers_t;
const radio_param_t radio_list[NUM_PKT_RADIOS] = {
{ /* Radio #1 */
.unit = PKT_RADIO_1,
.type = SI4464,
.band = {
(radio_band_t * const)&band_2m,
NULL
}
} /* End radio1 */
};
const SerialConfig debug_config = {
115200,
0,
0,
0
};
/*===========================================================================*/
/* Module local types. */
/*===========================================================================*/
/*===========================================================================*/
/* Module local variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Module local functions. */
/*===========================================================================*/
/*===========================================================================*/
/* Module exported functions. */
/*===========================================================================*/
void pktConfigSerialDiag(void) {
/* USART3 TX. */
palSetLineMode(LINE_USART3_TX, PAL_MODE_ALTERNATE(7));
/* USART3 RX. */
palSetLineMode(LINE_USART3_RX, PAL_MODE_ALTERNATE(7));
}
void pktConfigSerialPkt(void) {
}
/**
* TODO: Move this into pktconf.h and use general GPIO to setup.
*/
void pktSetLineModeICU(void) {
palSetLineMode(LINE_ICU, PAL_MODE_INPUT | PAL_MODE_ALTERNATE(2));
}
/*
* Read GPIO that are used for:
* a) general use or
* b) UART and s/w I2C external.
*
* @return State of lines regardless of general or specific use.
*/
uint8_t pktReadIOlines() {
return palReadLine(LINE_GPIO_PIN)
| palReadLine(LINE_IO_TXD) << 1
| palReadLine(LINE_IO_RXD) << 2;
}
void pktSerialStart(void) {
#if ENABLE_EXTERNAL_I2C == FALSE
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);
}
void dbgWrite(uint8_t level, uint8_t *buf, uint32_t len) {
(void)level;
#if ENABLE_EXTERNAL_I2C == FALSE
chnWrite((BaseSequentialStream*)SERIAL_CFG_DEBUG_DRIVER, buf, len);
#else
(void)buf;
(void)len;
#endif
}
int dbgPrintf(uint8_t level, const char *format, ...) {
(void)level;
#if ENABLE_EXTERNAL_I2C == FALSE
va_list arg;
int done;
va_start(arg, format);
done = chprintf((BaseSequentialStream*)SERIAL_CFG_DEBUG_DRIVER, format, arg);
va_end(arg);
return done;
#else
(void)format;
return 0;
#endif
}
void pktWrite(uint8_t *buf, uint32_t len) {
chnWrite((BaseSequentialStream*)SERIAL_CFG_DEBUG_DRIVER, buf, len);
}
void pktPowerUpRadio(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.
* The radio powers up in SDN mode.
*
* CS is set as push-pull and initialized to HIGH.
*/
// Power up transceiver
palClearLine(LINE_RADIO_SDN); // Radio SDN low (power up transceiver)
chThdSleep(TIME_MS2I(10)); // Wait for transceiver to power up
}
void pktPowerDownRadio(radio_unit_t radio) {
/* TODO: Implement hardware mapping. */
(void)radio;
/*
* Put radio in shutdown mode.
* All registers are lost.
*/
palSetLine(LINE_RADIO_SDN);
}
void sysConfigureCoreIO(void) {
/* Setup SPI3. */
palSetLineMode(LINE_SPI_SCK, PAL_MODE_ALTERNATE(6)
| PAL_STM32_OSPEED_HIGHEST); // SCK
palSetLineMode(LINE_SPI_MISO, PAL_MODE_ALTERNATE(6)
| PAL_STM32_OSPEED_HIGHEST); // MISO
palSetLineMode(LINE_SPI_MOSI, PAL_MODE_ALTERNATE(6)
| PAL_STM32_OSPEED_HIGHEST); // MOSI
/* Setup I2C1. */
palSetLineMode(LINE_I2C_SDA, PAL_MODE_ALTERNATE(4)
| PAL_STM32_OSPEED_HIGHEST
| PAL_STM32_OTYPE_OPENDRAIN); // SDA
palSetLineMode(LINE_I2C_SCL, PAL_MODE_ALTERNATE(4)
| PAL_STM32_OSPEED_HIGHEST
| PAL_STM32_OTYPE_OPENDRAIN); // SCL
#if ACTIVATE_USB
startUSB();
#endif
}
/*
* Return a single radio parameter record pointer
* The radio parameter picks a single records.
* The current system does not work if the same radio is listed multiple times.
* TODO: Have an enumeration and check radio array on startup.
*/
radio_param_t *pktGetRadioParameters(radio_unit_t radio) {
(void)radio;
return NULL;
}
/*
*
*/
radio_freq_t pktCheckAllowedFrequency(radio_unit_t radio, radio_freq_t freq) {
/* Check validity. */
uint8_t radios = NUM_PKT_RADIOS/*sizeof(radio_list) / sizeof(radio_param_t)*/;
for(uint8_t i = 0; i < radios; i++) {
if(radio_list[i].unit != radio)
continue;
for(uint8_t x = 0; x < NUM_BANDS_PER_RADIO; x++) {
if(radio_list[i].band[x] == NULL)
/* No more bands in this radio. */
return FREQ_RADIO_INVALID;
if(radio_list[i].band[x]->start <= freq
&& freq < radio_list[i].band[x]->end)
return freq;
} /* End for bands */
} /* End for radios*/
return FREQ_RADIO_INVALID;
}
/** @} */
/*
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 portab.c
* @brief Application portability module code.
*
* @addtogroup application_portability
* @{
*/
#include "hal.h"
#include "chprintf.h"
#include "pkttypes.h"
#include "portab.h"
#include "usb.h"
#include "types.h"
#include <stdarg.h>
/*===========================================================================*/
/* Module local definitions. */
/*===========================================================================*/
const radio_band_t band_2m = {
.start = BAND_MIN_2M_FREQ,
.end = BAND_MAX_2M_FREQ,
.step = BAND_STEP_2M_HZ,
.def_aprs = BAND_DEF_2M_APRS
};
const radio_band_t band_70cm = {
.start = BAND_MIN_70CM_FREQ,
.end = BAND_MAX_70CM_FREQ,
.step = BAND_STEP_70CM_HZ,
.def_aprs = BAND_DEF_70CM_APRS
};
/*===========================================================================*/
/* Module exported variables. */
/*===========================================================================*/
typedef struct SysProviders {
} providers_t;
const radio_config_t radio_list[NUM_PKT_RADIOS] = {
{ /* Radio #1 */
.unit = PKT_RADIO_1,
.type = SI4464,
.band = {
(radio_band_t * const)&band_2m,
NULL
}
} /* End radio1 */
};
const SerialConfig debug_config = {
115200,
0,
0,
0
};
/*===========================================================================*/
/* Module local types. */
/*===========================================================================*/
/*===========================================================================*/
/* Module local variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Module local functions. */
/*===========================================================================*/
/*===========================================================================*/
/* Module exported functions. */
/*===========================================================================*/
void pktConfigSerialDiag(void) {
/* USART3 TX. */
palSetLineMode(LINE_USART3_TX, PAL_MODE_ALTERNATE(7));
/* USART3 RX. */
palSetLineMode(LINE_USART3_RX, PAL_MODE_ALTERNATE(7));
}
void pktConfigSerialPkt(void) {
}
/**
* TODO: Move this into pktconf.h and use general GPIO to setup.
*/
void pktSetLineModeICU(void) {
palSetLineMode(LINE_ICU, PAL_MODE_INPUT | PAL_MODE_ALTERNATE(2));
}
/*
* Read GPIO that are used for:
* a) general use or
* b) UART and s/w I2C external.
*
* @return State of lines regardless of general or specific use.
*/
uint8_t pktReadIOlines() {
return palReadLine(LINE_GPIO_PIN)
| palReadLine(LINE_IO_TXD) << 1
| palReadLine(LINE_IO_RXD) << 2;
}
void pktSerialStart(void) {
#if ENABLE_EXTERNAL_I2C == FALSE
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);
}
void dbgWrite(uint8_t level, uint8_t *buf, uint32_t len) {
(void)level;
#if ENABLE_EXTERNAL_I2C == FALSE
chnWrite((BaseSequentialStream*)SERIAL_CFG_DEBUG_DRIVER, buf, len);
#else
(void)buf;
(void)len;
#endif
}
int dbgPrintf(uint8_t level, const char *format, ...) {
(void)level;
#if ENABLE_EXTERNAL_I2C == FALSE
va_list arg;
int done;
va_start(arg, format);
done = chprintf((BaseSequentialStream*)SERIAL_CFG_DEBUG_DRIVER, format, arg);
va_end(arg);
return done;
#else
(void)format;
return 0;
#endif
}
void pktWrite(uint8_t *buf, uint32_t len) {
chnWrite((BaseSequentialStream*)SERIAL_CFG_DEBUG_DRIVER, buf, len);
}
void pktPowerUpRadio(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.
* The radio powers up in SDN mode.
*
* CS is set as push-pull and initialized to HIGH.
*/
// Power up transceiver
palClearLine(LINE_RADIO_SDN); // Radio SDN low (power up transceiver)
chThdSleep(TIME_MS2I(10)); // Wait for transceiver to power up
}
void pktPowerDownRadio(radio_unit_t radio) {
/* TODO: Implement hardware mapping. */
(void)radio;
/*
* Put radio in shutdown mode.
* All registers are lost.
*/
palSetLine(LINE_RADIO_SDN);
}
void sysConfigureCoreIO(void) {
/* Setup SPI3. */
palSetLineMode(LINE_SPI_SCK, PAL_MODE_ALTERNATE(6)
| PAL_STM32_OSPEED_HIGHEST); // SCK
palSetLineMode(LINE_SPI_MISO, PAL_MODE_ALTERNATE(6)
| PAL_STM32_OSPEED_HIGHEST); // MISO
palSetLineMode(LINE_SPI_MOSI, PAL_MODE_ALTERNATE(6)
| PAL_STM32_OSPEED_HIGHEST); // MOSI
/* Setup I2C1. */
palSetLineMode(LINE_I2C_SDA, PAL_MODE_ALTERNATE(4)
| PAL_STM32_OSPEED_HIGHEST
| PAL_STM32_OTYPE_OPENDRAIN); // SDA
palSetLineMode(LINE_I2C_SCL, PAL_MODE_ALTERNATE(4)
| PAL_STM32_OSPEED_HIGHEST
| PAL_STM32_OTYPE_OPENDRAIN); // SCL
#if ACTIVATE_USB
startUSB();
#endif
}
/*
* Return a single radio parameter record pointer
* The radio parameter picks a single records.
* The current system does not work if the same radio is listed multiple times.
* TODO: Have an enumeration and check radio array on startup.
*/
radio_config_t *pktGetRadioParameters(radio_unit_t radio) {
(void)radio;
return NULL;
}
/*
*
*/
radio_freq_t pktCheckAllowedFrequency(radio_unit_t radio, radio_freq_t freq) {
/* Check validity. */
uint8_t radios = NUM_PKT_RADIOS/*sizeof(radio_list) / sizeof(radio_param_t)*/;
for(uint8_t i = 0; i < radios; i++) {
if(radio_list[i].unit != radio)
continue;
for(uint8_t x = 0; x < NUM_BANDS_PER_RADIO; x++) {
if(radio_list[i].band[x] == NULL)
/* No more bands in this radio. */
return FREQ_RADIO_INVALID;
if(radio_list[i].band[x]->start <= freq
&& freq < radio_list[i].band[x]->end)
return freq;
} /* End for bands */
} /* End for radios*/
return FREQ_RADIO_INVALID;
}
/** @} */

Wyświetl plik

@ -177,11 +177,11 @@ typedef struct radioBand {
radio_freq_t def_aprs;
} radio_band_t;
typedef struct radioParam {
typedef struct radioConfig {
radio_unit_t unit;
radio_type_t type;
radio_band_t *band[NUM_BANDS_PER_RADIO];
} radio_param_t;
} radio_config_t;
/*===========================================================================*/
/* Module macros. */

Wyświetl plik

@ -1,228 +1,228 @@
/*
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 portab.c
* @brief Application portability module code.
*
* @addtogroup application_portability
* @{
*/
#include "hal.h"
#include "chprintf.h"
#include "pkttypes.h"
#include "portab.h"
#include "usb.h"
#include "types.h"
#include <stdarg.h>
/*===========================================================================*/
/* Module local definitions. */
/*===========================================================================*/
const radio_band_t band_2m = {
.start = BAND_MIN_2M_FREQ,
.end = BAND_MAX_2M_FREQ,
.step = BAND_STEP_2M_HZ,
.def_aprs = BAND_DEF_2M_APRS
};
const radio_band_t band_70cm = {
.start = BAND_MIN_70CM_FREQ,
.end = BAND_MAX_70CM_FREQ,
.step = BAND_STEP_70CM_HZ,
.def_aprs = BAND_DEF_70CM_APRS
};
/*===========================================================================*/
/* Module exported variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Module local types. */
/*===========================================================================*/
/*===========================================================================*/
/* Module local variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Module local functions. */
/*===========================================================================*/
/*===========================================================================*/
/* Module exported functions. */
/*===========================================================================*/
typedef struct SysProviders {
} providers_t;
const radio_param_t radio_list[NUM_PKT_RADIOS] = {
{ /* Radio #1 */
.unit = PKT_RADIO_1,
.type = SI4464,
.band = {
(radio_band_t * const)&band_2m,
NULL
}
} /* End radio1 */
};
const SerialConfig debug_config = {
115200,
0,
0,
0
};
void pktConfigSerialDiag(void) {
/* USART3 TX. */
palSetLineMode(LINE_USART3_TX, PAL_MODE_ALTERNATE(7));
/* USART3 RX. */
palSetLineMode(LINE_USART3_RX, PAL_MODE_ALTERNATE(7));
}
void pktConfigSerialPkt(void) {
}
void pktSetLineModeICU(void) {
palSetLineMode(LINE_ICU, PAL_MODE_INPUT | PAL_MODE_ALTERNATE(2));
}
void pktSerialStart(void) {
#if ENABLE_EXTERNAL_I2C == FALSE
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);
}
void dbgWrite(uint8_t level, uint8_t *buf, uint32_t len) {
(void)level;
#if ENABLE_EXTERNAL_I2C == FALSE
chnWrite((BaseSequentialStream*)SERIAL_CFG_DEBUG_DRIVER, buf, len);
#else
(void)buf;
(void)len;
#endif
}
int dbgPrintf(uint8_t level, const char *format, ...) {
(void)level;
#if ENABLE_EXTERNAL_I2C == FALSE
va_list arg;
int done;
va_start(arg, format);
done = chprintf((BaseSequentialStream*)SERIAL_CFG_DEBUG_DRIVER, format, arg);
va_end(arg);
return done;
#else
(void)format;
return 0;
#endif
}
/*
* Read GPIO that are used for:
* a) general use or
* b) UART and s/w I2C external.
*
* @return State of lines regardless of general or specific use.
*/
uint8_t pktReadIOlines() {
return palReadLine(LINE_GPIO_PIN1)
| palReadLine(LINE_IO_TXD) << 1
| palReadLine(LINE_IO_RXD) << 2
| palReadLine(LINE_GPIO_PIN2);
}
void pktWrite(uint8_t *buf, uint32_t len) {
chnWrite((BaseSequentialStream*)SERIAL_CFG_DEBUG_DRIVER, buf, len);
}
void pktPowerUpRadio(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.
* The radio powers up in SDN mode.
*
* CS is set as push-pull and initialized to HIGH.
*/
// Power up transceiver
palClearLine(LINE_RADIO_SDN); // Radio SDN low (power up transceiver)
chThdSleep(TIME_MS2I(10)); // Wait for transceiver to power up
}
void pktPowerDownRadio(radio_unit_t radio) {
/* TODO: Implement hardware mapping. */
(void)radio;
/*
* Put radio in shutdown mode.
* All registers are lost.
*/
palSetLine(LINE_RADIO_SDN);
}
void sysConfigureCoreIO(void) {
/* Setup SPI3. */
palSetLineMode(LINE_SPI_SCK, PAL_MODE_ALTERNATE(6)
| PAL_STM32_OSPEED_HIGHEST); // SCK
palSetLineMode(LINE_SPI_MISO, PAL_MODE_ALTERNATE(6)
| PAL_STM32_OSPEED_HIGHEST); // MISO
palSetLineMode(LINE_SPI_MOSI, PAL_MODE_ALTERNATE(6)
| PAL_STM32_OSPEED_HIGHEST); // MOSI
/* Setup I2C1. */
palSetLineMode(LINE_I2C_SDA, PAL_MODE_ALTERNATE(4)
| PAL_STM32_OSPEED_HIGHEST
| PAL_STM32_OTYPE_OPENDRAIN); // SDA
palSetLineMode(LINE_I2C_SCL, PAL_MODE_ALTERNATE(4)
| PAL_STM32_OSPEED_HIGHEST
| PAL_STM32_OTYPE_OPENDRAIN); // SCL
#if ACTIVATE_USB
startUSB();
#endif
}
/*
*
*/
radio_freq_t pktCheckAllowedFrequency(radio_unit_t radio, radio_freq_t freq) {
/* Check validity. */
uint8_t radios = NUM_PKT_RADIOS/*sizeof(radio_list) / sizeof(radio_param_t)*/;
for(uint8_t i = 0; i < radios; i++) {
if(radio_list[i].unit != radio)
continue;
for(uint8_t x = 0; x < NUM_BANDS_PER_RADIO; x++) {
if(radio_list[i].band[x] == NULL)
/* No more bands in this radio. */
return FREQ_RADIO_INVALID;
if(radio_list[i].band[x]->start <= freq
&& freq < radio_list[i].band[x]->end)
return freq;
} /* End for bands */
} /* End for radios*/
return FREQ_RADIO_INVALID;
}
/** @} */
/*
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 portab.c
* @brief Application portability module code.
*
* @addtogroup application_portability
* @{
*/
#include "hal.h"
#include "chprintf.h"
#include "pkttypes.h"
#include "portab.h"
#include "usb.h"
#include "types.h"
#include <stdarg.h>
/*===========================================================================*/
/* Module local definitions. */
/*===========================================================================*/
const radio_band_t band_2m = {
.start = BAND_MIN_2M_FREQ,
.end = BAND_MAX_2M_FREQ,
.step = BAND_STEP_2M_HZ,
.def_aprs = BAND_DEF_2M_APRS
};
const radio_band_t band_70cm = {
.start = BAND_MIN_70CM_FREQ,
.end = BAND_MAX_70CM_FREQ,
.step = BAND_STEP_70CM_HZ,
.def_aprs = BAND_DEF_70CM_APRS
};
/*===========================================================================*/
/* Module exported variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Module local types. */
/*===========================================================================*/
/*===========================================================================*/
/* Module local variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Module local functions. */
/*===========================================================================*/
/*===========================================================================*/
/* Module exported functions. */
/*===========================================================================*/
typedef struct SysProviders {
} providers_t;
const radio_config_t radio_list[NUM_PKT_RADIOS] = {
{ /* Radio #1 */
.unit = PKT_RADIO_1,
.type = SI4464,
.band = {
(radio_band_t * const)&band_2m,
NULL
}
} /* End radio1 */
};
const SerialConfig debug_config = {
115200,
0,
0,
0
};
void pktConfigSerialDiag(void) {
/* USART3 TX. */
palSetLineMode(LINE_USART3_TX, PAL_MODE_ALTERNATE(7));
/* USART3 RX. */
palSetLineMode(LINE_USART3_RX, PAL_MODE_ALTERNATE(7));
}
void pktConfigSerialPkt(void) {
}
void pktSetLineModeICU(void) {
palSetLineMode(LINE_ICU, PAL_MODE_INPUT | PAL_MODE_ALTERNATE(2));
}
void pktSerialStart(void) {
#if ENABLE_EXTERNAL_I2C == FALSE
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);
}
void dbgWrite(uint8_t level, uint8_t *buf, uint32_t len) {
(void)level;
#if ENABLE_EXTERNAL_I2C == FALSE
chnWrite((BaseSequentialStream*)SERIAL_CFG_DEBUG_DRIVER, buf, len);
#else
(void)buf;
(void)len;
#endif
}
int dbgPrintf(uint8_t level, const char *format, ...) {
(void)level;
#if ENABLE_EXTERNAL_I2C == FALSE
va_list arg;
int done;
va_start(arg, format);
done = chprintf((BaseSequentialStream*)SERIAL_CFG_DEBUG_DRIVER, format, arg);
va_end(arg);
return done;
#else
(void)format;
return 0;
#endif
}
/*
* Read GPIO that are used for:
* a) general use or
* b) UART and s/w I2C external.
*
* @return State of lines regardless of general or specific use.
*/
uint8_t pktReadIOlines() {
return palReadLine(LINE_GPIO_PIN1)
| palReadLine(LINE_IO_TXD) << 1
| palReadLine(LINE_IO_RXD) << 2
| palReadLine(LINE_GPIO_PIN2);
}
void pktWrite(uint8_t *buf, uint32_t len) {
chnWrite((BaseSequentialStream*)SERIAL_CFG_DEBUG_DRIVER, buf, len);
}
void pktPowerUpRadio(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.
* The radio powers up in SDN mode.
*
* CS is set as push-pull and initialized to HIGH.
*/
// Power up transceiver
palClearLine(LINE_RADIO_SDN); // Radio SDN low (power up transceiver)
chThdSleep(TIME_MS2I(10)); // Wait for transceiver to power up
}
void pktPowerDownRadio(radio_unit_t radio) {
/* TODO: Implement hardware mapping. */
(void)radio;
/*
* Put radio in shutdown mode.
* All registers are lost.
*/
palSetLine(LINE_RADIO_SDN);
}
void sysConfigureCoreIO(void) {
/* Setup SPI3. */
palSetLineMode(LINE_SPI_SCK, PAL_MODE_ALTERNATE(6)
| PAL_STM32_OSPEED_HIGHEST); // SCK
palSetLineMode(LINE_SPI_MISO, PAL_MODE_ALTERNATE(6)
| PAL_STM32_OSPEED_HIGHEST); // MISO
palSetLineMode(LINE_SPI_MOSI, PAL_MODE_ALTERNATE(6)
| PAL_STM32_OSPEED_HIGHEST); // MOSI
/* Setup I2C1. */
palSetLineMode(LINE_I2C_SDA, PAL_MODE_ALTERNATE(4)
| PAL_STM32_OSPEED_HIGHEST
| PAL_STM32_OTYPE_OPENDRAIN); // SDA
palSetLineMode(LINE_I2C_SCL, PAL_MODE_ALTERNATE(4)
| PAL_STM32_OSPEED_HIGHEST
| PAL_STM32_OTYPE_OPENDRAIN); // SCL
#if ACTIVATE_USB
startUSB();
#endif
}
/*
*
*/
radio_freq_t pktCheckAllowedFrequency(radio_unit_t radio, radio_freq_t freq) {
/* Check validity. */
uint8_t radios = NUM_PKT_RADIOS/*sizeof(radio_list) / sizeof(radio_param_t)*/;
for(uint8_t i = 0; i < radios; i++) {
if(radio_list[i].unit != radio)
continue;
for(uint8_t x = 0; x < NUM_BANDS_PER_RADIO; x++) {
if(radio_list[i].band[x] == NULL)
/* No more bands in this radio. */
return FREQ_RADIO_INVALID;
if(radio_list[i].band[x]->start <= freq
&& freq < radio_list[i].band[x]->end)
return freq;
} /* End for bands */
} /* End for radios*/
return FREQ_RADIO_INVALID;
}
/** @} */

Wyświetl plik

@ -168,11 +168,11 @@ typedef struct radioBand {
radio_freq_t def_aprs;
} radio_band_t;
typedef struct radioParam {
typedef struct radioConfig {
radio_unit_t unit;
radio_type_t type;
radio_band_t *band[NUM_BANDS_PER_RADIO];
} radio_param_t;
} radio_config_t;
/*===========================================================================*/
/* Module macros. */

Wyświetl plik

@ -833,7 +833,7 @@ THD_FUNCTION(pktAFSKDecoder, arg) {
chFactoryReleaseObjectsFIFO(pkt_fifo);
pktAddEventFlags(myHandler, EVT_AX25_NO_BUFFER);
myDriver->active_demod_object->status |=
EVT_AX25_NO_BUFFER | EVT_PWM_QUEUE_LOCK;
EVT_AX25_NO_BUFFER;
myDriver->decoder_state = DECODER_ERROR;
break;
}
@ -903,17 +903,35 @@ THD_FUNCTION(pktAFSKDecoder, arg) {
if(radio.pwm.impulse == PWM_IN_BAND_PREFIX) {
switch(radio.pwm.valley) {
case PWM_TERM_DECODE_STOP:
case PWM_TERM_DECODE_ENDED: {
/* End of data flag from PWM. */
/*
* The decoder has issued a stop to PWM.
* The radio side PWM acks the close with this in-band message.
* This case can execute where a stream is queued by PWM..
* but not yet opened by the decoder.
* Can happen during transition from decoder reset to idle state.
*/
case PWM_ACK_DECODE_END: {
/*
* Decoder set decode end.
* The radio PWM side puts an in-band message in the open stream.
* This case should never execute.
* The decoder will have entered close state already.
* TODO: Deprecate this case.
*/
myDriver->decoder_state = DECODER_RESET;
continue; /* Enclosing state switch. */
} /* End case 0. */
case PWM_TERM_CCA_CLOSE:
/* If CCA ends before the decoder sees a closing flag. */
case PWM_TERM_NO_DATA:
/* If there is no PWM radio data within a timeout. */
case PWM_TERM_QUEUE_LOCK:
/* If the PWM queue is locked by the decoder (AX25 buffer full). */
case PWM_TERM_ICU_OVERFLOW:
/* If the ICU overflows while PWM is being received. */
case PWM_TERM_QUEUE_ERR:
/* If there is still a PWM stream open when a new CCA is validated. */
case PWM_TERM_QUEUE_FULL: {
/* PWM (producer side) events.
* The decoder should have detected a closing flag ahead of these.
@ -1016,7 +1034,7 @@ THD_FUNCTION(pktAFSKDecoder, arg) {
/*
* Lock the PWM queue to stop any further radio data being written.
*/
myDriver->active_demod_object->status |= EVT_PWM_QUEUE_LOCK;
myDriver->active_demod_object->status |= EVT_AFSK_DECODE_ERROR;
/* Copy latest status into packet buffer object. */
myHandler->active_packet_object->status =
@ -1097,7 +1115,7 @@ THD_FUNCTION(pktAFSKDecoder, arg) {
/*
* Indicate AFSK decode done & lock the PWM queue.
*/
eventflags_t evtf = EVT_AFSK_DECODE_DONE | EVT_PWM_QUEUE_LOCK;
eventflags_t evtf = EVT_AFSK_DECODE_DONE;
myDriver->active_demod_object->status |= evtf;
/* Copy latest status into packet buffer object. */

Wyświetl plik

@ -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_QUEUE_LOCK | evt);
myDemod->active_radio_object->status |= (EVT_PWM_STREAM_CLOSED | evt);
pktAddEventFlagsI(myHandler, evt);
#if USE_HEAP_PWM_BUFFER == TRUE
input_queue_t *myQueue =
@ -281,7 +281,7 @@ void pktOpenPWMChannelI(ICUDriver *myICU, eventflags_t evt) {
* Shouldn't happen unless CCA has not triggered an EXTI trailing edge.
* For now just flag that an error condition happened.
*/
pktClosePWMChannelI(myICU, EVT_RADIO_CCA_FIFO_ERR, PWM_TERM_QUEUE_ERR);
pktClosePWMChannelI(myICU, EVT_PWM_FIFO_REMNANT, PWM_TERM_QUEUE_ERR);
return;
}
/* Normal CCA handling. */
@ -499,7 +499,7 @@ void pktRadioCCALeadTimer(ICUDriver *myICU) {
/* CCA still high so open PWM channel now it is validated. */
case PAL_HIGH: {
pktOpenPWMChannelI(myICU, EVT_RADIO_CCA_OPEN);
pktOpenPWMChannelI(myICU, EVT_PWM_STREAM_OPEN);
break;
}
}
@ -531,7 +531,7 @@ void pktRadioCCATrailTimer(ICUDriver *myICU) {
* This caters for the case where the decoder finishes first.
* This may happen if the sender uses a long HDLC packet tail.
*/
pktClosePWMChannelI(myICU, EVT_RADIO_CCA_CLOSE, PWM_TERM_CCA_CLOSE);
pktClosePWMChannelI(myICU, EVT_PWM_STREAM_CLOSE, PWM_TERM_CCA_CLOSE);
break;
}
@ -645,24 +645,24 @@ void pktRadioICUPeriod(ICUDriver *myICU) {
/*
* Check if decoding has already finished while ICU is still active.
* The decoder terminates a frame on the first trailing HDLC flag.
* If CPU is fast (FPU enabled) it might finish decode before ICU stops.
* If CPU is fast (FPU enabled) it might finish decode before PWM stops.
* A long sequence of trailing HDLC flags or junk after a frame close
* flag may cause trailing ICU activity.
* flag may cause trailing PWM activity.
*
*/
if((myDemod->active_radio_object->status & EVT_AFSK_DECODE_DONE) != 0) {
pktClosePWMChannelI(myICU, EVT_PWM_STREAM_CLOSED, PWM_TERM_DECODE_ENDED);
pktClosePWMChannelI(myICU, EVT_NONE, PWM_ACK_DECODE_END);
chSysUnlockFromISR();
return;
}
/*
* Check if the PWM queue has been locked by the decoder.
* This will happen when an error (such as no AX25 buffer) occurs.
* Check if the the decoder encountered an error condition.
* 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_PWM_QUEUE_LOCK) != 0) {
pktClosePWMChannelI(myICU, EVT_PWM_QUEUE_LOCK, PWM_TERM_QUEUE_LOCK);
if((myDemod->active_radio_object->status & EVT_AFSK_DECODE_ERROR) != 0) {
pktClosePWMChannelI(myICU, EVT_NONE, PWM_ACK_DECODE_ERROR);
chSysUnlockFromISR();
return;
}

Wyświetl plik

@ -42,11 +42,12 @@
#define PWM_TERM_QUEUE_FULL 1
#define PWM_TERM_ICU_OVERFLOW 2
#define PWM_TERM_QUEUE_ERR 3
#define PWM_TERM_DECODE_ENDED 4
#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_INFO_QUEUE_SWAP 8
#define PWM_ACK_DECODE_ERROR 9
/* ICU will be stopped if no activity for this number of seconds. */
#define ICU_INACTIVITY_TIMEOUT 60

Wyświetl plik

@ -36,15 +36,8 @@
* @notapi
*/
THD_FUNCTION(pktRadioManager, arg) {
/* When no task in queue use this rate. */
#define PKT_RADIO_TASK_MANAGER_IDLE_RATE_MS 100
/* When a TX task is submitted to radio switch to this rate. */
#define PKT_RADIO_TASK_MANAGER_TX_RATE_MS 100
/* Continue at TX rate for this number of cycles. */
/* TODO: Deprecate this gear shift stuff. */
#define PKT_RADIO_TASK_MANAGER_TX_HYSTERESIS 10
/* When waiting for TX tasks to complete. */
#define PKT_RADIO_TASK_MANAGER_WAIT_RATE_MS 100
packet_svc_t *handler = arg;
@ -52,34 +45,48 @@ THD_FUNCTION(pktRadioManager, arg) {
chDbgCheck(arg != NULL);
sysinterval_t poll_rate = PKT_RADIO_TASK_MANAGER_IDLE_RATE_MS;
/* TODO: Deprecate this gear shift stuff. */
uint8_t poll_hysteresis = 0;
objects_fifo_t *radio_queue = chFactoryGetObjectsFIFO(the_radio_fifo);
chDbgAssert(radio_queue != NULL, "no queue in radio manager FIFO");
/* Run until terminate request and no outstanding TX tasks. */
while(!(chThdShouldTerminateX() && handler->tx_count == 0)) {
while(true) {
/* Check for task requests. */
radio_task_object_t *task_object;
msg_t fifo_msg = chFifoReceiveObjectTimeout(radio_queue,
(void *)&task_object,
TIME_MS2I(poll_rate));
if(fifo_msg == MSG_TIMEOUT) {
/* TODO: Deprecate this gear shift stuff. */
if(poll_hysteresis == 0)
poll_rate = PKT_RADIO_TASK_MANAGER_IDLE_RATE_MS;
else
--poll_hysteresis;
continue;
}
(void)chFifoReceiveObjectTimeout(radio_queue,
(void *)&task_object, TIME_INFINITE);
/* Something to do. */
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.
* When no TX tasks are outstanding release the FIFO and terminate.
* The task initiator waits with chThdWait(...).
*/
if(handler->tx_count == 0) {
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));
pktSubmitRadioTask(radio, task_object, NULL);
continue;
}
case PKT_RADIO_RX_RSSI: {
/* TODO: Implement read RSSI radio task. */
break;
}
case PKT_RADIO_RX_OPEN: {
/* Create the packet management services. */
@ -102,8 +109,6 @@ THD_FUNCTION(pktRadioManager, arg) {
/* If AFSK start failed send event but leave managers running. */
if(driver == NULL) {
pktAddEventFlags(handler, (EVT_AFSK_START_FAIL));
/* pktBufferManagerRelease(handler);
pktCallbackManagerRelease(handler);*/
break;
}
break;
@ -164,7 +169,6 @@ THD_FUNCTION(pktRadioManager, arg) {
case MOD_AFSK: {
pktAcquireRadio(radio, TIME_INFINITE);
pktStopDecoder(handler->radio);
//handler->rx_active = false;
pktReleaseRadio(radio);
break;
} /* End case. */
@ -178,13 +182,9 @@ THD_FUNCTION(pktRadioManager, arg) {
} /* End case PKT_RADIO_RX_STOP. */
case PKT_RADIO_TX_SEND: {
/*
* TODO: Currently the decoder is not paused.
* Is it necessary since the RX is not outputting data during TX?
*/
/* Give each send a sequence number. */
++handler->radio_tx_config.tx_seq_num;
/* Pause the decoder. */
pktPauseDecoding(radio);
if(pktLLDsendPacket(task_object)) {
/*
@ -193,13 +193,10 @@ THD_FUNCTION(pktRadioManager, arg) {
*/
handler->tx_count++;
/* TODO: Deprecate this gear shift stuff. */
poll_hysteresis = PKT_RADIO_TASK_MANAGER_TX_HYSTERESIS;
poll_rate = PKT_RADIO_TASK_MANAGER_TX_RATE_MS;
/* Send Successfully enqueued.
* Unlike receive the task object is held by the TX until complete.
* This is non blocking as radio transmit runs in a thread.
* The radio task object is released in the TX thread release task.
* This is non blocking as each radio transmit runs in a thread.
* The radio task object is released through a TX thread release task.
*/
continue;
}
@ -263,22 +260,22 @@ THD_FUNCTION(pktRadioManager, arg) {
/*
* Signal close completed for this session.
* Any new open that is queued on the sempahore will be readied.
* Any new open that is queued on the semaphore will be readied.
*/
chBSemSignal(&handler->close_sem);
break;
} /*end case close. */
case PKT_RADIO_TX_THREAD: {
/* Get thread exit code a free memory. */
/* Get thread exit code and free memory. */
msg_t send_msg = chThdWait(task_object->thread);
//if(send_msg != MSG_OK) {
if(send_msg == MSG_TIMEOUT) {
TRACE_ERROR("SI > Transmit timeout");
TRACE_ERROR("RAD > Transmit timeout");
}
if(send_msg == MSG_RESET) {
TRACE_ERROR("SI > Transmit failed to start");
TRACE_ERROR("RAD > Transmit failed to start");
}
//}
bool rxok = true;
@ -287,7 +284,7 @@ THD_FUNCTION(pktRadioManager, arg) {
if(pktIsReceivePaused(radio)) {
rxok = pktLLDresumeReceive(radio);
if(!rxok) {
TRACE_ERROR("SI > Receive failed to resume after transmit");
TRACE_ERROR("RAD > Receive failed to resume after transmit");
}
pktResumeDecoding(radio);
} else {
@ -309,6 +306,7 @@ THD_FUNCTION(pktRadioManager, arg) {
/* Return radio task object to free list. */
chFifoReturnObject(radio_queue, (radio_task_object_t *)task_object);
} /* End while should terminate(). */
chFactoryReleaseObjectsFIFO(handler->the_radio_fifo);
chThdExit(MSG_OK);
}
@ -359,13 +357,102 @@ thread_t *pktRadioManagerCreate(radio_unit_t radio) {
}
/**
* TODO: This needs review. Is it robust enough?
* @brief Release the radio task manager.
* @pre The packet session is stopped so new TX or RX requests are blocked.
* @notes Any outstanding TX tasks are allowed to complete.
* @post The radio task manager is terminated and released.
* @post The radio manager FIFO is released.
*
* @param[in] radio radio unit ID.
*
* @api
*/
void pktRadioManagerRelease(radio_unit_t radio) {
packet_svc_t *handler = pktGetServiceObject(radio);
chThdTerminate(handler->radio_manager);
/*
* Get a task object to send to the manager.
* The radio manager thread will terminate.
* The FIFO is released in the manager thread before terminating.
*/
radio_task_object_t *rto = NULL;
(void)pktGetRadioTaskObject(radio, TIME_INFINITE, &rto);
rto->command = PKT_RADIO_MGR_CLOSE;
pktSubmitRadioTask(radio, rto, NULL);
chThdWait(handler->radio_manager);
chFactoryReleaseObjectsFIFO(handler->the_radio_fifo);
}
/**
* @brief Get a radio command task object.
* @pre Called from ISR level.
* @post A task object is returned ready for filling and submission.
*
* @param[in] radio radio unit ID.
* @param[out] rt pointer to a task object.
*
* @return Status of the operation.
* @retval MSG_TIMEOUT an object could not be obtained.
* @retval MSG_OK an object has been fetched.
*
* @iclass
*/
msg_t pktGetRadioTaskObjectI(radio_unit_t radio,
radio_task_object_t **rt) {
packet_svc_t *handler = pktGetServiceObject(radio);
chDbgAssert(handler != NULL, "invalid radio ID");
dyn_objects_fifo_t *task_fifo = handler->the_radio_fifo;
chDbgAssert(task_fifo != NULL, "no radio task fifo");
objects_fifo_t *task_queue = chFactoryGetObjectsFIFO(task_fifo);
chDbgAssert(task_queue != NULL, "no objects fifo list");
*rt = chFifoTakeObjectI(task_queue);
if(*rt == NULL) {
/* No object available. */
return MSG_TIMEOUT;
}
(*rt)->handler = handler;
return MSG_OK;
}
/**
* @brief Submit a radio command to the task manager.
* @post A task object is populated and submitted to the radio manager.
*
* @param[in] radio radio unit ID.
* @param[in] object radio task object to be submitted.
* @param[in] cb function to call with result (can be NULL).
*
* @api
*/
void pktSubmitRadioTaskI(radio_unit_t radio,
radio_task_object_t *object,
radio_task_cb_t cb) {
packet_svc_t *handler = pktGetServiceObject(radio);
chDbgAssert(handler != NULL, "invalid radio ID");
dyn_objects_fifo_t *task_fifo = handler->the_radio_fifo;
chDbgAssert(task_fifo != NULL, "no radio task fifo");
objects_fifo_t *task_queue = chFactoryGetObjectsFIFO(task_fifo);
chDbgAssert(task_queue != NULL, "no objects fifo list");
/* Populate the object with information from request. */
object->handler = handler;
object->callback = cb;
/*
* Submit the task to the queue.
* The task thread will process the request.
* The task object is returned to the free list.
* If a callback is specified it is called before the task object is freed.
*/
chFifoSendObjectI(task_queue, object);
}
/**
@ -397,7 +484,7 @@ msg_t pktGetRadioTaskObject(radio_unit_t radio,
objects_fifo_t *task_queue = chFactoryGetObjectsFIFO(task_fifo);
chDbgAssert(task_queue != NULL, "no objects fifo list");
*rt = chFifoTakeObjectTimeout(task_queue, TIME_MS2I(timeout));
*rt = chFifoTakeObjectTimeout(task_queue, timeout);
if(*rt == NULL) {
/* Timeout waiting for object. */

Wyświetl plik

@ -30,6 +30,9 @@
#define RADIO_TASK_QUEUE_MAX 10
#define NUM_BANDS_PER_RADIO 2
#define PKT_RADIO_MANAGER_TASK_KILL TRUE
/*===========================================================================*/
/* Module data structures and types. */
/*===========================================================================*/
@ -46,7 +49,9 @@ typedef enum radioCommand {
PKT_RADIO_RX_STOP,
PKT_RADIO_TX_SEND,
PKT_RADIO_RX_CLOSE,
PKT_RADIO_TX_THREAD
PKT_RADIO_TX_THREAD,
PKT_RADIO_MGR_CLOSE,
PKT_RADIO_RX_RSSI
} radio_command_t;
/**
@ -54,7 +59,9 @@ typedef enum radioCommand {
*/
typedef struct radioTask radio_task_object_t;
typedef struct packetHandlerData packet_svc_t;
typedef struct radioParam radio_param_t;
typedef struct radioConfig radio_config_t;
typedef struct radioSettings radio_settings_t;
typedef struct radioAction radio_action_t;
/**
* @brief Radio task notification callback type.
@ -64,6 +71,30 @@ typedef struct radioParam radio_param_t;
typedef void (*radio_task_cb_t)(radio_task_object_t *task_object);
#include "ax25_pad.h"
struct radioSettings {
mod_t type;
radio_freq_t base_frequency;
channel_hz_t step_hz;
radio_ch_t channel;
radio_squelch_t squelch;
};
struct radioAction {
radio_command_t command;
radio_task_cb_t callback;
msg_t result;
thread_t *thread;
char tx_thd_name[16];
packet_svc_t *handler;
packet_t packet_out;
};
struct radioTaskx {
radio_settings_t settings;
radio_action_t action;
};
/**
* @brief Radio task object.
* @details queue object submitted via FIFO or radio task requests.
@ -80,6 +111,7 @@ struct radioTask {
radio_task_cb_t callback;
msg_t result;
thread_t *thread;
/* TODO: Create thread name in the radio unit thread itself. */
char tx_thd_name[16];
packet_svc_t *handler;
packet_t packet_out;
@ -93,7 +125,7 @@ struct radioTask {
/*===========================================================================*/
//extern const radio_param_t radio_list[NUM_PKT_RADIOS];
//extern const radio_config_t radio_list[NUM_PKT_RADIOS];
#ifdef __cplusplus
extern "C" {

Wyświetl plik

@ -57,45 +57,45 @@
* 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_RADIO_CCA_GLITCH EVENT_MASK(EVT_PRIORITY_BASE + 1)
#define EVT_RADIO_CCA_CLOSE EVENT_MASK(EVT_PRIORITY_BASE + 2)
#define EVT_PWM_QUEUE_OVERRUN EVENT_MASK(EVT_PRIORITY_BASE + 3)
#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 EVT_AFSK_TERMINATED EVENT_MASK(EVT_PRIORITY_BASE + 4)
#define EVT_PWM_UNKNOWN_INBAND EVENT_MASK(EVT_PRIORITY_BASE + 5)
#define EVT_ICU_OVERFLOW EVENT_MASK(EVT_PRIORITY_BASE + 6)
#define EVT_PKT_FAILED_CB_THD EVENT_MASK(EVT_PRIORITY_BASE + 7)
#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_ERROR EVENT_MASK(EVT_PRIORITY_BASE + 6)
#define EVT_AFSK_DECODE_DONE EVENT_MASK(EVT_PRIORITY_BASE + 7)
#define EVT_PWM_NO_DATA EVENT_MASK(EVT_PRIORITY_BASE + 8)
#define EVT_AFSK_START_FAIL EVENT_MASK(EVT_PRIORITY_BASE + 9)
#define EVT_RADIO_CCA_OPEN EVENT_MASK(EVT_PRIORITY_BASE + 10)
#define EVT_PWM_NO_DATA EVENT_MASK(EVT_PRIORITY_BASE + 8)
#define EVT_PWM_UNKNOWN_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_FIFO_EMPTY EVENT_MASK(EVT_PRIORITY_BASE + 12)
#define EVT_PWM_STREAM_CLOSED EVENT_MASK(EVT_PRIORITY_BASE + 12)
#define EVT_PWM_STREAM_TIMEOUT EVENT_MASK(EVT_PRIORITY_BASE + 13)
#define EVT_PWM_QUEUE_LOCK EVENT_MASK(EVT_PRIORITY_BASE + 14)
#define EVT_PKT_DECODER_START EVENT_MASK(EVT_PRIORITY_BASE + 15)
#define EVT_PWM_QUEUE_OVERRUN EVENT_MASK(EVT_PRIORITY_BASE + 14)
#define EVT_PWM_BUFFER_FAIL EVENT_MASK(EVT_PRIORITY_BASE + 15)
#define EVT_PKT_CHANNEL_STOP EVENT_MASK(EVT_PRIORITY_BASE + 16)
#define EVT_RADIO_CCA_FIFO_ERR EVENT_MASK(EVT_PRIORITY_BASE + 17)
#define EVT_AX25_BUFFER_FULL EVENT_MASK(EVT_PRIORITY_BASE + 18)
#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_AX25_CRC_ERROR EVENT_MASK(EVT_PRIORITY_BASE + 20)
#define EVT_HDLC_RESET_RCVD EVENT_MASK(EVT_PRIORITY_BASE + 21)
#define EVT_AX25_NO_BUFFER EVENT_MASK(EVT_PRIORITY_BASE + 22)
#define EVT_ICU_SLEEP_TIMEOUT EVENT_MASK(EVT_PRIORITY_BASE + 23)
#define EVT_PKT_FAILED_CB_THD EVENT_MASK(EVT_PRIORITY_BASE + 20)
#define EVT_PKT_BUFFER_MGR_FAIL EVENT_MASK(EVT_PRIORITY_BASE + 21)
#define EVT_PKT_DECODER_START EVENT_MASK(EVT_PRIORITY_BASE + 22)
#define EVT_PKT_CBK_MGR_FAIL EVENT_MASK(EVT_PRIORITY_BASE + 23)
#define EVT_PWM_STREAM_CLOSED EVENT_MASK(EVT_PRIORITY_BASE + 24)
#define EVT_PKT_CHANNEL_STOP EVENT_MASK(EVT_PRIORITY_BASE + 24)
#define EVT_PKT_CHANNEL_CLOSE EVENT_MASK(EVT_PRIORITY_BASE + 25)
#define EVT_PKT_CHANNEL_OPEN EVENT_MASK(EVT_PRIORITY_BASE + 26)
#define EVT_AFSK_DECODE_DONE EVENT_MASK(EVT_PRIORITY_BASE + 27)
#define EVT_RADIO_CCA_GLITCH EVENT_MASK(EVT_PRIORITY_BASE + 27)
#define EVT_RADIO_CCA_SPIKE EVENT_MASK(EVT_PRIORITY_BASE + 28)
#define EVT_PKT_BUFFER_MGR_FAIL EVENT_MASK(EVT_PRIORITY_BASE + 29)
#define EVT_PWM_BUFFER_FAIL EVENT_MASK(EVT_PRIORITY_BASE + 30)
#define EVT_PKT_CBK_MGR_FAIL EVENT_MASK(EVT_PRIORITY_BASE + 31)
#define EVT_ICU_SLEEP_TIMEOUT EVENT_MASK(EVT_PRIORITY_BASE + 29)
#define EVT_ICU_OVERFLOW EVENT_MASK(EVT_PRIORITY_BASE + 30)
#define EVT_HDLC_RESET_RCVD EVENT_MASK(EVT_PRIORITY_BASE + 31)
/* Decoder thread event masks (sent from initiator to decoder). */
@ -220,11 +220,13 @@ static inline int8_t pktReadGPIOline(ioline_t line) {
}
/**
* @brief Sends a command request to a radio.
* @brief Sends a command request to the radio manager.
* @notes The task descriptor is copied into a task object which is posted.
* @post The command object posted to the radio manager queue.
*
* @param[in] radio radio unit ID.
* @param[in] task pointer to a task object.
* @param[in] task pointer to the task descriptor.
* this is usually a persistent descriptor in the handler.
* @param[in] cb function to call with result (can be NULL).
*
* @api