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 decoder
pull/4/head
bob 2018-07-05 00:15:00 +10:00
rodzic b02ac2c1e8
commit 9d012cb49b
20 zmienionych plików z 1780 dodań i 1601 usunięć

Wyświetl plik

@ -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

Wyświetl plik

@ -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);

Wyświetl plik

@ -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

Wyświetl plik

@ -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);

Wyświetl plik

@ -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();

Wyświetl plik

@ -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,

Wyświetl plik

@ -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;
}

Wyświetl plik

@ -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

Wyświetl plik

@ -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). */
}

Wyświetl plik

@ -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);

Wyświetl plik

@ -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);

Wyświetl plik

@ -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);
}
/** @} */

Wyświetl plik

@ -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

Wyświetl plik

@ -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,

Wyświetl plik

@ -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);

Wyświetl plik

@ -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,

Wyświetl plik

@ -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. */

Wyświetl plik

@ -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) {

Wyświetl plik

@ -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