kopia lustrzana https://github.com/DL7AD/pecanpico10
Multiple changes:
- WIP LLD functions for abstraction of radio interfaces - Add new string output functions for GPS states and model - Trim WA size for image thread - Further tidy up in AFSK decoderpull/4/head
rodzic
b02ac2c1e8
commit
9d012cb49b
|
@ -180,7 +180,7 @@ void pktWrite(uint8_t *buf, uint32_t len) {
|
|||
chnWrite((BaseSequentialStream*)SERIAL_CFG_DEBUG_DRIVER, buf, len);
|
||||
}
|
||||
|
||||
void sysConfigureCoreIO(void) {
|
||||
void pktConfigureCoreIO(void) {
|
||||
/* Setup SPI3. */
|
||||
palSetLineMode(LINE_SPI_SCK, PAL_MODE_ALTERNATE(6)
|
||||
| PAL_STM32_OSPEED_HIGHEST); // SCK
|
||||
|
|
|
@ -200,7 +200,7 @@ extern "C" {
|
|||
#endif
|
||||
void pktConfigSerialDiag(void);
|
||||
void pktConfigSerialPkt(void);
|
||||
void sysConfigureCoreIO(void);
|
||||
void pktConfigureCoreIO(void);
|
||||
void pktSetLineModeICU(void);
|
||||
void pktSerialStart(void);
|
||||
void dbgWrite(uint8_t level, uint8_t *buf, uint32_t len);
|
||||
|
|
|
@ -174,7 +174,7 @@ void pktWrite(uint8_t *buf, uint32_t len) {
|
|||
}
|
||||
|
||||
|
||||
void sysConfigureCoreIO(void) {
|
||||
void pktConfigureCoreIO(void) {
|
||||
/* Setup SPI3. */
|
||||
palSetLineMode(LINE_SPI_SCK, PAL_MODE_ALTERNATE(6)
|
||||
| PAL_STM32_OSPEED_HIGHEST); // SCK
|
||||
|
|
|
@ -191,7 +191,7 @@ extern "C" {
|
|||
#endif
|
||||
void pktConfigSerialDiag(void);
|
||||
void pktConfigSerialPkt(void);
|
||||
void sysConfigureCoreIO(void);
|
||||
void pktConfigureCoreIO(void);
|
||||
void pktSetLineModeICU(void);
|
||||
void pktSerialStart(void);
|
||||
void dbgWrite(uint8_t level, uint8_t *buf, uint32_t len);
|
||||
|
|
|
@ -13,11 +13,22 @@ int main(void) {
|
|||
chSysInit(); // Startup RTOS
|
||||
|
||||
/* Setup core IO peripherals. */
|
||||
sysConfigureCoreIO();
|
||||
pktConfigureCoreIO();
|
||||
|
||||
// Init debugging (Serial debug port, LEDs)
|
||||
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");
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Setup buffers in CCM if available.
|
||||
* Setup packet primary data.
|
||||
|
@ -26,12 +37,7 @@ int main(void) {
|
|||
|
||||
chDbgAssert(pkt == true, "failed to init packet system");
|
||||
|
||||
#if ACTIVATE_USB
|
||||
/* Start Serial Over USB. */
|
||||
startSDU();
|
||||
#endif
|
||||
|
||||
/* Start serial channels if selected. */
|
||||
/* Start serial diagnostic channels if selected. */
|
||||
pktSerialStart();
|
||||
|
||||
/* Create packet radio service. */
|
||||
|
@ -41,12 +47,13 @@ int main(void) {
|
|||
pktEnableEventTrace();
|
||||
}
|
||||
|
||||
TRACE_INFO("MAIN > Startup");
|
||||
TRACE_INFO("MAIN > Starting 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");
|
||||
while(true) {
|
||||
#if ACTIVATE_USB
|
||||
manageTraceAndShell();
|
||||
|
|
|
@ -178,7 +178,7 @@ const conf_t conf_flash_default = {
|
|||
.gps_off_vbat = 3000, // mV
|
||||
.gps_onper_vbat = 4000, // mV
|
||||
|
||||
// GPS altitude model control (air pressure determined by on-board BME280)
|
||||
// GPS altitude model control (air pressure controlled using on-board BME280)
|
||||
.gps_pressure = 90000, // Air pressure (Pa) threshold for alt model switch
|
||||
.gps_low_alt = GPS_STATIONARY,
|
||||
.gps_high_alt = GPS_AIRBORNE_1G,
|
||||
|
|
Plik diff jest za duży
Load Diff
|
@ -12,7 +12,7 @@
|
|||
#include "collector.h"
|
||||
|
||||
bool gps_enabled = false;
|
||||
int8_t gps_model = GPS_MODEL_UNSET;
|
||||
uint8_t gps_model = GPS_MODEL_PORTABLE;
|
||||
|
||||
#if defined(UBLOX_UART_CONNECTED)
|
||||
// Serial driver configuration for GPS
|
||||
|
@ -25,6 +25,20 @@ const SerialConfig gps_config =
|
|||
};
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Array for looking up model name
|
||||
*/
|
||||
static const char *model[] = {GPS_MODEL_NAMES};
|
||||
|
||||
/**
|
||||
* Get pointer to model name as string
|
||||
*/
|
||||
const char *gps_get_model_name(uint8_t index) {
|
||||
if(index > GPS_MODEL_MAX)
|
||||
return "INVALID";
|
||||
return model[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Transmits a string of bytes to the GPS
|
||||
*/
|
||||
|
@ -264,11 +278,11 @@ bool gps_get_fix(gpsFix_t *fix) {
|
|||
} else {
|
||||
fix->alt = (uint16_t)alt_tmp;
|
||||
}
|
||||
/* }*/
|
||||
TRACE_INFO("GPS > Polling OK time=%04d-%02d-%02d %02d:%02d:%02d lat=%d.%05d lon=%d.%05d alt=%dm sats=%d fixOK=%d pDOP=%02d.%02d model=%d",
|
||||
fix->model = gps_model;
|
||||
TRACE_INFO("GPS > Polling OK time=%04d-%02d-%02d %02d:%02d:%02d lat=%d.%05d lon=%d.%05d alt=%dm sats=%d fixOK=%d pDOP=%02d.%02d model=%s",
|
||||
fix->time.year, fix->time.month, fix->time.day, fix->time.hour, fix->time.minute, fix->time.second,
|
||||
fix->lat/10000000, (fix->lat > 0 ? 1:-1)*(fix->lat/100)%100000, fix->lon/10000000, (fix->lon > 0 ? 1:-1)*(fix->lon/100)%100000,
|
||||
fix->alt, fix->num_svs, fix->fixOK, fix->pdop/100, fix->pdop%100, gps_model
|
||||
fix->alt, fix->num_svs, fix->fixOK, fix->pdop/100, fix->pdop%100, gps_get_model_name(fix->model)
|
||||
);
|
||||
|
||||
return true;
|
||||
|
@ -599,7 +613,7 @@ bool GPS_Init() {
|
|||
// Wait for GPS startup
|
||||
chThdSleep(TIME_S2I(1));
|
||||
|
||||
gps_model = GPS_MODEL_UNSET;
|
||||
gps_model = GPS_MODEL_PORTABLE;
|
||||
// Configure GPS
|
||||
TRACE_INFO("GPS > Transmit config to GPS");
|
||||
|
||||
|
@ -632,7 +646,7 @@ void GPS_Deinit(void)
|
|||
palSetLineMode(LINE_GPS_RXD, PAL_MODE_INPUT); // UART RXD
|
||||
palSetLineMode(LINE_GPS_TXD, PAL_MODE_INPUT); // UART TXD
|
||||
#endif
|
||||
gps_model = GPS_MODEL_UNSET;
|
||||
gps_model = GPS_MODEL_PORTABLE;
|
||||
gps_enabled = false;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,9 @@
|
|||
#include "hal.h"
|
||||
#include "ptime.h"
|
||||
|
||||
#define GPS_MODEL_UNSET -1
|
||||
/**
|
||||
* @brief GPS model values.
|
||||
*/
|
||||
#define GPS_MODEL_PORTABLE 0
|
||||
#define GPS_MODEL_STATIONARY 2
|
||||
#define GPS_MODEL_PEDESTRIAN 3
|
||||
|
@ -19,6 +21,20 @@
|
|||
#define GPS_MODEL_AIRBORNE2G 7
|
||||
#define GPS_MODEL_AIRBORNE4G 8
|
||||
|
||||
|
||||
/* Model limits. */
|
||||
//#define GPS_MODEL_UNSET -1
|
||||
#define GPS_MODEL_MAX GPS_MODEL_AIRBORNE4G
|
||||
|
||||
/**
|
||||
* @brief GPS models as array of strings.
|
||||
* @details Each element in an array initialized with this macro can be
|
||||
* indexed using a numeric GPS model value.
|
||||
*/
|
||||
#define GPS_MODEL_NAMES \
|
||||
"PORTABLE", "NONE", "STATIONARY", "PEDESTRIAN", "AUTOMOTIVE", "SEA", \
|
||||
"AIRBORNE1G", "AIRBORNE2G", "AIRBORNE4G"
|
||||
|
||||
typedef enum {
|
||||
GPS_PORTABLE = GPS_MODEL_PORTABLE,
|
||||
GPS_STATIONARY = GPS_MODEL_STATIONARY,
|
||||
|
@ -75,6 +91,7 @@ typedef struct {
|
|||
int32_t alt; // altitude in m, range 0m, up to ~40000m, clamped
|
||||
bool fixOK; // Flag that is set to true, when DOP is with the limits
|
||||
uint16_t pdop; // Position DOP
|
||||
uint8_t model; // Dynamic model
|
||||
} gpsFix_t;
|
||||
|
||||
uint8_t gps_set_gps_only(void);
|
||||
|
@ -92,6 +109,7 @@ bool GPS_Init(void);
|
|||
void GPS_Deinit(void);
|
||||
uint32_t GPS_get_mcu_frequency(void);
|
||||
bool gps_calc_ubx_csum(uint8_t *mbuf, uint16_t mlen);
|
||||
const char *gps_get_model_name(uint8_t index);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -913,7 +913,7 @@ THD_FUNCTION(pktAFSKDecoder, arg) {
|
|||
*/
|
||||
myDriver->decoder_state = DECODER_RESET;
|
||||
continue; /* Continue in main loop. */
|
||||
}
|
||||
} /* End case. */
|
||||
|
||||
case PWM_ACK_DECODE_ERROR:
|
||||
case PWM_ACK_DECODE_END: {
|
||||
|
@ -928,8 +928,8 @@ THD_FUNCTION(pktAFSKDecoder, arg) {
|
|||
pktAddEventFlags(myHandler, EVT_PWM_INVALID_INBAND);
|
||||
myDriver->decoder_state = DECODER_RESET;
|
||||
|
||||
continue; /* Enclosing state switch. */
|
||||
} /* End case 0. */
|
||||
continue; /* Decoder state switch. */
|
||||
} /* End case. */
|
||||
|
||||
/* If CCA ends and the decoder has not validated any frame.
|
||||
* The PWM side has already posted a PWM_STREAM_CLOSE event.
|
||||
|
@ -941,27 +941,25 @@ THD_FUNCTION(pktAFSKDecoder, arg) {
|
|||
*/
|
||||
case PWM_TERM_NO_DATA:
|
||||
|
||||
|
||||
//case PWM_TERM_QUEUE_LOCK:
|
||||
|
||||
/* If the ICU timer overflows during PWM capture.
|
||||
* The PWM side has already posted a ICU_OVERFLOW event.
|
||||
*/
|
||||
case PWM_TERM_ICU_OVERFLOW:
|
||||
|
||||
/* This is a debug error if a CCA is validated but a PWM is still active.
|
||||
/* This is a debug error.
|
||||
* CCA is validated but a PWM is still active.
|
||||
* The PWM side has already posted a PWM_FIFO_REMNANT event.
|
||||
*/
|
||||
case PWM_TERM_QUEUE_ERR:
|
||||
|
||||
/* If there are no more PWM buffers available.
|
||||
/* If there is no more PWM buffer space available.
|
||||
* The PWM side has already posted a PWM_QUEUE_FULL event.
|
||||
*/
|
||||
case PWM_TERM_QUEUE_FULL: {
|
||||
/* Transit to RESET state where all buffers/objects are released. */
|
||||
myDriver->decoder_state = DECODER_RESET;
|
||||
continue; /* Enclosing state switch. */
|
||||
} /* End case 1. */
|
||||
continue; /* Decoder state switch. */
|
||||
} /* End case. */
|
||||
|
||||
#if USE_HEAP_PWM_BUFFER == TRUE
|
||||
case PWM_INFO_QUEUE_SWAP: {
|
||||
|
@ -988,24 +986,22 @@ THD_FUNCTION(pktAFSKDecoder, arg) {
|
|||
/* TODO: Need an EVT code freed up to add INVALID_SWAP. */
|
||||
myDriver->decoder_state = DECODER_RESET;
|
||||
}
|
||||
continue; /* Enclosing state switch. */
|
||||
}
|
||||
continue; /* Decoder state switch. */
|
||||
} /* End case. */
|
||||
#endif
|
||||
|
||||
default: {
|
||||
/* Unknown in-band message from PWM. */
|
||||
pktAddEventFlags(myHandler, EVT_PWM_INVALID_INBAND);
|
||||
//myDriver->active_demod_object->status |= EVT_PWM_INVALID_INBAND;
|
||||
myDriver->decoder_state = DECODER_RESET;
|
||||
continue; /* Enclosing state switch. */
|
||||
} /* End case default. */
|
||||
} /* End switch. */
|
||||
/* Execute primary loop switch on state. */
|
||||
continue;
|
||||
} /* End switch on in-band. */
|
||||
continue; /* Decoder state switch. */
|
||||
} /* End if in-band. */
|
||||
|
||||
/*
|
||||
* Process the AFSK into HDLC bit and AX25 data.
|
||||
* If not in-band the process the AFSK into an HDLC bit and AX25 data.
|
||||
*/
|
||||
if(!pktProcessAFSK(myDriver, radio.array)) {
|
||||
/* AX25 character decoded but buffer is full.
|
||||
|
@ -1038,12 +1034,13 @@ THD_FUNCTION(pktAFSKDecoder, arg) {
|
|||
continue; /* From this case. */
|
||||
}
|
||||
} /* End switch. */
|
||||
break; /* Keep GCC 7 happy. */
|
||||
} /* End case DECODER_ACTIVE. */
|
||||
|
||||
/*
|
||||
* RESET readies the decoder for the next session.
|
||||
* It frees all still active buffer/objects.
|
||||
* Then the DSP system is reset prior to set state to IDLE.
|
||||
* It frees any held buffers/objects.
|
||||
* The DSP system is reset and then transition to IDLE.
|
||||
*/
|
||||
case DECODER_RESET: {
|
||||
if(myHandler->active_packet_object != NULL) {
|
||||
|
@ -1059,7 +1056,7 @@ THD_FUNCTION(pktAFSKDecoder, arg) {
|
|||
|
||||
chFifoReturnObject(pkt_fifo, myHandler->active_packet_object);
|
||||
|
||||
/* Forget the buffer management object. */
|
||||
/* Forget the AX25 buffer management object. */
|
||||
myHandler->active_packet_object = NULL;
|
||||
}
|
||||
|
||||
|
@ -1119,6 +1116,7 @@ THD_FUNCTION(pktAFSKDecoder, arg) {
|
|||
case DECODER_DISPATCH: {
|
||||
if(myHandler->active_packet_object != NULL) {
|
||||
|
||||
/* TODO: PWM chain is also released in RESET so this can be removed. */
|
||||
#if USE_HEAP_PWM_BUFFER == TRUE
|
||||
/* Release PWM queue/buffer objects back to the pool. */
|
||||
radio_pwm_fifo_t *myFIFO = myDriver->active_demod_object;
|
||||
|
@ -1134,7 +1132,8 @@ THD_FUNCTION(pktAFSKDecoder, arg) {
|
|||
#endif
|
||||
#endif
|
||||
/*
|
||||
* Indicate AFSK decode done which also locks the PWM queue.
|
||||
* 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;
|
||||
|
@ -1149,38 +1148,13 @@ THD_FUNCTION(pktAFSKDecoder, arg) {
|
|||
/* Forget the packet object. */
|
||||
myHandler->active_packet_object = NULL;
|
||||
|
||||
/*
|
||||
* Send events then update PWM/demod object status.
|
||||
* (the PWM input side doesn't care about AX25 events actually...)
|
||||
*/
|
||||
/* Send events then update demod object status. */
|
||||
pktAddEventFlags(myHandler, evtf);
|
||||
myDriver->active_demod_object->status |= evtf;
|
||||
|
||||
#if AFSK_DEBUG_TYPE == AFSK_PWM_DATA_CAPTURE_DEBUG
|
||||
event_listener_t p_listener;
|
||||
chEvtRegisterMaskWithFlags(
|
||||
chnGetEventSource ((SerialDriver *)pkt_out),
|
||||
&p_listener, DEC_DIAG_OUT_END,
|
||||
CHN_TRANSMISSION_END);
|
||||
char buf[80];
|
||||
int out = chsnprintf(buf, sizeof(buf),
|
||||
"\r\n======= END (%s) =========\r\n",
|
||||
(myDriver->active_demod_object->status & EVT_AFSK_INVALID_FRAME)
|
||||
? "invalid frame"
|
||||
: (myDriver->active_demod_object->status & EVT_AX25_FRAME_RDY)
|
||||
? "good CRC" : "bad CRC");
|
||||
chnWrite(pkt_out, (uint8_t *)buf, out);
|
||||
eventflags_t clear;
|
||||
do {
|
||||
clear = chEvtWaitAnyTimeout(DEC_DIAG_OUT_END, TIME_MS2I(100));
|
||||
} while(clear != 0);
|
||||
chEvtUnregister(chnGetEventSource ((SerialDriver *)pkt_out),
|
||||
&p_listener);
|
||||
#endif
|
||||
} /* Active packet object != NULL. */
|
||||
myDriver->decoder_state = DECODER_RESET;
|
||||
break;
|
||||
} /* End case DECODER_SUSPEND. */
|
||||
} /* End case DECODER_DISPATCH. */
|
||||
} /* End switch on decoder state. */
|
||||
} /* End thread while(true). */
|
||||
}
|
||||
|
|
|
@ -168,7 +168,10 @@ static void Si446x_init(const radio_unit_t radio) {
|
|||
|
||||
chDbgAssert(handler != NULL, "invalid radio ID");
|
||||
|
||||
pktPowerUpRadio(radio);
|
||||
//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
|
||||
|
||||
// Power up (send oscillator type)
|
||||
const uint8_t x3 = (Si446x_CCLK >> 24) & 0x0FF;
|
||||
|
@ -376,7 +379,7 @@ bool Si446x_setBandParameters(const radio_unit_t radio,
|
|||
Si446x_write(set_modem_freq_dev_command, 7);
|
||||
}*/
|
||||
|
||||
static void Si446x_setPowerLevel(radio_pwr_t level)
|
||||
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};
|
||||
|
@ -469,7 +472,7 @@ static void Si446x_setModemAFSK_RX(const radio_unit_t radio) {
|
|||
Si446x_setProperty8(Si446x_MODEM_CHFLT_RX2_CHFLT_COEM3, 0x00);*/
|
||||
}
|
||||
|
||||
static void Si446x_setModem2FSK_TX(uint32_t speed)
|
||||
static void Si446x_setModem2FSK_TX(const uint32_t speed)
|
||||
{
|
||||
// Setup the NCO modulo and oversampling mode
|
||||
uint32_t s = Si446x_CCLK / 10;
|
||||
|
@ -497,30 +500,32 @@ static void Si446x_setModem2FSK_TX(uint32_t speed)
|
|||
|
||||
/* ====================================================================== Radio Settings ====================================================================== */
|
||||
|
||||
static uint8_t __attribute__((unused)) Si446x_getChannel(void) {
|
||||
static uint8_t __attribute__((unused)) Si446x_getChannel(const radio_unit_t radio) {
|
||||
/* TODO: add hardware mapping. */
|
||||
const uint8_t state_info[] = {Si446x_REQUEST_DEVICE_STATE};
|
||||
uint8_t rxData[4];
|
||||
Si446x_read(state_info, sizeof(state_info), rxData, sizeof(rxData));
|
||||
return rxData[3];
|
||||
(void)radio;
|
||||
const uint8_t state_info[] = {Si446x_REQUEST_DEVICE_STATE};
|
||||
uint8_t rxData[4];
|
||||
Si446x_read(state_info, sizeof(state_info), rxData, sizeof(rxData));
|
||||
return rxData[3];
|
||||
}
|
||||
|
||||
/* ======================================================================= Radio FIFO ======================================================================= */
|
||||
|
||||
static void Si446x_writeFIFO(uint8_t *msg, uint8_t size) {
|
||||
/* TODO: add hardware mapping. */
|
||||
uint8_t write_fifo[size+1];
|
||||
write_fifo[0] = Si446x_WRITE_TX_FIFO;
|
||||
memcpy(&write_fifo[1], msg, size);
|
||||
Si446x_write(write_fifo, size+1);
|
||||
uint8_t write_fifo[size+1];
|
||||
write_fifo[0] = Si446x_WRITE_TX_FIFO;
|
||||
memcpy(&write_fifo[1], msg, size);
|
||||
Si446x_write(write_fifo, size+1);
|
||||
}
|
||||
|
||||
static uint8_t Si446x_getTXfreeFIFO(void) {
|
||||
static uint8_t Si446x_getTXfreeFIFO(const radio_unit_t radio) {
|
||||
/* TODO: add hardware mapping. */
|
||||
const uint8_t fifo_info[] = {Si446x_FIFO_INFO, 0x00};
|
||||
uint8_t rxData[4];
|
||||
Si446x_read(fifo_info, sizeof(fifo_info), rxData, sizeof(rxData));
|
||||
return rxData[3];
|
||||
(void)radio;
|
||||
const uint8_t fifo_info[] = {Si446x_FIFO_INFO, 0x00};
|
||||
uint8_t rxData[4];
|
||||
Si446x_read(fifo_info, sizeof(fifo_info), rxData, sizeof(rxData));
|
||||
return rxData[3];
|
||||
}
|
||||
|
||||
/* ====================================================================== Radio States ====================================================================== */
|
||||
|
@ -539,64 +544,78 @@ 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};
|
||||
//uint8_t rxData[10];
|
||||
Si446x_read(status_info, sizeof(status_info), (uint8_t *)info, sizeof(si446x_info_t));
|
||||
//return rxData[4];
|
||||
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;
|
||||
const uint8_t state_info[] = {Si446x_REQUEST_DEVICE_STATE};
|
||||
uint8_t rxData[4];
|
||||
Si446x_read(state_info, sizeof(state_info), rxData, sizeof(rxData));
|
||||
return rxData[2] & 0xF;
|
||||
const uint8_t state_info[] = {Si446x_REQUEST_DEVICE_STATE};
|
||||
uint8_t rxData[4];
|
||||
Si446x_read(state_info, sizeof(state_info), rxData, sizeof(rxData));
|
||||
return rxData[2] & 0xF;
|
||||
}
|
||||
|
||||
static void Si446x_setTXState(const radio_unit_t radio, uint8_t chan, uint16_t size){
|
||||
/* TODO: add hardware mapping. */
|
||||
(void)radio;
|
||||
uint8_t change_state_command[] = {0x31, chan,
|
||||
(Si446x_STATE_READY << 4),
|
||||
(size >> 8) & 0x1F, size & 0xFF};
|
||||
Si446x_write(change_state_command, sizeof(change_state_command));
|
||||
uint8_t change_state_command[] = {0x31, chan,
|
||||
(Si446x_STATE_READY << 4),
|
||||
(size >> 8) & 0x1F, size & 0xFF};
|
||||
Si446x_write(change_state_command, sizeof(change_state_command));
|
||||
}
|
||||
|
||||
static void Si446x_setReadyState(const radio_unit_t radio) {
|
||||
/* TODO: add hardware mapping. */
|
||||
(void)radio;
|
||||
const uint8_t change_state_command[] = {0x34, 0x03};
|
||||
Si446x_write(change_state_command, sizeof(change_state_command));
|
||||
const uint8_t change_state_command[] = {0x34, 0x03};
|
||||
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,
|
||||
0x00, 0x00, 0x08, 0x08};
|
||||
Si446x_write(change_state_command, sizeof(change_state_command));
|
||||
const uint8_t change_state_command[] = {0x32, chan, 0x00, 0x00,
|
||||
0x00, 0x00, 0x08, 0x08};
|
||||
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);
|
||||
|
||||
void Si446x_shutdown(radio_unit_t 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_shutdown(const radio_unit_t radio) {
|
||||
TRACE_INFO("SI > Shutdown radio %i", radio);
|
||||
packet_svc_t *handler = pktGetServiceObject(radio);
|
||||
|
||||
chDbgAssert(handler != NULL, "invalid radio ID");
|
||||
|
||||
pktPowerDownRadio(radio);
|
||||
//pktPowerDownRadio(radio);
|
||||
palSetLine(LINE_RADIO_SDN);
|
||||
handler->radio_init = false;
|
||||
}
|
||||
|
||||
/* ====================================================================== Radio TX/RX ======================================================================= */
|
||||
|
||||
/*
|
||||
/**
|
||||
* Get CCA over measurement interval.
|
||||
* Algorithm counts CCA pulses per millisecond (in systick time slices).
|
||||
* If more than one pulse per millisecond is counted then CCA is not true.
|
||||
*/
|
||||
static bool Si446x_checkCCAthreshold(radio_unit_t radio, uint8_t ms) {
|
||||
static bool Si446x_checkCCAthreshold(const radio_unit_t radio, uint8_t ms) {
|
||||
/* TODO: Hardware mapping of radio. */
|
||||
(void)radio;
|
||||
uint16_t cca = 0;
|
||||
|
@ -612,10 +631,10 @@ static bool Si446x_checkCCAthreshold(radio_unit_t radio, uint8_t ms) {
|
|||
return cca > ms;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* Wait for a clear time slot and initiate packet transmission.
|
||||
*/
|
||||
static bool Si446x_transmit(radio_unit_t radio,
|
||||
static bool Si446x_transmit(const radio_unit_t radio,
|
||||
radio_freq_t freq,
|
||||
channel_hz_t step,
|
||||
radio_ch_t chan,
|
||||
|
@ -699,7 +718,7 @@ static bool Si446x_transmit(radio_unit_t radio,
|
|||
/*
|
||||
*
|
||||
*/
|
||||
bool Si446x_receiveNoLock(radio_unit_t radio,
|
||||
bool Si446x_receiveNoLock(const radio_unit_t radio,
|
||||
radio_freq_t freq,
|
||||
channel_hz_t step,
|
||||
radio_ch_t channel,
|
||||
|
@ -754,7 +773,7 @@ bool Si446x_receiveNoLock(radio_unit_t radio,
|
|||
* return true if RX was enabled and/or resumed OK.
|
||||
* return false if RX was not enabled.
|
||||
*/
|
||||
bool Si4464_resumeReceive(radio_unit_t radio,
|
||||
bool Si4464_resumeReceive(const radio_unit_t radio,
|
||||
radio_freq_t rx_frequency,
|
||||
channel_hz_t rx_step,
|
||||
radio_ch_t rx_chan,
|
||||
|
@ -786,7 +805,7 @@ bool Si4464_resumeReceive(radio_unit_t radio,
|
|||
/*
|
||||
*
|
||||
*/
|
||||
void Si446x_disableReceive(radio_unit_t radio) {
|
||||
void Si446x_disableReceive(const radio_unit_t radio) {
|
||||
/* FIXME: */
|
||||
if(Si446x_getState(radio) == Si446x_STATE_RX) {
|
||||
//rx_frequency = 0;
|
||||
|
@ -797,7 +816,7 @@ void Si446x_disableReceive(radio_unit_t radio) {
|
|||
/*
|
||||
*
|
||||
*/
|
||||
void Si446x_pauseReceive(radio_unit_t radio) {
|
||||
void Si446x_pauseReceive(const radio_unit_t radio) {
|
||||
/* FIXME: Should provide status. */
|
||||
if(Si446x_getState(radio) == Si446x_STATE_RX) {
|
||||
Si446x_setReadyState(radio);
|
||||
|
@ -865,7 +884,7 @@ THD_FUNCTION(bloc_si_fifo_feeder_afsk, arg) {
|
|||
pktReleaseBufferChain(pp);
|
||||
|
||||
/* Schedule thread and task object memory release. */
|
||||
pktScheduleSendComplete(rto, chThdGetSelfX());
|
||||
pktLLDradioSendComplete(rto, chThdGetSelfX());
|
||||
|
||||
/* Exit thread. */
|
||||
chThdExit(MSG_RESET);
|
||||
|
@ -920,7 +939,7 @@ THD_FUNCTION(bloc_si_fifo_feeder_afsk, arg) {
|
|||
pktReleaseBufferChain(pp);
|
||||
|
||||
/* Schedule thread and task object memory release. */
|
||||
pktScheduleSendComplete(rto, chThdGetSelfX());
|
||||
pktLLDradioSendComplete(rto, chThdGetSelfX());
|
||||
|
||||
/* Unlock radio. */
|
||||
pktReleaseRadio(radio);
|
||||
|
@ -945,7 +964,7 @@ THD_FUNCTION(bloc_si_fifo_feeder_afsk, arg) {
|
|||
uint8_t localBuffer[Si446x_FIFO_COMBINED_SIZE];
|
||||
|
||||
/* Get the FIFO buffer amount currently available. */
|
||||
uint8_t free = Si446x_getTXfreeFIFO();
|
||||
uint8_t free = Si446x_getTXfreeFIFO(radio);
|
||||
|
||||
/* Calculate initial FIFO fill. */
|
||||
uint16_t c = (all > free) ? free : all;
|
||||
|
@ -980,7 +999,7 @@ THD_FUNCTION(bloc_si_fifo_feeder_afsk, arg) {
|
|||
/* Feed the FIFO while data remains to be sent. */
|
||||
while((all - c) > 0) {
|
||||
/* Get TX FIFO free count. */
|
||||
uint8_t more = Si446x_getTXfreeFIFO();
|
||||
uint8_t more = Si446x_getTXfreeFIFO(radio);
|
||||
/* Update the FIFO free low water mark. */
|
||||
lower = (more > lower) ? more : lower;
|
||||
|
||||
|
@ -1054,7 +1073,7 @@ THD_FUNCTION(bloc_si_fifo_feeder_afsk, arg) {
|
|||
rto->result = exit_msg;
|
||||
|
||||
/* Finished send so schedule thread memory and task object release. */
|
||||
pktScheduleSendComplete(rto, chThdGetSelfX());
|
||||
pktLLDradioSendComplete(rto, chThdGetSelfX());
|
||||
|
||||
/* Unlock radio. */
|
||||
pktReleaseRadio(radio);
|
||||
|
@ -1117,7 +1136,7 @@ THD_FUNCTION(bloc_si_fifo_feeder_fsk, arg) {
|
|||
pktReleaseBufferChain(pp);
|
||||
|
||||
/* Schedule thread and task object memory release. */
|
||||
pktScheduleSendComplete(rto, chThdGetSelfX());
|
||||
pktLLDradioSendComplete(rto, chThdGetSelfX());
|
||||
|
||||
/* Exit thread. */
|
||||
chThdExit(MSG_RESET);
|
||||
|
@ -1177,7 +1196,7 @@ THD_FUNCTION(bloc_si_fifo_feeder_fsk, arg) {
|
|||
rto->result = MSG_ERROR;
|
||||
|
||||
/* Schedule thread and task object memory release. */
|
||||
pktScheduleSendComplete(rto, chThdGetSelfX());
|
||||
pktLLDradioSendComplete(rto, chThdGetSelfX());
|
||||
|
||||
/* Unlock radio. */
|
||||
pktReleaseRadio(radio);
|
||||
|
@ -1196,7 +1215,7 @@ THD_FUNCTION(bloc_si_fifo_feeder_fsk, arg) {
|
|||
Si446x_write(reset_fifo, 2);
|
||||
|
||||
/* Get the FIFO buffer amount currently available. */
|
||||
uint8_t free = Si446x_getTXfreeFIFO();
|
||||
uint8_t free = Si446x_getTXfreeFIFO(radio);
|
||||
|
||||
/* Calculate initial FIFO fill. */
|
||||
uint16_t c = (all > free) ? free : all;
|
||||
|
@ -1230,7 +1249,7 @@ THD_FUNCTION(bloc_si_fifo_feeder_fsk, arg) {
|
|||
/* Feed the FIFO while data remains to be sent. */
|
||||
while((all - c) > 0) {
|
||||
/* Get TX FIFO free count. */
|
||||
uint8_t more = Si446x_getTXfreeFIFO();
|
||||
uint8_t more = Si446x_getTXfreeFIFO(radio);
|
||||
/* Update the FIFO free low water mark. */
|
||||
lower = (more > lower) ? more : lower;
|
||||
|
||||
|
@ -1301,7 +1320,7 @@ THD_FUNCTION(bloc_si_fifo_feeder_fsk, arg) {
|
|||
rto->result = exit_msg;
|
||||
|
||||
/* Finished send so schedule thread memory and task object release. */
|
||||
pktScheduleSendComplete(rto, chThdGetSelfX());
|
||||
pktLLDradioSendComplete(rto, chThdGetSelfX());
|
||||
|
||||
/* Unlock radio. */
|
||||
pktReleaseRadio(radio);
|
||||
|
|
|
@ -245,6 +245,7 @@ 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);
|
||||
void Si446x_sendAFSK(packet_t pp);
|
||||
bool Si446x_blocSendAFSK(radio_task_object_t *rto);
|
||||
|
|
|
@ -58,7 +58,7 @@ THD_FUNCTION(pktRadioManager, arg) {
|
|||
(void *)&task_object, TIME_INFINITE);
|
||||
/* Something to do. */
|
||||
|
||||
radio_unit_t radio = handler->radio;
|
||||
const radio_unit_t radio = handler->radio;
|
||||
/* Process command. */
|
||||
switch(task_object->command) {
|
||||
case PKT_RADIO_MGR_CLOSE: {
|
||||
|
@ -110,6 +110,7 @@ THD_FUNCTION(pktRadioManager, arg) {
|
|||
/* Switch on modulation type. */
|
||||
switch(task_object->type) {
|
||||
case MOD_AFSK: {
|
||||
/* TODO: abstract this into the LLD for the radio. */
|
||||
/* Create the AFSK decoder (includes PWM, filters, etc.). */
|
||||
AFSKDemodDriver *driver = pktCreateAFSKDecoder(handler);
|
||||
handler->link_controller = driver;
|
||||
|
@ -129,8 +130,7 @@ THD_FUNCTION(pktRadioManager, arg) {
|
|||
} /* End switch on modulation type. */
|
||||
|
||||
/* Initialise the radio. */
|
||||
/* TODO: Move this 446x call into abstracted LLD. */
|
||||
Si446x_conditional_init(radio);
|
||||
pktLLDradioInit(radio);
|
||||
break;
|
||||
} /* End case PKT_RADIO_OPEN. */
|
||||
|
||||
|
@ -139,26 +139,14 @@ THD_FUNCTION(pktRadioManager, arg) {
|
|||
/* The function switches on mod type so no need for switch here. */
|
||||
switch(task_object->type) {
|
||||
case MOD_AFSK: {
|
||||
/* TODO: Add LLD abstraction. */
|
||||
pktAcquireRadio(radio, TIME_INFINITE);
|
||||
/* Enable receive. */
|
||||
if(pktLLDradioEnableReceive(radio, task_object))
|
||||
pktLLDradioStartDecoder(radio);
|
||||
//pktStartDecoder(radio);
|
||||
|
||||
/* TODO: Move and aggregate these 446x calls into abstracted LLD.
|
||||
* pktLLDenableReceive(...)
|
||||
*/
|
||||
Si446x_setBandParameters(radio,
|
||||
task_object->base_frequency,
|
||||
task_object->step_hz);
|
||||
|
||||
Si446x_receiveNoLock(radio,
|
||||
task_object->base_frequency,
|
||||
task_object->step_hz,
|
||||
task_object->channel,
|
||||
task_object->squelch,
|
||||
MOD_AFSK);
|
||||
/* TODO: If decoder is not running error out. */
|
||||
|
||||
pktStartDecoder(radio);
|
||||
|
||||
/* Allow transmit requests. */
|
||||
/* Unlock radio and allow transmit requests. */
|
||||
pktReleaseRadio(radio);
|
||||
break;
|
||||
} /* End case MOD_AFSK. */
|
||||
|
@ -174,8 +162,10 @@ THD_FUNCTION(pktRadioManager, arg) {
|
|||
case PKT_RADIO_RX_STOP: {
|
||||
switch(task_object->type) {
|
||||
case MOD_AFSK: {
|
||||
/* TODO: Abstract acquire and release in LLD. */
|
||||
pktAcquireRadio(radio, TIME_INFINITE);
|
||||
pktStopDecoder(handler->radio);
|
||||
pktLLDradioStopDecoder(radio);
|
||||
//pktStopDecoder(handler->radio);
|
||||
pktReleaseRadio(radio);
|
||||
break;
|
||||
} /* End case. */
|
||||
|
@ -192,8 +182,9 @@ THD_FUNCTION(pktRadioManager, arg) {
|
|||
/* Give each send a sequence number. */
|
||||
++handler->radio_tx_config.tx_seq_num;
|
||||
/* Pause the decoder. */
|
||||
pktPauseDecoding(radio);
|
||||
if(pktLLDsendPacket(task_object)) {
|
||||
pktLLDradioPauseDecoding(radio);
|
||||
//pktPauseDecoding(radio);
|
||||
if(pktLLDradioSendPacket(task_object)) {
|
||||
/*
|
||||
* Keep count of active sends.
|
||||
* Shutdown or resume receive when all done.
|
||||
|
@ -210,7 +201,13 @@ THD_FUNCTION(pktRadioManager, arg) {
|
|||
/* Send failed so release send packet object(s) and task object. */
|
||||
packet_t pp = task_object->packet_out;
|
||||
pktReleaseBufferChain(pp);
|
||||
pktResumeDecoding(radio);
|
||||
if(pktIsReceivePaused(radio)) {
|
||||
if(!pktLLDradioResumeReceive(radio)) {
|
||||
TRACE_ERROR("RAD > Receive failed to resume after transmit");
|
||||
break;
|
||||
}
|
||||
pktLLDradioResumeDecoding(radio);
|
||||
}
|
||||
break;
|
||||
} /* End case PKT_RADIO_TX. */
|
||||
|
||||
|
@ -220,9 +217,10 @@ THD_FUNCTION(pktRadioManager, arg) {
|
|||
thread_t *decoder = NULL;
|
||||
switch(task_object->type) {
|
||||
case MOD_AFSK: {
|
||||
/* TODO: Implement LLD function for this. */
|
||||
Si446x_disableReceive(radio);
|
||||
/* TODO: This should be a function back in pktservice or pktradio. */
|
||||
/* TODO: Implement LLD abstraction closing decoder. */
|
||||
//Si446x_disableReceive(radio);
|
||||
pktLLDradioDisableReceive(radio);
|
||||
/* TODO: This should be a function back in pktservice or rxafsk. */
|
||||
esp = pktGetEventSource((AFSKDemodDriver *)handler->link_controller);
|
||||
pktRegisterEventListener(esp, &el, USR_COMMAND_ACK, DEC_CLOSE_EXEC);
|
||||
decoder = ((AFSKDemodDriver *)(handler->link_controller))->decoder_thd;
|
||||
|
@ -279,26 +277,26 @@ THD_FUNCTION(pktRadioManager, arg) {
|
|||
/* 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("RAD > Transmit timeout");
|
||||
}
|
||||
if(send_msg == MSG_RESET) {
|
||||
TRACE_ERROR("RAD > Transmit failed to start");
|
||||
}
|
||||
//}
|
||||
bool rxok = true;
|
||||
/* If no transmissions pending then enable RX or shutdown. */
|
||||
/* 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)) {
|
||||
rxok = pktLLDresumeReceive(radio);
|
||||
if(!rxok) {
|
||||
if(!pktLLDradioResumeReceive(radio)) {
|
||||
TRACE_ERROR("RAD > Receive failed to resume after transmit");
|
||||
break;
|
||||
}
|
||||
pktResumeDecoding(radio);
|
||||
/* TODO: Implement LLD since resume depends on radio and mod type. */
|
||||
pktLLDradioResumeDecoding(radio);
|
||||
//pktResumeDecoding(radio);
|
||||
} else {
|
||||
/* TODO: Implement LLD function for this. */
|
||||
Si446x_shutdown(radio);
|
||||
/* Power down radio. */
|
||||
pktLLDradioPowerDown(radio);
|
||||
}
|
||||
} /* Else more TX tasks outstanding so let those complete. */
|
||||
break;
|
||||
|
@ -315,6 +313,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(). */
|
||||
/* Thread has been terminated. */
|
||||
chFactoryReleaseObjectsFIFO(handler->the_radio_fifo);
|
||||
chThdExit(MSG_OK);
|
||||
}
|
||||
|
@ -322,7 +321,7 @@ THD_FUNCTION(pktRadioManager, arg) {
|
|||
/**
|
||||
* Create the radio manager thread.
|
||||
*/
|
||||
thread_t *pktRadioManagerCreate(radio_unit_t radio) {
|
||||
thread_t *pktRadioManagerCreate(const radio_unit_t radio) {
|
||||
|
||||
packet_svc_t *handler = pktGetServiceObject(radio);
|
||||
|
||||
|
@ -376,7 +375,7 @@ thread_t *pktRadioManagerCreate(radio_unit_t radio) {
|
|||
*
|
||||
* @api
|
||||
*/
|
||||
void pktRadioManagerRelease(radio_unit_t radio) {
|
||||
void pktRadioManagerRelease(const radio_unit_t radio) {
|
||||
packet_svc_t *handler = pktGetServiceObject(radio);
|
||||
/*
|
||||
* Get a task object to send to the manager.
|
||||
|
@ -404,7 +403,7 @@ void pktRadioManagerRelease(radio_unit_t radio) {
|
|||
*
|
||||
* @iclass
|
||||
*/
|
||||
msg_t pktGetRadioTaskObjectI(radio_unit_t radio,
|
||||
msg_t pktGetRadioTaskObjectI(const radio_unit_t radio,
|
||||
radio_task_object_t **rt) {
|
||||
|
||||
packet_svc_t *handler = pktGetServiceObject(radio);
|
||||
|
@ -437,9 +436,9 @@ msg_t pktGetRadioTaskObjectI(radio_unit_t radio,
|
|||
*
|
||||
* @api
|
||||
*/
|
||||
void pktSubmitRadioTaskI(radio_unit_t radio,
|
||||
void pktSubmitRadioTaskI(const radio_unit_t radio,
|
||||
radio_task_object_t *object,
|
||||
radio_task_cb_t cb) {
|
||||
const radio_task_cb_t cb) {
|
||||
|
||||
packet_svc_t *handler = pktGetServiceObject(radio);
|
||||
chDbgAssert(handler != NULL, "invalid radio ID");
|
||||
|
@ -478,8 +477,8 @@ void pktSubmitRadioTaskI(radio_unit_t radio,
|
|||
*
|
||||
* @api
|
||||
*/
|
||||
msg_t pktGetRadioTaskObject(radio_unit_t radio,
|
||||
sysinterval_t timeout,
|
||||
msg_t pktGetRadioTaskObject(const radio_unit_t radio,
|
||||
const sysinterval_t timeout,
|
||||
radio_task_object_t **rt) {
|
||||
|
||||
packet_svc_t *handler = pktGetServiceObject(radio);
|
||||
|
@ -515,9 +514,9 @@ msg_t pktGetRadioTaskObject(radio_unit_t radio,
|
|||
*
|
||||
* @api
|
||||
*/
|
||||
void pktSubmitRadioTask(radio_unit_t radio,
|
||||
void pktSubmitRadioTask(const radio_unit_t radio,
|
||||
radio_task_object_t *object,
|
||||
radio_task_cb_t cb) {
|
||||
const radio_task_cb_t cb) {
|
||||
|
||||
packet_svc_t *handler = pktGetServiceObject(radio);
|
||||
chDbgAssert(handler != NULL, "invalid radio ID");
|
||||
|
@ -551,7 +550,7 @@ void pktSubmitRadioTask(radio_unit_t radio,
|
|||
*
|
||||
* @api
|
||||
*/
|
||||
void pktScheduleSendComplete(radio_task_object_t *rto,
|
||||
void pktLLDradioSendComplete(radio_task_object_t *rto,
|
||||
thread_t *thread) {
|
||||
|
||||
packet_svc_t *handler = rto->handler;
|
||||
|
@ -600,7 +599,7 @@ void pktReleaseRadio(const radio_unit_t radio) {
|
|||
/*
|
||||
*
|
||||
*/
|
||||
int pktDisplayFrequencyCode(radio_freq_t code, char *buf, size_t size) {
|
||||
int pktDisplayFrequencyCode(const radio_freq_t code, char *buf, size_t size) {
|
||||
char* str = NULL;
|
||||
switch(code) {
|
||||
case FREQ_RADIO_INVALID:
|
||||
|
@ -691,7 +690,8 @@ radio_freq_t pktGetReceiveOperatingFrequency(const radio_unit_t radio) {
|
|||
/*
|
||||
*
|
||||
*/
|
||||
radio_freq_t pktCheckAllowedFrequency(radio_unit_t radio, radio_freq_t freq) {
|
||||
radio_freq_t pktCheckAllowedFrequency(const radio_unit_t radio,
|
||||
radio_freq_t freq) {
|
||||
/* Check validity. */
|
||||
uint8_t radios = pktGetNumRadios();
|
||||
const radio_config_t *list = pktGetRadioList();
|
||||
|
@ -767,7 +767,18 @@ radio_freq_t pktComputeOperatingFrequency(const radio_unit_t radio,
|
|||
return pktCheckAllowedFrequency(radio, op_freq);
|
||||
}
|
||||
|
||||
void pktPowerUpRadio(radio_unit_t radio) {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void 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;
|
||||
/*
|
||||
|
@ -779,11 +790,10 @@ void pktPowerUpRadio(radio_unit_t radio) {
|
|||
*/
|
||||
|
||||
// Power up transceiver
|
||||
palClearLine(LINE_RADIO_SDN); // Radio SDN low (power up transceiver)
|
||||
chThdSleep(TIME_MS2I(10)); // Wait for transceiver to power up
|
||||
Si446x_powerup(radio);
|
||||
}
|
||||
|
||||
void pktPowerDownRadio(radio_unit_t radio) {
|
||||
void pktLLDradioPowerDown(const radio_unit_t radio) {
|
||||
/* TODO: Implement hardware mapping. */
|
||||
(void)radio;
|
||||
|
||||
|
@ -791,7 +801,8 @@ void pktPowerDownRadio(radio_unit_t radio) {
|
|||
* Put radio in shutdown mode.
|
||||
* All registers are lost.
|
||||
*/
|
||||
palSetLine(LINE_RADIO_SDN);
|
||||
//palSetLine(LINE_RADIO_SDN);
|
||||
Si446x_shutdown(radio);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -804,7 +815,7 @@ void pktPowerDownRadio(radio_unit_t radio) {
|
|||
*
|
||||
* @notapi
|
||||
*/
|
||||
bool pktLLDsendPacket(radio_task_object_t *rto) {
|
||||
bool pktLLDradioSendPacket(radio_task_object_t *rto) {
|
||||
bool status;
|
||||
/* TODO: Implement VMT to functions per radio type. */
|
||||
switch(rto->type) {
|
||||
|
@ -822,6 +833,52 @@ bool pktLLDsendPacket(radio_task_object_t *rto) {
|
|||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable reception.
|
||||
* @notes This is the API interface to the radio LLD.
|
||||
* @notes Currently just map directly to 446x driver.
|
||||
* @notes In future would implement a lookup and VMT to access radio methods.
|
||||
*
|
||||
* @param[in] radio radio unit ID.
|
||||
* @param[in] rto pointer to radio task object
|
||||
*
|
||||
* @return status of the operation
|
||||
* @retval true operation succeeded.
|
||||
* retval false operation failed.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
bool pktLLDradioEnableReceive(const radio_unit_t radio,
|
||||
radio_task_object_t *rto) {
|
||||
packet_svc_t *handler = pktGetServiceObject(radio);
|
||||
|
||||
chDbgAssert(handler != NULL, "invalid radio ID");
|
||||
|
||||
if(handler == NULL)
|
||||
return false;
|
||||
|
||||
Si446x_setBandParameters(radio,
|
||||
rto->base_frequency,
|
||||
rto->step_hz);
|
||||
|
||||
Si446x_receiveNoLock(radio,
|
||||
rto->base_frequency,
|
||||
rto->step_hz,
|
||||
rto->channel,
|
||||
rto->squelch,
|
||||
rto->type);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void pktLLDradioDisableReceive(const radio_unit_t radio) {
|
||||
/* TODO: Implement hardware mapping. */
|
||||
Si446x_disableReceive(radio);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Resume reception paused by transmit task.
|
||||
* @notes This is the API interface to the radio LLD.
|
||||
|
@ -836,7 +893,7 @@ bool pktLLDsendPacket(radio_task_object_t *rto) {
|
|||
*
|
||||
* @notapi
|
||||
*/
|
||||
bool pktLLDresumeReceive(const radio_unit_t radio) {
|
||||
bool pktLLDradioResumeReceive(const radio_unit_t radio) {
|
||||
packet_svc_t *handler = pktGetServiceObject(radio);
|
||||
|
||||
chDbgAssert(handler != NULL, "invalid radio ID");
|
||||
|
@ -847,7 +904,6 @@ bool pktLLDresumeReceive(const radio_unit_t radio) {
|
|||
radio_squelch_t rssi = handler->radio_rx_config.squelch;
|
||||
mod_t mod = handler->radio_rx_config.type;
|
||||
bool result = Si4464_resumeReceive(radio, freq, step, chan, rssi, mod);
|
||||
//pktResumeDecoding(radio);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -859,13 +915,62 @@ bool pktLLDresumeReceive(const radio_unit_t radio) {
|
|||
* @notes The function should be called directly from the RX front end handler.
|
||||
* @notes Calling from a deferred level will not capture the instantaneous level.
|
||||
*
|
||||
* @param[in] handler pointer to packet handler object.
|
||||
* @param[in] radio radio unit ID.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void pktLLDcaptureReceiveStrength(packet_svc_t *handler) {
|
||||
|
||||
chDbgAssert(handler != NULL, "invalid handler");
|
||||
handler->rx_stength = Si446x_getCurrentRSSI(handler->radio);
|
||||
void pktLLDradioCaptureRSSI(const radio_unit_t radio) {
|
||||
packet_svc_t *handler = pktGetServiceObject(radio);
|
||||
chDbgAssert(handler != NULL, "invalid radio ID");
|
||||
handler->rx_stength = Si446x_getCurrentRSSI(radio);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void pktLLDradioPauseDecoding(const radio_unit_t radio) {
|
||||
/*
|
||||
* TODO: Implement as VMT inside radio driver (Si446x is only one at present).
|
||||
* - Lookup radio type from radio ID.
|
||||
* - Then call VMT dispatcher of radio driver.
|
||||
*/
|
||||
pktPauseDecoding(radio);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void pktLLDradioResumeDecoding(const radio_unit_t radio) {
|
||||
/*
|
||||
* TODO: Implement as VMT inside radio driver (Si446x is only one at present).
|
||||
* - Lookup radio type from radio ID.
|
||||
* - Then call VMT dispatcher inside radio driver.
|
||||
*/
|
||||
pktResumeDecoding(radio);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void pktLLDradioStartDecoder(const radio_unit_t radio) {
|
||||
/*
|
||||
* TODO: Implement as VMT inside radio driver (Si446x is only one at present).
|
||||
* - Lookup radio type from radio ID.
|
||||
* - Then call VMT dispatcher inside radio driver.
|
||||
*/
|
||||
pktStartDecoder(radio);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void pktLLDradioStopDecoder(const radio_unit_t radio) {
|
||||
/*
|
||||
* TODO: Implement as VMT inside radio driver (Si446x is only one at present).
|
||||
* - Lookup radio type from radio ID.
|
||||
* - Then call VMT dispatcher inside radio driver.
|
||||
*/
|
||||
pktStopDecoder(radio);
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
|
|
@ -139,27 +139,35 @@ extern "C" {
|
|||
void pktSubmitRadioTask(const radio_unit_t radio,
|
||||
radio_task_object_t *object,
|
||||
radio_task_cb_t cb);
|
||||
void pktScheduleThreadRelease(radio_unit_t radio,
|
||||
void pktScheduleThreadRelease(const radio_unit_t radio,
|
||||
thread_t *thread);
|
||||
msg_t pktAcquireRadio(radio_unit_t radio, sysinterval_t timeout);
|
||||
void pktReleaseRadio(radio_unit_t radio);
|
||||
radio_freq_t pktCheckAllowedFrequency(radio_unit_t radio, radio_freq_t freq);
|
||||
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 base_freq,
|
||||
channel_hz_t step,
|
||||
radio_ch_t chan,
|
||||
const radio_mode_t mode);
|
||||
bool pktLLDresumeReceive(const radio_unit_t radio);
|
||||
bool pktLLDsendPacket(radio_task_object_t *rto);
|
||||
void pktLLDcaptureReceiveStrength(packet_svc_t *handler);
|
||||
void pktScheduleSendComplete(radio_task_object_t *rto,
|
||||
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,
|
||||
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 pktPowerUpRadio(radio_unit_t radio);
|
||||
void pktPowerDownRadio(radio_unit_t radio);
|
||||
radio_freq_t pktCheckAllowedFrequency(radio_unit_t radio, radio_freq_t freq);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -668,7 +668,7 @@ thread_t *pktCreateBufferCallback(pkt_data_object_t *pkt_buffer) {
|
|||
/* Create a callback thread name which is the address of the buffer. */
|
||||
/* TODO: Create a more meaningful but still unique thread name. */
|
||||
chsnprintf(pkt_buffer->cb_thd_name, sizeof(pkt_buffer->cb_thd_name),
|
||||
"%x", pkt_buffer);
|
||||
PKT_CALLBACK_THD_PREFIX"%x", pkt_buffer);
|
||||
|
||||
/* Start a callback dispatcher thread. */
|
||||
thread_t *cb_thd = chThdCreateFromHeap(NULL,
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
#define PKT_FRAME_QUEUE_PREFIX "pktr_"
|
||||
#define PKT_CALLBACK_TERMINATOR_PREFIX "cbte_"
|
||||
#define PKT_CALLBACK_THD_PREFIX "cb_"
|
||||
|
||||
#define PKT_SEND_BUFFER_SEM_NAME "pbsem"
|
||||
|
||||
|
@ -67,7 +68,7 @@ typedef struct packetBuffer {
|
|||
packet_svc_t *handler;
|
||||
dyn_objects_fifo_t *pkt_factory;
|
||||
thread_t *cb_thread;
|
||||
char cb_thd_name[sizeof(size_t) + 1];
|
||||
char cb_thd_name[PKT_THREAD_NAME_MAX];
|
||||
pkt_buffer_cb_t cb_func;
|
||||
volatile eventflags_t status;
|
||||
size_t buffer_size;
|
||||
|
@ -165,7 +166,6 @@ typedef struct packetHandlerData {
|
|||
*/
|
||||
pkt_data_object_t *active_packet_object;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Counter for active callback threads.
|
||||
* TODO: type should be of a generic counter?
|
||||
|
@ -426,6 +426,7 @@ static inline void pktReleaseDataBuffer(pkt_data_object_t *object) {
|
|||
* If the service is closed and all buffers freed then the FIFO is destroyed.
|
||||
* Terminate this thread and have idle clean up memory.
|
||||
*/
|
||||
object->handler->cb_count--;
|
||||
chFifoReturnObject(pkt_fifo, object);
|
||||
chFactoryReleaseObjectsFIFO(pkt_factory);
|
||||
pktThdTerminateSelf();
|
||||
|
@ -436,8 +437,6 @@ static inline void pktReleaseDataBuffer(pkt_data_object_t *object) {
|
|||
* It will be released in the collector thread.
|
||||
* The callback thread memory will be recovered.
|
||||
* The semaphore will be signaled.
|
||||
* TODO: Release the FIFO here and send the thread to idle loop terminator.
|
||||
* This will simplify the release mechanism and make the FIFO available sooner.
|
||||
*/
|
||||
chSysLock();
|
||||
chFifoSendObjectI(pkt_fifo, object);
|
||||
|
|
|
@ -33,11 +33,26 @@ static dataPoint_t* lastDataPoint;
|
|||
static bool threadStarted = false;
|
||||
static uint8_t bme280_error;
|
||||
|
||||
/**
|
||||
* Array for looking up model name
|
||||
*/
|
||||
static const char *state[] = {GPS_STATE_NAMES};
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module external variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
thread_t *collector_thd;
|
||||
|
||||
/**
|
||||
* Get pointer to state name as string
|
||||
*/
|
||||
const char *get_gps_state_name(uint8_t index) {
|
||||
if(index > GPS_STATE_MAX)
|
||||
return "INVALID";
|
||||
return state[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns most recent data point which is complete.
|
||||
*/
|
||||
|
@ -175,6 +190,8 @@ static bool aquirePosition(dataPoint_t* tp, dataPoint_t* ltp,
|
|||
* Output SV info.
|
||||
* Switch off GPS (unless cycle is less than 60 seconds).
|
||||
*/
|
||||
TRACE_INFO("GPS > Lock acquired. Model in use is %s",
|
||||
gps_get_model_name(gpsFix.model));
|
||||
gps_svinfo_t svinfo;
|
||||
if(gps_get_sv_info(&svinfo, sizeof(svinfo))) {
|
||||
TRACE_INFO("GPS > Space Vehicle info iTOW=%d numCh=%02d globalFlags=%d",
|
||||
|
@ -399,7 +416,7 @@ THD_FUNCTION(collectorThread, arg) {
|
|||
dataPoints[1].gps_time = date2UnixTimestamp(&time);
|
||||
|
||||
lastDataPoint = &dataPoints[0];
|
||||
dataPoint_t *newDataPoint = lastDataPoint++;
|
||||
//dataPoint_t *newDataPoint = lastDataPoint++;
|
||||
|
||||
// Get last data point from memory
|
||||
TRACE_INFO("COLL > Read last data point from flash memory");
|
||||
|
@ -491,12 +508,9 @@ THD_FUNCTION(collectorThread, arg) {
|
|||
* Enable the GPS and attempt a lock which results in setting the RTC.
|
||||
*/
|
||||
TRACE_INFO("COLL > Acquire time using GPS");
|
||||
if(aquirePosition(newDataPoint, lastDataPoint, TIME_S2I(600))) {
|
||||
if(aquirePosition(tp, ltp, TIME_S2I(600))) {
|
||||
/* Acquisition succeeded. */
|
||||
TRACE_INFO("COLL > Time update acquired from GPS");
|
||||
/* Update with freshly acquired data. */
|
||||
lastDataPoint = newDataPoint;
|
||||
GPS_Deinit();
|
||||
} else {
|
||||
/* Time is stale record. */
|
||||
TRACE_INFO("COLL > Time update not acquired from GPS");
|
||||
|
@ -541,10 +555,13 @@ THD_FUNCTION(collectorThread, arg) {
|
|||
}
|
||||
|
||||
tp->id = ++id; // Serial ID
|
||||
|
||||
extern uint8_t gps_model;
|
||||
// Trace data
|
||||
unixTimestamp2Date(&time, tp->gps_time);
|
||||
TRACE_INFO( "COLL > New data point available (ID=%d, GPS state=%d)\r\n"
|
||||
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"
|
||||
"%s Time %04d-%02d-%02d %02d:%02d:%02d\r\n"
|
||||
"%s Pos %d.%05d %d.%05d Alt %dm\r\n"
|
||||
"%s Sats %d TTFF %dsec\r\n"
|
||||
|
@ -552,7 +569,7 @@ THD_FUNCTION(collectorThread, arg) {
|
|||
"%s AIR p=%d.%01dPa T=%d.%02ddegC phi=%d.%01d%%\r\n"
|
||||
"%s IOP IO1=%d IO2=%d IO3=%d IO4=%d\r\n"
|
||||
"%s STN %s",
|
||||
tp->id, tp->gps_state,
|
||||
tp->id,
|
||||
TRACE_TAB, time.year, time.month, time.day, time.hour, time.minute, time.day,
|
||||
TRACE_TAB, tp->gps_lat/10000000, (tp->gps_lat > 0 ? 1:-1)*(tp->gps_lat/100)%100000, tp->gps_lon/10000000, (tp->gps_lon > 0 ? 1:-1)*(tp->gps_lon/100)%100000, tp->gps_alt,
|
||||
TRACE_TAB, tp->gps_sats, tp->gps_ttff,
|
||||
|
|
|
@ -27,6 +27,15 @@
|
|||
#define BME280_E1_IS_FITTED FALSE
|
||||
#define BME280_E2_IS_FITTED TRUE
|
||||
|
||||
/**
|
||||
* @brief GPS states as array of strings.
|
||||
* @details Each element in an array initialized with this macro can be
|
||||
* indexed using a numeric GPS model value.
|
||||
*/
|
||||
#define GPS_STATE_NAMES \
|
||||
"LOCKED1", "LOCKED2", "LOSS", "LOWBATT1", "LOWBATT2", "LOG", "OFF", \
|
||||
"ERROR", "FIXED"
|
||||
|
||||
typedef enum {
|
||||
GPS_LOCKED1, // The GPS is locked, the GPS has been switched off
|
||||
GPS_LOCKED2, // The GPS is locked, the GPS has been kept switched on
|
||||
|
@ -39,6 +48,8 @@ typedef enum {
|
|||
GPS_FIXED // Fixed location data used from APRS location
|
||||
} gpsState_t;
|
||||
|
||||
#define GPS_STATE_MAX GPS_FIXED
|
||||
|
||||
typedef struct {
|
||||
// Voltage and current measurement
|
||||
uint16_t adc_vsol; // Current solar voltage in mV
|
||||
|
@ -110,6 +121,7 @@ dataPoint_t* getLastDataPoint(void);
|
|||
void getSensors(dataPoint_t* tp);
|
||||
void setSystemStatus(dataPoint_t* tp);
|
||||
void init_data_collector(void);
|
||||
const char *get_gps_state_name(uint8_t index);
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module inline functions. */
|
||||
|
|
|
@ -47,6 +47,7 @@ THD_FUNCTION(bcnThread, arg) {
|
|||
*/
|
||||
dataPoint_t *dataPoint =
|
||||
(dataPoint_t *)chMsgSend(collector_thd, (msg_t)conf);
|
||||
|
||||
/* Continue here when collector responds. */
|
||||
if(!p_sleep(&conf->beacon.sleep_conf)) {
|
||||
if(!isPositionValid(dataPoint) || dataPoint == NULL) {
|
||||
|
|
|
@ -747,7 +747,7 @@ THD_FUNCTION(imgThread, arg) {
|
|||
void start_image_thread(img_app_conf_t *conf)
|
||||
{
|
||||
thread_t *th = chThdCreateFromHeap(NULL,
|
||||
THD_WORKING_AREA_SIZE(40 * 1024),
|
||||
THD_WORKING_AREA_SIZE(30 * 1024),
|
||||
"IMG", LOWPRIO, imgThread, conf);
|
||||
if(!th) {
|
||||
// Print startup error, do not start watchdog for this thread
|
||||
|
|
Ładowanie…
Reference in New Issue