int main(int argc, char *argv[]) { #ifdef __XENO__ struct sched_param param = { 99 }; mlockall(MCL_CURRENT | MCL_FUTURE); pthread_setschedparam(pthread_self(), SCHED_FIFO, ¶m); #endif if (!raspi_map_hw()) { perror("Could not map hardware registers"); exit(1); } #ifdef __XENO__ pthread_set_mode_np(0, PTHREAD_WARNSW|PTHREAD_PRIMARY); #endif // ILI9341(int8_t _CS, int8_t _DC, int8_t _RST, int8_t _BL, int8_t _MOSI, int8_t _SCLK, int8_t _MISO); ILI9341 tft = ILI9341(PIN_CS, PIN_DC, PIN_RESET, PIN_BL, PIN_MOSI, PIN_SCLK, PIN_MISO); printf("Setting up TFT...\n"); tft.begin(); g_HWSPI=0; if (argc > 1) { g_HWSPI=1; } if (g_HWSPI) { printf("Setup HW SPI parameters...\n"); } else { printf("Setup SW SPI (Bit-Banger) parameters...\n"); } printf("HWReset done, initializing display\n") ; int i, colors[8] = { ILI9341_BLACK, ILI9341_BLUE, ILI9341_RED, ILI9341_GREEN, ILI9341_CYAN, ILI9341_MAGENTA, ILI9341_WHITE, ILI9341_YELLOW }; begin(); printf("Done intializing, now fill screens...\n"); for (i=0;i<8 ;i++ ) { fillScreen(ILI9341_BLACK); //sleep(1); fillScreen(colors[i]); //sleep (2); } printf("Setting up for HWreset\n"); printf("Benchmark\tTime (microseconds)\n"); printf("Screen fill\t%f\n", testFillScreen()); sl_delay(500); printf("Text\t%f\n",testText()); sl_delay(3000); printf("Lines\t%f\n",testLines(ILI9341_CYAN)); sl_delay(500); printf("Horiz/Vert Lines\t%f\n", testFastLines(ILI9341_RED, ILI9341_BLUE)); sl_delay(500); printf("Rectangles (outline)\t%f",testRects(ILI9341_GREEN)); sl_delay(500); printf("Rectangles (filled)\t%f\n", testFilledRects(ILI9341_YELLOW, ILI9341_MAGENTA)); sl_delay(500); printf("Circles (filled)\t%f\n", testFilledCircles(10, ILI9341_MAGENTA)); printf("Circles (outline)\t%f\n", testCircles(10, ILI9341_WHITE)); sl_delay(500); printf("Triangles (outline)\t%f\n", testTriangles()); sl_delay(500); printf("Triangles (filled)\t%f\n", testFilledTriangles()); sl_delay(500); printf("Rounded rects (outline)\t%f\n", testRoundRects()); sl_delay(500); printf("Rounded rects (filled)\t%f\n", testFilledRoundRects()); sl_delay(500); printf("Done!\n"); for(uint8_t rotation=0; rotation<4; rotation++) { tft.setRotation(rotation); testText(); sl_delay(1000); } #ifdef __XENO__ pthread_set_mode_np(PTHREAD_WARNSW, 0); #endif return 1; }
// main entry point, go ahead, have fun! int main(void) { // hold the power button for 3 seconds or shutdown //_delay_ms(STARTUP_DELAY); // keep power pin High unless we want to shutdown powerControl = 1; // disable JTAG so we can use PF4,PF5,PF6,PF7 for ADC and GPIO MCUCSR |=(1<<JTD);MCUCSR |=(1<<JTD); // two times!! // init time RTC time.init(callback_timeSecond, callback_timeMinute); time.startInterval(); // microcontroller features adc.init(); // needed by gp2y10 and more spi_init(); // needed by ILI9341 i2c_init(); // needed by bmp180 and mics-vz-89t uart1.init(1, 9600, 1); // needed by esp8266 . Interrupts are hard on parsing, polling would be easier but blocking uart0.init(0, 9600, 1); // CONFIGURE INTERRUPT INT4 to count pulses from Geiger Counter EICRB |= (1<<ISC00) | (1<<ISC01); // Configure INT4 to trigger on RISING EDGE EIMSK |= (1<<INT4); // Configure INT4 to fire interrupts // CREATE Timer T1 PWM to drive inverter for regulated Geiger tube voltage inverter.initPWM(); // init display lcd.init(); lcd.setRotation(ILI9341::ROT0); //lcd.drawClear(BLACK); backlight(true); // init sensors bmp180.init(); dust.init(&dustFlash, &adc, PF1); beep(); // start UI // enter main menu // ## touchscreen calibration code /*while (1) { uint16_t x = 0, y = 0, z = 0; if (touch.read(&x, &y , &z)) { lcd.drawPixel(x,y, 2, RED); } lcd.drawStringF(0,0,2,WHITE, BLACK, "%4u %4u %4u", touch.readRawX(), touch.readRawY(), touch.readRawPressure()); }*/ // draw GUI first page with self check if (!gui.drawPage(PAGE_INIT)) shutdown(); _delay_ms(1000); gui.drawPage(PAGE_MAIN); // ## main code loop while (1) { // ## beep if (cmdBeep && !cmdAlarm && !isMuted) { beep(); cmdBeep = false; } // ## read sensors // read inverter voltage, via 10M/47K resistive divider, connected to pin ADC2 data.geiger_voltage = readTubeVoltage(); inverter.adjustDutyCycle(data.geiger_voltage); // do nothing on failure, we can't reset // read battery data.battery_voltage = readBatVoltage(); // turn backlight off when timeout is reached if (secTimeout > BACKLIGHT_TIMEOUT) { backlight(false); secTimeout = 0; } // ## draw titlebar and refresh data display if (cmdRefreshText) { // sensor BMP180 bmp180.readAll(&data.bmp180_temp, &data.bmp180_pressure, &data.bmp180_altitude); dust.readDust(&data.gp2y10_dust); // sensor MICS-VZ-89T uint8_t reactivity = 0; // repeat until successful read with timeout? //int timeout = 10; //while (!vz89.read(&data.vz89_co2, &reactivity, &data.vz89_voc) && timeout) { _delay_ms(1500); timeout--; } vz89.read(&data.vz89_co2, &reactivity, &data.vz89_voc); // geiger readings //float dose = aux_CPM2uSVh((uint8_t)DEV_RAD_DETECTOR, geigerCPM); data.geiger_cpm = geigerCPM; data.time_hour = time.getHour(); data.time_minute = time.getMin(); data.time_second = time.getSec(); data.setLimits(); // must be changed to proper OOP set/get for all fields gui.updateValues(); // ## alarm condition if (geigerCPM >= GEIGER_CPM_ALARM) { // threshold to sound alarm reached cmdAlarm = ALARM_RADIATION; } else if (cmdAlarm) { // alarm should be turned off cmdAlarm = 0; speaker = 0; } cmdRefreshText = false; } // ## every minute we can dispatch data over serial or over WLAN to uradmonitor if (cmdSend) { char tmp[200]; sprintf(tmp,"{\"data\":{ \"id\":\"%08lX\"," "\"type\":\"%X\",\"detector\":\"%s\"," "\"cpm\":%lu,\"temperature\":%.2f,\"uptime\": %lu," "\"pressure\":%lu,\"dust\":%.2f,\"co2\":%.2f,\"voc\":%.2f," "\"battery\":%.2f,\"tube\":%u}}", deviceID, DEV_MODEL, aux_detectorName(DEV_RAD_DETECTOR), geigerCPM, data.bmp180_temp, time.getTotalSec(), data.bmp180_pressure, data.gp2y10_dust,data.vz89_co2, data.vz89_voc, data.battery_voltage, data.geiger_voltage); data.serial_sent += strlen(tmp); uart0.send(tmp); // internet code here sprintf(tmp,"id=%08lX&ts=%ld&inv=%d&ind=%d&s1t=%2.2f&cpm=%ld&voc=%.2f&co2=%.2f", deviceID, time.getTotalSec(), data.geiger_voltage, data.geiger_duty, data.bmp180_temp, geigerCPM, data.vz89_voc, data.vz89_co2); wifi.sendData(tmp); cmdSend = false; } // ## act on the gui elements // read a new touch event only if we are done with previous: useful for handling confirmation "modal" "dialogs" if (uiResult == 0) { uiResult = gui.readTouchEvent(); // reset backlight timeout on valid touch if (uiResult > 0) { secTimeout = 0; backlight(true); // if screen is pressed while alarm is on, stop alarm if (cmdAlarm) { cmdAlarm = false; speaker = 0; } } } // handle special cases: click on wlan AP buttons if (uiResult >= ID_BUTTON_WLAN_START && uiResult < ID_BUTTON_WLAN_STOP) { uint8_t ap_index = uiResult - ID_BUTTON_WLAN_START; // connect and return to main screen wifi.connectWiFi(data.freeAPList[ap_index], ""); uiResult = 0; gui.drawPage(PAGE_MAIN); } // handle regular buttons switch (uiResult) { case ID_BUTTON_SHUTDOWN: { uint16_t result = gui.showYesNoPopup("Are you sure?"); if (result == ID_YES) shutdown(); else if (result == ID_NO) { uiResult = 0; gui.drawPage(PAGE_MAIN); } } break; case ID_BUTTON_MEASURE: { uiResult = 0; gui.drawPage(PAGE_MEASURE); } break; case ID_BUTTON_MONITOR: { uiResult = 0; gui.drawPage(PAGE_MONITOR); } break; case ID_BUTTON_SETTINGS: { uiResult = 0; gui.drawPage(PAGE_SETTINGS); } break; case ID_BUTTON_BACK: { uiResult = 0; gui.drawPage(PAGE_MAIN); } break; case ID_BUTTON_MUTE: { isMuted = !isMuted; if (!isMuted) beep(); // test beep that sound is on uiResult = 0; } break; case ID_BUTTON_CALIBRATE: { uiResult = 0; gui.drawPage(PAGE_CALIBRATE); } break; case ID_BUTTON_WLAN: { // request list of WLAN APs data.freeAPCount = 0; //wifi.setMode(); wifi.listAP(); uiResult = 0; gui.drawPage(PAGE_WLAN); } break; // other commands that don't require a popup so we consume asap default: uiResult = 0; } //uint16_t x, y,z; //gui.getLastTouch(&x, &y, &z); //lcd.drawStringF(0,288, 2, RED, BLACK,"%u %d,%d ", uiResult, x,y); } }