kopia lustrzana https://github.com/DL7AD/pecanpico9
- Merged dbgon and dbgoff command to debug
- Fixed error in SOI-not-found flag in debug.c - Added camera-command command (for testing different camera options while watching the livestream) - Fixed table header in readLog USB command - Added last-image-id to track-point struct (which is also logged), SSDV transmission will start with next ID on STM32 reset. This has been done while habhub alway mixes up different images with the same image id. - Added thread (module) configuration printout on USB debug - Added GPS_LOG and GPS_OFF flag - Changed tracking manager initialization strategy: Tracking Manager runs all time and also logs when there is no new GPS fix Tracking Manager logs images ID Tracking Manager doesnt switch on GPS unless there is a position thread running (in order to save energy when position is not sent out) Implemented several flags in decoder2.py Added script command.c which sends camera registers via USB to the OV5640.Develop
rodzic
e9cff81fa4
commit
37180ab892
|
@ -0,0 +1,18 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
import serial,os,re,sys
|
||||||
|
import pygame
|
||||||
|
from pygame.locals import *
|
||||||
|
import pygame.time
|
||||||
|
from cStringIO import StringIO
|
||||||
|
|
||||||
|
try:
|
||||||
|
ser = serial.Serial(port='/dev/ttyACM1')
|
||||||
|
except:
|
||||||
|
sys.stderr.write('Error: Could not open serial port\n')
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
ser.write('\r\n')
|
||||||
|
ser.write('command '+str(int(sys.argv[1], 16))+' '+str(int(sys.argv[2], 16))+'\r\n')
|
||||||
|
ser.close()
|
|
@ -40,8 +40,15 @@ while True:
|
||||||
print line.strip()
|
print line.strip()
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
if int(size) == 0:
|
||||||
|
ser.write('picture\r\n')
|
||||||
|
continue
|
||||||
|
|
||||||
imgbuf = ser.read(int(size))
|
imgbuf = ser.read(int(size))
|
||||||
|
|
||||||
|
|
||||||
for event in pygame.event.get():
|
for event in pygame.event.get():
|
||||||
if event.type == QUIT:
|
if event.type == QUIT:
|
||||||
exit(0)
|
exit(0)
|
||||||
|
@ -61,6 +68,11 @@ while True:
|
||||||
screen.blit(textsurface,(0,0))
|
screen.blit(textsurface,(0,0))
|
||||||
pygame.display.flip()
|
pygame.display.flip()
|
||||||
pygame.display.update(displaygroup.draw(screen))
|
pygame.display.update(displaygroup.draw(screen))
|
||||||
|
|
||||||
|
f = open('data/data'+str(i)+'.jpg','wb')
|
||||||
|
f.write(imgbuf)
|
||||||
|
f.close()
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print str(e)
|
print str(e)
|
||||||
textsurface = myfont.render('Error %s' % (e), False, (255, 100, 100))
|
textsurface = myfont.render('Error %s' % (e), False, (255, 100, 100))
|
||||||
|
@ -69,7 +81,6 @@ while True:
|
||||||
pygame.display.update(displaygroup.draw(screen))
|
pygame.display.update(displaygroup.draw(screen))
|
||||||
|
|
||||||
ser.write('picture\r\n')
|
ser.write('picture\r\n')
|
||||||
i += 1
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
import serial,os,re,sys
|
||||||
|
import pygame
|
||||||
|
from pygame.locals import *
|
||||||
|
import pygame.time
|
||||||
|
from cStringIO import StringIO
|
||||||
|
|
||||||
|
try:
|
||||||
|
ser = serial.Serial(port='/dev/ttyACM1')
|
||||||
|
except:
|
||||||
|
sys.stderr.write('Error: Could not open serial port\n')
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
while True:
|
||||||
|
ser.read(1)
|
|
@ -463,7 +463,7 @@ void start_user_modules(void)
|
||||||
config[4].ssdv_conf.ram_size = sizeof(ssdv_buffer); // Buffer size
|
config[4].ssdv_conf.ram_size = sizeof(ssdv_buffer); // Buffer size
|
||||||
config[4].ssdv_conf.res = RES_VGA; // Resolution VGA
|
config[4].ssdv_conf.res = RES_VGA; // Resolution VGA
|
||||||
config[4].ssdv_conf.quality = 4; // Image quality
|
config[4].ssdv_conf.quality = 4; // Image quality
|
||||||
//start_image_thread(&config[4]);
|
start_image_thread(&config[4]);
|
||||||
|
|
||||||
// Module IMAGE, SSDV 2m 2FSK
|
// Module IMAGE, SSDV 2m 2FSK
|
||||||
config[5].power = 127; // Transmission Power
|
config[5].power = 127; // Transmission Power
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "image.h"
|
#include "image.h"
|
||||||
#include "tracking.h"
|
#include "tracking.h"
|
||||||
|
#include "pi2c.h"
|
||||||
|
|
||||||
const SerialConfig uart_config =
|
const SerialConfig uart_config =
|
||||||
{
|
{
|
||||||
|
@ -18,23 +19,19 @@ mutex_t trace_mtx; // Used internal to synchronize multiple chprintf in debug.h
|
||||||
|
|
||||||
bool debug_on_usb = false;
|
bool debug_on_usb = false;
|
||||||
|
|
||||||
void debugOnUSB_Off(BaseSequentialStream *chp, int argc, char *argv[])
|
void debugOnUSB(BaseSequentialStream *chp, int argc, char *argv[])
|
||||||
{
|
{
|
||||||
(void)chp;
|
if(argc < 1)
|
||||||
(void)argc;
|
{
|
||||||
(void)argv;
|
chprintf(chp, "Argument missing!\r\n");
|
||||||
debug_on_usb = false;
|
chprintf(chp, "Argument 1: 1 for switch on, 0 for switch off!\r\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
debug_on_usb = atoi(argv[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void debugOnUSB_On(BaseSequentialStream *chp, int argc, char *argv[])
|
static uint8_t usb_buffer[64*1024] __attribute__((aligned(32))); // USB image buffer
|
||||||
{
|
|
||||||
(void)chp;
|
|
||||||
(void)argc;
|
|
||||||
(void)argv;
|
|
||||||
debug_on_usb = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint8_t usb_buffer[96*1024] __attribute__((aligned(32))); // USB image buffer
|
|
||||||
void printPicture(BaseSequentialStream *chp, int argc, char *argv[])
|
void printPicture(BaseSequentialStream *chp, int argc, char *argv[])
|
||||||
{
|
{
|
||||||
(void)argc;
|
(void)argc;
|
||||||
|
@ -67,8 +64,8 @@ void printPicture(BaseSequentialStream *chp, int argc, char *argv[])
|
||||||
}
|
}
|
||||||
if(!start_detected)
|
if(!start_detected)
|
||||||
{
|
{
|
||||||
TRACE_USB("DATA > image,jpeg,0");
|
TRACE_USB("DATA > image/jpeg,0");
|
||||||
TRACE_USB("DATA > error,no SOI flag found");
|
TRACE_USB("DATA > text/trace,no SOI flag found");
|
||||||
}
|
}
|
||||||
|
|
||||||
} else { // No camera found
|
} else { // No camera found
|
||||||
|
@ -79,16 +76,11 @@ void printPicture(BaseSequentialStream *chp, int argc, char *argv[])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
trackPoint_t* getLogBuffer(uint16_t id)
|
void command2Camera(BaseSequentialStream *chp, int argc, char *argv[])
|
||||||
{
|
{
|
||||||
if(sizeof(trackPoint_t)*id < LOG_SECTOR_SIZE-sizeof(trackPoint_t))
|
(void)chp;
|
||||||
{
|
(void)argc;
|
||||||
return (trackPoint_t*)(LOG_FLASH_ADDR1 + id * sizeof(trackPoint_t));
|
I2C_write8_16bitreg(0x3C, atoi(argv[0]), atoi(argv[1]));
|
||||||
} else if((id-(LOG_SECTOR_SIZE/sizeof(trackPoint_t)))*sizeof(trackPoint_t) < LOG_SECTOR_SIZE-sizeof(trackPoint_t)) {
|
|
||||||
return (trackPoint_t*)(LOG_FLASH_ADDR2 + (id-(LOG_SECTOR_SIZE/sizeof(trackPoint_t))) * sizeof(trackPoint_t));
|
|
||||||
} else { // Outside of memory address allocation
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void readLog(BaseSequentialStream *chp, int argc, char *argv[])
|
void readLog(BaseSequentialStream *chp, int argc, char *argv[])
|
||||||
|
@ -96,17 +88,19 @@ void readLog(BaseSequentialStream *chp, int argc, char *argv[])
|
||||||
(void)argc;
|
(void)argc;
|
||||||
(void)argv;
|
(void)argv;
|
||||||
|
|
||||||
|
chprintf(chp, "id,date,time,lat,lon,alt,sats,ttff,vbat,vsol,vsub,pbat,rbat,press,temp,hum,idimg\r\n");
|
||||||
|
|
||||||
trackPoint_t *tp;
|
trackPoint_t *tp;
|
||||||
for(uint16_t i=0; (tp = getLogBuffer(i)) != NULL; i++)
|
for(uint16_t i=0; (tp = getLogBuffer(i)) != NULL; i++)
|
||||||
if(tp->id != 0xFFFFFFFF)
|
if(tp->id != 0xFFFFFFFF)
|
||||||
{
|
{
|
||||||
chprintf( chp,
|
chprintf( chp,
|
||||||
"%d,%04d-%02d-%02d,%02d:%02d:%02d,%d.%05d,%d.%05d,%d,%d,%d,%d.%03d,%d.%03d,%d.%03d,%d,%d,%d.%01d,%2d.%02d,%2d.%01d\r\n",
|
"%d,%04d-%02d-%02d,%02d:%02d:%02d,%d.%05d,%d.%05d,%d,%d,%d,%d.%03d,%d.%03d,%d.%03d,%d,%d,%d.%01d,%2d.%02d,%2d.%01d,%d\r\n",
|
||||||
tp->id,tp->time.year, tp->time.month, tp->time.day, tp->time.hour, tp->time.minute, tp->time.day,
|
tp->id,tp->time.year, tp->time.month, tp->time.day, tp->time.hour, tp->time.minute, tp->time.day,
|
||||||
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,
|
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,
|
||||||
tp->gps_sats, tp->gps_ttff,
|
tp->gps_sats, tp->gps_ttff,
|
||||||
tp->adc_vbat/1000, (tp->adc_vbat%1000), tp->adc_vsol/1000, (tp->adc_vsol%1000), tp->adc_vusb/1000, (tp->adc_vusb%1000), tp->adc_pbat, tp->adc_rbat,
|
tp->adc_vbat/1000, (tp->adc_vbat%1000), tp->adc_vsol/1000, (tp->adc_vsol%1000), tp->adc_vusb/1000, (tp->adc_vusb%1000), tp->adc_pbat, tp->adc_rbat,
|
||||||
tp->air_press/10, tp->air_press%10, tp->air_temp/100, tp->air_temp%100, tp->air_hum/10, tp->air_hum%10
|
tp->air_press/10, tp->air_press%10, tp->air_temp/100, tp->air_temp%100, tp->air_hum/10, tp->air_hum%10, tp->id_image
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -117,6 +111,7 @@ void printConfig(BaseSequentialStream *chp, int argc, char *argv[])
|
||||||
{
|
{
|
||||||
chprintf(chp, "Argument missing!\r\n");
|
chprintf(chp, "Argument missing!\r\n");
|
||||||
chprintf(chp, "Argument 1: Id of config!\r\n");
|
chprintf(chp, "Argument 1: Id of config!\r\n");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t id = atoi(argv[0]);
|
uint8_t id = atoi(argv[0]);
|
||||||
|
@ -125,9 +120,14 @@ void printConfig(BaseSequentialStream *chp, int argc, char *argv[])
|
||||||
chprintf(chp, "Power: %d\r\n", config[id].power);
|
chprintf(chp, "Power: %d\r\n", config[id].power);
|
||||||
|
|
||||||
if(config[id].frequency.type == FREQ_STATIC) {
|
if(config[id].frequency.type == FREQ_STATIC) {
|
||||||
chprintf(chp, "Frequency: %d Hz\r\n", config[id].frequency.hz);
|
uint32_t freq = config[id].frequency.hz;
|
||||||
|
if((freq/1000)*1000 == freq)
|
||||||
|
chprintf(chp, "Frequency: %d.%03d MHz\r\n", freq/1000000, (freq%1000000)/1000);
|
||||||
|
else
|
||||||
|
chprintf(chp, "Frequency: %d.%03d MHz\r\n", freq/1000000, (freq%1000000));
|
||||||
} else {
|
} else {
|
||||||
chprintf(chp, "Frequency: APRS region dependent (currently %d Hz\r\n", getFrequency(&config[id].frequency));
|
uint32_t freq = getFrequency(&config[id].frequency);
|
||||||
|
chprintf(chp, "Frequency: APRS region dependent (currently %d.%03d MHz)\r\n", freq/1000000, (freq%1000000)/1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
chprintf(chp, "Protocol: %d\r\n", config[id].protocol);
|
chprintf(chp, "Protocol: %d\r\n", config[id].protocol);
|
||||||
|
|
|
@ -104,11 +104,11 @@ extern bool debug_on_usb;
|
||||||
TRACE_INFO("%-4s > Current time: %02d-%02d-%02d %02d:%02d:%02d:%03d", thd, dbgtime.year, dbgtime.month, dbgtime.day, dbgtime.hour, dbgtime.minute, dbgtime.second, dbgtime.millisecond); \
|
TRACE_INFO("%-4s > Current time: %02d-%02d-%02d %02d:%02d:%02d:%03d", thd, dbgtime.year, dbgtime.month, dbgtime.day, dbgtime.hour, dbgtime.minute, dbgtime.second, dbgtime.millisecond); \
|
||||||
}
|
}
|
||||||
|
|
||||||
void debugOnUSB_Off(BaseSequentialStream *chp, int argc, char *argv[]);
|
void debugOnUSB(BaseSequentialStream *chp, int argc, char *argv[]);
|
||||||
void debugOnUSB_On(BaseSequentialStream *chp, int argc, char *argv[]);
|
|
||||||
void printConfig(BaseSequentialStream *chp, int argc, char *argv[]);
|
void printConfig(BaseSequentialStream *chp, int argc, char *argv[]);
|
||||||
void printPicture(BaseSequentialStream *chp, int argc, char *argv[]);
|
void printPicture(BaseSequentialStream *chp, int argc, char *argv[]);
|
||||||
void readLog(BaseSequentialStream *chp, int argc, char *argv[]);
|
void readLog(BaseSequentialStream *chp, int argc, char *argv[]);
|
||||||
|
void command2Camera(BaseSequentialStream *chp, int argc, char *argv[]);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -27,11 +27,11 @@ static const struct regval_list OV5640YUV_Sensor_Dvp_Init[] =
|
||||||
{ 0x4051, 0x8f },
|
{ 0x4051, 0x8f },
|
||||||
|
|
||||||
{ 0x3008, 0x42 },
|
{ 0x3008, 0x42 },
|
||||||
{ 0x3103, 0x03 },
|
{ 0x3103, 0x03 },
|
||||||
{ 0x3017, 0x7f },
|
{ 0x3017, 0x7f },
|
||||||
{ 0x3018, 0xff },
|
{ 0x3018, 0xff },
|
||||||
{ 0x302c, 0x02 },
|
{ 0x302c, 0x02 },
|
||||||
{ 0x3108, 0x21 },
|
{ 0x3108, 0x21 }, // PCLK root divider [5:4]
|
||||||
{ 0x3630, 0x2e },//2e
|
{ 0x3630, 0x2e },//2e
|
||||||
{ 0x3632, 0xe2 },
|
{ 0x3632, 0xe2 },
|
||||||
{ 0x3633, 0x23 },//23
|
{ 0x3633, 0x23 },//23
|
||||||
|
@ -92,12 +92,12 @@ static const struct regval_list OV5640YUV_Sensor_Dvp_Init[] =
|
||||||
{ 0x3814, 0x31 },
|
{ 0x3814, 0x31 },
|
||||||
{ 0x3815, 0x31 },
|
{ 0x3815, 0x31 },
|
||||||
|
|
||||||
{ 0x3034, 0x1a },
|
{ 0x3034, 0x1a }, // PLL charge pump control [7:4]
|
||||||
{ 0x3035, 0x11 }, //15fps
|
{ 0x3035, 0x11 }, // System clock divider [7:4]
|
||||||
{ 0x3036, 0x46 },
|
{ 0x3036, 0x46 }, // PLL multiplier [7:0]
|
||||||
{ 0x3037, 0x14 },
|
{ 0x3037, 0x14 }, // PLL root divider [4], PLL pre-divider [3:0]
|
||||||
{ 0x3038, 0x00 },
|
{ 0x3038, 0x00 }, // System control registers (changing not recommended)
|
||||||
{ 0x3039, 0x00 },
|
{ 0x3039, 0x00 }, // PLL bypass [7]
|
||||||
|
|
||||||
{ 0x380c, 0x07 },
|
{ 0x380c, 0x07 },
|
||||||
{ 0x380d, 0x68 },
|
{ 0x380d, 0x68 },
|
||||||
|
@ -802,7 +802,6 @@ void set6MHz(void)
|
||||||
*/
|
*/
|
||||||
static bool analyze_image(uint8_t *image, uint32_t image_len)
|
static bool analyze_image(uint8_t *image, uint32_t image_len)
|
||||||
{
|
{
|
||||||
return true;
|
|
||||||
ssdv_t ssdv;
|
ssdv_t ssdv;
|
||||||
uint8_t pkt[SSDV_PKT_SIZE];
|
uint8_t pkt[SSDV_PKT_SIZE];
|
||||||
uint8_t *b;
|
uint8_t *b;
|
||||||
|
@ -851,7 +850,7 @@ static bool analyze_image(uint8_t *image, uint32_t image_len)
|
||||||
*/
|
*/
|
||||||
uint32_t OV5640_Snapshot2RAM(uint8_t* buffer, uint32_t size, resolution_t res, bool enableJpegValidation)
|
uint32_t OV5640_Snapshot2RAM(uint8_t* buffer, uint32_t size, resolution_t res, bool enableJpegValidation)
|
||||||
{
|
{
|
||||||
uint8_t cntr = 5;
|
uint8_t cntr = 10;
|
||||||
bool status;
|
bool status;
|
||||||
bool jpegValid;
|
bool jpegValid;
|
||||||
uint32_t size_sampled;
|
uint32_t size_sampled;
|
||||||
|
|
|
@ -8,16 +8,16 @@
|
||||||
#include "shell.h"
|
#include "shell.h"
|
||||||
|
|
||||||
static const ShellCommand commands[] = {
|
static const ShellCommand commands[] = {
|
||||||
{"dbgon", debugOnUSB_On},
|
{"debug", debugOnUSB},
|
||||||
{"dbgoff", debugOnUSB_Off},
|
|
||||||
{"picture", printPicture},
|
{"picture", printPicture},
|
||||||
{"log", readLog},
|
{"log", readLog},
|
||||||
// {"printconfig", printConfig}, FIXME: This feature is faulty at the moment
|
{"config", printConfig},
|
||||||
|
{"command", command2Camera},
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
static const ShellConfig shell_cfg = {
|
static const ShellConfig shell_cfg = {
|
||||||
(BaseSequentialStream *)&SDU1,
|
(BaseSequentialStream*)&SDU1,
|
||||||
commands
|
commands
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ int main(void) {
|
||||||
|
|
||||||
// Voltage switching (1.8V <=> 3.0V)
|
// Voltage switching (1.8V <=> 3.0V)
|
||||||
#if ACTIVATE_USB || ACTIVATE_3V
|
#if ACTIVATE_USB || ACTIVATE_3V
|
||||||
boost_voltage(true); // Ramp up voltage to 3V
|
boost_voltage(true); // Ramp up voltage to 3V
|
||||||
chThdSleepMilliseconds(100);
|
chThdSleepMilliseconds(100);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -54,9 +54,8 @@ int main(void) {
|
||||||
start_essential_threads(); // Startup required modules (tracking managemer, watchdog)
|
start_essential_threads(); // Startup required modules (tracking managemer, watchdog)
|
||||||
start_user_modules(); // Startup optional modules (eg. POSITION, LOG, ...)
|
start_user_modules(); // Startup optional modules (eg. POSITION, LOG, ...)
|
||||||
|
|
||||||
// Print time every 10 sec
|
|
||||||
while(true) {
|
while(true) {
|
||||||
if (SDU1.config->usbp->state == USB_ACTIVE) {
|
if(SDU1.config->usbp->state == USB_ACTIVE) {
|
||||||
thread_t *shelltp = chThdCreateFromHeap(NULL, THD_WORKING_AREA_SIZE(512), "shell", NORMALPRIO+1, shellThread, (void*)&shell_cfg);
|
thread_t *shelltp = chThdCreateFromHeap(NULL, THD_WORKING_AREA_SIZE(512), "shell", NORMALPRIO+1, shellThread, (void*)&shell_cfg);
|
||||||
chThdWait(shelltp);
|
chThdWait(shelltp);
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,6 +125,11 @@ uint32_t aprs_encode_position(uint8_t* message, mod_t mod, const aprs_conf_t *co
|
||||||
chsnprintf(temp, sizeof(temp), "%d", ++loss_of_gps_counter);
|
chsnprintf(temp, sizeof(temp), "%d", ++loss_of_gps_counter);
|
||||||
ax25_send_string(&packet, temp);
|
ax25_send_string(&packet, temp);
|
||||||
|
|
||||||
|
} else if(trackPoint->gps_lock == GPS_LOG) { // GPS position from log (because the tracker has been just switched on)
|
||||||
|
|
||||||
|
ax25_send_string(&packet, " GPS FROM LOG");
|
||||||
|
loss_of_gps_counter = 0;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
loss_of_gps_counter = 0;
|
loss_of_gps_counter = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -305,45 +305,48 @@ void shutdownRadio(void)
|
||||||
uint32_t getAPRSRegionFrequency(void) {
|
uint32_t getAPRSRegionFrequency(void) {
|
||||||
trackPoint_t *point = getLastTrackPoint();
|
trackPoint_t *point = getLastTrackPoint();
|
||||||
|
|
||||||
uint32_t freq = 0; // Position unknown
|
// Position unknown
|
||||||
|
if(point == NULL || (point->gps_lat == 0 && point->gps_lon == 0))
|
||||||
|
return 0;
|
||||||
|
|
||||||
// America 144.390 MHz
|
// America 144.390 MHz
|
||||||
if(isPointInAmerica(point->gps_lat, point->gps_lon))
|
if(isPointInAmerica(point->gps_lat, point->gps_lon))
|
||||||
freq = APRS_FREQ_AMERICA;
|
return APRS_FREQ_AMERICA;
|
||||||
|
|
||||||
// China 144.640 MHz
|
// China 144.640 MHz
|
||||||
if(isPointInChina(point->gps_lat, point->gps_lon))
|
if(isPointInChina(point->gps_lat, point->gps_lon))
|
||||||
freq = APRS_FREQ_CHINA;
|
return APRS_FREQ_CHINA;
|
||||||
|
|
||||||
// Japan 144.660 MHz
|
// Japan 144.660 MHz
|
||||||
if(isPointInJapan(point->gps_lat, point->gps_lon))
|
if(isPointInJapan(point->gps_lat, point->gps_lon))
|
||||||
freq = APRS_FREQ_JAPAN;
|
return APRS_FREQ_JAPAN;
|
||||||
|
|
||||||
// Southkorea 144.620 MHz
|
// Southkorea 144.620 MHz
|
||||||
if(isPointInSouthkorea(point->gps_lat, point->gps_lon))
|
if(isPointInSouthkorea(point->gps_lat, point->gps_lon))
|
||||||
freq = APRS_FREQ_SOUTHKOREA;
|
return APRS_FREQ_SOUTHKOREA;
|
||||||
|
|
||||||
// Southkorea 144.620 MHz
|
// Southkorea 144.620 MHz
|
||||||
if(isPointInSoutheastAsia(point->gps_lat, point->gps_lon))
|
if(isPointInSoutheastAsia(point->gps_lat, point->gps_lon))
|
||||||
freq = APRS_FREQ_SOUTHEASTASIA;
|
return APRS_FREQ_SOUTHEASTASIA;
|
||||||
|
|
||||||
// Australia 145.175 MHz
|
// Australia 145.175 MHz
|
||||||
if(isPointInAustralia(point->gps_lat, point->gps_lon))
|
if(isPointInAustralia(point->gps_lat, point->gps_lon))
|
||||||
freq = APRS_FREQ_AUSTRALIA;
|
return APRS_FREQ_AUSTRALIA;
|
||||||
|
|
||||||
// Australia 144.575 MHz
|
// Australia 144.575 MHz
|
||||||
if(isPointInNewZealand(point->gps_lat, point->gps_lon))
|
if(isPointInNewZealand(point->gps_lat, point->gps_lon))
|
||||||
freq = APRS_FREQ_NEWZEALAND;
|
return APRS_FREQ_NEWZEALAND;
|
||||||
|
|
||||||
// Argentina/Paraguay/Uruguay 144.930 MHz
|
// Argentina/Paraguay/Uruguay 144.930 MHz
|
||||||
if(isPointInArgentina(point->gps_lat, point->gps_lon))
|
if(isPointInArgentina(point->gps_lat, point->gps_lon))
|
||||||
freq = APRS_FREQ_ARGENTINA;
|
return APRS_FREQ_ARGENTINA;
|
||||||
|
|
||||||
// Brazil 145.575 MHz
|
// Brazil 145.575 MHz
|
||||||
if(isPointInBrazil(point->gps_lat, point->gps_lon))
|
if(isPointInBrazil(point->gps_lat, point->gps_lon))
|
||||||
freq = APRS_FREQ_BRAZIL;
|
return APRS_FREQ_BRAZIL;
|
||||||
|
|
||||||
return freq;
|
// For the rest of the world 144.800 MHz
|
||||||
|
return 144800000;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -420,7 +423,7 @@ uint32_t getFrequency(freq_conf_t *config)
|
||||||
switch(config->type) {
|
switch(config->type) {
|
||||||
case FREQ_APRS_REGION:; // Dynamic frequency (determined by GPS position)
|
case FREQ_APRS_REGION:; // Dynamic frequency (determined by GPS position)
|
||||||
uint32_t freq = getAPRSRegionFrequency();
|
uint32_t freq = getAPRSRegionFrequency();
|
||||||
if(!freq) // Use default frequency (if freq is not set = position unknown)
|
if(!freq) // Use default frequency (if freq is 0 = position unknown)
|
||||||
return config->hz;
|
return config->hz;
|
||||||
return freq;
|
return freq;
|
||||||
|
|
||||||
|
|
|
@ -273,7 +273,7 @@ const uint8_t noCameraFound[4071] = {
|
||||||
0xBD, 0xC0, 0x20, 0x00, 0x01, 0xFF, 0xD9
|
0xBD, 0xC0, 0x20, 0x00, 0x01, 0xFF, 0xD9
|
||||||
};
|
};
|
||||||
|
|
||||||
static uint8_t gimage_id; // Global image ID (for all image threads)
|
uint8_t gimage_id; // Global image ID (for all image threads)
|
||||||
mutex_t camera_mtx;
|
mutex_t camera_mtx;
|
||||||
bool camera_mtx_init = false;
|
bool camera_mtx_init = false;
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
void start_image_thread(module_conf_t *conf);
|
void start_image_thread(module_conf_t *conf);
|
||||||
bool takePicture(ssdv_conf_t *conf, bool enableJpegValidation);
|
bool takePicture(ssdv_conf_t *conf, bool enableJpegValidation);
|
||||||
extern mutex_t camera_mtx;
|
extern mutex_t camera_mtx;
|
||||||
|
extern uint8_t gimage_id;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -213,7 +213,7 @@ void start_position_thread(module_conf_t *conf)
|
||||||
if(conf->init_delay) chThdSleepMilliseconds(conf->init_delay);
|
if(conf->init_delay) chThdSleepMilliseconds(conf->init_delay);
|
||||||
|
|
||||||
// Start tracking manager (if not running yet)
|
// Start tracking manager (if not running yet)
|
||||||
init_tracking_manager();
|
init_tracking_manager(true);
|
||||||
|
|
||||||
// Start position thread
|
// Start position thread
|
||||||
TRACE_INFO("POS > Startup position thread");
|
TRACE_INFO("POS > Startup position thread");
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
#include "ch.h"
|
#include "ch.h"
|
||||||
#include "hal.h"
|
#include "hal.h"
|
||||||
|
|
||||||
#include "debug.h"
|
|
||||||
#include "threads.h"
|
#include "threads.h"
|
||||||
#include "tracking.h"
|
#include "tracking.h"
|
||||||
#include "watchdog.h"
|
#include "watchdog.h"
|
||||||
#include "image.h"
|
|
||||||
#include "pi2c.h"
|
#include "pi2c.h"
|
||||||
#include "pac1720.h"
|
#include "pac1720.h"
|
||||||
|
|
||||||
|
@ -15,9 +13,8 @@ void start_essential_threads(void) {
|
||||||
// Init watchdog
|
// Init watchdog
|
||||||
init_watchdog();
|
init_watchdog();
|
||||||
|
|
||||||
// Initialize essential mutex's
|
// Initialize tracking manager (without GPS, GPS is initialized if needed by position thread)
|
||||||
|
init_tracking_manager(false);
|
||||||
|
|
||||||
|
|
||||||
pi2cInit(); // Initialize I2C
|
pi2cInit(); // Initialize I2C
|
||||||
pac1720_init(); // Initialize current measurement
|
pac1720_init(); // Initialize current measurement
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
|
|
||||||
#include "tracking.h"
|
#include "tracking.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "ptime.h"
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "ublox.h"
|
#include "ublox.h"
|
||||||
#include "bme280.h"
|
#include "bme280.h"
|
||||||
|
@ -12,12 +11,14 @@
|
||||||
#include "radio.h"
|
#include "radio.h"
|
||||||
#include "flash.h"
|
#include "flash.h"
|
||||||
#include "watchdog.h"
|
#include "watchdog.h"
|
||||||
|
#include "image.h"
|
||||||
|
|
||||||
static trackPoint_t trackPoints[2];
|
static trackPoint_t trackPoints[2];
|
||||||
static trackPoint_t* lastTrackPoint;
|
static trackPoint_t* lastTrackPoint;
|
||||||
static systime_t nextLogEntryTimer;
|
static systime_t nextLogEntryTimer;
|
||||||
static module_conf_t trac_conf = {.name = "TRAC"}; // Fake config needed for watchdog tracking
|
static module_conf_t trac_conf = {.name = "TRAC"}; // Fake config needed for watchdog tracking
|
||||||
static bool threadStarted = false;
|
static bool threadStarted = false;
|
||||||
|
static bool tracking_useGPS = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns most recent track point witch is complete.
|
* Returns most recent track point witch is complete.
|
||||||
|
@ -27,73 +28,48 @@ trackPoint_t* getLastTrackPoint(void)
|
||||||
return lastTrackPoint;
|
return lastTrackPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
trackPoint_t* getLogBuffer(uint16_t id)
|
||||||
* Returns next free log entry address in memory. Returns 0 if all cells are
|
|
||||||
* filled with data
|
|
||||||
*/
|
|
||||||
static uint32_t getNextFreeLogAddress(void)
|
|
||||||
{
|
{
|
||||||
// Search in flash sector 10
|
if(sizeof(trackPoint_t)*id < LOG_SECTOR_SIZE-sizeof(trackPoint_t))
|
||||||
for(uint32_t address = LOG_FLASH_ADDR1; address < LOG_FLASH_ADDR1+LOG_SECTOR_SIZE; address += sizeof(trackPoint_t))
|
|
||||||
{
|
{
|
||||||
trackPoint_t pt;
|
return (trackPoint_t*)(LOG_FLASH_ADDR1 + id * sizeof(trackPoint_t));
|
||||||
flashRead(address, (char*)&pt, sizeof(trackPoint_t));
|
} else if((id-(LOG_SECTOR_SIZE/sizeof(trackPoint_t)))*sizeof(trackPoint_t) < LOG_SECTOR_SIZE-sizeof(trackPoint_t)) {
|
||||||
if(pt.id == 0xFFFFFFFF)
|
return (trackPoint_t*)(LOG_FLASH_ADDR2 + (id-(LOG_SECTOR_SIZE/sizeof(trackPoint_t))) * sizeof(trackPoint_t));
|
||||||
return address;
|
} else { // Outside of memory address allocation
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Search in flash sector 11
|
|
||||||
for(uint32_t address = LOG_FLASH_ADDR2; address < LOG_FLASH_ADDR2+LOG_SECTOR_SIZE; address += sizeof(trackPoint_t))
|
|
||||||
{
|
|
||||||
trackPoint_t pt;
|
|
||||||
flashRead(address, (char*)&pt, sizeof(trackPoint_t));
|
|
||||||
if(pt.id == 0xFFFFFFFF)
|
|
||||||
return address;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns next free log entry address in memory. Returns 0 if all cells are
|
* Returns next free log entry address in memory. Returns 0 if all cells are
|
||||||
* filled with data
|
* filled with data
|
||||||
*/
|
*/
|
||||||
static bool getLastLog(trackPoint_t* last)
|
static trackPoint_t* getNextFreeLogAddress(void)
|
||||||
{
|
{
|
||||||
TRACE_INFO("TRAC > Read last track point from flash memory");
|
trackPoint_t* tp;
|
||||||
|
for(uint16_t i=0; (tp = getLogBuffer(i)) != NULL; i++)
|
||||||
|
if(tp->id == 0xFFFFFFFF)
|
||||||
|
return tp;
|
||||||
|
|
||||||
uint64_t last_time = 0;
|
return NULL;
|
||||||
uint32_t last_address = 0;
|
}
|
||||||
|
|
||||||
// Search in flash sector 10
|
/**
|
||||||
for(uint32_t address = LOG_FLASH_ADDR1; address < LOG_FLASH_ADDR1+LOG_SECTOR_SIZE; address += sizeof(trackPoint_t))
|
* Returns next free log entry address in memory. Returns 0 if all cells are
|
||||||
{
|
* filled with data
|
||||||
trackPoint_t pt;
|
*/
|
||||||
flashRead(address, (char*)&pt, sizeof(trackPoint_t));
|
static trackPoint_t* getLastLog(void)
|
||||||
if(pt.id != 0xFFFFFFFF && date2UnixTimestamp(pt.time) >= last_time) {
|
{
|
||||||
last_address = address;
|
trackPoint_t* last = NULL;
|
||||||
last_time = date2UnixTimestamp(pt.time);
|
trackPoint_t* tp;
|
||||||
}
|
for(uint16_t i=0; (tp = getLogBuffer(i)) != NULL; i++) {
|
||||||
}
|
if(tp->id == 0xFFFFFFFF)
|
||||||
|
return last; // Found last entry
|
||||||
// Search in flash sector 11
|
last = tp;
|
||||||
for(uint32_t address = LOG_FLASH_ADDR2; address < LOG_FLASH_ADDR2+LOG_SECTOR_SIZE; address += sizeof(trackPoint_t))
|
|
||||||
{
|
|
||||||
trackPoint_t pt;
|
|
||||||
flashRead(address, (char*)&pt, sizeof(trackPoint_t));
|
|
||||||
if(pt.id != 0xFFFFFFFF && date2UnixTimestamp(pt.time) >= last_time) {
|
|
||||||
last_address = address;
|
|
||||||
last_time = date2UnixTimestamp(pt.time);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(last_address) {
|
|
||||||
flashRead(last_address, (char*)last, sizeof(trackPoint_t));
|
|
||||||
TRACE_INFO("TRAC > Found track point in flash memory ID=%d", last->id);
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
TRACE_INFO("TRAC > No track point found in flash memory");
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
if(last->id != 0xFFFFFFFF)
|
||||||
|
return last; // All memory entries are use, so the very last one must be the most recent one.
|
||||||
|
return NULL; // There is no log entry in memory
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -119,13 +95,13 @@ static void eraseOldestLogData(void)
|
||||||
static void writeLogTrackPoint(trackPoint_t* tp)
|
static void writeLogTrackPoint(trackPoint_t* tp)
|
||||||
{
|
{
|
||||||
// Get address to write on
|
// Get address to write on
|
||||||
uint32_t address = getNextFreeLogAddress();
|
trackPoint_t* address = getNextFreeLogAddress();
|
||||||
if(!address) // Memory completly used, erase oldest data
|
if(address == NULL) // Memory completly used, erase oldest data
|
||||||
{
|
{
|
||||||
eraseOldestLogData();
|
eraseOldestLogData();
|
||||||
address = getNextFreeLogAddress();
|
address = getNextFreeLogAddress();
|
||||||
}
|
}
|
||||||
if(!address) // Something went wront at erasing the memory
|
if(address == NULL) // Something went wront at erasing the memory
|
||||||
{
|
{
|
||||||
TRACE_ERROR("TRAC > Erasing flash failed");
|
TRACE_ERROR("TRAC > Erasing flash failed");
|
||||||
return;
|
return;
|
||||||
|
@ -133,12 +109,12 @@ static void writeLogTrackPoint(trackPoint_t* tp)
|
||||||
|
|
||||||
// Write data into flash
|
// Write data into flash
|
||||||
TRACE_INFO("TRAC > Flash write (ADDR=%08x)", address);
|
TRACE_INFO("TRAC > Flash write (ADDR=%08x)", address);
|
||||||
flashSectorBegin(flashSectorAt(address));
|
flashSectorBegin(flashSectorAt((uint32_t)address));
|
||||||
flashWrite(address, (char*)tp, sizeof(trackPoint_t));
|
flashWrite((uint32_t)address, (char*)tp, sizeof(trackPoint_t));
|
||||||
flashSectorEnd(flashSectorAt(address));
|
flashSectorEnd(flashSectorAt((uint32_t)address));
|
||||||
|
|
||||||
// Verify
|
// Verify
|
||||||
if(flashCompare(address, (char*)tp, sizeof(trackPoint_t)))
|
if(flashCompare((uint32_t)address, (char*)tp, sizeof(trackPoint_t)))
|
||||||
TRACE_INFO("TRAC > Flash write OK")
|
TRACE_INFO("TRAC > Flash write OK")
|
||||||
else
|
else
|
||||||
TRACE_ERROR("TRAC > Flash write failed");
|
TRACE_ERROR("TRAC > Flash write failed");
|
||||||
|
@ -172,20 +148,25 @@ THD_FUNCTION(trackingThread, arg) {
|
||||||
lastTrackPoint->time.minute = rtc.minute;
|
lastTrackPoint->time.minute = rtc.minute;
|
||||||
lastTrackPoint->time.second = rtc.second;
|
lastTrackPoint->time.second = rtc.second;
|
||||||
|
|
||||||
// Get last GPS fix from memory
|
// Get last tracking point from memory
|
||||||
trackPoint_t lastLogPoint;
|
TRACE_INFO("TRAC > Read last track point from flash memory");
|
||||||
if(getLastLog(&lastLogPoint)) { // If there has been stored a trackpoint, then get the last know GPS fix
|
trackPoint_t* lastLogPoint = getLastLog();
|
||||||
lastTrackPoint->gps_lat = lastLogPoint.gps_lat;
|
|
||||||
lastTrackPoint->gps_lon = lastLogPoint.gps_lon;
|
if(lastLogPoint != NULL) { // If there has been stored a trackpoint, then get the last know GPS fix
|
||||||
lastTrackPoint->gps_alt = lastLogPoint.gps_alt;
|
TRACE_INFO("TRAC > Found track point in flash memory ID=%d", lastLogPoint->id);
|
||||||
|
lastTrackPoint->gps_lat = lastLogPoint->gps_lat;
|
||||||
|
lastTrackPoint->gps_lon = lastLogPoint->gps_lon;
|
||||||
|
lastTrackPoint->gps_alt = lastLogPoint->gps_alt;
|
||||||
|
} else {
|
||||||
|
TRACE_INFO("TRAC > No track point found in flash memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
lastTrackPoint->gps_lock = GPS_LOSS; // But tell the user that there is no current lock nor any GPS sats locked
|
lastTrackPoint->gps_lock = GPS_LOG; // Tell other threads that it has been taken from log
|
||||||
lastTrackPoint->gps_sats = 0;
|
lastTrackPoint->gps_sats = 0;
|
||||||
lastTrackPoint->gps_ttff = 0;
|
lastTrackPoint->gps_ttff = 0;
|
||||||
|
|
||||||
// Debug last stored GPS position
|
// Debug last stored GPS position
|
||||||
if(lastLogPoint.id != 0xFFFFFFFF) {
|
if(lastLogPoint != NULL) {
|
||||||
TRACE_INFO(
|
TRACE_INFO(
|
||||||
"TRAC > Last GPS position (from memory)\r\n"
|
"TRAC > Last GPS position (from memory)\r\n"
|
||||||
"%s Latitude: %d.%07ddeg\r\n"
|
"%s Latitude: %d.%07ddeg\r\n"
|
||||||
|
@ -220,6 +201,14 @@ THD_FUNCTION(trackingThread, arg) {
|
||||||
lastTrackPoint->air_temp = 0;
|
lastTrackPoint->air_temp = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get last image ID. This is important because Habhub does mix up different
|
||||||
|
* images with the same it. So it is good to use a new image ID when the
|
||||||
|
* tracker has been reset.
|
||||||
|
*/
|
||||||
|
if(lastLogPoint != NULL)
|
||||||
|
gimage_id = lastLogPoint->id_image;
|
||||||
|
|
||||||
systime_t time = chVTGetSystemTimeX();
|
systime_t time = chVTGetSystemTimeX();
|
||||||
while(true)
|
while(true)
|
||||||
{
|
{
|
||||||
|
@ -232,9 +221,9 @@ THD_FUNCTION(trackingThread, arg) {
|
||||||
// Search for GPS satellites
|
// Search for GPS satellites
|
||||||
gpsFix_t gpsFix = {{0,0,0,0,0,0,0},0,0,0,0,0};
|
gpsFix_t gpsFix = {{0,0,0,0,0,0,0},0,0,0,0,0};
|
||||||
|
|
||||||
// Switch on GPS is enough power is available
|
// Switch on GPS is enough power is available and GPS is needed by any position thread
|
||||||
uint16_t batt = getBatteryVoltageMV();
|
uint16_t batt = getBatteryVoltageMV();
|
||||||
if(batt >= gps_on_vbat)
|
if(batt >= gps_on_vbat && tracking_useGPS)
|
||||||
{
|
{
|
||||||
// Switch on GPS
|
// Switch on GPS
|
||||||
GPS_Init();
|
GPS_Init();
|
||||||
|
@ -304,8 +293,11 @@ THD_FUNCTION(trackingThread, arg) {
|
||||||
tp->gps_lon = ltp->gps_lon;
|
tp->gps_lon = ltp->gps_lon;
|
||||||
tp->gps_alt = ltp->gps_alt;
|
tp->gps_alt = ltp->gps_alt;
|
||||||
|
|
||||||
// Mark GPS loss (or low batt)
|
// Mark GPS loss (or low batt, GPS switch off)
|
||||||
tp->gps_lock = batt < gps_off_vbat ? GPS_LOWBATT : GPS_LOSS;
|
if(tracking_useGPS)
|
||||||
|
tp->gps_lock = batt < gps_off_vbat ? GPS_LOWBATT : GPS_LOSS;
|
||||||
|
else
|
||||||
|
tp->gps_lock = GPS_OFF;
|
||||||
tp->gps_sats = 0;
|
tp->gps_sats = 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -335,23 +327,26 @@ THD_FUNCTION(trackingThread, arg) {
|
||||||
tp->air_temp = 0;
|
tp->air_temp = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set last time ID
|
||||||
|
tp->id_image = gimage_id;
|
||||||
|
|
||||||
// Trace data
|
// Trace data
|
||||||
TRACE_INFO( "TRAC > New tracking point available (ID=%d)\r\n"
|
TRACE_INFO( "TRAC > New tracking point available (ID=%d)\r\n"
|
||||||
"%s Time %04d-%02d-%02d %02d:%02d:%02d\r\n"
|
"%s Time %04d-%02d-%02d %02d:%02d:%02d\r\n"
|
||||||
"%s Pos %d.%05d %d.%05d Alt %dm\r\n"
|
"%s Pos %d.%05d %d.%05d Alt %dm\r\n"
|
||||||
"%s Sats %d TTFF %dsec\r\n"
|
"%s Sats %d TTFF %dsec\r\n"
|
||||||
"%s ADC Vbat=%d.%03dV Vsol=%d.%03dV VUSB=%d.%03dV Pbat=%dmW Rbat=%dmOhm\r\n"
|
"%s ADC Vbat=%d.%03dV Vsol=%d.%03dV VUSB=%d.%03dV Pbat=%dmW Rbat=%dmOhm\r\n"
|
||||||
"%s AIR p=%6d.%01dPa T=%2d.%02ddegC phi=%2d.%01d%%",
|
"%s AIR p=%6d.%01dPa T=%2d.%02ddegC phi=%2d.%01d%% ImageID=%d",
|
||||||
tp->id,
|
tp->id,
|
||||||
TRACE_TAB, tp->time.year, tp->time.month, tp->time.day, tp->time.hour, tp->time.minute, tp->time.day,
|
TRACE_TAB, tp->time.year, tp->time.month, tp->time.day, tp->time.hour, tp->time.minute, tp->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_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,
|
TRACE_TAB, tp->gps_sats, tp->gps_ttff,
|
||||||
TRACE_TAB, tp->adc_vbat/1000, (tp->adc_vbat%1000), tp->adc_vsol/1000, (tp->adc_vsol%1000), tp->adc_vusb/1000, (tp->adc_vusb%1000), tp->adc_pbat, tp->adc_rbat,
|
TRACE_TAB, tp->adc_vbat/1000, (tp->adc_vbat%1000), tp->adc_vsol/1000, (tp->adc_vsol%1000), tp->adc_vusb/1000, (tp->adc_vusb%1000), tp->adc_pbat, tp->adc_rbat,
|
||||||
TRACE_TAB, tp->air_press/10, tp->air_press%10, tp->air_temp/100, tp->air_temp%100, tp->air_hum/10, tp->air_hum%10
|
TRACE_TAB, tp->air_press/10, tp->air_press%10, tp->air_temp/100, tp->air_temp%100, tp->air_hum/10, tp->air_hum%10, tp->id_image
|
||||||
);
|
);
|
||||||
|
|
||||||
// Append logging (timeout)
|
// Append logging (timeout)
|
||||||
if(nextLogEntryTimer <= chVTGetSystemTimeX() && isGPSLocked(&gpsFix))
|
if(nextLogEntryTimer <= chVTGetSystemTimeX())
|
||||||
{
|
{
|
||||||
writeLogTrackPoint(tp);
|
writeLogTrackPoint(tp);
|
||||||
nextLogEntryTimer += log_cycle_time;
|
nextLogEntryTimer += log_cycle_time;
|
||||||
|
@ -365,8 +360,11 @@ THD_FUNCTION(trackingThread, arg) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_tracking_manager(void)
|
void init_tracking_manager(bool useGPS)
|
||||||
{
|
{
|
||||||
|
if(useGPS)
|
||||||
|
tracking_useGPS = true;
|
||||||
|
|
||||||
if(!threadStarted)
|
if(!threadStarted)
|
||||||
{
|
{
|
||||||
threadStarted = true;
|
threadStarted = true;
|
||||||
|
|
|
@ -5,16 +5,20 @@
|
||||||
#include "hal.h"
|
#include "hal.h"
|
||||||
#include "ptime.h"
|
#include "ptime.h"
|
||||||
|
|
||||||
#define GPS_LOCKED 0 /* GPS is locked and could aquire a fix */
|
typedef enum {
|
||||||
#define GPS_LOSS 1 /* GPS was switched on all time but it couln't aquire a fix */
|
GPS_LOCKED, // GPS is locked and could aquire a fix
|
||||||
#define GPS_LOWBATT 2 /* GPS was switched on but had to be switched off prematurely while the battery is almost empty (or is too cold) */
|
GPS_LOSS, // GPS was switched on all time but it couln't aquire a fix
|
||||||
|
GPS_LOWBATT, // GPS was switched on but had to be switched off prematurely while the battery is almost empty (or is too cold)
|
||||||
|
GPS_LOG, // The tracker has been just switched on and the position has been taken from the log
|
||||||
|
GPS_OFF, // There is no active position thread so the GPS was never switched on (in oder to save power)
|
||||||
|
} gpsLock_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t id; // Serial ID
|
uint32_t id; // Serial ID
|
||||||
ptime_t time; // GPS time
|
ptime_t time; // GPS time
|
||||||
|
|
||||||
// GPS
|
// GPS
|
||||||
uint8_t gps_lock; // 0: locked, 1: GPS loss, 2: low power (switched off)
|
gpsLock_t gps_lock; // 0: locked, 1: GPS loss, 2: low power (switched off), 3: taken from log, 4: GPS switch off permanently
|
||||||
int32_t gps_lat; // Latitude in °*10^7
|
int32_t gps_lat; // Latitude in °*10^7
|
||||||
int32_t gps_lon; // Longitude in °*10^7
|
int32_t gps_lon; // Longitude in °*10^7
|
||||||
int32_t gps_alt; // Altitude in meter
|
int32_t gps_alt; // Altitude in meter
|
||||||
|
@ -32,12 +36,15 @@ typedef struct {
|
||||||
uint32_t air_press; // Airpressure in Pa*10 (in 0.1Pa)
|
uint32_t air_press; // Airpressure in Pa*10 (in 0.1Pa)
|
||||||
uint16_t air_hum; // Rel. humidity in %*10 (in 0.1%)
|
uint16_t air_hum; // Rel. humidity in %*10 (in 0.1%)
|
||||||
int16_t air_temp; // Temperature in degC*100 (in 0.01°C)
|
int16_t air_temp; // Temperature in degC*100 (in 0.01°C)
|
||||||
|
|
||||||
|
int8_t id_image; // Last image ID (this is important because it will set the image counter at reset so the last image wont get overwritten with the same image ID)
|
||||||
} trackPoint_t;
|
} trackPoint_t;
|
||||||
|
|
||||||
void waitForNewTrackPoint(void);
|
void waitForNewTrackPoint(void);
|
||||||
trackPoint_t* getLastTrackPoint(void);
|
trackPoint_t* getLastTrackPoint(void);
|
||||||
void getNextLogTrackPoint(trackPoint_t* log);
|
void getNextLogTrackPoint(trackPoint_t* log);
|
||||||
void init_tracking_manager(void);
|
void init_tracking_manager(bool useGPS);
|
||||||
|
trackPoint_t* getLogBuffer(uint16_t id);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Ładowanie…
Reference in New Issue