/** * Initialize the system controller. In particular: * - Load settings * - Setup the log interval alarm. */ Controller::Controller() { m_sleeping=false; m_powerup=false; //m_log_interval_seconds = 60*30; m_log_interval_seconds = 0; // default set to zero to save power rtc_clear_alarmed(); rtc_enable_alarm(RTC); m_interval_stored = rtc_get_time(RTC); m_counts_stored = 0; m_alarm_log = false; system_controller = this; m_last_switch_state = true; m_never_dim = false; bool sstate = switch_state(); m_last_switch_state = sstate; m_warning_raised = false; m_dim_off = false; m_cpm_cps_switch = false; m_current_units = 2; m_cpm_cps_threshold = 1100.0; m_cps_cpm_threshold = 1000.0; // Get warning cpm from flash m_warncpm = 0; const char *swarncpm = flashstorage_keyval_get("WARNCPM"); if(swarncpm != 0) { int32_t c; sscanf(swarncpm, "%"PRIu32"", &c); m_warncpm = c; } // Get never dim from flash m_warncpm = -1; const char *sneverdim = flashstorage_keyval_get("NEVERDIM"); if(sneverdim != 0) { if(strcmp(sneverdim,"true") == 0) m_never_dim=true; else m_never_dim=false; } else m_never_dim=false; if(m_never_dim) tick_item("Never Dim" ,true); // Get logging interval from flash const char *sloginter = flashstorage_keyval_get("LOGINTERVAL"); if(sloginter != 0) { int32_t c; sscanf(sloginter, "%"PRIu32"", &c); m_log_interval_seconds = c; } else { // m_log_interval_seconds = 30*60; m_log_interval_seconds = 0; // default set to zero to save power } rtc_set_alarm(RTC,rtc_get_time(RTC)+m_log_interval_seconds); }
void Controller::send_svrem() { const char *svrem = flashstorage_keyval_get("SVREM"); if((svrem != 0) && (strcmp(svrem,"REM") == 0)) { char text_rem[50]; char text_rem_tmp[50]; text_rem[0]=0; sprintf(text_rem_tmp,"%8.3f",system_geiger->get_microrems()); sprintf(text_rem ,"%8.8s",text_rem_tmp); if((system_geiger->get_cpm_deadtime_compensated() > MAX_CPM) || (system_geiger->get_microrems() > 99999999)) { sprintf(text_rem,"TOO HIGH"); } m_gui->receive_update("SVREM", text_rem); m_gui->receive_update("SVREMLABEL"," \x80R/h"); } else { char text_sieverts[50]; char text_sieverts_tmp[50]; text_sieverts[0]=0; sprintf(text_sieverts_tmp,"%8.3f",system_geiger->get_microsieverts()); sprintf(text_sieverts,"%8.8s",text_sieverts_tmp); if((system_geiger->get_cpm_deadtime_compensated() > MAX_CPM) || (system_geiger->get_microsieverts() > 99999999)) { sprintf(text_sieverts,"TOO HIGH"); } m_gui->receive_update("SVREM", text_sieverts); m_gui->receive_update("SVREMLABEL"," \x80Sv/h"); } }
/** * Dim the screen if necessary. Called by the Controller. Will dim in * several steps (one dim level at each call) */ void Controller::do_dimming() { if(m_never_dim) return; // only dim if not in brightness changing mode if(!m_dim_off) { // Check for no key presses then dim screen uint32_t release_time = cap_last_press_any(); uint32_t press_time = cap_last_release_any(); uint32_t current_time = realtime_get_unixtime(); uint8_t current_brightness = display_get_brightness(); if(((current_time - press_time) > 10) && ((current_time - release_time) > 10)) { if(current_brightness > 1) display_set_brightness(current_brightness-1); } else { const char *sbright = flashstorage_keyval_get("BRIGHTNESS"); unsigned int user_brightness=15; if(sbright != 0) { sscanf(sbright, "%u", &user_brightness); } if(current_brightness < user_brightness) { display_set_brightness(current_brightness+1); } } } }
void Controller::event_leftbrightness(const char *event,const char *value) { const char *sbright = flashstorage_keyval_get("BRIGHTNESS"); if(sbright != 0) { unsigned int c; sscanf(sbright, "%u", &c); display_set_brightness(c); } m_dim_off=false; }
/** * Outputs device tag */ void cmd_getdevicetag(char *line) { const char *devicetag = flashstorage_keyval_get("DEVICETAG"); JSONNODE *n = json_new(JSON_NODE); if(devicetag != 0) { json_push_back(n, json_new_a("devicetag", devicetag)); } else { json_push_back(n, json_new_a("devicetag", "No device tag set")); } json_char *jc = json_write_formatted(n); serial_write_string(jc); json_free(jc); json_delete(n); }
void Controller::event_brightnessscn(const char *event,const char *value) { const char *sbright = flashstorage_keyval_get("BRIGHTNESS"); unsigned int c=15; if(sbright != 0) { sscanf(sbright, "%u", &c); display_set_brightness(c); } uint8 b; if(c <= 11) b = (c-1)/2; if(c > 11) b = c-6; m_gui->receive_update("BRIGHTNESS",&b); m_gui->redraw(); }
void Controller::event_becqscreen(const char *event,const char *value) { float becq_val = 0; const char *val = flashstorage_keyval_get("BECQEFF"); if(val != NULL) { sscanf(val,"%f",&becq_val); } uint8_t b1 = ((int)becq_val%10000) /1000; uint8_t b2 = ((int)becq_val%1000) /100; uint8_t b3 = ((int)becq_val%100) /10; uint8_t b4 = ((int)becq_val%10); m_gui->receive_update("BECQ1",&b1); m_gui->receive_update("BECQ2",&b2); m_gui->receive_update("BECQ3",&b3); m_gui->receive_update("BECQ4",&b4); m_gui->redraw(); }
/** * Checks position of "Sleep" (standby) switch at the back of the device and * take action if switch position changed. */ void Controller::check_sleep_switch() { #ifndef NEVERSLEEP bool sstate = switch_state(); if(sstate != m_last_switch_state) { m_last_switch_state = sstate; if(sstate == false) { if(m_alarm_log && (!m_sleeping)) { m_sleeping=true; display_powerdown(); } else { m_sleeping=true; power_standby(); } } if(sstate == true) { m_powerup = true; } } #endif if(m_powerup == true) { buzzer_nonblocking_buzz(0.5); display_powerup(); m_gui->set_sleeping(false); m_gui->redraw(); m_sleeping=false; m_powerup =false; const char *devicetag = flashstorage_keyval_get("DEVICETAG"); char revtext[10]; sprintf(revtext,"VERSION: %s ",OS100VERSION); display_splashscreen(devicetag,revtext); delay_us(3000000); display_clear(0); } if(m_sleeping) { // go back to sleep. if((!rtc_alarmed()) && (!m_alarm_log)) { power_standby(); } return; } }
void Controller::event_warnscreen(const char *event,const char *value) { int32_t warn_level = 0; const char *val = flashstorage_keyval_get("WARNCPM"); if(val != NULL) { sscanf(val,"%"PRIi32"",&warn_level); } uint8_t w1 = (warn_level%100000)/10000; uint8_t w2 = (warn_level%10000) /1000; uint8_t w3 = (warn_level%1000) /100; uint8_t w4 = (warn_level%100) /10; uint8_t w5 = (warn_level%10) /1; m_gui->receive_update("WARNCPM1",&w1); m_gui->receive_update("WARNCPM2",&w2); m_gui->receive_update("WARNCPM3",&w3); m_gui->receive_update("WARNCPM4",&w4); m_gui->receive_update("WARNCPM5",&w5); m_gui->redraw(); }
/** * Displays status of log area: records used, total records * and logging interval (in seconds) */ void cmd_logstatus(char *line) { JSONNODE *n = json_new(JSON_NODE); JSONNODE *n2 = json_new(JSON_NODE); json_set_name(n2, "logstatus"); json_push_back(n2, json_new_i("used", flashstorage_log_currentrecords())); json_push_back(n2, json_new_i("total", flashstorage_log_maxrecords())); const char *sloginter = flashstorage_keyval_get("LOGINTERVAL"); uint32_t c = 0; if(sloginter != 0) { sscanf(sloginter, "%"PRIu32"", &c); } else { c = 30 * 60; } json_push_back(n2, json_new_i("interval", c)); json_push_back(n, n2); json_char *jc = json_write_formatted(n); serial_write_string(jc); json_free(jc); json_delete(n); }
void Controller::event_loginterval(const char *event,const char *value) { int32_t log_interval = 0; const char *val = flashstorage_keyval_get("LOGINTERVAL"); if (val != NULL) { sscanf(val,"%"PRIi32"",&log_interval); } else { //log_interval = 30*60; log_interval = 0; // default to save power } log_interval = log_interval/60; // Turn it into minutes uint8_t l1 = (log_interval%1000)/100; uint8_t l2 = (log_interval%100) /10; uint8_t l3 = (log_interval%10) /1; m_gui->receive_update("LOGINTER1",&l1); m_gui->receive_update("LOGINTER2",&l2); m_gui->receive_update("LOGINTER3",&l3); m_gui->redraw(); }
void serial_process_command(char *line) { if(in_displayparams) { serial_displayparams_run(line); in_displayparams = false; } if(in_setdevicetag) { serial_setdevicetag_run(line); in_setdevicetag = false; } if(in_setrtc) { serial_setrtc_run(line); in_setrtc = false; } if(in_setkeyval) { serial_setkeyval_run(line); in_setkeyval = false; } serial_write_string("\r\n"); if(strcmp(line,"HELLO") == 0) { serial_write_string("GREETINGS PROFESSOR FALKEN.\r\n"); } else if(strcmp(line,"LIST GAMES") == 0) { serial_write_string("I'M KIND OF BORED OF GAMES, TURNS OUT THE ONLY WAY TO WIN IS NOT TO PLAY...\r\n"); } else if(strcmp(line,"LOGXFER") == 0) { serial_sendlog(); } else if(strcmp(line,"DISPLAYPARAMS") == 0) { serial_displayparams(); } else if(strcmp(line,"HELP") == 0) { serial_write_string("Available commands: HELP, LOGXFER, DISPLAYTEST, HELLO"); } else if(strcmp(line,"DISPLAYTEST") == 0) { display_test(); } else if(strcmp(line,"LOGTEST") == 0) { char stemp[100]; sprintf(stemp,"Raw log data\r\n"); serial_write_string(stemp); uint8_t *flash_log = flashstorage_log_get(); for(int n=0;n<1024;n++) { sprintf(stemp,"%u ",flash_log[n]); serial_write_string(stemp); if(n%64 == 0) serial_write_string("\r\n"); } serial_write_string("\r\n"); log_data_t data; data.time = 0; data.cpm = 1; data.accel_x_start = 2; data.accel_y_start = 3; data.accel_z_start = 4; data.accel_x_end = 5; data.accel_y_end = 6; data.accel_z_end = 7; data.log_type = UINT_MAX; sprintf(stemp,"Log size: %u\r\n",flashstorage_log_size()); serial_write_string(stemp); sprintf(stemp,"Writing test log entry of size: %u\r\n",sizeof(log_data_t)); serial_write_string(stemp); flashstorage_log_pushback((uint8 *) &data,sizeof(log_data_t)); sprintf(stemp,"Log size: %u\r\n",flashstorage_log_size()); serial_write_string(stemp); } else if(strcmp(line,"VERSION") == 0) { char stemp[50]; sprintf(stemp,"Version: %s\r\n",OS100VERSION); serial_write_string(stemp); } else if(strcmp(line,"GETDEVICETAG") == 0) { const char *devicetag = flashstorage_keyval_get("DEVICETAG"); if(devicetag != 0) { char stemp[100]; sprintf(stemp,"Devicetag: %s\r\n",devicetag); serial_write_string(stemp); } else { serial_write_string("No device tag set"); } } else if(strcmp(line,"SETDEVICETAG") == 0) { serial_setdevicetag(); } else if(strcmp(line,"READPRIVATEKEY") == 0) { // serial_readprivatekey(); // removed for production } else if(strcmp(line,"WRITEPRIVATEKEY") == 0) { // serial_writeprivatekey(); // maybe this should be removed for production? } else if(strcmp(line,"MAGREAD") == 0) { gpio_set_mode (PIN_MAP[41].gpio_device,PIN_MAP[41].gpio_bit, GPIO_OUTPUT_PP); // MAGPOWER gpio_set_mode (PIN_MAP[29].gpio_device,PIN_MAP[29].gpio_bit, GPIO_INPUT_PU); // MAGSENSE // Power up magsense gpio_write_bit(PIN_MAP[41].gpio_device,PIN_MAP[41].gpio_bit,1); // wait... delay_us(1000); // Read magsense int magsense = gpio_read_bit(PIN_MAP[29].gpio_device,PIN_MAP[29].gpio_bit); char magsenses[50]; sprintf(magsenses,"%u\r\n",magsense); serial_write_string(magsenses); } else if(strcmp(line,"WRITEDAC") == 0) { dac_init(DAC,DAC_CH2); int8_t idelta=1; uint8_t i=0; for(int n=0;n<1000000;n++) { if(i == 254) idelta = -1; if(i == 0 ) idelta = 1; i += idelta; dac_write_channel(DAC,2,i); } serial_write_string("WRITEDACFIN"); } else if(strcmp(line,"TESTHP") == 0) { gpio_set_mode (PIN_MAP[12].gpio_device,PIN_MAP[12].gpio_bit, GPIO_OUTPUT_PP); // HP_COMBINED for(int n=0;n<100000;n++) { gpio_write_bit(PIN_MAP[12].gpio_device,PIN_MAP[12].gpio_bit,1); delay_us(100); gpio_write_bit(PIN_MAP[12].gpio_device,PIN_MAP[12].gpio_bit,0); delay_us(100); } } else if(strcmp(line,"READADC") == 0) { adc_init(PIN_MAP[12].adc_device); // all on ADC1 adc_set_extsel(PIN_MAP[12].adc_device, ADC_SWSTART); adc_set_exttrig(PIN_MAP[12].adc_device, true); adc_enable(PIN_MAP[12].adc_device); adc_calibrate(PIN_MAP[12].adc_device); adc_set_sample_rate(PIN_MAP[12].adc_device, ADC_SMPR_55_5); gpio_set_mode (PIN_MAP[12].gpio_device,PIN_MAP[12].gpio_bit, GPIO_INPUT_ANALOG); gpio_set_mode (PIN_MAP[19].gpio_device,PIN_MAP[19].gpio_bit, GPIO_INPUT_ANALOG); gpio_set_mode (PIN_MAP[20].gpio_device,PIN_MAP[20].gpio_bit, GPIO_INPUT_ANALOG); int n=0; uint16 value1 = adc_read(PIN_MAP[12].adc_device,PIN_MAP[12].adc_channel); uint16 value2 = adc_read(PIN_MAP[19].adc_device,PIN_MAP[19].adc_channel); uint16 value3 = adc_read(PIN_MAP[20].adc_device,PIN_MAP[20].adc_channel); char values[50]; sprintf(values,"PA6 ADC Read: %u\r\n",value1); serial_write_string(values); sprintf(values,"PC4 ADC Read: %u\r\n",value2); serial_write_string(values); sprintf(values,"PC5 ADC Read: %u\r\n",value3); serial_write_string(values); } else if(strcmp(line,"SETMICREVERSE") == 0) { gpio_set_mode (PIN_MAP[36].gpio_device,PIN_MAP[36].gpio_bit, GPIO_OUTPUT_PP); // MICREVERSE gpio_set_mode (PIN_MAP[35].gpio_device,PIN_MAP[35].gpio_bit, GPIO_OUTPUT_PP); // MICIPHONE gpio_write_bit(PIN_MAP[36].gpio_device,PIN_MAP[36].gpio_bit,1); // MICREVERSE gpio_write_bit(PIN_MAP[35].gpio_device,PIN_MAP[35].gpio_bit,0); // MICIPHONE serial_write_string("Set MICREVERSE to 1, MICIPHONE to 0\r\n"); } else if(strcmp(line,"SETMICIPHONE") == 0) { gpio_set_mode (PIN_MAP[36].gpio_device,PIN_MAP[36].gpio_bit, GPIO_OUTPUT_PP); // MICREVERSE gpio_set_mode (PIN_MAP[35].gpio_device,PIN_MAP[35].gpio_bit, GPIO_OUTPUT_PP); // MICIPHONE gpio_write_bit(PIN_MAP[36].gpio_device,PIN_MAP[36].gpio_bit,0); // MICREVERSE gpio_write_bit(PIN_MAP[35].gpio_device,PIN_MAP[35].gpio_bit,1); // MICIPHONE serial_write_string("Set MICREVERSE to 0, MICIPHONE to 1\r\n"); } else if(strcmp(line,"TESTSIGN") == 0) { serial_signing_test(); } else if(strcmp(line,"PUBKEY") == 0) { signing_printPubKey(); serial_write_string("\n\r"); } else if(strcmp(line,"GUID") == 0) { signing_printGUID(); serial_write_string("\n\r"); } else if(strcmp(line,"KEYVALID") == 0) { if( signing_isKeyValid() == 1 ) serial_write_string("uu_valid VALID KEY\r\n"); else serial_write_string("uu_valid IMPROPER OR UNINITIALIZED KEY\r\n"); } else if(strcmp(line,"LOGSIG") == 0) { signing_hashLog(); serial_write_string("\n\r"); } else if(strcmp(line,"LOGPAUSE") == 0) { flashstorage_log_pause(); } else if(strcmp(line,"LOGRESUME") == 0) { flashstorage_log_resume(); } else if(strcmp(line,"LOGCLEAR") == 0) { serial_write_string("Clearing flash log\r\n"); flashstorage_log_clear(); serial_write_string("Cleared\r\n"); } else if(strcmp(line,"KEYVALDUMP") == 0) { serial_keyvaldump(); } else if(strcmp(line,"KEYVALSET") == 0) { serial_setkeyval(); } else if(strcmp(line,"SETRTC") == 0) { serial_setrtc(); } else if(strcmp(line,"RTCALARM") == 0) { serial_write_string("Alarm triggered for 10s\r\n"); rtc_set_alarm(RTC,rtc_get_time(RTC)+10); } serial_write_string("\r\n>"); }
/** * Output a string in morse code only if we are in debug mode */ void buzzer_morse_debug(char const* c) { const char *dbg= flashstorage_keyval_get("DEBUG"); if (dbg != NULL && dbg[0] == '1') { buzzer_morse(c); } }
int main(void) { Geiger g; power_initialise(); if(power_battery_level() < 1) { power_standby(); } flashstorage_initialise(); buzzer_initialise(); realtime_initialise(); g.initialise(); uint8_t *private_key = ((uint8_t *) &_binary___binary_data_private_key_data_start); if(private_key[0] != 0) delay_us(1000); delay_us(10000); // can be removed? #ifndef DISABLE_ACCEL accel_init(); #endif Controller c(g); switch_initialise(); // if we woke up on an alarm, we're going to be sending the system back. #ifndef NEVERSLEEP if(power_get_wakeup_source() == WAKEUP_RTC) { c.m_sleeping = true; } else { buzzer_nonblocking_buzz(0.05); display_initialise(); const char *devicetag = flashstorage_keyval_get("DEVICETAG"); char revtext[10]; sprintf(revtext,"VERSION: %s ",OS100VERSION); display_splashscreen(devicetag,revtext); delay_us(3000000); display_clear(0); } #endif #ifdef NEVERSLEEP buzzer_nonblocking_buzz(0.05); display_initialise(); #endif GUI m_gui(c); bool full = flashstorage_log_isfull(); if((full == true) && (c.m_sleeping == false)) { m_gui.show_dialog("Flash Log","is full",0,0,0); } c.set_gui(m_gui); UserInput u(m_gui); u.initialise(); serial_initialise(); int8_t utcoffsetmins_n = 0; const char *utcoffsetmins = flashstorage_keyval_get("UTCOFFSETMINS"); if(utcoffsetmins != 0) { unsigned int c; sscanf(utcoffsetmins, "%u", &c); utcoffsetmins_n = c; realtime_setutcoffset_mins(utcoffsetmins_n); } // Need to refactor out stored settings if(c.m_sleeping == false) { const char *sbright = flashstorage_keyval_get("BRIGHTNESS"); if(sbright != 0) { unsigned int c; sscanf(sbright, "%u", &c); display_set_brightness(c); } const char *sbeep = flashstorage_keyval_get("GEIGERBEEP"); if(sbeep != 0) { if(strcmp(sbeep,"true") == 0) { g.set_beep(true); tick_item("Geiger Beep",true); } else g.set_beep(false); } const char *scpmcps = flashstorage_keyval_get("CPMCPSAUTO"); if(scpmcps != 0) { if(strcmp(scpmcps,"true") == 0) { c.m_cpm_cps_switch = true; tick_item("CPM/CPS Auto",true); } } const char *language = flashstorage_keyval_get("LANGUAGE"); if(language != 0) { if(strcmp(language,"English" ) == 0) { m_gui.set_language(LANGUAGE_ENGLISH); tick_item("English" ,true); } else if(strcmp(language,"Japanese") == 0) { m_gui.set_language(LANGUAGE_JAPANESE); tick_item("Japanese" ,true); } } else { m_gui.set_language(LANGUAGE_ENGLISH); tick_item("English",true); } const char *svrem = flashstorage_keyval_get("SVREM"); if(strcmp(svrem,"REM") == 0) { tick_item("Roentgen",true); } else { tick_item("Sievert",true);} } m_gui.jump_to_screen(1); m_gui.push_stack(0,1); for(;;) { if(power_battery_level() < 1) { power_standby(); } //display_draw_text(0,110,"preupdate",0); c.update(); //display_draw_text(0,110,"prerender",0); m_gui.render(); //display_draw_text(0,110,"preserial",0); serial_eventloop(); //display_draw_text(0,110,"preserial",0); // It might be a good idea to move the following code to Controller. // Hack to check that captouch is ok, and reset it if not. bool c = cap_check(); if(c == false) { display_draw_text(0,90,"CAPFAIL",0); cap_init(); } // Screen lock code uint32_t release1_time = cap_last_press(KEY_BACK); uint32_t press1_time = cap_last_release(KEY_BACK); uint32_t release2_time = cap_last_press(KEY_SELECT); uint32_t press2_time = cap_last_release(KEY_SELECT); uint32_t current_time = realtime_get_unixtime(); if((release1_time != 0) && (release2_time != 0) && ((current_time-press1_time) > 3) && ((current_time-press2_time) > 3) && cap_ispressed(KEY_BACK ) && cap_ispressed(KEY_SELECT)) { system_gui->toggle_screen_lock(); cap_clear_press(); } power_wfi(); } // should never get here for(int n=0;n<60;n++) { delay_us(100000); buzzer_blocking_buzz(1000); } return 0; }