diff --git a/decoder/command.py b/decoder/command.py new file mode 100644 index 0000000..4a19df7 --- /dev/null +++ b/decoder/command.py @@ -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() diff --git a/decoder/decoder2.py b/decoder/decoder2.py index 598ffc4..e02cf64 100644 --- a/decoder/decoder2.py +++ b/decoder/decoder2.py @@ -40,8 +40,15 @@ while True: print line.strip() continue + i += 1 + + if int(size) == 0: + ser.write('picture\r\n') + continue + imgbuf = ser.read(int(size)) + for event in pygame.event.get(): if event.type == QUIT: exit(0) @@ -61,6 +68,11 @@ while True: screen.blit(textsurface,(0,0)) pygame.display.flip() pygame.display.update(displaygroup.draw(screen)) + + f = open('data/data'+str(i)+'.jpg','wb') + f.write(imgbuf) + f.close() + except Exception as e: print str(e) textsurface = myfont.render('Error %s' % (e), False, (255, 100, 100)) @@ -69,7 +81,6 @@ while True: pygame.display.update(displaygroup.draw(screen)) ser.write('picture\r\n') - i += 1 diff --git a/decoder/empty.py b/decoder/empty.py new file mode 100644 index 0000000..3cdc906 --- /dev/null +++ b/decoder/empty.py @@ -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) diff --git a/tracker/software/config.c b/tracker/software/config.c index e93e907..069f502 100644 --- a/tracker/software/config.c +++ b/tracker/software/config.c @@ -463,7 +463,7 @@ void start_user_modules(void) config[4].ssdv_conf.ram_size = sizeof(ssdv_buffer); // Buffer size config[4].ssdv_conf.res = RES_VGA; // Resolution VGA config[4].ssdv_conf.quality = 4; // Image quality - //start_image_thread(&config[4]); + start_image_thread(&config[4]); // Module IMAGE, SSDV 2m 2FSK config[5].power = 127; // Transmission Power diff --git a/tracker/software/debug.c b/tracker/software/debug.c index 95edd1d..04f8727 100644 --- a/tracker/software/debug.c +++ b/tracker/software/debug.c @@ -5,6 +5,7 @@ #include "config.h" #include "image.h" #include "tracking.h" +#include "pi2c.h" 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; -void debugOnUSB_Off(BaseSequentialStream *chp, int argc, char *argv[]) +void debugOnUSB(BaseSequentialStream *chp, int argc, char *argv[]) { - (void)chp; - (void)argc; - (void)argv; - debug_on_usb = false; + if(argc < 1) + { + chprintf(chp, "Argument missing!\r\n"); + 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[]) -{ - (void)chp; - (void)argc; - (void)argv; - debug_on_usb = true; -} - -static uint8_t usb_buffer[96*1024] __attribute__((aligned(32))); // USB image buffer +static uint8_t usb_buffer[64*1024] __attribute__((aligned(32))); // USB image buffer void printPicture(BaseSequentialStream *chp, int argc, char *argv[]) { (void)argc; @@ -67,8 +64,8 @@ void printPicture(BaseSequentialStream *chp, int argc, char *argv[]) } if(!start_detected) { - TRACE_USB("DATA > image,jpeg,0"); - TRACE_USB("DATA > error,no SOI flag found"); + TRACE_USB("DATA > image/jpeg,0"); + TRACE_USB("DATA > text/trace,no SOI flag 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)) - { - return (trackPoint_t*)(LOG_FLASH_ADDR1 + id * sizeof(trackPoint_t)); - } 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)chp; + (void)argc; + I2C_write8_16bitreg(0x3C, atoi(argv[0]), atoi(argv[1])); } void readLog(BaseSequentialStream *chp, int argc, char *argv[]) @@ -96,17 +88,19 @@ void readLog(BaseSequentialStream *chp, int argc, char *argv[]) (void)argc; (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; for(uint16_t i=0; (tp = getLogBuffer(i)) != NULL; i++) if(tp->id != 0xFFFFFFFF) { 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->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->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 1: Id of config!\r\n"); + return; } 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); 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 { - 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); diff --git a/tracker/software/debug.h b/tracker/software/debug.h index 5f5a747..60a6123 100644 --- a/tracker/software/debug.h +++ b/tracker/software/debug.h @@ -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); \ } -void debugOnUSB_Off(BaseSequentialStream *chp, int argc, char *argv[]); -void debugOnUSB_On(BaseSequentialStream *chp, int argc, char *argv[]); +void debugOnUSB(BaseSequentialStream *chp, int argc, char *argv[]); void printConfig(BaseSequentialStream *chp, int argc, char *argv[]); void printPicture(BaseSequentialStream *chp, int argc, char *argv[]); void readLog(BaseSequentialStream *chp, int argc, char *argv[]); +void command2Camera(BaseSequentialStream *chp, int argc, char *argv[]); #endif diff --git a/tracker/software/drivers/ov5640.c b/tracker/software/drivers/ov5640.c index 4642140..b7f9ee7 100644 --- a/tracker/software/drivers/ov5640.c +++ b/tracker/software/drivers/ov5640.c @@ -27,11 +27,11 @@ static const struct regval_list OV5640YUV_Sensor_Dvp_Init[] = { 0x4051, 0x8f }, { 0x3008, 0x42 }, - { 0x3103, 0x03 }, + { 0x3103, 0x03 }, { 0x3017, 0x7f }, { 0x3018, 0xff }, { 0x302c, 0x02 }, - { 0x3108, 0x21 }, + { 0x3108, 0x21 }, // PCLK root divider [5:4] { 0x3630, 0x2e },//2e { 0x3632, 0xe2 }, { 0x3633, 0x23 },//23 @@ -92,12 +92,12 @@ static const struct regval_list OV5640YUV_Sensor_Dvp_Init[] = { 0x3814, 0x31 }, { 0x3815, 0x31 }, - { 0x3034, 0x1a }, - { 0x3035, 0x11 }, //15fps - { 0x3036, 0x46 }, - { 0x3037, 0x14 }, - { 0x3038, 0x00 }, - { 0x3039, 0x00 }, + { 0x3034, 0x1a }, // PLL charge pump control [7:4] + { 0x3035, 0x11 }, // System clock divider [7:4] + { 0x3036, 0x46 }, // PLL multiplier [7:0] + { 0x3037, 0x14 }, // PLL root divider [4], PLL pre-divider [3:0] + { 0x3038, 0x00 }, // System control registers (changing not recommended) + { 0x3039, 0x00 }, // PLL bypass [7] { 0x380c, 0x07 }, { 0x380d, 0x68 }, @@ -802,7 +802,6 @@ void set6MHz(void) */ static bool analyze_image(uint8_t *image, uint32_t image_len) { - return true; ssdv_t ssdv; uint8_t pkt[SSDV_PKT_SIZE]; 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) { - uint8_t cntr = 5; + uint8_t cntr = 10; bool status; bool jpegValid; uint32_t size_sampled; diff --git a/tracker/software/main.c b/tracker/software/main.c index f7b2ac0..70f8e95 100644 --- a/tracker/software/main.c +++ b/tracker/software/main.c @@ -8,16 +8,16 @@ #include "shell.h" static const ShellCommand commands[] = { - {"dbgon", debugOnUSB_On}, - {"dbgoff", debugOnUSB_Off}, + {"debug", debugOnUSB}, {"picture", printPicture}, {"log", readLog}, -// {"printconfig", printConfig}, FIXME: This feature is faulty at the moment + {"config", printConfig}, + {"command", command2Camera}, {NULL, NULL} }; static const ShellConfig shell_cfg = { - (BaseSequentialStream *)&SDU1, + (BaseSequentialStream*)&SDU1, commands }; @@ -30,7 +30,7 @@ int main(void) { // Voltage switching (1.8V <=> 3.0V) #if ACTIVATE_USB || ACTIVATE_3V - boost_voltage(true); // Ramp up voltage to 3V + boost_voltage(true); // Ramp up voltage to 3V chThdSleepMilliseconds(100); #endif @@ -54,9 +54,8 @@ int main(void) { start_essential_threads(); // Startup required modules (tracking managemer, watchdog) start_user_modules(); // Startup optional modules (eg. POSITION, LOG, ...) - // Print time every 10 sec 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); chThdWait(shelltp); } diff --git a/tracker/software/protocols/aprs/aprs.c b/tracker/software/protocols/aprs/aprs.c index ec00f58..be59c74 100644 --- a/tracker/software/protocols/aprs/aprs.c +++ b/tracker/software/protocols/aprs/aprs.c @@ -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); 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 { loss_of_gps_counter = 0; } diff --git a/tracker/software/radio.c b/tracker/software/radio.c index c625d91..b2be683 100644 --- a/tracker/software/radio.c +++ b/tracker/software/radio.c @@ -305,45 +305,48 @@ void shutdownRadio(void) uint32_t getAPRSRegionFrequency(void) { 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 if(isPointInAmerica(point->gps_lat, point->gps_lon)) - freq = APRS_FREQ_AMERICA; + return APRS_FREQ_AMERICA; // China 144.640 MHz if(isPointInChina(point->gps_lat, point->gps_lon)) - freq = APRS_FREQ_CHINA; + return APRS_FREQ_CHINA; // Japan 144.660 MHz if(isPointInJapan(point->gps_lat, point->gps_lon)) - freq = APRS_FREQ_JAPAN; + return APRS_FREQ_JAPAN; // Southkorea 144.620 MHz if(isPointInSouthkorea(point->gps_lat, point->gps_lon)) - freq = APRS_FREQ_SOUTHKOREA; + return APRS_FREQ_SOUTHKOREA; // Southkorea 144.620 MHz if(isPointInSoutheastAsia(point->gps_lat, point->gps_lon)) - freq = APRS_FREQ_SOUTHEASTASIA; + return APRS_FREQ_SOUTHEASTASIA; // Australia 145.175 MHz if(isPointInAustralia(point->gps_lat, point->gps_lon)) - freq = APRS_FREQ_AUSTRALIA; + return APRS_FREQ_AUSTRALIA; // Australia 144.575 MHz if(isPointInNewZealand(point->gps_lat, point->gps_lon)) - freq = APRS_FREQ_NEWZEALAND; + return APRS_FREQ_NEWZEALAND; // Argentina/Paraguay/Uruguay 144.930 MHz if(isPointInArgentina(point->gps_lat, point->gps_lon)) - freq = APRS_FREQ_ARGENTINA; + return APRS_FREQ_ARGENTINA; // Brazil 145.575 MHz 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) { case FREQ_APRS_REGION:; // Dynamic frequency (determined by GPS position) 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 freq; diff --git a/tracker/software/threads/image.c b/tracker/software/threads/image.c index d8d59aa..4e863ef 100644 --- a/tracker/software/threads/image.c +++ b/tracker/software/threads/image.c @@ -273,7 +273,7 @@ const uint8_t noCameraFound[4071] = { 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; bool camera_mtx_init = false; diff --git a/tracker/software/threads/image.h b/tracker/software/threads/image.h index a8a2560..3d1d672 100644 --- a/tracker/software/threads/image.h +++ b/tracker/software/threads/image.h @@ -7,6 +7,7 @@ void start_image_thread(module_conf_t *conf); bool takePicture(ssdv_conf_t *conf, bool enableJpegValidation); extern mutex_t camera_mtx; +extern uint8_t gimage_id; #endif diff --git a/tracker/software/threads/position.c b/tracker/software/threads/position.c index a4b516c..7ff285d 100644 --- a/tracker/software/threads/position.c +++ b/tracker/software/threads/position.c @@ -213,7 +213,7 @@ void start_position_thread(module_conf_t *conf) if(conf->init_delay) chThdSleepMilliseconds(conf->init_delay); // Start tracking manager (if not running yet) - init_tracking_manager(); + init_tracking_manager(true); // Start position thread TRACE_INFO("POS > Startup position thread"); diff --git a/tracker/software/threads/threads.c b/tracker/software/threads/threads.c index cb80d5a..a1de7a6 100644 --- a/tracker/software/threads/threads.c +++ b/tracker/software/threads/threads.c @@ -1,11 +1,9 @@ #include "ch.h" #include "hal.h" -#include "debug.h" #include "threads.h" #include "tracking.h" #include "watchdog.h" -#include "image.h" #include "pi2c.h" #include "pac1720.h" @@ -15,9 +13,8 @@ void start_essential_threads(void) { // 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 pac1720_init(); // Initialize current measurement diff --git a/tracker/software/threads/tracking.c b/tracker/software/threads/tracking.c index 766fb9f..d0e7ce1 100644 --- a/tracker/software/threads/tracking.c +++ b/tracker/software/threads/tracking.c @@ -3,7 +3,6 @@ #include "tracking.h" #include "debug.h" -#include "ptime.h" #include "config.h" #include "ublox.h" #include "bme280.h" @@ -12,12 +11,14 @@ #include "radio.h" #include "flash.h" #include "watchdog.h" +#include "image.h" static trackPoint_t trackPoints[2]; static trackPoint_t* lastTrackPoint; static systime_t nextLogEntryTimer; static module_conf_t trac_conf = {.name = "TRAC"}; // Fake config needed for watchdog tracking static bool threadStarted = false; +static bool tracking_useGPS = false; /** * Returns most recent track point witch is complete. @@ -27,73 +28,48 @@ trackPoint_t* getLastTrackPoint(void) return lastTrackPoint; } -/** - * Returns next free log entry address in memory. Returns 0 if all cells are - * filled with data - */ -static uint32_t getNextFreeLogAddress(void) +trackPoint_t* getLogBuffer(uint16_t id) { - // Search in flash sector 10 - for(uint32_t address = LOG_FLASH_ADDR1; address < LOG_FLASH_ADDR1+LOG_SECTOR_SIZE; address += sizeof(trackPoint_t)) + if(sizeof(trackPoint_t)*id < LOG_SECTOR_SIZE-sizeof(trackPoint_t)) { - trackPoint_t pt; - flashRead(address, (char*)&pt, sizeof(trackPoint_t)); - if(pt.id == 0xFFFFFFFF) - return address; + return (trackPoint_t*)(LOG_FLASH_ADDR1 + id * sizeof(trackPoint_t)); + } 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; } - - // 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 * 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; - uint32_t last_address = 0; + return NULL; +} - // Search in flash sector 10 - for(uint32_t address = LOG_FLASH_ADDR1; address < LOG_FLASH_ADDR1+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); - } - } - - // 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 && 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; +/** + * Returns next free log entry address in memory. Returns 0 if all cells are + * filled with data + */ +static trackPoint_t* getLastLog(void) +{ + trackPoint_t* last = NULL; + trackPoint_t* tp; + for(uint16_t i=0; (tp = getLogBuffer(i)) != NULL; i++) { + if(tp->id == 0xFFFFFFFF) + return last; // Found last entry + last = tp; } + 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) { // Get address to write on - uint32_t address = getNextFreeLogAddress(); - if(!address) // Memory completly used, erase oldest data + trackPoint_t* address = getNextFreeLogAddress(); + if(address == NULL) // Memory completly used, erase oldest data { eraseOldestLogData(); 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"); return; @@ -133,12 +109,12 @@ static void writeLogTrackPoint(trackPoint_t* tp) // Write data into flash TRACE_INFO("TRAC > Flash write (ADDR=%08x)", address); - flashSectorBegin(flashSectorAt(address)); - flashWrite(address, (char*)tp, sizeof(trackPoint_t)); - flashSectorEnd(flashSectorAt(address)); + flashSectorBegin(flashSectorAt((uint32_t)address)); + flashWrite((uint32_t)address, (char*)tp, sizeof(trackPoint_t)); + flashSectorEnd(flashSectorAt((uint32_t)address)); // 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") else TRACE_ERROR("TRAC > Flash write failed"); @@ -172,20 +148,25 @@ THD_FUNCTION(trackingThread, arg) { lastTrackPoint->time.minute = rtc.minute; lastTrackPoint->time.second = rtc.second; - // Get last GPS fix from memory - trackPoint_t lastLogPoint; - if(getLastLog(&lastLogPoint)) { // If there has been stored a trackpoint, then get the last know GPS fix - lastTrackPoint->gps_lat = lastLogPoint.gps_lat; - lastTrackPoint->gps_lon = lastLogPoint.gps_lon; - lastTrackPoint->gps_alt = lastLogPoint.gps_alt; + // Get last tracking point from memory + TRACE_INFO("TRAC > Read last track point from flash memory"); + trackPoint_t* lastLogPoint = getLastLog(); + + if(lastLogPoint != NULL) { // If there has been stored a trackpoint, then get the last know GPS fix + 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_ttff = 0; // Debug last stored GPS position - if(lastLogPoint.id != 0xFFFFFFFF) { + if(lastLogPoint != NULL) { TRACE_INFO( "TRAC > Last GPS position (from memory)\r\n" "%s Latitude: %d.%07ddeg\r\n" @@ -220,6 +201,14 @@ THD_FUNCTION(trackingThread, arg) { 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(); while(true) { @@ -232,9 +221,9 @@ THD_FUNCTION(trackingThread, arg) { // Search for GPS satellites 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(); - if(batt >= gps_on_vbat) + if(batt >= gps_on_vbat && tracking_useGPS) { // Switch on GPS GPS_Init(); @@ -304,8 +293,11 @@ THD_FUNCTION(trackingThread, arg) { tp->gps_lon = ltp->gps_lon; tp->gps_alt = ltp->gps_alt; - // Mark GPS loss (or low batt) - tp->gps_lock = batt < gps_off_vbat ? GPS_LOWBATT : GPS_LOSS; + // Mark GPS loss (or low batt, GPS switch off) + if(tracking_useGPS) + tp->gps_lock = batt < gps_off_vbat ? GPS_LOWBATT : GPS_LOSS; + else + tp->gps_lock = GPS_OFF; tp->gps_sats = 0; } @@ -335,23 +327,26 @@ THD_FUNCTION(trackingThread, arg) { tp->air_temp = 0; } + // Set last time ID + tp->id_image = gimage_id; + // Trace data TRACE_INFO( "TRAC > New tracking point available (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" "%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, 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_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->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) - if(nextLogEntryTimer <= chVTGetSystemTimeX() && isGPSLocked(&gpsFix)) + if(nextLogEntryTimer <= chVTGetSystemTimeX()) { writeLogTrackPoint(tp); 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) { threadStarted = true; diff --git a/tracker/software/threads/tracking.h b/tracker/software/threads/tracking.h index c9b6c42..ae2203a 100644 --- a/tracker/software/threads/tracking.h +++ b/tracker/software/threads/tracking.h @@ -5,16 +5,20 @@ #include "hal.h" #include "ptime.h" -#define GPS_LOCKED 0 /* GPS is locked and could aquire a fix */ -#define GPS_LOSS 1 /* GPS was switched on all time but it couln't 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) */ +typedef enum { + GPS_LOCKED, // GPS is locked and could aquire a fix + 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 { uint32_t id; // Serial ID ptime_t time; // GPS time // 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_lon; // Longitude in °*10^7 int32_t gps_alt; // Altitude in meter @@ -32,12 +36,15 @@ typedef struct { uint32_t air_press; // Airpressure in Pa*10 (in 0.1Pa) uint16_t air_hum; // Rel. humidity in %*10 (in 0.1%) 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; void waitForNewTrackPoint(void); trackPoint_t* getLastTrackPoint(void); void getNextLogTrackPoint(trackPoint_t* log); -void init_tracking_manager(void); +void init_tracking_manager(bool useGPS); +trackPoint_t* getLogBuffer(uint16_t id); #endif