/* * Author: Richard Diego & Kyle Phillips & Jay June * Target PIC: PIC32MX250F128B * //http://stackoverflow.com/questions/28133020/how-to-convert-bcd-to-decimal * This code implements a real time clock module that has * an alarm clock feature with an EEG sensor that will * allow the alarm clock to go off earlier if you're * closer to being awake. We also have a touch screen * implemended for the 2.4inch Adafruit TFT touchscreen */ #define SYS_FREQ 40000000 #include "adc_intf.h" #include "config.h" #include "plib.h" #include "tft_master.h" #include "tft_gfx.h" #include "pt_cornell_1_2.h" #include #include #include #include "TouchScreen.h" #define SS LATBbits.LATB3 #define dirSS TRISBbits.TRISB3 char number; char number2; char number3; char number4; char clockBuffer[100]; //char buffers used for printing strings to screen with more than enough values char ONOFFBuffer[100]; char setBuffer[100]; char alarmBuffer[100]; char amPmBuffer[100]; char showBuffer[100]; char timeBuffer[100]; char myOwnBuffer[100]; char buffer[100]; int hour = 12; //Default Time is 12:23AM int minute = 23; int am = 1; int toggleAlarm = 0; int toggleONOFF =0; int setTime = 0; int timeChanged = 1; int alarmHour = 11; //Default alarm is 11:30AM - Clearly the perfect time to get up every day int alarmMinute = 30; int alarmAM = 1; int16_t xpos; int16_t ypos; int16_t zpos; int lastAMPM = 0; int alarmTriggered = 0; int alarmNote = 0; // === thread structures ============================================ static struct pt pt_clockDisplay, pt_pointGetter, pt_rtcConfig, pt_alarmControl; uint16_t scaleTouchX(uint16_t scale) { uint16_t checkVal = (((scale*0x01A0)>>10)-50); if(checkVal<0) { checkVal =0; } return checkVal; //This converts the touch input X variable to our scaled Screen Value } uint16_t scaleTouchY(uint16_t scale) { return (((scale*0x0180)>>10)-75); //This converts the touch input Y variable to our scaled Screen Value } inline void drawScreenBlack(){ //Draws the area in which time is displayed black tft_fillRoundRect(47, 120, 300, 60, 3, ILI9341_BLACK); } inline void drawDisplay(){ //draw set and alarm button on right side tft_fillRoundRect(190, 0 , 200, 60, 3, ILI9341_WHITE); tft_drawRoundRect(191, 0, 200, 59, 3, ILI9341_NAVY); //x, y, w, h, r, color tft_fillRoundRect(190, 2 , 10, 10, 0, ILI9341_WHITE); tft_drawLine(191, 1, 191, 12, ILI9341_NAVY); //x0, y0, x1, y1, color tft_drawLine(245, 0, 245, 58, ILI9341_NAVY); //x0, y0, x1, y1, color tft_drawLine(247, 0, 247, 58, ILI9341_NAVY); //x0, y0, x1, y1, color //draw onoff button on left side tft_fillRoundRect(0, 0, 65, 60, 3, ILI9341_WHITE); tft_drawRoundRect(0, 0, 64, 59, 3, ILI9341_NAVY); //x, y, w, h, r, color tft_fillRoundRect(60, 1 , 5, 10, 0, ILI9341_WHITE); tft_drawLine(63, 1, 63, 12, ILI9341_NAVY); //Print Set Time tft_setTextSize(2); tft_setCursor(200, 15); sprintf(setBuffer,"Set"); tft_setTextColor(ILI9341_BLACK); tft_writeString(setBuffer); tft_setCursor(195, 32); sprintf(setBuffer,"Time"); tft_setTextColor(ILI9341_BLACK); tft_writeString(setBuffer); // Print Set Alarm tft_setCursor(264, 15); sprintf(alarmBuffer,"Set"); tft_writeString(alarmBuffer); tft_setCursor(254, 32); sprintf(alarmBuffer,"Alarm"); tft_writeString(alarmBuffer); //Print Alarm On/Off tft_setCursor(3, 7); sprintf(ONOFFBuffer,"Alarm\n ON/\n OFF"); tft_writeString(ONOFFBuffer); // Dim sign tft_drawCircle(20, 85, 10, ILI9341_WHITE); //x, y, r, color 25,25 tft_fillCircle(5, 85, 2, ILI9341_WHITE); tft_fillCircle(10, 75, 2, ILI9341_WHITE); tft_fillCircle(20, 70, 2, ILI9341_WHITE); tft_fillCircle(30, 75, 2, ILI9341_WHITE); tft_fillCircle(35, 85, 2, ILI9341_WHITE); tft_fillCircle(30, 95, 2, ILI9341_WHITE); tft_fillCircle(20, 100, 2, ILI9341_WHITE); tft_fillCircle(10, 95, 2, ILI9341_WHITE); // Bright sign tft_fillCircle(60, 85, 10, ILI9341_WHITE); //x, y, r, color tft_fillCircle(45, 85, 2, ILI9341_WHITE); tft_fillCircle(50, 75, 2, ILI9341_WHITE); tft_fillCircle(60, 70, 2, ILI9341_WHITE); tft_fillCircle(70, 75, 2, ILI9341_WHITE); tft_fillCircle(75, 85, 2, ILI9341_WHITE); tft_fillCircle(70, 95, 2, ILI9341_WHITE); tft_fillCircle(60, 100, 2, ILI9341_WHITE); tft_fillCircle(50, 95, 2, ILI9341_WHITE); } char hourBuff[2]; char minuteBuff[2]; char rtcc[8]; int thisHour = 0; int thisMinute = 0; void setTimeRTCC() { thisHour = 0; thisMinute = 0; memset(rtcc, 0, sizeof rtcc); memset(hourBuff, 0, sizeof hourBuff); memset(minuteBuff, 0, sizeof minuteBuff); if(am==0) { thisHour = hour +12; } else { thisHour = hour; } if(thisHour==12 || thisHour ==24) //If time is 12 or 24 hours aka, post midnight or post noon, time should be = to 12AM/12PM { thisHour = thisHour -12; } thisMinute = minute; if(thisHour > 9){ sprintf(hourBuff, "%d", thisHour); }else{ sprintf(hourBuff, "0%d", thisHour); } if(thisMinute > 9){ sprintf(minuteBuff, "%d", thisMinute); }else{ sprintf(minuteBuff, "0%d", thisMinute); } strcat(rtcc, hourBuff); //Adds the time in the hour buffer to the string to give to RTCC strcat(rtcc, minuteBuff); //Adds the time in the minute buffer to the string to give to RTCC strcat(rtcc, "0000"); int rtccValue = (int)strtol(rtcc,NULL,16); RtccSetTime(rtccValue); } void setAlarmRTCC() { thisHour = 0; thisMinute = 0; memset(rtcc, 0, sizeof rtcc); memset(hourBuff, 0, sizeof hourBuff); memset(minuteBuff, 0, sizeof minuteBuff); if(alarmAM==0) { thisHour = alarmHour +12; } else { thisHour = alarmHour; } if(thisHour==12||thisHour==24) { thisHour = thisHour-12; } thisMinute = alarmMinute; if(thisHour > 9){ sprintf(hourBuff, "%d", thisHour); }else{ sprintf(hourBuff, "0%d", thisHour); } if(thisMinute > 9){ sprintf(minuteBuff, "%d", thisMinute); }else{ sprintf(minuteBuff, "0%d", thisMinute); } strcat(rtcc, hourBuff);//Adds the time in the hour buffer to the string to give to RTCC strcat(rtcc, minuteBuff); //Adds the time in the minute buffer to the string to give to RTCC strcat(rtcc, "0000"); int rtccValue = (int)strtol(rtcc,NULL,16); RtccSetAlarmTime(rtccValue); } static PT_THREAD(protothread_rtcConfig(struct pt *pt)) //com6 { PT_BEGIN(pt); while(1) { PT_YIELD_TIME_msec(1); int cal = -0x80; if(RTCCON&0x8000) { // RTCC is ON unsigned int t0, t1; do { t0=RTCTIME; t1=RTCTIME; }while(t0!=t1); // read valid time value if((t0&0xFF)==00) { // we're at second 00, wait auto-adjust to be performed while(!(RTCCON&0x2)); // wait until second half... } } RTCCONCLR=0x03FF0000; // clear the calibration RTCCONSET=cal; } PT_END(pt); } int lastONOFF = 1; int lastsetON = 0; int lastMin; rtccTime time; int hexSec; int hexMin; int hexHour; int convertedSec; //http://stackoverflow.com/questions/28133020/how-to-convert-bcd-to-decimal int convertedMin; int convertedHour; int convertedAM; int writeScreen = 0; static PT_THREAD(protothread_clockDisplay(struct pt *pt)) //com6 { PT_BEGIN(pt); while(1) { PT_YIELD_TIME_msec(1); if(toggleONOFF ==0 && (lastONOFF==1)) //This should occur when you set alarm from on-> off { tft_setTextSize(2); tft_setCursor(3, 7); sprintf(ONOFFBuffer,"Alarm\n ON/\n OFF"); tft_fillRoundRect(60, 1 , 5, 10, 0, ILI9341_RED); tft_fillRoundRect(0, 0, 65, 60, 3, ILI9341_RED); tft_setTextColor(ILI9341_WHITE); tft_writeString(ONOFFBuffer); tft_drawLine(63, 1, 63, 12, ILI9341_NAVY); tft_drawRoundRect(0, 0, 64, 59, 3, ILI9341_NAVY); tft_drawRoundRect(191, 0, 200, 59, 3, ILI9341_NAVY); //x, y, w, h, r, color tft_drawLine(191, 1, 191, 12, ILI9341_NAVY); //x0, y0, x1, y1, color tft_drawLine(245, 0, 245, 58, ILI9341_NAVY); //x0, y0, x1, y1, color tft_drawLine(247, 0, 247, 58, ILI9341_NAVY); //x0, y0, x1, y1, color drawSet(); } if(toggleONOFF==1 && (lastONOFF==0)) //This should occur when you set alarm from off-> on { tft_setTextSize(2); tft_setCursor(3, 7); sprintf(ONOFFBuffer,"Alarm\n ON\n OFF"); tft_fillRoundRect(60, 1 , 5, 10, 0, ILI9341_GREEN); tft_fillRoundRect(0, 0, 65, 60, 3, ILI9341_GREEN); tft_setTextColor(ILI9341_WHITE); tft_writeString(ONOFFBuffer); tft_drawLine(63, 1, 63, 12, ILI9341_NAVY); tft_drawRoundRect(0, 0, 64, 59, 3, ILI9341_NAVY); drawSet(); } lastONOFF=toggleONOFF; if((setTime==0)&&(toggleAlarm==0)) //If you're not setting the alarm draw set should be white { if(lastsetON!=0) { tft_fillRoundRect(190, 0 , 200, 60, 3, ILI9341_WHITE); tft_fillRoundRect(190, 2 , 10, 10, 0, ILI9341_WHITE); drawSet(); } lastsetON=0; } if(setTime==1) //If you're setting time its associated button should be green { if(lastsetON==2) { tft_fillRoundRect(190, 0 , 200, 60, 3, ILI9341_WHITE); tft_fillRoundRect(190, 2 , 10, 10, 0, ILI9341_WHITE); tft_drawRoundRect(191, 0, 200, 59, 3, ILI9341_NAVY); //x, y, w, h, r, color tft_drawLine(191, 1, 191, 12, ILI9341_NAVY); //x0, y0, x1, y1, color tft_drawLine(245, 0, 245, 58, ILI9341_NAVY); //x0, y0, x1, y1, color tft_drawLine(247, 0, 247, 58, ILI9341_NAVY); //x0, y0, x1, y1, color drawSet(); } if(lastsetON!=1) { tft_fillRoundRect(190, 0 , 57, 60, 0, ILI9341_GREEN); tft_drawRoundRect(191, 0, 200, 59, 3, ILI9341_NAVY); //x, y, w, h, r, color tft_drawLine(191, 1, 191, 12, ILI9341_NAVY); //x0, y0, x1, y1, color tft_drawLine(245, 0, 245, 58, ILI9341_NAVY); //x0, y0, x1, y1, color tft_drawLine(247, 0, 247, 58, ILI9341_NAVY); //x0, y0, x1, y1, color drawSet(); } lastsetON=1; } if(toggleAlarm==1) //If you're setting alarm its associated button should be green { if(lastsetON==1) { tft_fillRoundRect(190, 0 , 200, 60, 3, ILI9341_WHITE); tft_fillRoundRect(190, 2 , 10, 10, 0, ILI9341_WHITE); tft_drawRoundRect(191, 0, 200, 59, 3, ILI9341_NAVY); //x, y, w, h, r, color tft_drawLine(191, 1, 191, 12, ILI9341_NAVY); //x0, y0, x1, y1, color tft_drawLine(245, 0, 245, 58, ILI9341_NAVY); //x0, y0, x1, y1, color tft_drawLine(247, 0, 247, 58, ILI9341_NAVY); //x0, y0, x1, y1, color drawSet(); } if(lastsetON!=2) { tft_fillRoundRect(247, 0 , 200, 60, 3, ILI9341_GREEN); tft_drawRoundRect(191, 0, 200, 59, 3, ILI9341_NAVY); //x, y, w, h, r, color tft_drawLine(191, 1, 191, 12, ILI9341_NAVY); //x0, y0, x1, y1, color tft_drawLine(245, 0, 245, 58, ILI9341_NAVY); //x0, y0, x1, y1, color tft_drawLine(247, 0, 247, 58, ILI9341_NAVY); //x0, y0, x1, y1, color drawSet(); } lastsetON=2; } if(toggleONOFF ==1) //If you have the alarm on it should write alarm enabled { if(timeChanged==1) //If you've changed the time it should update { tft_setTextSize(1); tft_setCursor(75, 23); tft_setTextColor(ILI9341_BLACK); tft_writeString(showBuffer); } if(alarmAM==1) { if(alarmMinute<10) { sprintf(showBuffer,"Alarm Enabled\n Time:%d:0%dAM",alarmHour,alarmMinute); } else { sprintf(showBuffer,"Alarm Enabled\n Time:%d:%dAM",alarmHour,alarmMinute); } } else { if(alarmMinute<10) { sprintf(showBuffer,"Alarm Enabled\n Time:%d:0%dPM",alarmHour,alarmMinute); } else { sprintf(showBuffer,"Alarm Enabled\n Time:%d:%dPM",alarmHour,alarmMinute); } } if(timeChanged==1) { tft_setCursor(75, 23); tft_setTextColor(ILI9341_WHITE); tft_writeString(showBuffer); timeChanged=0; } } if(toggleONOFF ==0) //If you have the alarm off it should write alarm disable { if(timeChanged==1) { tft_setTextSize(1); tft_setCursor(75, 23); tft_setTextColor(ILI9341_BLACK); tft_writeString(showBuffer); } if(alarmAM==1) { if(alarmMinute<10) { sprintf(showBuffer,"Alarm Disabled\n Time:%d:0%dAM",alarmHour,alarmMinute); } else { sprintf(showBuffer,"Alarm Disabled\n Time:%d:%dAM",alarmHour,alarmMinute); } } if(alarmAM==0) { if(alarmMinute<10) { sprintf(showBuffer,"Alarm Disabled\n Time:%d:0%dPM",alarmHour,alarmMinute); } else { sprintf(showBuffer,"Alarm Disabled\n Time:%d:%dPM",alarmHour,alarmMinute); } } if(timeChanged==1) { tft_setCursor(75, 23); tft_setTextColor(ILI9341_WHITE); tft_writeString(showBuffer); timeChanged=0; } } if(setTime==1 || toggleAlarm == 1){ //If you're in a mode that they should be able to change a time //draw upper control buttons tft_fillTriangle(70, 110, 99, 110, 85, 85, ILI9341_WHITE); //x0, y0, x1, y1, x2, y2, color up left tft_drawTriangle(72, 109, 97, 109, 85, 88, ILI9341_NAVY); tft_fillTriangle(198, 110, 228, 110, 213, 85, ILI9341_WHITE); //upright tft_drawTriangle(200, 109, 226, 109, 213, 88, ILI9341_NAVY); //draw lower control tft_fillTriangle(70, 190, 99, 190, 85, 215, ILI9341_WHITE); //Down Left tft_drawTriangle(72, 191, 97, 191, 85, 212, ILI9341_NAVY); tft_fillTriangle(198, 190, 228, 190, 213, 215, ILI9341_WHITE); //Down Right tft_drawTriangle(200, 191, 226, 191, 213, 212, ILI9341_NAVY); //draw AM/PM Control Triangles tft_fillTriangle(273, 110, 303, 110, 288, 85, ILI9341_WHITE); //upright tft_drawTriangle(275, 109, 301, 109, 288, 88, ILI9341_NAVY); tft_fillTriangle(273, 190, 303, 190, 288, 215, ILI9341_WHITE); //Down Right tft_drawTriangle(275, 191, 301, 191, 288, 212, ILI9341_NAVY); } if(setTime==0 && toggleAlarm==0){ //If you're in a mode that they shouldn't be able to change a time //draw upper control buttons tft_fillTriangle(70, 110, 99, 110, 85, 85, ILI9341_BLACK); //x0, y0, x1, y1, x2, y2, color up left tft_drawTriangle(72, 109, 97, 109, 85, 88, ILI9341_BLACK); tft_fillTriangle(198, 110, 228, 110, 213, 85, ILI9341_BLACK); //upright tft_drawTriangle(200, 109, 226, 109, 213, 88, ILI9341_BLACK); //draw lower control tft_fillTriangle(70, 190, 99, 190, 85, 215, ILI9341_BLACK); //Down Left tft_drawTriangle(72, 191, 97, 191, 85, 212, ILI9341_BLACK); tft_fillTriangle(198, 190, 228, 190, 213, 215, ILI9341_BLACK); //Down Right tft_drawTriangle(200, 191, 226, 191, 213, 212, ILI9341_BLACK); //draw AM/PM Control Triangles tft_fillTriangle(273, 110, 303, 110, 288, 85, ILI9341_BLACK); //upright tft_drawTriangle(275, 109, 301, 109, 288, 88, ILI9341_BLACK); tft_fillTriangle(273, 190, 303, 190, 288, 215, ILI9341_BLACK); //Down Right tft_drawTriangle(275, 191, 301, 191, 288, 212, ILI9341_BLACK); } if(setTime==1) { if(writeScreen) { drawScreenBlack(); tft_setTextSize(7); tft_setTextColor(ILI9341_WHITE); if(minute<10) { sprintf(clockBuffer,"%d:0%d", hour, minute); } else { sprintf(clockBuffer,"%d:%d", hour, minute); } if(hour > 9){ tft_setCursor(47, 125); tft_writeString(clockBuffer); }else{ tft_setCursor(92, 125); tft_writeString(clockBuffer); } tft_setTextSize(4); tft_setTextColor(ILI9341_WHITE); tft_setCursor(265, 146); if(am==1) { sprintf(amPmBuffer,"am"); tft_writeString(amPmBuffer); } if(am==0) { sprintf(amPmBuffer,"pm"); tft_writeString(amPmBuffer); } writeScreen = 0; } } if((toggleAlarm==0)&&(setTime!=1)) //Just print the RTCC to screen if you're not changing anything currently { tft_setTextSize(7); tft_setTextColor(ILI9341_WHITE); time.l= RtccGetTime(); hexSec = time.sec; hexMin = time.min; hexHour = time.hour; convertedSec = ((hexSec & 0xF0) >> 4) * 10 + (hexSec & 0x0F); //http://stackoverflow.com/questions/28133020/how-to-convert-bcd-to-decimal convertedMin = ((hexMin & 0xF0) >> 4) * 10 + (hexMin & 0x0F); convertedHour = ((hexHour & 0xF0) >> 4) * 10 + (hexHour & 0x0F); lastAMPM = convertedAM; if(lastMin != convertedMin) { if(lastAMPM == convertedAM) { drawScreenBlack(); } drawScreenBlack(); } if(convertedHour >= 12) { convertedHour = convertedHour -12; convertedAM = 0; }else{ convertedAM = 1; convertedHour = convertedHour; } if(lastAMPM != convertedAM) { drawScreenBlack(); lastAMPM = convertedAM; } lastAMPM = convertedAM; if(convertedMin<10) { sprintf(clockBuffer,"%d:0%d", convertedHour, convertedMin); } else { sprintf(clockBuffer,"%d:%d", convertedHour, convertedMin); } if(convertedHour ==0) { convertedAM = 1; if(convertedMin<10) { sprintf(clockBuffer,"12:0%d",convertedMin); } else { sprintf(clockBuffer,"12:%d",convertedMin); } } if(convertedHour != 0) { if(convertedHour > 9){ tft_setCursor(47, 125); tft_writeString(clockBuffer); } else{ tft_setCursor(92, 125); tft_writeString(clockBuffer); } } if(convertedHour ==0) { tft_setCursor(47, 125); tft_writeString(clockBuffer); } lastMin = convertedMin; tft_setTextSize(4); tft_setTextColor(ILI9341_WHITE); tft_setCursor(265, 146); if(convertedAM==1) { sprintf(amPmBuffer,"am"); tft_writeString(amPmBuffer); } else{ sprintf(amPmBuffer,"pm"); tft_writeString(amPmBuffer); } } if(toggleAlarm==1) //If setting Alarm { tft_setTextSize(7); tft_setTextColor(ILI9341_WHITE); if(alarmMinute<10) { sprintf(clockBuffer,"%d:0%d", alarmHour, alarmMinute); } else { sprintf(clockBuffer,"%d:%d", alarmHour, alarmMinute); } if(alarmHour > 9){ tft_setCursor(47, 125); tft_writeString(clockBuffer); }else{ tft_setCursor(92, 125); tft_writeString(clockBuffer); } tft_setTextSize(4); tft_setTextColor(ILI9341_WHITE); tft_setCursor(265, 146); if(alarmAM==1) { sprintf(amPmBuffer,"am"); tft_writeString(amPmBuffer); } if(alarmAM==0) { sprintf(amPmBuffer,"pm"); tft_writeString(amPmBuffer); } } } PT_END(pt); } int latch = 0; int16_t thisxpos; int16_t thisypos; int16_t thiszpos; int clickUpHour = 0; int clickUpMinute = 0; int clickDownHour = 0; int clickDownMinute = 0; int clickUpHourAlarm = 0; int clickUpMinuteAlarm= 0; int clickDownHourAlarm = 0; int clickDownMinuteAlarm = 0; int clickSet = 0; int clickAlarm = 0; int clickONOFF=0; int clickAMPM = 0; int backlightSetting = 4; struct TSPoint p; int lastbacklightSetting =4; static PT_THREAD (protothread_pointGetter(struct pt *pt)) { PT_BEGIN(pt); while(1) { PT_YIELD_TIME_msec(1); tft_setTextSize(1); tft_setCursor(0, 225); tft_setTextColor(ILI9341_BLACK); tft_writeString(myOwnBuffer); if(latch==1) //If pressed down take in no input { thisxpos = -50; thisypos = -50; //thisxpos = xpos; //Used for testing touch regions if you comment out the 2 previous lines and uncomment out these //thisypos = ypos; //You will just be able to move your finger around on the screen to get different points } if(p.z>1 && latch ==0) //If you haven't been holding it down and just pressed it take a point { thisxpos = scaleTouchX(p.x); thisypos = scaleTouchY(p.y); thiszpos = p.z; latch = 1; } if(p.z==0) //Once you take off pressure reset the point and latch { latch = 0; thisxpos = scaleTouchX(p.x); thisypos = scaleTouchY(p.y); thiszpos = p.z; } xpos=thisxpos; ypos=thisypos; zpos=thiszpos; if(setTime ==1) { if((xpos>=85 )&&(xpos<=175)&&(ypos<=225)&&(ypos>=150)) //UpLeft - Working { clickUpHour=1; } if((xpos>=235 )&&(xpos<300)&&(ypos<=225)&&(ypos>=150)) //downLeft - Working { clickDownHour=1; } if((xpos>= 85)&&(xpos<=175)&&(ypos<=100)&&(ypos>=80)) //upRight - Working { clickUpMinute=1; } if((xpos>=235)&&(xpos<=300)&&(ypos<=100)&&(ypos>=80)) //downRight - Working { clickDownMinute=1; } if(((xpos>=100)&&(xpos<=160)&&(ypos<=70)&&(ypos>=50)||((xpos>=245)&&(xpos<=275)&&(ypos<=70)&&(ypos>=50)))) //AMPM clicker { clickAMPM=1; } } if(toggleAlarm ==1) { if((xpos>=90 )&&(xpos<=150)&&(ypos<=215)&&(ypos>=165)) //UpLeft - Working { clickUpHourAlarm=1; } if((xpos>=235 )&&(xpos<280)&&(ypos<=215)&&(ypos>=175)) //downLeft - Working { clickDownHourAlarm=1; } if((xpos>= 100)&&(xpos<=160)&&(ypos<=105)&&(ypos>=85)) //upRight - Working { clickUpMinuteAlarm=1; } if((xpos>=240)&&(xpos<=280)&&(ypos<=100)&&(ypos>=80)) //downRight - Working { clickDownMinuteAlarm=1; } if(((xpos>=100)&&(xpos<=160)&&(ypos<=70)&&(ypos>=50)||((xpos>=245)&&(xpos<=275)&&(ypos<=70)&&(ypos>=50)))) //AMPM clicker { clickAMPM=1; } } if((xpos>= 20)&&(xpos<=100)&&(ypos<=115)&&(ypos>=80)) { clickSet=1; } if((xpos>= 20)&&(xpos<=80)&&(ypos<=80)&&(ypos>=50)) { clickAlarm=1; } if((xpos>=25 )&&(xpos<=95)&&(ypos<=255)&&(ypos>=200) &&(zpos>5) &&(zpos<300)) { clickONOFF=1; } // Backlight Dim /////////////////////////////////////////////////////////////////////////////////////////// if((xpos>=110 )&&(xpos<=135)&&(ypos<=270)&&(ypos>=240)){ //Empty Sun, hitting this should darken screen if(backlightSetting == 0) { backlightSetting = 0; } else if(backlightSetting != 0) { backlightSetting = backlightSetting - 1; } } // Backlight Bright////////////////////////////////////////////////////////////////////////////////////////////////// if((xpos>=110 )&&(xpos<=135)&&(ypos<=220)&&(ypos>=200)){ //Filled Sun, hitting this should brighten screen if(backlightSetting == 4) { backlightSetting = 4; } else if(backlightSetting != 4) { backlightSetting = backlightSetting + 1; } } setup_backlightSetting(); if (backlightSetting == 4) //Brightness should be based on how many times you've hit the sun button { set_duty_cycle(100); } else if (backlightSetting == 3) { set_duty_cycle(75); } else if (backlightSetting == 2) { set_duty_cycle(50); } else if (backlightSetting == 1) { set_duty_cycle(25); } else if (backlightSetting == 0) { set_duty_cycle(5); } buttonClick(); int hexSec = time.sec; int hexMin = time.min; int hexHour = time.hour; int convertedSec = ((hexSec & 0xF0) >> 4) * 10 + (hexSec & 0x0F); //http://stackoverflow.com/questions/28133020/how-to-convert-bcd-to-decimal int convertedMin = ((hexMin & 0xF0) >> 4) * 10 + (hexMin & 0x0F); int convertedHour = ((hexHour & 0xF0) >> 4) * 10 + (hexHour & 0x0F); // tft_setTextSize(1); // tft_setCursor(0, 225); //Prints out all of the requested values in one go // //sprintf(myOwnBuffer,"Hour %d : Minute %d : Second %d", convertedHour,convertedMin,convertedSec); //You can use these lines to print out the current real time clock time to test the Real Time clock // sprintf(myOwnBuffer,"x %d : y %d : z %d", xpos,ypos,zpos); //You can use these lines to print out the XYZ Positions on the botton of the screen to test clicking regions // tft_setTextColor(ILI9341_WHITE); // tft_writeString(myOwnBuffer); } PT_END(pt); } void buttonClick() //When you hit a button in any region it should call this method so that it can set the correct variables to change based on what you've hit { if(clickUpHour==1) { drawScreenBlack(); if(hour==12) { hour = 0; } hour++; clickUpHour = 0; writeScreen =1; } if(clickUpMinute==1) { drawScreenBlack(); if(minute==59) { minute = -1; } minute++; clickUpMinute = 0; writeScreen =1; } if(clickDownHour==1) { drawScreenBlack(); if(hour==1) { hour = 13; } hour--; clickDownHour = 0; writeScreen =1; } if(clickDownMinute==1) { drawScreenBlack(); if(minute==0) { minute = 60; } minute--; clickDownMinute = 0; writeScreen =1; } if(clickAlarm==1) { drawScreenBlack(); if(toggleAlarm==1) { toggleAlarm = 0; setAlarmRTCC(); } else { toggleAlarm = 1; if(setTime ==1) { setTime =0; setTimeRTCC(); } } clickAlarm = 0; } if(clickONOFF==1) { if(toggleONOFF==1) { toggleONOFF = 0; if(alarmTriggered){ alarmTriggered = 0; alarmNote = 0; } } else { toggleONOFF = 1; } clickONOFF = 0; timeChanged =1; } if(clickSet ==1) { drawScreenBlack(); if(setTime==1) { setTime = 0; setTimeRTCC(); } else { setTime = 1; if(toggleAlarm ==1) { toggleAlarm =0; } } writeScreen =1; clickSet = 0; } if(clickAMPM==1) //For set & alarm, need set alarm so that it doesn't change to 1 and then back every time { drawScreenBlack(); if(setTime==1) { int setAlarm = am; if(setAlarm==0) { am=1; } if(setAlarm==1) { am=0; } writeScreen =1; } if(toggleAlarm==1) { int setAlarm2 = alarmAM; if(setAlarm2==0) { alarmAM=1; } if(setAlarm2==1) { alarmAM=0; } timeChanged =1; } clickAMPM = 0; drawScreenBlack(); } //Alarm Settings if(clickUpHourAlarm==1) { drawScreenBlack(); if(alarmHour==12) { alarmHour = 0; } alarmHour++; clickUpHourAlarm = 0; timeChanged =1; } if(clickUpMinuteAlarm==1) { drawScreenBlack(); if(alarmMinute==59) { alarmMinute = -1; } alarmMinute++; clickUpMinuteAlarm = 0; timeChanged =1; } if(clickDownHourAlarm==1) { drawScreenBlack(); if(alarmHour==1) { alarmHour = 13; } alarmHour--; clickDownHourAlarm = 0; timeChanged =1; } if(clickDownMinuteAlarm==1) { drawScreenBlack(); if(alarmMinute==0) { alarmMinute = 60; } alarmMinute--; clickDownMinuteAlarm = 0; timeChanged =1; } } //EEG Code uint8_t signalQuality = 3; uint8_t attention = 2; uint8_t meditation = 1; uint32_t eegPower[8] = {4, 3, 2, 1, 4, 3, 2, 1}; char csvBuffer[100]; uint8_t latestByte; uint8_t lastByte; uint8_t packetIndex = 0; uint8_t inPacket = 0; uint8_t packetLength = 0; uint8_t freshPacket = 0; uint8_t hasPower = 0; uint8_t dataPacket[32]; uint8_t recievedData[32]; void clearEegPower() { // Zero the power bands. int i = 0; while(i < 8) { eegPower[i] = 0; i++; } } int parsePacket() { // Loop through the packet, extracting data. // Based on mindset_communications_protocol.pdf from the Neurosky Mindset SDK. // Returns true if passing succeeds hasPower = 0; int parseSuccess = 1; int rawValue = 0; //clearEegPower(); // clear the eeg power to make sure we're honest about missing values int i = 0; while(i < 32){ switch (dataPacket[i]) { case 0x2: signalQuality = dataPacket[++i]; break; case 0x4: attention = dataPacket[++i]; break; case 0x5: meditation = dataPacket[++i]; break; case 0x83: // ASIC_EEG_POWER: eight big-endian 3-uint8_t unsigned integer values representing delta, theta, low-alpha high-alpha, low-beta, high-beta, low-gamma, and mid-gamma EEG band power values // The next uint8_t sets the length, usually 24 (Eight 24-bit numbers... big endian?) // We dont' use this value so let's skip it and just increment i i++; // Extract the values int j = 0; while(j < 8){ eegPower[j] = ((uint32_t)dataPacket[++i] << 16) | ((uint32_t)dataPacket[++i] << 8) | (uint32_t)dataPacket[++i]; j++; } hasPower = 1; // This seems to happen once during start-up on the force trainer. Strange. Wise to wait a couple of packets before // you start reading. break; case 0x80: // We dont' use this value so let's skip it and just increment i // uint8_t packetLength = packetData[++i]; i++; rawValue = ((int)dataPacket[++i] << 8) | dataPacket[++i]; break; default: parseSuccess = 0; break; } i++; } return parseSuccess; } char* readCSV() { // spit out a big string? // find out how big this really needs to be // should be popped off the stack once it goes out of scope? // make the character array as small as possible if(hasPower == 1) { sprintf(csvBuffer,"%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d", signalQuality, attention, meditation, eegPower[0], eegPower[1], eegPower[2], eegPower[3], eegPower[4], eegPower[5], eegPower[6], eegPower[7] ); return csvBuffer; } else { sprintf(csvBuffer,"%d,%d,%d", signalQuality, attention, meditation ); return csvBuffer; } } int alphaCount = 0; int hexSec; int hexMin; int hexHour; int convSec; int convMin; int convHour; int alarmHexSec; int alarmHexMin; int alarmHexHour; int alarmConvertedSec; int alarmConvertedMin; int alarmConvertedHour; static PT_THREAD (protothread_alarmControl(struct pt *pt)) { PT_BEGIN(pt); while(1) { PT_YIELD_TIME_msec(1000); if(freshPacket && toggleONOFF) { parsePacket(); } rtccTime time; time.l= RtccGetTime(); rtccTime alarmTime; alarmTime.l= mRtccGetAlarmTime(); hexSec = time.sec; hexMin = time.min; hexHour = time.hour; convSec = ((hexSec & 0xF0) >> 4) * 10 + (hexSec & 0x0F); //http://stackoverflow.com/questions/28133020/how-to-convert-bcd-to-decimal convMin = ((hexMin & 0xF0) >> 4) * 10 + (hexMin & 0x0F); convHour = ((hexHour & 0xF0) >> 4) * 10 + (hexHour & 0x0F); alarmHexSec = alarmTime.sec; alarmHexMin = alarmTime.min; alarmHexHour = alarmTime.hour; alarmConvertedSec = ((alarmHexSec & 0xF0) >> 4) * 10 + (alarmHexSec & 0x0F); //http://stackoverflow.com/questions/28133020/how-to-convert-bcd-to-decimal alarmConvertedMin = ((alarmHexMin & 0xF0) >> 4) * 10 + (alarmHexMin & 0x0F); alarmConvertedHour = ((alarmHexHour & 0xF0) >> 4) * 10 + (alarmHexHour & 0x0F); //if alarm is on begin reading if(toggleONOFF && !alarmTriggered){ if(alarmConvertedHour == convHour && alarmConvertedMin == convMin) { alarmTriggered = 1; alphaCount = 0; } //check if within 30 minutes of alarm if(alarmConvertedMin < 30){ //condition if alarm is set less than 30 past an hour if((abs((alarmConvertedHour - convHour)) == 1) && (convMin > (30 + alarmConvertedMin))){ //check for alpha intensity spikes if(eegPower[3] > 50000 && eegPower[4] > 50000){ alphaCount = alphaCount + 1; } //decide if light sleep state if(alphaCount > 10){ alarmTriggered = 1; alphaCount = 0; } } }else if (((alarmConvertedHour - convHour) == 0) && (abs((alarmConvertedMin - convMin)) < 30)){ //check for alpha intensity spikes if(eegPower[3] > 50000 && eegPower[4] > 50000){ alphaCount = alphaCount + 1; } //decide if light sleep state if(alphaCount > 10){ alarmTriggered = 1; alphaCount = 0; } } } //initiate alarm if(alarmTriggered){ if(alarmNote){ alarmNote = 0; }else{ alarmNote = 1; } } } // and indicate the end of the thread PT_END(pt); } #define __UART_2_ISR __ISR(_UART_2_VECTOR, ipl2) void __UART_2_ISR UART_2_InterruptRoutine(void) { latestByte = ReadUART2(); U2STA = (U2STA ^ 0x00000002); if(inPacket){ if(packetIndex <= 32){ recievedData[packetIndex] = latestByte; packetIndex++; }else{ freshPacket = 1; inPacket = 0; int i = 0; while(i < 32){ dataPacket[i] = recievedData[i]; i++; } memset(recievedData, 0, 32); } } if(latestByte == 170 && lastByte == 170){ inPacket = 1; packetIndex = 0; } lastByte = latestByte; INTClearFlag(INT_U2RX); } //Audio Generation int accumulator1 = 0x0000; int16_t sineTable[256] = {2047, 2096, 2145,2194, 2243, 2292, 2340, 2389, 2437, 2485, 2533, 2580, 2627, 2674, 2720, 2766, 2812, 2857, 2902 ,2946, 2989 ,3032, 3075, 3116, 3158, 3198 ,3238, 3277, 3315, 3353, 3389, 3425, 3461, 3495, 3528, 3561, 3592, 3623, 3653, 3681, 3709, 3736, 3762, 3786, 3810, 3833, 3854, 3875, 3894, 3912, 3929, 3945, 3960, 3974, 3986, 3997, 4008, 4017, 4024, 4031, 4036, 4041, 4044, 4045, 4046, 4045, 4044, 4041, 4036, 4031, 4024, 4017, 4008, 3997, 3986, 3974, 3960, 3945, 3929, 3912, 3894, 3875, 3854, 3833, 3810, 3786, 3762, 3736, 3709, 3681, 3653, 3623, 3592, 3561, 3528, 3495, 3461, 3425, 3389, 3353, 3315, 3277, 3238, 3198, 3158, 3116, 3075, 3032, 2989, 2946, 2902, 2857, 2812, 2766, 2720, 2674, 2627, 2580, 2533, 2485, 2437, 2389, 2340, 2292, 2243, 2194, 2145, 2096, 2047, 1998, 1949, 1900, 1851, 1802, 1754, 1705, 1657, 1609, 1561, 1514, 1467, 1420, 1374, 1328, 1282, 1237, 1192, 1148, 1105, 1062, 1019, 978 ,936, 896, 856, 817, 779, 741, 705, 669, 633, 599, 566, 533, 502, 471, 441, 413, 385, 358, 332, 308, 284, 261, 240, 219, 200, 182, 165, 149, 134, 120, 108, 97, 86, 77, 70, 63, 58, 53, 50, 49, 48, 49, 50, 53, 58, 63, 70, 77, 86, 97, 108, 120, 134, 149, 165, 182, 200, 219, 240, 261, 284, 308, 332, 358, 385, 413, 441, 471, 502, 533, 566, 599, 633, 669, 705 ,741, 779, 817, 856, 896, 936, 978, 1019, 1062, 1105, 1148 ,1192, 1237, 1282, 1328, 1374, 1420, 1467, 1514, 1561, 1609, 1657, 1705, 1754, 1802, 1851, 1900, 1949, 1998}; uint16_t amplitude1; void initDAC(void){ dirSS = 0; SS = 1; SpiChnOpen(2, SPI_OPEN_MSTEN | SPI_OPEN_MODE16 | SPI_OPEN_ON |SPI_OPEN_DISSDI | SPI_OPEN_CKE_REV , 2); PPSOutput(2, RPB5, SDO2); // Clock at 20MHz } inline void writeDAC(uint16_t data){ SS = 0; while (TxBufFullSPI2()); WriteSPI2(data); while (SPI2STATbits.SPIBUSY); // wait for it to end of transaction SS = 1; } void setup_backlightSetting(){ OpenTimer2(T2_ON | T2_PS_1_1 , 0xFFFF); OpenOC1(OC_ON | OC_TIMER_MODE16 | OC_TIMER2_SRC | OC_PWM_FAULT_PIN_ENABLE, 0, 0); } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// inline void set_duty_cycle(unsigned int percent) { unsigned int dutycycle = 0xFFFF * percent / 100; SetDCOC1PWM(dutycycle); } void __ISR(_TIMER_1_VECTOR,ipl1) TIMER1_Handler(void) { accumulator1 += 0x0100; if(accumulator1 == 0xff00) { accumulator1 = 0x0000; } amplitude1 = (sineTable[accumulator1>>8 & 0xff]>>1); if(alarmNote){ writeDAC(0x3000 |amplitude1); } INTClearFlag(INT_T1); //clear interrupt flag } // === Main ====================================================== void main(void) { SYSTEMConfigPerformance(PBCLK); ANSELA = 0; ANSELB = 0; CM1CON = 0; CM2CON = 0; PT_setup(); // === config threads ==========// turns OFF UART support and debugger pin tft_init_hw();// init the display tft_begin(); //Setup Display tft_fillScreen(ILI9341_BLACK); tft_setRotation(3); mOSCEnableSOSC(); rtccRes res = RtccInit(); if(res == RTCC_CLK_ON) //{ RtccWrEnable(1); RtccOpen(0x23595500, 0x00000000, 0); // hour min second 2 extra bit, 2extrabit month, day RtccSetAlarmTime(0x12000000); //} INTEnableSystemMultiVectoredInt(); // === setup system wide interrupts ======== drawDisplay(); INTEnable(INT_SOURCE_UART_RX(UART2), INT_ENABLED); INTSetVectorPriority(INT_VECTOR_UART(UART2), INT_PRIORITY_LEVEL_2); INTSetVectorSubPriority(INT_VECTOR_UART(UART2), INT_SUB_PRIORITY_LEVEL_0); OpenTimer1(T1_ON|T23_PS_1_1,237); INTEnable(INT_T1, INT_ENABLED); //Enable Interrupt on the InputCapture INTSetVectorPriority(INT_TIMER_1_VECTOR, INT_PRIORITY_LEVEL_1); //Set the Priority of the Input Capture ISR initDAC(); PT_INIT(&pt_clockDisplay); PT_INIT(&pt_pointGetter); PT_INIT(&pt_rtcConfig); PT_INIT(&pt_alarmControl); PORTSetPinsDigitalOut(IOPORT_B, BIT_7); //7 PPSOutput(1, RPB7, OC1); OpenOC1(OC_ON | OC_TIMER_MODE16 | OC_TIMER2_SRC | OC_PWM_FAULT_PIN_ENABLE, 0, 0); OpenTimer2(T2_ON | T2_PS_1_1 , 0xFFFF); set_duty_cycle(20); configureADC(); // round-robin scheduler for thread while (1)//Run all protothreads { p.x = 0; p.y = 0; p.z = 0; getPoint(&p); //Get a point all the time PT_SCHEDULE(protothread_clockDisplay(&pt_clockDisplay)); //Run all threads PT_SCHEDULE(protothread_pointGetter(&pt_pointGetter)); PT_SCHEDULE(protothread_rtcConfig(&pt_rtcConfig)); PT_SCHEDULE(protothread_alarmControl(&pt_alarmControl)); } } // main // === end ====================================================== void drawSet() //This function rewrites the Set time buttons and Set Alarm buttons { tft_drawLine(63, 1, 63, 12, ILI9341_NAVY); tft_drawRoundRect(0, 0, 64, 59, 3, ILI9341_NAVY); tft_drawRoundRect(191, 0, 200, 59, 3, ILI9341_NAVY); //x, y, w, h, r, color tft_drawLine(191, 1, 191, 12, ILI9341_NAVY); //x0, y0, x1, y1, color tft_drawLine(245, 0, 245, 58, ILI9341_NAVY); //x0, y0, x1, y1, color tft_drawLine(247, 0, 247, 58, ILI9341_NAVY); //x0, y0, x1, y1, color //Print Set Time tft_setTextSize(2); tft_setCursor(200, 15); //Prints out all of the requested values in one go sprintf(setBuffer,"Set"); tft_setTextColor(ILI9341_BLACK); tft_writeString(setBuffer); tft_setCursor(195, 32); //Prints out all of the requested values in one go sprintf(setBuffer,"Time"); tft_setTextColor(ILI9341_BLACK); tft_writeString(setBuffer); //Print Set Alarm tft_setCursor(264, 15); sprintf(alarmBuffer,"Set"); tft_writeString(alarmBuffer); tft_setCursor(254, 32); sprintf(alarmBuffer,"Alarm"); tft_writeString(alarmBuffer); }