Wakeup Light with touch user interface, anti-aliased Font, SD card access and RTC usage on STM32F746NG-DISCO board

Dependencies:   BSP_DISCO_F746NG_patch_fixed LCD_DISCO_F746NG TS_DISCO_F746NG FATFileSystem TinyJpgDec_interwork mbed-src

Files at this revision

API Documentation at this revision

Comitter:
the_sz
Date:
Thu Oct 29 18:09:31 2015 +0000
Parent:
2:80026d18fcf3
Child:
4:2fe89414d4df
Commit message:
ui menu working, time() added

Changed in this revision

LED.cpp Show annotated file Show diff for this revision Revisions of this file
LED.h Show annotated file Show diff for this revision Revisions of this file
SDFileSystem.lib Show annotated file Show diff for this revision Revisions of this file
UI.cpp Show annotated file Show diff for this revision Revisions of this file
UI.h Show annotated file Show diff for this revision Revisions of this file
UI_Main.cpp Show annotated file Show diff for this revision Revisions of this file
UI_Wakup.cpp Show annotated file Show diff for this revision Revisions of this file
WakeupLight.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- a/LED.cpp	Thu Oct 29 12:59:54 2015 +0000
+++ b/LED.cpp	Thu Oct 29 18:09:31 2015 +0000
@@ -48,6 +48,44 @@
             LED_SetColor(color);
         }
     }
+    else if (ledAnimation==LAE_OFF)
+    {
+        float       red;
+        float       green;
+        float       blue;
+        float       white;
+        uint32_t    redInt;
+        uint32_t    greenInt;
+        uint32_t    blueInt;
+        uint32_t    whiteInt;
+
+        red=ledRed.read();
+        if (red>0.0)
+            red-=0.001;
+        red=MAX(red,0.0);
+        redInt=(int32_t)(red*255.0);
+
+        green=ledGreen.read();
+        if (green>0.0)
+            green-=0.001;
+        green=MAX(green,0.0);
+        greenInt=(int32_t)(green*255.0);
+
+        blue=ledBlue.read();
+        if (blue>0)
+            blue-=0.001;
+        blue=MAX(blue,0.0);
+        blueInt=(int32_t)(blue*255.0);
+
+        white=ledWhite.read();
+        if (white>0)
+            white-=0.001;
+        white=MAX(white,0.0);
+        whiteInt=(int32_t)(white*255.0);
+
+        color=COLOR_CREATE(redInt,greenInt,blueInt,whiteInt);
+        LED_SetColor(color);
+    }
 }
 
 void LED_StartAnimation(LED_ANIMATION_ENUM animation)
--- a/LED.h	Thu Oct 29 12:59:54 2015 +0000
+++ b/LED.h	Thu Oct 29 18:09:31 2015 +0000
@@ -5,6 +5,7 @@
 {
     LAE_NONE,
     LAE_WAKEUP,
+    LAE_OFF,
 
 } LED_ANIMATION_ENUM;
      
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SDFileSystem.lib	Thu Oct 29 18:09:31 2015 +0000
@@ -0,0 +1,1 @@
+http://developer.mbed.org/teams/mbed/code/SDFileSystem/#7b35d1709458
--- a/UI.cpp	Thu Oct 29 12:59:54 2015 +0000
+++ b/UI.cpp	Thu Oct 29 18:09:31 2015 +0000
@@ -1,6 +1,6 @@
 #include "WakeupLight.h"
 
-#define CLIENT_COLOR_BG         ((uint32_t)0xFF602020)
+#define CLIENT_COLOR_BG         ((uint32_t)0xFF000000)
 #define CLIENT_COLOR_FG         ((uint32_t)0xFFD0D0D0)
 
 #define HEADER_HEIGHT           25
@@ -12,10 +12,25 @@
 
 #define COLOR_BG                ((uint32_t)0xFF000000)
 
+#define MAX_BOXES_PER_LINE      3
+#define BOX_SPACING             10
+#define BOX_TEXT_SPACING        10
+#define BOX_COLOR_BG            ((uint32_t)0xFF808080)
+#define BOX_COLOR_FG            CLIENT_COLOR_FG
+
 LCD_DISCO_F746NG                uiLcd;
 TS_DISCO_F746NG                 uiTs;
-int32_t                         uiCounter=0;
+uint16_t                        uiLastTouchX;
+uint16_t                        uiLastTouchY;
 UI_STRUCT                       *uiCurrent=NULL;
+UI_STRUCT                       uiClock;
+UI_STRUCT                       uiClockInWords;
+UI_STRUCT                       uiWakeup;
+UI_STRUCT                       uiMain;
+UI_BOX_LIST_ITEM_STRUCT         uiMainItems[]=
+{
+    { "Clock" }, { "Clock\nWith Words" }, { "Adjust\nTimers" }, { "Lights On" }, { "Lights Off" }
+};
 
 //
 // helper function
@@ -26,6 +41,33 @@
     uiLcd.FillRect(0,HEADER_HEIGHT,uiLcd.GetXSize()-1,uiLcd.GetYSize()-1);
 }
 
+void UI_ShowDisplayText(int16_t x,int16_t y,char *text)
+{
+    int16_t             xStart;
+    int16_t             charWidth;
+    int16_t             charHeight;
+
+    xStart=x;
+    charHeight=uiLcd.GetFont()->Height+3;
+    charWidth=uiLcd.GetFont()->Width;
+    
+    while ((*text)!='\0')
+    {
+        if ((*text)=='\n')
+        {
+            y+=charHeight;
+            x=xStart;
+        }
+        else
+        {
+            uiLcd.DisplayChar(x,y,*text);
+            x+=charWidth;
+        }
+
+        text++;
+    }
+}
+    
 //
 // box list
 //
@@ -33,14 +75,81 @@
 {
     if (initial==true)
     {
+        int8_t          lines;
+        int8_t          columns;
+        int8_t          box;
+        int16_t         width;
+        int16_t         height;
+        int16_t         startX;
+        int16_t         startY;
+
         // fill background
         UI_ShowClearClientRect();
-    }
+
+        // paint boxes
+        if (uiCurrent->data.boxList.count<=MAX_BOXES_PER_LINE)
+            lines=1;
+        else
+            lines=2;
+
+        columns=((uiCurrent->data.boxList.count + (lines-1)) / lines);
+
+        width=(uiLcd.GetXSize() - BOX_SPACING) / columns;
+        height=(uiLcd.GetYSize() - HEADER_HEIGHT - BOX_SPACING) / lines;
+
+        for (box=0;box<uiCurrent->data.boxList.count;box++)
+        {
+            startX=BOX_SPACING+(width*(box % columns));
+            startY=HEADER_HEIGHT+BOX_SPACING+(height*(box/columns));
+
+            // paint box background
+            uiLcd.SetTextColor(BOX_COLOR_BG);
+            uiLcd.FillRect(startX,startY,width-BOX_SPACING,height-BOX_SPACING);
+            
+            // paint box text
+            uiLcd.SetFont(&display_font_12x22);
+            uiLcd.SetBackColor(BOX_COLOR_BG);
+            uiLcd.SetTextColor(BOX_COLOR_FG);
+            UI_ShowDisplayText(startX+BOX_TEXT_SPACING,startY+BOX_TEXT_SPACING,uiCurrent->data.boxList.items[box].name);
+        }
+      }
 }
 
 void UI_ClickBoxList(uint16_t x,uint16_t y)
 {
-    // detect at which block was clicked
+    int8_t          lines;
+    int8_t          columns;
+    int8_t          box;
+    int16_t         width;
+    int16_t         height;
+    int16_t         startX;
+    int16_t         startY;
+
+    // detect at which box was clicked
+    if (uiCurrent->data.boxList.count<=MAX_BOXES_PER_LINE)
+        lines=1;
+    else
+        lines=2;
+
+    columns=((uiCurrent->data.boxList.count + (lines-1)) / lines);
+
+    width=(uiLcd.GetXSize() - BOX_SPACING) / columns;
+    height=(uiLcd.GetYSize() - HEADER_HEIGHT - BOX_SPACING) / lines;
+
+    for (box=0;box<uiCurrent->data.boxList.count;box++)
+    {
+        startX=BOX_SPACING+(width*(box % columns));
+        startY=HEADER_HEIGHT+BOX_SPACING+(height*(box/columns));
+
+        if (        (x>=startX) && (x<(startX+width-BOX_SPACING))
+                &&
+                    (y>=startY) && (y<(startY+height-BOX_SPACING))
+           )
+        {
+            uiCurrent->handler(UR_CLICK,box,uiCurrent);
+            break;
+        }
+    }
 }
 
 //
@@ -57,7 +166,12 @@
 
 void UI_ClickMessageBox(uint16_t x,uint16_t y)
 {
+    uint32_t                    index;
+
     // detect at which button was clicked
+    index=0;
+
+    uiCurrent->handler(UR_CLICK,index,uiCurrent);
 }
 
 //
@@ -66,6 +180,8 @@
 void UI_ShowClock(bool initial)
 {
     char                        buffer[100];
+    struct tm                   *tmStruct;
+    time_t                      timeValue;
 
     if (initial==true)
     {
@@ -78,14 +194,16 @@
     uiLcd.SetFont(&display_font_12x22);
     uiLcd.SetBackColor(CLOCK_COLOR_BG);
     uiLcd.SetTextColor(CLOCK_COLOR_FG);
-    snprintf(buffer,sizeof(buffer),"ABC %u",uiCounter);
-    uiCounter++;
+    timeValue=time(NULL);
+    tmStruct=localtime(&timeValue);
+    snprintf(buffer,sizeof(buffer),"%u:%02u:%02u",tmStruct->tm_hour,tmStruct->tm_min,tmStruct->tm_sec);
     uiLcd.DisplayStringAt(0,100,(uint8_t *)buffer,CENTER_MODE);
 }
 
 void UI_ClickClock(uint16_t x,uint16_t y)
 {
     // exit view
+    UI_Show(&uiMain);
 }
 
 //
@@ -122,6 +240,7 @@
 void UI_ClickClockInWords(uint16_t x,uint16_t y)
 {
     // exit view
+    UI_Show(&uiMain);
 }
 
 //
@@ -138,7 +257,12 @@
 
 void UI_ClickTimerAdjust(uint16_t x,uint16_t y)
 {
+    uint32_t                    index;
+
     // detect at which button was clicked
+    index=0;
+
+    uiCurrent->handler(UR_CLICK,index,uiCurrent);
 }
 
 //
@@ -148,6 +272,9 @@
 {
     uiCurrent=NULL;
 
+    uiLastTouchX=0;
+    uiLastTouchY=0;
+
     uiLcd.Init();
     uiLcd.Clear(COLOR_BG);
 
@@ -155,11 +282,27 @@
         DPrintf("UI_Init: Size: %ux%u.\r\n",uiLcd.GetXSize(),uiLcd.GetYSize());
     else
         DPrintf("UI_Init: Can't init touch screen.\r\n");
+
+    // setup ui structs
+    uiClock.flags=UI_FLAG_TYPE_CLOCK;
+    uiClock.handler=NULL;
+    uiClockInWords.flags=UI_FLAG_TYPE_CLOCK_IN_WORDS;
+    uiClockInWords.handler=NULL;
+    uiWakeup.flags=UI_FLAG_TYPE_BOX_LIST;
+    uiWakeup.handler=UI_WakeupHandler;
+    uiMain.flags=UI_FLAG_TYPE_BOX_LIST;
+    uiMain.handler=UI_MainHandler;
+    uiMain.data.boxList.items=uiMainItems;
+    uiMain.data.boxList.count=COUNT_OF(uiMainItems);
+
+    UI_Show(&uiMain);
 }
 
 void UI_ShowChrome(bool initial)
 {
     char                        buffer[100];
+    struct tm                   *tmStruct;
+    time_t                      timeValue;
 
     if (initial==true)
     {
@@ -172,48 +315,61 @@
     uiLcd.SetFont(&display_font_12x22);
     uiLcd.SetBackColor(HEADER_COLOR_BG);
     uiLcd.SetTextColor(HEADER_COLOR_FG);
-    snprintf(buffer,sizeof(buffer),"ABC %u",uiCounter);
-    uiCounter++;
+    timeValue=time(NULL);
+    tmStruct=localtime(&timeValue);
+    snprintf(buffer,sizeof(buffer),"%u:%02u",tmStruct->tm_hour,tmStruct->tm_min);
     uiLcd.DisplayStringAt(0,3,(uint8_t *)buffer,CENTER_MODE);
 
     // show next alarm
+    //XXX
 }
 
 void UI_Update(bool initial)
 {
+    uint8_t     typeFlag;
+
     if ((uiCurrent->flags & UI_FLAG_NEEDS_CHROME)!=0)
         UI_ShowChrome(initial);
 
-    if ((uiCurrent->flags & UI_FLAG_TYPE_BOX_LIST)!=0)
+    typeFlag=uiCurrent->flags & ~UI_FLAG_NEEDS_CHROME;
+    if ((typeFlag & UI_FLAG_TYPE_BOX_LIST)!=0)
         UI_ShowBoxList(initial);
-    else if ((uiCurrent->flags & UI_FLAG_TYPE_MESSAGE_BOX)!=0)
+    else if ((typeFlag & UI_FLAG_TYPE_MESSAGE_BOX)!=0)
         UI_ShowMessageBox(initial);
-    else if ((uiCurrent->flags & UI_FLAG_TYPE_CLOCK)!=0)
+    else if ((typeFlag & UI_FLAG_TYPE_CLOCK)!=0)
         UI_ShowClock(initial);
-    else if ((uiCurrent->flags & UI_FLAG_TYPE_CLOCK_IN_WORDS)!=0)
+    else if ((typeFlag & UI_FLAG_TYPE_CLOCK_IN_WORDS)!=0)
         UI_ShowClockInWords(initial);
-    else if ((uiCurrent->flags & UI_FLAG_TYPE_TIMER_ADJUST)!=0)
+    else if ((typeFlag & UI_FLAG_TYPE_TIMER_ADJUST)!=0)
         UI_ShowTimerAdjust(initial);
 }
 
 void UI_Show(UI_STRUCT *ui)
 {
+    DPrintf("UI_Show: 0x%X.\r\n",ui->flags);
+
     uiCurrent=ui;
 
+    if (uiCurrent->handler!=NULL)
+        uiCurrent->handler(UR_SHOW,0,uiCurrent);
+
     UI_Update(true);
 }
 
 void UI_Click(uint16_t x,uint16_t y)
 {
-    if ((uiCurrent->flags & UI_FLAG_TYPE_BOX_LIST)!=0)
+    uint8_t     typeFlag;
+
+    typeFlag=uiCurrent->flags & ~UI_FLAG_NEEDS_CHROME;
+    if ((typeFlag & UI_FLAG_TYPE_BOX_LIST)!=0)
         UI_ClickBoxList(x,y);
-    else if ((uiCurrent->flags & UI_FLAG_TYPE_MESSAGE_BOX)!=0)
+    else if ((typeFlag & UI_FLAG_TYPE_MESSAGE_BOX)!=0)
         UI_ClickMessageBox(x,y);
-    else if ((uiCurrent->flags & UI_FLAG_TYPE_CLOCK)!=0)
+    else if ((typeFlag & UI_FLAG_TYPE_CLOCK)!=0)
         UI_ClickClock(x,y);
-    else if ((uiCurrent->flags & UI_FLAG_TYPE_CLOCK_IN_WORDS)!=0)
+    else if ((typeFlag & UI_FLAG_TYPE_CLOCK_IN_WORDS)!=0)
         UI_ClickClockInWords(x,y);
-    else if ((uiCurrent->flags & UI_FLAG_TYPE_TIMER_ADJUST)!=0)
+    else if ((typeFlag & UI_FLAG_TYPE_TIMER_ADJUST)!=0)
         UI_ClickTimerAdjust(x,y);
 }
 
@@ -224,10 +380,26 @@
     uiTs.GetState(&tsState);
     if (tsState.touchDetected>0)
     {
-        DPrintf("UI_Poll: #%u - %ux%u.\r\n",tsState.touchDetected,tsState.touchX[0],tsState.touchY[0]);
-        UI_Click(tsState.touchX[0],tsState.touchY[0]);
+        if (        (ABS(uiLastTouchX-tsState.touchX[0])>4)
+                ||
+                    (ABS(uiLastTouchY-tsState.touchY[0])>4)
+           )
+        {
+            DPrintf("UI_Poll: #%u - %ux%u.\r\n",tsState.touchDetected,tsState.touchX[0],tsState.touchY[0]);
+
+            uiLastTouchX=tsState.touchX[0];
+            uiLastTouchY=tsState.touchY[0];
+    
+            if (uiCurrent!=NULL)
+                UI_Click(tsState.touchX[0],tsState.touchY[0]);
+        }
     }
   
     if (uiCurrent!=NULL)
+    {
+        if (uiCurrent->handler!=NULL)
+            uiCurrent->handler(UR_TIMER,0,uiCurrent);
+
         UI_Update(false);
+    }
 }
--- a/UI.h	Thu Oct 29 12:59:54 2015 +0000
+++ b/UI.h	Thu Oct 29 18:09:31 2015 +0000
@@ -8,14 +8,35 @@
 #define UI_FLAG_TYPE_TIMER_ADJUST       (0x10 | UI_FLAG_NEEDS_CHROME)
 #define UI_FLAG_NEEDS_CHROME            0x20
 
+typedef enum
+{
+    UR_CLICK,
+    UR_TIMER,
+    UR_SHOW,
+
+} UI_REASON_ENUM;
+
+struct UI_STRUCT_;
+typedef void (*UI_HANDLER_CALLBACK)(UI_REASON_ENUM reason,uint32_t index,UI_STRUCT_ *ui);
+
 typedef struct
 {
+    char                                *name;
+
+} UI_BOX_LIST_ITEM_STRUCT;
+    
+typedef struct UI_STRUCT_
+{
     int8_t                              flags;      // UI_FLAG_...
+    UI_HANDLER_CALLBACK                 handler;
 
     union
     {
         struct
         {
+            UI_BOX_LIST_ITEM_STRUCT     *items;
+            uint8_t                     count;
+
         } boxList;
 
         struct
@@ -24,22 +45,23 @@
 
         struct
         {
-        } clock;
-
-        struct
-        {
-        } clockInWords;
-
-        struct
-        {
         } timerAdjust;
 
     } data;
 
 } UI_STRUCT;
-    
+
+extern UI_STRUCT                        uiClock;
+extern UI_STRUCT                        uiClockInWords;
+extern UI_STRUCT                        uiWakeup;
+extern UI_STRUCT                        uiMain;
+
 void UI_Init(void);
 void UI_Poll(void);
 void UI_Show(UI_STRUCT *ui);
 
+void UI_MainHandler(UI_REASON_ENUM reason,uint32_t index,UI_STRUCT *ui);
+
+void UI_WakeupHandler(UI_REASON_ENUM reason,uint32_t index,UI_STRUCT *ui);
+
 #endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/UI_Main.cpp	Thu Oct 29 18:09:31 2015 +0000
@@ -0,0 +1,31 @@
+#include "WakeupLight.h"
+
+int32_t                         timeOut;
+
+void UI_MainHandler(UI_REASON_ENUM reason,uint32_t index,UI_STRUCT *ui)
+{
+    switch (reason)
+    {
+        case UR_CLICK:
+            if (index==0)
+                UI_Show(&uiClock);
+            else if (index==1)
+                UI_Show(&uiClockInWords);
+            else if (index==2)
+                UI_Show(&uiWakeup);
+            else if (index==3)
+                LED_StartAnimation(LAE_WAKEUP);
+            else if (index==4)
+                LED_StartAnimation(LAE_OFF);
+            break;
+
+        case UR_TIMER:
+            if ((time(NULL)-timeOut)>10)
+                UI_Show(&uiClock);
+            break;
+            
+        case UR_SHOW:
+            timeOut=time(NULL);
+            break;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/UI_Wakup.cpp	Thu Oct 29 18:09:31 2015 +0000
@@ -0,0 +1,13 @@
+#include "WakeupLight.h"
+
+void UI_WakeupHandler(UI_REASON_ENUM reason,uint32_t index,UI_STRUCT *ui)
+{
+    switch (reason)
+    {
+        case UR_CLICK:
+            break;
+
+        case UR_TIMER:
+            break;
+    }
+}
--- a/WakeupLight.h	Thu Oct 29 12:59:54 2015 +0000
+++ b/WakeupLight.h	Thu Oct 29 18:09:31 2015 +0000
@@ -6,6 +6,11 @@
 #include "TS_DISCO_F746NG.h"
 #include "LCD_DISCO_F746NG.h"
 
+#define COUNT_OF(__ARRAY__)                                 (sizeof(__ARRAY__)/sizeof(__ARRAY__[0]))
+#define MIN(X,Y)                                            ((X) < (Y) ? (X) : (Y))
+#define MAX(X,Y)                                            ((X) > (Y) ? (X) : (Y))
+#define ABS(_VALUE_)                                        (((_VALUE_) < 0) ? -(_VALUE_) : (_VALUE_))
+
 #include "OnBoardLED.h"
 #include "LED.h"
 #include "UI.h"
--- a/main.cpp	Thu Oct 29 12:59:54 2015 +0000
+++ b/main.cpp	Thu Oct 29 18:09:31 2015 +0000
@@ -1,7 +1,5 @@
 #include "WakeupLight.h"
 
-    UI_STRUCT ui;
-
 int main()
 {
     debug_Init();
@@ -14,11 +12,6 @@
 
     UI_Init();
 
-    //LED_StartAnimation(LAE_WAKEUP);
-
-    ui.flags=UI_FLAG_TYPE_CLOCK;
-    UI_Show(&ui);
-
     for (;;)
     {
         UI_Poll();
--- a/mbed.bld	Thu Oct 29 12:59:54 2015 +0000
+++ b/mbed.bld	Thu Oct 29 18:09:31 2015 +0000
@@ -1,1 +1,1 @@
-http://mbed.org/users/mbed_official/code/mbed/builds/34e6b704fe68
\ No newline at end of file
+http://mbed.org/users/mbed_official/code/mbed/builds/9296ab0bfc11
\ No newline at end of file