Fixed camera memory clear bug. Various fixes. Add CRC calc to UBLOX.

pull/4/head
CInsights 2018-04-09 17:27:02 +10:00
rodzic 2f1eb1c547
commit 9e3c499fae
18 zmienionych plików z 270 dodań i 148 usunięć

Wyświetl plik

@ -12,8 +12,8 @@ const conf_t conf_flash_default = {
.pos_pri = {
.thread_conf = {
.active = true,
.cycle = TIME_S2I(1800),
.init_delay = TIME_S2I(60)
.cycle = TIME_S2I(60),
.init_delay = TIME_S2I(10)
},
.radio_conf = {
.pwr = 0x7F,
@ -56,9 +56,9 @@ const conf_t conf_flash_default = {
.img_pri = {
.thread_conf = {
.active = true,
.cycle = TIME_S2I(60),
.init_delay = TIME_S2I(2*60),
.send_spacing = TIME_S2I(2)
.cycle = TIME_S2I(120),
.init_delay = TIME_S2I(60*2),
.send_spacing = TIME_S2I(3)
},
.radio_conf = {
.pwr = 0x7F,

Wyświetl plik

@ -8,7 +8,7 @@
* 3V, because USB would not work at 1.8V. Note that the transmission power is increased
* too when operating at 3V. This option will also run the STM32 at 48MHz (AHB) permanently
* because USB needs that speed, otherwise it is running at 6MHz which saves a lot of power. */
#define ENABLE_EXTERNAL_I2C FALSE /* The external port can be used for bit bang I2C. */
#define ENABLE_EXTERNAL_I2C TRUE /* The external port can be used for bit bang I2C. */
#include "types.h"

Wyświetl plik

@ -698,6 +698,14 @@ static uint8_t* dma_buffer;
static resolution_t last_res = RES_NONE;
/*
* Memory pool integrity checking... will expand to be that
*/
static struct pool_header *pktSystemCheck(void) {
extern guarded_memory_pool_t *ccm_pool;
return ((struct pool_header *)(ccm_pool->pool.next))->next;
}
/**
* Captures an image from the camera.
* @buffer Buffer in which the image can be sampled
@ -724,25 +732,19 @@ uint32_t OV5640_Snapshot2RAM(uint8_t* buffer,
}
// Capture image until we get a good image or reach max retries.
TRACE_INFO("CAM > Capture image");
TRACE_DEBUG("CAM > Pool link 0x%x", pktSystemCheck());
TRACE_INFO("CAM > Capture image into buffer @ 0x%08x size 0x%08x",
buffer, size);
do {
// Clearing buffer
for(uint32_t i = 0; i < size; i++)
buffer[i] = 0;
//status = false;
TRACE_DEBUG("CAM > Pool link 0x%x", pktSystemCheck());
size_sampled = OV5640_Capture(buffer, size);
//TRACE_INFO("CAM > Capture finished");
//size_sampled = size - 1;
while(!buffer[size_sampled - 1] && size_sampled > 0)
size_sampled--;
if(size_sampled > 0)
if(size_sampled > 0) {
TRACE_INFO("CAM > Image size: %d bytes", size_sampled);
return size_sampled;
} while(/*!status && */cntr--);
TRACE_INFO("CAM > Image size: %d bytes", size_sampled);
return size_sampled;
}
} while(cntr--);
TRACE_ERROR("CAM > No image captured");
return 0;
}
const stm32_dma_stream_t *dmastp;
@ -992,7 +994,7 @@ void OV5640_unlockResourcesForCapture(void) {
}
uint32_t OV5640_Capture(uint8_t* buffer, uint32_t size) {
OV5640_setLightIntensity();
TRACE_DEBUG("CAM > Pool link 0x%x", pktSystemCheck());
/*
* Note:
@ -1102,7 +1104,7 @@ uint32_t OV5640_Capture(uint8_t* buffer, uint32_t size) {
#endif
// Wait for capture to be finished
uint8_t timout = 100; // 1000ms max
uint8_t timout = 50; // 500ms max
do {
chThdSleep(TIME_MS2I(10));
} while(!capture_finished && !dma_error && --timout);
@ -1141,6 +1143,7 @@ uint32_t OV5640_Capture(uint8_t* buffer, uint32_t size) {
TRACE_ERROR("CAM > Timeout error capturing image");
return 0;
}
TRACE_DEBUG("CAM > Pool link 0x%x", pktSystemCheck());
TRACE_INFO("CAM > Capture success");

Wyświetl plik

@ -296,6 +296,7 @@ uint8_t gps_disable_nmea_output(void) {
0xaa, 0x79 // checksum
};
gps_calc_ubx_csum(nonmea, sizeof(nonmea));
gps_transmit_string(nonmea, sizeof(nonmea));
return gps_receive_ack(0x06, 0x00, 1000);
}
@ -335,6 +336,7 @@ uint8_t gps_set_airborne_model(void) {
0x1a, 0x28 // checksum
};
gps_calc_ubx_csum(model6, sizeof(model6));
gps_transmit_string(model6, sizeof(model6));
return gps_receive_ack(0x06, 0x24, 1000);
}
@ -445,3 +447,24 @@ void GPS_Deinit(void)
palClearLine(LINE_GPS_EN);
}
/*
* Calculate checksum and insert into buffer.
*
*/
bool gps_calc_ubx_csum(uint8_t *mbuf, uint16_t mlen) {
uint16_t i;
uint8_t ck_a = 0, ck_b = 0;
if(mlen < 5)
/* Excluding sync bytes there must be at at least one byte to checksum. */
return false;
for (i = 2; i < mlen - 2; i++) {
ck_b += (ck_a += mbuf[i]);
}
mbuf[mlen - 2] = ck_a;
mbuf[mlen - 1] = ck_b;
return true;
}

Wyświetl plik

@ -39,6 +39,6 @@ bool gps_get_fix(gpsFix_t *fix);
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);
#endif

Wyświetl plik

@ -28,7 +28,7 @@ extern uint8_t usb_trace_level;
} \
chprintf((BaseSequentialStream*)&SDU1, "[%s]", type); \
if(TRACE_FILE) { \
chprintf((BaseSequentialStream*)&SDU1, "[%10s %04d]", __FILENAME__, __LINE__); \
chprintf((BaseSequentialStream*)&SDU1, "[%12s %04d]", __FILENAME__, __LINE__); \
} \
chprintf((BaseSequentialStream*)&SDU1, " "); \
chprintf((BaseSequentialStream*)&SDU1, (format), ##args); \
@ -43,7 +43,7 @@ extern uint8_t usb_trace_level;
#define TRACE_ERROR(format, args...) if(usb_trace_level > 0) { TRACE_BASE(format, "ERROR", ##args) }
#if TRACE_TIME && TRACE_FILE
#define TRACE_TAB " "
#define TRACE_TAB " "
#elif TRACE_TIME && !TRACE_FILE
#define TRACE_TAB " "
#elif !TRACE_TIME && TRACE_FILE

Wyświetl plik

@ -186,7 +186,7 @@
#define STM32_SERIAL_USE_USART2 FALSE
#define STM32_SERIAL_USE_USART3 TRUE
#define STM32_SERIAL_USE_UART4 FALSE
#define STM32_SERIAL_USE_UART5 FALSE
#define STM32_SERIAL_USE_UART5 TRUE
#define STM32_SERIAL_USE_USART6 FALSE
#define STM32_SERIAL_USART1_PRIORITY 12
#define STM32_SERIAL_USART2_PRIORITY 12

Wyświetl plik

@ -982,7 +982,7 @@ THD_FUNCTION(bloc_si_fifo_feeder_afsk, arg) {
if(exit_msg == MSG_OK) {
/* Send was OK. Release the just completed packet. */
pktReleaseSendObject(pp);
pktReleaseBufferObject(pp);
} else {
/* Send failed so release any queue and terminate. */
pktReleaseBufferChain(pp);
@ -1202,7 +1202,7 @@ THD_FUNCTION(bloc_si_fifo_feeder_fsk, arg) {
if(exit_msg == MSG_OK) {
/* Send was OK. Release the just completed packet. */
pktReleaseSendObject(pp);
pktReleaseBufferObject(pp);
} else {
/* Send failed so release any queue and terminate. */
pktReleaseBufferChain(pp);

Wyświetl plik

@ -18,6 +18,7 @@
/*===========================================================================*/
memory_heap_t *ccm_heap = NULL;
guarded_memory_pool_t *ccm_pool = NULL;
/*===========================================================================*/
/* Module local types. */
@ -29,6 +30,8 @@ memory_heap_t *ccm_heap = NULL;
#if USE_CCM_FOR_PKT_TX == TRUE
static memory_heap_t _ccm_heap;
#elif USE_CCM_FOR_PKT_POOL == TRUE
static guarded_memory_pool_t _ccm_pool;
#endif
/*===========================================================================*/
@ -39,6 +42,7 @@ static memory_heap_t _ccm_heap;
/* Module exported functions. */
/*===========================================================================*/
/**
* @brief Initializes the packet system.
*
@ -58,13 +62,23 @@ bool pktSystemInit(void) {
ccm_heap = &_ccm_heap;
chHeapObjectInit(ccm_heap, (void *)0x10000000, 0x10000);
}
#endif
#elif USE_CCM_FOR_PKT_POOL == TRUE
if(ccm_pool == NULL) {
ccm_pool = &_ccm_pool;
chGuardedPoolObjectInitAligned(ccm_pool, sizeof(packet_gen_t), 4);
chGuardedPoolLoadArray(ccm_pool, (void *)0x10000000,
NUMBER_COMMON_PKT_BUFFERS);
}
return true;
#else
/*
* Create common packet buffer control.
*/
if(pktInitBufferControl() == NULL)
return false;
return true;
#endif
}
/**
@ -871,6 +885,16 @@ dyn_semaphore_t *pktInitBufferControl() {
*/
msg_t pktGetPacketBuffer(packet_t *pp, sysinterval_t timeout) {
#if USE_CCM_FOR_PKT_POOL == TRUE
(void)timeout;
if(ccm_pool == NULL)
return MSG_TIMEOUT;
*pp = ax25_new();
if(pp == NULL)
return MSG_TIMEOUT;
return MSG_OK;
#else
/* Check if the packet buffer semaphore already exists.
* If so we get a pointer to it and get the semaphore.
*/
@ -902,6 +926,7 @@ msg_t pktGetPacketBuffer(packet_t *pp, sysinterval_t timeout) {
if(pp == NULL)
return MSG_TIMEOUT;
return MSG_OK;
#endif
}
/*
@ -909,6 +934,10 @@ msg_t pktGetPacketBuffer(packet_t *pp, sysinterval_t timeout) {
*/
void pktReleasePacketBuffer(packet_t pp) {
#if USE_CCM_FOR_PKT_POOL == TRUE
chDbgAssert(pp != NULL, "packet is invalid");
ax25_delete(pp);
#else
/* Check if the packet buffer semaphore exists.
* If not this is a system error.
*/
@ -925,13 +954,14 @@ void pktReleasePacketBuffer(packet_t pp) {
/* Decrease factory ref count. */
chFactoryReleaseSemaphore(dyn_sem);
#endif
}
/*
* Send shares a common pool of buffers.
*/
void pktReleaseBufferSemaphore(radio_unit_t radio) {
#if USE_CCM_FOR_PKT_POOL != TRUE
packet_svc_t *handler = pktGetServiceObject(radio);
chDbgAssert(handler != NULL, "invalid radio ID");
@ -942,6 +972,9 @@ void pktReleaseBufferSemaphore(radio_unit_t radio) {
*/
chFactoryReleaseSemaphore(handler->tx_packet_sem);
handler->tx_packet_sem = NULL;
#else
(void)radio;
#endif
}
/*

Wyświetl plik

@ -537,7 +537,6 @@ static inline bool pktIsTransmitOpen(radio_unit_t radio) {
return !(state == PACKET_IDLE || state == PACKET_INVALID);
}
#endif /* PKT_CHANNELS_PKTSERVICE_H_ */
/** @} */

Wyświetl plik

@ -379,14 +379,10 @@ static inline msg_t pktSendRadioCommand(radio_unit_t radio,
*
* @api
*/
static inline void pktReleaseSendObject(packet_t pp) {
static inline void pktReleaseBufferObject(packet_t pp) {
#if USE_SPI_ATTACHED_RADIO == TRUE
#if USE_NEW_PKT_TX_ALLOC == TRUE
chDbgAssert(pp != NULL, "no packet pointer");
pktReleasePacketBuffer(pp);
#else
ax25_delete (pp);
#endif
#else
(void)pp;
#endif
@ -403,17 +399,14 @@ static inline void pktReleaseSendObject(packet_t pp) {
*/
static inline void pktReleaseBufferChain(packet_t pp) {
#if USE_SPI_ATTACHED_RADIO == TRUE
#if USE_NEW_PKT_TX_ALLOC == TRUE
chDbgAssert(pp != NULL, "no packet pointer");
/* Release all packets in linked list. */
do {
packet_t np = pp->nextp;
pktReleasePacketBuffer(pp);
pp = np;
} while(pp != NULL);
#else
ax25_delete (pp);
#endif
#else
(void)pp;
#endif

Wyświetl plik

@ -262,7 +262,11 @@ packet_t ax25_new (void) {
}
#if USE_NEW_PKT_TX_ALLOC == TRUE
#if USE_CCM_FOR_PKT_TX == TRUE
#if USE_CCM_FOR_PKT_POOL == TRUE
extern guarded_memory_pool_t *ccm_pool;
this_p = chGuardedPoolAllocTimeout(ccm_pool, TIME_INFINITE);
TRACE_DEBUG("PKT > Allocated buffer 0x%x, link 0x%x", this_p, ((struct pool_header *)(this_p))->next);
#elif USE_CCM_FOR_PKT_TX == TRUE
extern memory_heap_t *ccm_heap;
this_p = chHeapAlloc(ccm_heap, sizeof (struct packet_s));
#else
@ -331,8 +335,13 @@ void ax25_delete (packet_t this_p)
this_p->magic1 = 0;
this_p->magic1 = 0;
#if USE_CCM_FOR_PKT_POOL == TRUE
extern guarded_memory_pool_t *ccm_pool;
TRACE_DEBUG("PKT > Returning buffer 0x%x", this_p);
chGuardedPoolFree(ccm_pool, this_p);
#else
chHeapFree(this_p);
#endif
}
@ -396,9 +405,10 @@ packet_t ax25_from_text (char *monitor, int strict)
packet_t this_p;
msg_t msg = pktGetPacketBuffer(&this_p, TIME_INFINITE);
/* If the semaphore is reset then exit. */
if(msg == MSG_RESET || this_p == NULL)
if(msg == MSG_RESET || this_p == NULL) {
TRACE_ERROR("PKT > No packet buffer available");
return NULL;
}
#if AX25MEMDEBUG
if (ax25memdebug) {
TRACE_DEBUG ("PKT > ax25_from_text, seq=%d, called from %s %d", this_p->seq, src_file, src_line);
@ -442,6 +452,7 @@ packet_t ax25_from_text (char *monitor, int strict)
pinfo = strchr (stuff, ':');
if (pinfo == NULL) {
TRACE_ERROR("PKT > No address separator");
pktReleasePacketBuffer(this_p);
return (NULL);
}
@ -512,9 +523,8 @@ packet_t ax25_from_text (char *monitor, int strict)
k = this_p->num_addr;
if ( ! ax25_parse_addr (k, pa, strict, atemp, &ssid_temp, &heard_temp)) {
TRACE_ERROR("PKT > Bad digipeater address in packet");
//TRACE_ERROR ("Failed to create packet from text. Bad digipeater address");
pktReleasePacketBuffer(this_p);
TRACE_ERROR("PKT > Bad digipeater address in packet");
pktReleasePacketBuffer(this_p);
return (NULL);
}
@ -525,12 +535,12 @@ packet_t ax25_from_text (char *monitor, int strict)
// TODO: Complain if more than one "*".
// Could also check for all has been repeated bits are adjacent.
if (heard_temp) {
if (heard_temp) {
for ( ; k >= AX25_REPEATER_1; k--) {
ax25_set_h (this_p, k);
}
}
}
}
/*
@ -541,7 +551,6 @@ packet_t ax25_from_text (char *monitor, int strict)
* We might want to manually generate UTF-8 characters such as degree.
*/
//#define DEBUG14H 1
#if DEBUG14H
TRACE_DEBUG ("PKT > BEFORE: %s\nSAFE: ", pinfo);
@ -581,8 +590,13 @@ packet_t ax25_from_text (char *monitor, int strict)
/*
* Append the info part.
*/
/* FIXME: Check for buffer overflow here. */
memcpy ((char*)(this_p->frame_data+this_p->frame_len), info_part, info_len);
/* Check for buffer overflow here. */
if((this_p->frame_len + info_len) > AX25_MAX_PACKET_LEN) {
TRACE_ERROR ("PKT > frame buffer overrun");
pktReleasePacketBuffer(this_p);
return (NULL);
}
memcpy ((char*)(this_p->frame_data + this_p->frame_len), info_part, info_len);
this_p->frame_len += info_len;
return (this_p);
@ -994,10 +1008,10 @@ void ax25_set_addr (packet_t this_p, int n, char *ad)
ax25_parse_addr (n, ad, 0, atemp, &ssid_temp, &heard_temp);
memset (this_p->frame_data + n*7, ' ' << 1, 6);
memset (this_p->frame_data + n * 7, ' ' << 1, 6);
for (i=0; i<6 && atemp[i] != '\0'; i++) {
this_p->frame_data[n*7+i] = atemp[i] << 1;
for (i = 0; i < 6 && atemp[i] != '\0'; i++) {
this_p->frame_data[n * 7 + i] = atemp[i] << 1;
}
ax25_set_ssid (this_p, n, ssid_temp);
}

Wyświetl plik

@ -73,6 +73,7 @@
#define USE_NEW_PKT_TX_ALLOC TRUE
#define USE_CCM_FOR_PKT_TX FALSE
#define USE_CCM_FOR_PKT_POOL TRUE
#include "pkttypes.h"
@ -154,7 +155,7 @@ typedef struct packet_s {
/* Will get stomped on if above overflows. */
int magic2;
} packet_tx_t;
} packet_gen_t;
/*
* packet_t is a pointer to a packet object.

Wyświetl plik

@ -91,8 +91,8 @@
/* Number of frame receive buffers. */
#define NUMBER_RX_PKT_BUFFERS 3U
/* Number of frame send buffers. */
#define NUMBER_COMMON_PKT_BUFFERS 10U
/* Number of general AX25/APRS processing & frame send buffers. */
#define NUMBER_COMMON_PKT_BUFFERS 20U
/*===========================================================================*/
/* Module pre-compile time settings. */

Wyświetl plik

@ -45,7 +45,7 @@ static bool dedupe_initialized;
const conf_command_t command_list[] = {
{TYPE_INT, "pos_pri.active", sizeof(conf_sram.pos_pri.thread_conf.active), &conf_sram.pos_pri.thread_conf.active },
{TYPE_TIME, "pos_pri.init_delay", sizeof(conf_sram.pos_pri.thread_conf.init_delay), &conf_sram.pos_pri.thread_conf.init_delay },
{TYPE_TIME, "pos_pri.send_spacing", sizeof(conf_sram.pos_pri.thread_conf.send_spacing), &conf_sram.pos_pri.thread_conf.send_spacing },
/* {TYPE_TIME, "pos_pri.send_spacing", sizeof(conf_sram.pos_pri.thread_conf.send_spacing), &conf_sram.pos_pri.thread_conf.send_spacing },*/
{TYPE_INT, "pos_pri.sleep_conf.type", sizeof(conf_sram.pos_pri.thread_conf.sleep_conf.type), &conf_sram.pos_pri.thread_conf.sleep_conf.type },
{TYPE_INT, "pos_pri.sleep_conf.vbat_thres", sizeof(conf_sram.pos_pri.thread_conf.sleep_conf.vbat_thres), &conf_sram.pos_pri.thread_conf.sleep_conf.vbat_thres},
{TYPE_INT, "pos_pri.sleep_conf.vsol_thres", sizeof(conf_sram.pos_pri.thread_conf.sleep_conf.vsol_thres), &conf_sram.pos_pri.thread_conf.sleep_conf.vsol_thres},
@ -54,8 +54,8 @@ const conf_command_t command_list[] = {
{TYPE_INT, "pos_pri.freq", sizeof(conf_sram.pos_pri.radio_conf.freq), &conf_sram.pos_pri.radio_conf.freq },
{TYPE_INT, "pos_pri.mod", sizeof(conf_sram.pos_pri.radio_conf.mod), &conf_sram.pos_pri.radio_conf.mod },
{TYPE_INT, "pos_pri.rssi", sizeof(conf_sram.pos_pri.radio_conf.rssi), &conf_sram.pos_pri.radio_conf.rssi },
{TYPE_INT, "pos_pri.speed", sizeof(conf_sram.pos_pri.radio_conf.speed), &conf_sram.pos_pri.radio_conf.speed },
{TYPE_INT, "pos_pri.redundantTx", sizeof(conf_sram.pos_pri.radio_conf.redundantTx), &conf_sram.pos_pri.radio_conf.redundantTx },
/* {TYPE_INT, "pos_pri.speed", sizeof(conf_sram.pos_pri.radio_conf.speed), &conf_sram.pos_pri.radio_conf.speed },*/
/* {TYPE_INT, "pos_pri.redundantTx", sizeof(conf_sram.pos_pri.radio_conf.redundantTx), &conf_sram.pos_pri.radio_conf.redundantTx },*/
{TYPE_STR, "pos_pri.call", sizeof(conf_sram.pos_pri.call), &conf_sram.pos_pri.call },
{TYPE_STR, "pos_pri.path", sizeof(conf_sram.pos_pri.path), &conf_sram.pos_pri.path },
{TYPE_INT, "pos_pri.symbol", sizeof(conf_sram.pos_pri.symbol), &conf_sram.pos_pri.symbol },
@ -64,7 +64,7 @@ const conf_command_t command_list[] = {
{TYPE_INT, "pos_sec.active", sizeof(conf_sram.pos_sec.thread_conf.active), &conf_sram.pos_sec.thread_conf.active },
{TYPE_TIME, "pos_sec.init_delay", sizeof(conf_sram.pos_sec.thread_conf.init_delay), &conf_sram.pos_sec.thread_conf.init_delay },
{TYPE_TIME, "pos_sec.send_spacing", sizeof(conf_sram.pos_sec.thread_conf.send_spacing), &conf_sram.pos_sec.thread_conf.send_spacing },
/* {TYPE_TIME, "pos_sec.send_spacing", sizeof(conf_sram.pos_sec.thread_conf.send_spacing), &conf_sram.pos_sec.thread_conf.send_spacing },*/
{TYPE_INT, "pos_sec.sleep_conf.type", sizeof(conf_sram.pos_sec.thread_conf.sleep_conf.type), &conf_sram.pos_sec.thread_conf.sleep_conf.type },
{TYPE_INT, "pos_sec.sleep_conf.vbat_thres", sizeof(conf_sram.pos_sec.thread_conf.sleep_conf.vbat_thres), &conf_sram.pos_sec.thread_conf.sleep_conf.vbat_thres},
{TYPE_INT, "pos_sec.sleep_conf.vsol_thres", sizeof(conf_sram.pos_sec.thread_conf.sleep_conf.vsol_thres), &conf_sram.pos_sec.thread_conf.sleep_conf.vsol_thres},
@ -73,8 +73,8 @@ const conf_command_t command_list[] = {
{TYPE_INT, "pos_sec.freq", sizeof(conf_sram.pos_sec.radio_conf.freq), &conf_sram.pos_sec.radio_conf.freq },
{TYPE_INT, "pos_sec.mod", sizeof(conf_sram.pos_sec.radio_conf.mod), &conf_sram.pos_sec.radio_conf.mod },
{TYPE_INT, "pos_sec.rssi", sizeof(conf_sram.pos_sec.radio_conf.rssi), &conf_sram.pos_sec.radio_conf.rssi },
{TYPE_INT, "pos_sec.speed", sizeof(conf_sram.pos_sec.radio_conf.speed), &conf_sram.pos_sec.radio_conf.speed },
{TYPE_INT, "pos_sec.redundantTx", sizeof(conf_sram.pos_sec.radio_conf.redundantTx), &conf_sram.pos_sec.radio_conf.redundantTx },
/* {TYPE_INT, "pos_sec.speed", sizeof(conf_sram.pos_sec.radio_conf.speed), &conf_sram.pos_sec.radio_conf.speed },*/
/* {TYPE_INT, "pos_sec.redundantTx", sizeof(conf_sram.pos_sec.radio_conf.redundantTx), &conf_sram.pos_sec.radio_conf.redundantTx },*/
{TYPE_STR, "pos_sec.call", sizeof(conf_sram.pos_sec.call), &conf_sram.pos_sec.call },
{TYPE_STR, "pos_sec.path", sizeof(conf_sram.pos_sec.path), &conf_sram.pos_sec.path },
{TYPE_INT, "pos_sec.symbol", sizeof(conf_sram.pos_sec.symbol), &conf_sram.pos_sec.symbol },
@ -221,12 +221,14 @@ packet_t aprs_encode_position(const char *callsign, const char *path, uint16_t s
uint32_t a1 = a / 91;
uint32_t a1r = a % 91;
uint8_t gpsFix = dataPoint->gps_state == GPS_LOCKED1 || dataPoint->gps_state == GPS_LOCKED2 ? GSP_FIX_CURRENT : GSP_FIX_OLD;
uint8_t gpsFix = dataPoint->gps_state == GPS_LOCKED1
|| dataPoint->gps_state == GPS_LOCKED2 ? GSP_FIX_CURRENT : GSP_FIX_OLD;
uint8_t src = NMEA_SRC_GGA;
uint8_t origin = ORIGIN_PICO;
char xmit[256];
uint32_t len = chsnprintf(xmit, sizeof(xmit), "%s>%s,%s:!", callsign, APRS_DEST_CALLSIGN, path);
uint32_t len = chsnprintf(xmit, sizeof(xmit), "%s>%s,%s:!",
callsign, APRS_DEST_CALLSIGN, path);
xmit[len+0] = (symbol >> 8) & 0xFF;
xmit[len+1] = y3+33;
@ -243,7 +245,9 @@ packet_t aprs_encode_position(const char *callsign, const char *path, uint16_t s
xmit[len+12] = ((gpsFix << 5) | (src << 3) | origin) + 33;
// Comments
uint32_t len2 = base91_encode((uint8_t*)dataPoint, (uint8_t*)&xmit[len+13], sizeof(dataPoint_t));
uint32_t len2 = base91_encode((uint8_t*)dataPoint,
(uint8_t*)&xmit[len+13],
sizeof(dataPoint_t));
xmit[len+len2+13] = '|';
@ -272,10 +276,12 @@ packet_t aprs_encode_position(const char *callsign, const char *path, uint16_t s
return ax25_from_text(xmit, true);
}
packet_t aprs_encode_data_packet(const char *callsign, const char *path, char packetType, uint8_t *data)
packet_t aprs_encode_data_packet(const char *callsign, const char *path,
char packetType, uint8_t *data)
{
char xmit[256];
chsnprintf(xmit, sizeof(xmit), "%s>%s,%s:{{%c%s", callsign, APRS_DEST_CALLSIGN, path, packetType, data);
chsnprintf(xmit, sizeof(xmit), "%s>%s,%s:{{%c%s", callsign,
APRS_DEST_CALLSIGN, path, packetType, data);
return ax25_from_text(xmit, true);
}
@ -283,13 +289,17 @@ packet_t aprs_encode_data_packet(const char *callsign, const char *path, char pa
/**
* Transmit message packet
*/
packet_t aprs_encode_message(const char *callsign, const char *path, const char *receiver, const char *text, const bool noCounter)
packet_t aprs_encode_message(const char *callsign, const char *path,
const char *receiver, const char *text,
const bool noCounter)
{
char xmit[256];
if(noCounter)
chsnprintf(xmit, sizeof(xmit), "%s>%s,%s::%-9s:%s", callsign, APRS_DEST_CALLSIGN, path, receiver, text);
chsnprintf(xmit, sizeof(xmit), "%s>%s,%s::%-9s:%s", callsign,
APRS_DEST_CALLSIGN, path, receiver, text);
else
chsnprintf(xmit, sizeof(xmit), "%s>%s,%s::%-9s:%s{%d", callsign, APRS_DEST_CALLSIGN, path, receiver, text, ++msg_id);
chsnprintf(xmit, sizeof(xmit), "%s>%s,%s::%-9s:%s{%d", callsign,
APRS_DEST_CALLSIGN, path, receiver, text, ++msg_id);
return ax25_from_text(xmit, true);
}
@ -299,8 +309,11 @@ packet_t aprs_encode_query_answer_aprsd(const char *callsign, const char *path,
char buf[256] = "Directs=";
uint32_t out = 8;
for(uint8_t i=0; i<20; i++) {
if(heard_list[i].time && heard_list[i].time + TIME_S2I(600) >= chVTGetSystemTime() && heard_list[i].time <= chVTGetSystemTime())
out += chsnprintf(&buf[out], sizeof(buf)-out, "%s ", heard_list[i].call);
if(heard_list[i].time
&& heard_list[i].time + TIME_S2I(600) >= chVTGetSystemTime()
&& heard_list[i].time <= chVTGetSystemTime())
out += chsnprintf(&buf[out], sizeof(buf)-out, "%s ",
heard_list[i].call);
}
buf[out-1] = 0; // Remove last space
@ -371,7 +384,6 @@ static bool aprs_decode_message(packet_t pp)
}
}
char *command = strlwr((char*)&pinfo[11]);
// Trace
@ -414,7 +426,9 @@ static bool aprs_decode_message(packet_t pp)
} else if(!strcmp(command, "?aprsd")) { // Transmit position
TRACE_INFO("RX > Message: Directs query");
packet_t pp = aprs_encode_query_answer_aprsd(conf_sram.aprs.tx.call, conf_sram.aprs.tx.path, src);
packet_t pp =
aprs_encode_query_answer_aprsd(conf_sram.aprs.tx.call,
conf_sram.aprs.tx.path, src);
if(pp == NULL) {
TRACE_WARN("RX > No free packet objects");
return false;
@ -482,7 +496,9 @@ static bool aprs_decode_message(packet_t pp)
packetRepeats[i].packet_id = req & 0xFFFF;
packetRepeats[i].n_done = true;
TRACE_INFO("RX > ... Image %3d Packet %3d", packetRepeats[i].image_id, packetRepeats[i].packet_id);
TRACE_INFO("RX > ... Image %3d Packet %3d",
packetRepeats[i].image_id,
packetRepeats[i].packet_id);
break;
}
}
@ -494,22 +510,28 @@ static bool aprs_decode_message(packet_t pp)
for(uint8_t i=0; command_list[i].type != TYPE_NULL; i++)
{
if(!strncmp(&command[6], command_list[i].name, strlen(command_list[i].name))) {
if(!strncmp(&command[6], command_list[i].name,
strlen(command_list[i].name))) {
char *value = &command[strlen(command_list[i].name) + 6];
TRACE_INFO("RX > Message: Configuration Command");
TRACE_INFO("RX > %s => %s", &command[6], value);
if(command_list[i].type == TYPE_INT && command_list[i].size == 1) {
if(command_list[i].type == TYPE_INT
&& command_list[i].size == 1) {
*((uint8_t*)command_list[i].ptr) = atoi(value);
} else if(command_list[i].type == TYPE_INT && command_list[i].size == 2) {
} else if(command_list[i].type == TYPE_INT
&& command_list[i].size == 2) {
*((uint16_t*)command_list[i].ptr) = atoi(value);
} else if(command_list[i].type == TYPE_INT && command_list[i].size == 4) {
} else if(command_list[i].type == TYPE_INT
&& command_list[i].size == 4) {
*((uint32_t*)command_list[i].ptr) = atoi(value);
} else if(command_list[i].type == TYPE_TIME) {
*((sysinterval_t*)command_list[i].ptr) = TIME_MS2I(atoi(value));
*((sysinterval_t*)command_list[i].ptr) =
TIME_MS2I(atoi(value));
} else if(command_list[i].type == TYPE_STR) {
strncpy((char*)command_list[i].ptr, value, sizeof(command_list[i].size)-1);
strncpy((char*)command_list[i].ptr, value,
sizeof(command_list[i].size)-1);
}
}
}
@ -522,7 +544,9 @@ static bool aprs_decode_message(packet_t pp)
char buf[16];
chsnprintf(buf, sizeof(buf), "ack%s", msg_id_rx);
packet_t pp = aprs_encode_message(conf_sram.aprs.tx.call, conf_sram.aprs.tx.path, src, buf, true);
packet_t pp = aprs_encode_message(conf_sram.aprs.tx.call,
conf_sram.aprs.tx.path,
src, buf, true);
if(pp == NULL) {
TRACE_WARN("RX > No free packet objects");
return false;
@ -576,10 +600,14 @@ packet_t aprs_encode_telemetry_configuration(const char *callsign,
{
switch(type)
{
case 0: return aprs_encode_message(callsign, path, callsign, "PARM.Vbat,Vsol,Pbat,Temperature,Airpressure", true);
case 1: return aprs_encode_message(callsign, path, callsign, "UNIT.V,V,W,degC,Pa", true);
case 2: return aprs_encode_message(callsign, path, callsign, "EQNS.0,.001,0,0,.001,0,0,.001,-4.096,0,.1,-100,0,12.5,500", true);
case 3: return aprs_encode_message(callsign, path, callsign, "BITS.11111111,", true);
case 0: return aprs_encode_message(callsign, path, callsign,
"PARM.Vbat,Vsol,Pbat,Temperature,Airpressure", true);
case 1: return aprs_encode_message(callsign, path, callsign,
"UNIT.V,V,W,degC,Pa", true);
case 2: return aprs_encode_message(callsign, path, callsign,
"EQNS.0,.001,0,0,.001,0,0,.001,-4.096,0,.1,-100,0,12.5,500", true);
case 3: return aprs_encode_message(callsign, path, callsign,
"BITS.11111111,", true);
default: return NULL;
}
}

Wyświetl plik

@ -165,7 +165,7 @@ static void getSensors(dataPoint_t* tp)
tp->sen_e1_press = BME280_getPressure(&handle, 32);
tp->sen_e1_hum = BME280_getHumidity(&handle);
tp->sen_e1_temp = BME280_getTemperature(&handle);
} else { // No internal BME280 found
} else { // No external BME280 found
TRACE_ERROR("COLL > External BME280 E1 not found");
tp->sen_e1_press = 0;
tp->sen_e1_hum = 0;
@ -179,7 +179,7 @@ static void getSensors(dataPoint_t* tp)
tp->sen_e2_press = BME280_getPressure(&handle, 32);
tp->sen_e2_hum = BME280_getHumidity(&handle);
tp->sen_e2_temp = BME280_getTemperature(&handle);
} else { // No internal BME280 found
} else { // No external BME280 found
TRACE_ERROR("COLL > External BME280 E2 not found");
tp->sen_e2_press = 0;
tp->sen_e2_hum = 0;
@ -329,7 +329,7 @@ void init_data_collector(void)
threadStarted = true;
TRACE_INFO("COLL > Startup data collector thread");
thread_t *th = chThdCreateFromHeap(NULL, THD_WORKING_AREA_SIZE(2*1024), "TRA", LOWPRIO, collectorThread, NULL);
thread_t *th = chThdCreateFromHeap(NULL, THD_WORKING_AREA_SIZE(10*1024), "TRA", LOWPRIO, collectorThread, NULL);
if(!th) {
// Print startup error, do not start watchdog for this thread
TRACE_ERROR("COLL > Could not startup thread (not enough memory available)");

Wyświetl plik

@ -285,6 +285,14 @@ ssdv_packet_t packetRepeats[16];
bool reject_pri;
bool reject_sec;
/*
* Memory pool integrity checking... will expand to be that
*/
static struct pool_header *pktSystemCheck(void) {
extern guarded_memory_pool_t *ccm_pool;
return ((struct pool_header *)(ccm_pool->pool.next))->next;
}
static bool transmit_image_packet(const uint8_t *image,
uint32_t image_len,
thd_img_conf_t* conf,
@ -364,8 +372,7 @@ static bool transmit_image_packets(const uint8_t *image,
uint8_t pkt[SSDV_PKT_SIZE];
uint8_t pkt_base91[256] = {0};
/* FIXME: This doesn't work with 'en bloc' packet sends. */
/* FIXME: This doesn't work with burst mode packet sends. */
// Process redundant transmission from last cycle
if(strlen((char*)pkt_base91)
&& conf->radio_conf.redundantTx) {
@ -389,11 +396,7 @@ static bool transmit_image_packets(const uint8_t *image,
chThdSleep(TIME_MS2I(10)); // Leave other threads some time
}
// Init SSDV (FEC at 2FSK, non FEC at APRS)
//bi = 0;
/* Prepare for image encode and send. */
/* Prepare for new image encode and send. */
ssdv_t ssdv;
const uint8_t *b;
uint32_t bi = 0;
@ -405,11 +408,19 @@ static bool transmit_image_packets(const uint8_t *image,
ssdv_enc_feed(&ssdv, image, 0);
while(c != SSDV_EOI) {
// Encode packet(s)
/* Packet burst send is available if redundant TX is not requested. */
/*
* Next encode packets.
* Packet burst send is available if redundant TX is not requested.
* Limiting the number of packets in a burst is important.
* Else APRS-IS may drop fast arriving packets.
* Also having a send_spacing > 0 is important.
* This allows APRS-IS time to forward packets from its buffer.
*/
uint8_t buffers = fmin((NUMBER_COMMON_PKT_BUFFERS / 2), 5);
uint8_t chain = (conf->radio_conf.mod == MOD_2FSK
&& !conf->radio_conf.redundantTx) ?
(NUMBER_COMMON_PKT_BUFFERS / 2) : 1;
buffers : 1;
TRACE_INFO("IMG > Encode APRS/SSDV packet(s) %i", chain);
/* Packet linking control. */
@ -417,7 +428,6 @@ static bool transmit_image_packets(const uint8_t *image,
packet_t previous = NULL;
while(chain-- > 0) {
/* TODO: re-implement chunk sized SSDV conversions? */
while((c = ssdv_enc_get_packet(&ssdv)) == SSDV_FEED_ME) {
b = &image[bi++];
if(bi > image_len) {
@ -457,12 +467,13 @@ static bool transmit_image_packets(const uint8_t *image,
}
return false;
}
if(head == NULL)
head = packet;
if(previous != NULL)
/* Link the next packet into the chain. */
previous->nextp = packet;
/* Now set previous as current. */
else
/* This is the first packet. */
head = packet;
/* Now set new packet as previous. */
previous = packet;
} /* End while(chain-- > 0) */
@ -534,26 +545,20 @@ static bool analyze_image(uint8_t *image, uint32_t image_len)
ssdv_enc_init(&ssdv, SSDV_TYPE_NOFEC, "", 0, 7);
ssdv_enc_set_buffer(&ssdv, pkt);
while(true) // FIXME: I get caught in these loops occasionally and never return
{
while((c = ssdv_enc_get_packet(&ssdv)) == SSDV_FEED_ME)
{
b = &image[bi];
uint8_t r = bi < image_len-128 ? 128 : image_len - bi;
bi += r;
if(r <= 0)
{
while(true) {
while((c = ssdv_enc_get_packet(&ssdv)) == SSDV_FEED_ME) {
b = &image[bi++];
if(bi > image_len) {
TRACE_ERROR("CAM > Error in image (Premature end of file %d)", i);
return false;
}
ssdv_enc_feed(&ssdv, b, r);
ssdv_enc_feed(&ssdv, b, 1);
}
if(c == SSDV_EOI) // End of image
return true;
if(c != SSDV_OK) // Error in JPEG image
{
if(c != SSDV_OK) {
TRACE_ERROR("CAM > Error in image (ssdv_enc_get_packet failed: %d %d)", c, i);
return false;
}
@ -591,10 +596,12 @@ uint32_t takePicture(uint8_t* buffer, uint32_t size,
OV5640_init();
camInitialized = true;
}
TRACE_DEBUG("CAM > Pool link 0x%x", pktSystemCheck());
// Sample data from pseudo DCMI through DMA into RAM
size_sampled = OV5640_Snapshot2RAM(buffer, size, res);
TRACE_DEBUG("CAM > Pool link 0x%x", pktSystemCheck());
if(size_sampled == 0)
continue;
// Switch off camera
if(!conf_sram.keep_cam_switched_on) {
OV5640_deinit();
@ -682,7 +689,7 @@ THD_FUNCTION(imgThread, arg) {
/* Allow time for output queue to be processed. */
chThdSleep(TIME_S2I(10));
}
} else { // No camera found
} else { // No camera found or capture failed after retries.
TRACE_INFO("IMG > Encode/Transmit SSDV (camera error) ID=%d",
gimage_id-1);
if(!transmit_image_packets(noCameraFound, sizeof(noCameraFound),

Wyświetl plik

@ -12,6 +12,9 @@
#include <math.h>
#include "watchdog.h"
/*
*
*/
THD_FUNCTION(posThread, arg)
{
thd_pos_conf_t* conf = (thd_pos_conf_t*)arg;
@ -26,74 +29,89 @@ THD_FUNCTION(posThread, arg)
TRACE_INFO("POS > Startup position thread");
// Set telemetry configuration transmission variables
sysinterval_t last_conf_transmission = chVTGetSystemTime() - conf->tel_enc_cycle;
sysinterval_t last_conf_transmission =
chVTGetSystemTime() - conf->tel_enc_cycle;
sysinterval_t time = chVTGetSystemTime();
while(true)
{
while(true) {
TRACE_INFO("POS > Do module POSITION cycle");
TRACE_INFO("POS > Get last data point");
dataPoint_t* dataPoint = getLastDataPoint();
if(!p_sleep(&conf->thread_conf.sleep_conf))
{
if(!p_sleep(&conf->thread_conf.sleep_conf)) {
TRACE_INFO("POS > Transmit position");
// Encode/Transmit position packet
packet_t packet = aprs_encode_position(conf->call, conf->path, conf->symbol, dataPoint);
packet_t packet = aprs_encode_position(conf->call, conf->path,
conf->symbol, dataPoint);
if(packet == NULL) {
TRACE_WARN("POS > No free packet objects for position transmission");
TRACE_WARN("POS > No free packet objects"
" for position transmission");
} else {
transmitOnRadio(packet,
if(!transmitOnRadio(packet,
conf->radio_conf.freq,
0,
0,
conf->radio_conf.pwr,
conf->radio_conf.mod,
conf->radio_conf.rssi);
conf->radio_conf.rssi)) {
TRACE_ERROR("POS > failed to transmit position data");
}
chThdSleep(TIME_S2I(5));
}
chThdSleep(TIME_S2I(5));
// Encode/Transmit APRSD packet
/*
* FIXME: When sending out an unsolicited APRSD who to send it to?
* Should there be a callsign set in config that APRSD is sent to?
* For now just send to self... doesn't make sense though.
*/
bool rx = conf->aprs_msg;
packet_t pp = aprs_encode_query_answer_aprsd(conf->call,
packet = aprs_encode_query_answer_aprsd(conf->call,
conf->path,
rx ? conf->call
: conf_sram.aprs.rx.call);
: conf_sram.aprs.tx.call);
if(packet == NULL) {
TRACE_WARN("POS > No free packet objects for APRSD transmission");
TRACE_WARN("POS > No free packet objects for "
"APRSD transmission");
} else {
transmitOnRadio(pp,
if(!transmitOnRadio(packet,
conf->radio_conf.freq,
0,
0,
conf->radio_conf.pwr,
conf->radio_conf.mod,
conf->radio_conf.rssi);
conf->radio_conf.rssi)) {
TRACE_ERROR("POS > Failed to transmit APRSD data");
}
chThdSleep(TIME_S2I(5));
}
// Telemetry encoding parameter transmission
if(conf->tel_enc_cycle != 0 && last_conf_transmission + conf->tel_enc_cycle < chVTGetSystemTime())
{
chThdSleep(TIME_S2I(5)); // Take a little break between the packet transmissions
if(conf->tel_enc_cycle != 0 && last_conf_transmission
+ conf->tel_enc_cycle < chVTGetSystemTime()) {
TRACE_INFO("POS > Transmit telemetry configuration");
// Encode and transmit telemetry config packet
for(uint8_t type=0; type<4; type++)
{
packet = aprs_encode_telemetry_configuration(conf->call, conf->path, type);
for(uint8_t type = 0; type < 4; type++) {
packet = aprs_encode_telemetry_configuration(conf->call,
conf->path, type);
if(packet == NULL) {
TRACE_WARN("POS > No free packet objects for telemetry transmission");
TRACE_WARN("POS > No free packet objects for"
" telemetry transmission");
} else {
transmitOnRadio(packet,
if(!transmitOnRadio(packet,
conf->radio_conf.freq,
0,
0,
conf->radio_conf.pwr,
conf->radio_conf.mod,
conf->radio_conf.rssi);
conf->radio_conf.rssi)) {
TRACE_ERROR("POS > Failed to transmit telemetry data");
}
chThdSleep(TIME_S2I(5));
}
}
@ -101,14 +119,17 @@ THD_FUNCTION(posThread, arg)
last_conf_transmission += conf->tel_enc_cycle;
}
}
time = waitForTrigger(time, conf->thread_conf.cycle);
}
}
/*
*
*/
void start_position_thread(thd_pos_conf_t *conf)
{
thread_t *th = chThdCreateFromHeap(NULL, THD_WORKING_AREA_SIZE(10*1024), "POS", LOWPRIO, posThread, conf);
thread_t *th = chThdCreateFromHeap(NULL, THD_WORKING_AREA_SIZE(20*1024),
"POS", LOWPRIO, posThread, conf);
if(!th) {
// Print startup error, do not start watchdog for this thread
TRACE_ERROR("POS > Could not startup thread (not enough memory available)");