PSoC 6 pioneer kit multi library code for emwin driven tft display, capsense and mechanical button input.

Dependencies:   PinDetect

Revision:
2:02954bc28fc5
Parent:
1:f8f4e789361f
--- a/main.cpp	Fri Oct 11 12:43:11 2019 +0000
+++ b/main.cpp	Thu Oct 17 15:55:03 2019 +0000
@@ -10,10 +10,12 @@
 DigitalOut ledGreen(LED_GREEN);
 DigitalIn  sw2(SWITCH2, PullUp);
 DigitalOut ledRed(LED_RED);
+DigitalOut userLed(LED4); /* Amber LED */
 DigitalOut ledBlue(LED_BLUE);
 DigitalOut ledBlue2(P13_4);
 DigitalOut ledGreen2(P13_3);
 DigitalOut ledRed2(P13_2);
+PwmOut myPwm(LED5); /* Red Ststus LED */
 
 PinDetect pb2(P0_4);
 
@@ -25,8 +27,10 @@
 * Global constants
 ***************************************************************************/
 #define SLIDER_NUM_TOUCH                        (1u)    /* Number of touches on the slider */
-#define LED_OFF                                 (1u) 
-#define LED_ON                                  (0u)
+#define nLED_OFF                                (1u)
+#define nLED_ON                                 (0u)
+#define LED_OFF                                 (0u)
+#define LED_ON                                  (1u)
 #define CAPSENSE_SCAN_PERIOD_MS                 (20u)   /* milliseconds */
 
 
@@ -40,13 +44,15 @@
 void CapSense_InterruptHandler(void);
 void CapSenseEndOfScanCallback(cy_stc_active_scan_sns_t * ptrActiveScan);
 void InitCapSenseClock(void);
-
+void LED_Init(void);
+void Display_Init(void);
+void CapSense_Init(void);
+void Button_Init(void);
 
 /*******************************************************************************
 * Interrupt configuration
 *******************************************************************************/
-const cy_stc_sysint_t CapSense_ISR_cfg =
-{
+const cy_stc_sysint_t CapSense_ISR_cfg = {
     .intrSrc = CYBSP_CSD_IRQ,
     .intrPriority = 4u
 };
@@ -64,29 +70,34 @@
 Semaphore capsense_sem;
 EventQueue queue;
 cy_stc_scb_ezi2c_context_t EZI2C_context;
-uint32_t prevBtn0Status = 0u; 
+uint32_t prevBtn0Status = 0u;
 uint32_t prevBtn1Status = 0u;
 uint32_t prevSliderPos = 0u;
 bool    sw2Pressed = false;
 bool    prevSw2Pressed = false;
+bool    sw2ToggleStatus = false;
+bool    btn0ToggleStatus = false;
+bool    btn1ToggleStatus = false;
 
 
 /* External global references */
 //extern GUI_CONST_STORAGE GUI_BITMAP bmCypressLogo_1bpp;
 
-extern GUI_CONST_STORAGE GUI_BITMAP bmExampleImage;  
+extern GUI_CONST_STORAGE GUI_BITMAP bmExampleImage;
 extern GUI_CONST_STORAGE GUI_BITMAP bmCypressLogo;
 
 // Callback routine is interrupt activated by a debounced pb1 hit
-void pb2_hit_callback (void) {
+void pb2_hit_callback (void)
+{
 //   printf("Count is %d\n", ++countit);
     sw2Pressed = true;
-    }
+}
 // Callback routine is interrupt activated by a debounced pb1 hit
-void pb2_released_callback (void) {
+void pb2_released_callback (void)
+{
 //   printf("Count is %d\n", ++countit);
     sw2Pressed = false;
-    }
+}
 /*******************************************************************************
 * Function Name: bool IsBtnClicked
 ********************************************************************************
@@ -98,46 +109,49 @@
 *
 * Return:
 *  Status of the SW2 button:
-*  true when button was pressed and then released and 
+*  true when button was pressed and then released and
 *  false in other cases
 *
+* This code is not used in this version of the program as PinDetect Library
+* is employed to debounce the switch.
+*
 *******************************************************************************/
-bool IsBtnClicked(void)
-{
-    int currBtnState;
-    static int prevBtnState  = BTN_RELEASED;
-
-    bool result = false;
-
-    currBtnState = sw2;
-
-    if((prevBtnState == BTN_RELEASED) && (currBtnState == BTN_PRESSED))
-    {
-        result = true;
-    }
-
-    prevBtnState = currBtnState;
-
-    wait_ms(5);
-
-    return result;
-}
-
+/*
+ * bool IsBtnClicked(void)
+ * {
+ *     int currBtnState;
+ *     static int prevBtnState  = BTN_RELEASED;
+ * 
+ *     bool result = false;
+ * 
+ *     currBtnState = sw2;
+ * 
+ *     if((prevBtnState == BTN_RELEASED) && (currBtnState == BTN_PRESSED)) {
+ *         result = true;
+ *     }
+ * 
+ *     prevBtnState = currBtnState;
+ * 
+ *     wait_ms(5);
+ * 
+ *     return result;
+ * }
+ */
 /*****************************************************************************
 * Function Name: RunCapSenseScan()
 ******************************************************************************
 * Summary:
 *   This function starts the scan, and processes the touch status. It is
-* periodically called by an event dispatcher. 
+* periodically called by an event dispatcher.
 *
 *****************************************************************************/
 void RunCapSenseScan(void)
 {
     Cy_CapSense_ScanAllWidgets(&cy_capsense_context);
-    capsense_sem.acquire();          
+    capsense_sem.acquire();
     Cy_CapSense_ProcessAllWidgets(&cy_capsense_context);
     Cy_CapSense_RunTuner(&cy_capsense_context);
-    ProcessTouchStatus();     
+    ProcessTouchStatus();
 }
 
 
@@ -158,13 +172,13 @@
     /* Initialize EZI2C pins */
     Cy_GPIO_Pin_Init(CYBSP_EZI2C_SCL_PORT, CYBSP_EZI2C_SCL_PIN, &CYBSP_EZI2C_SCL_config);
     Cy_GPIO_Pin_Init(CYBSP_EZI2C_SDA_PORT, CYBSP_EZI2C_SDA_PIN, &CYBSP_EZI2C_SDA_config);
-    
+
     /* Configure the peripheral clock for EZI2C */
     Cy_SysClk_PeriphAssignDivider(PCLK_SCB3_CLOCK, CY_SYSCLK_DIV_8_BIT, 1U);
     Cy_SysClk_PeriphDisableDivider(CY_SYSCLK_DIV_8_BIT, 1U);
     Cy_SysClk_PeriphSetDivider(CY_SYSCLK_DIV_8_BIT, 1U, 7U);
     Cy_SysClk_PeriphEnableDivider(CY_SYSCLK_DIV_8_BIT, 1U);
-    
+
     Cy_SCB_EZI2C_Init(CYBSP_CSD_COMM_HW, &CYBSP_CSD_COMM_config, &EZI2C_context);
 
     /* Initialize and enable EZI2C interrupts */
@@ -175,7 +189,7 @@
      * to I2C master at primary slave address request.
      */
     Cy_SCB_EZI2C_SetBuffer1(CYBSP_CSD_COMM_HW, (uint8 *)&cy_capsense_tuner,
-        sizeof(cy_capsense_tuner), sizeof(cy_capsense_tuner), &EZI2C_context);
+                            sizeof(cy_capsense_tuner), sizeof(cy_capsense_tuner), &EZI2C_context);
 
     /* Enable EZI2C block */
     Cy_SCB_EZI2C_Enable(CYBSP_CSD_COMM_HW);
@@ -193,49 +207,111 @@
 *******************************************************************************/
 void ProcessTouchStatus(void)
 {
-    uint32_t currSliderPos;    
-    uint32_t currBtn0Status = Cy_CapSense_IsSensorActive(CY_CAPSENSE_BUTTON0_WDGT_ID, CY_CAPSENSE_BUTTON0_SNS0_ID, &cy_capsense_context);        
-    uint32_t currBtn1Status = Cy_CapSense_IsSensorActive(CY_CAPSENSE_BUTTON1_WDGT_ID, CY_CAPSENSE_BUTTON1_SNS0_ID, &cy_capsense_context);       
+    uint32_t currSliderPos;
+    uint32_t currBtn0Status = Cy_CapSense_IsSensorActive(CY_CAPSENSE_BUTTON0_WDGT_ID, CY_CAPSENSE_BUTTON0_SNS0_ID, &cy_capsense_context);
+    uint32_t currBtn1Status = Cy_CapSense_IsSensorActive(CY_CAPSENSE_BUTTON1_WDGT_ID, CY_CAPSENSE_BUTTON1_SNS0_ID, &cy_capsense_context);
     cy_stc_capsense_touch_t *sldrTouch = Cy_CapSense_GetTouchInfo(CY_CAPSENSE_LINEARSLIDER0_WDGT_ID, &cy_capsense_context);
     char outputString[80];
-    if(currBtn0Status != prevBtn0Status)
-    {
+    if(currBtn0Status != prevBtn0Status) {
         printf("Button_0 status: %u\r\n", currBtn0Status);
         sprintf(outputString,"  Button_0 status: %u   ", currBtn0Status);
         GUI_SetTextAlign(GUI_TA_HCENTER);
         GUI_DispStringAt(outputString, 160, 60);
+        if (currBtn0Status) {
+            if(btn0ToggleStatus) {
+                btn0ToggleStatus = false;
+                /* Turn The Blue RGB LED off */
+                ledBlue2 = LED_OFF;
+                 /* turn virtual Blue led off */
+                GUI_SetColor(50);
+                GUI_FillCircle(240,70,8);
+            } else {
+                btn0ToggleStatus = true;
+                /* Turn The Blue RGB LED on */
+                ledBlue2 = LED_ON;
+                /* turn virtual led on */
+                GUI_SetColor(255);
+                GUI_FillCircle(240,70,8);
+            }
+        }
+        GUI_SetColor(GUI_WHITE);
+
         prevBtn0Status = currBtn0Status;
     }
-    
-    if(currBtn1Status != prevBtn1Status)
-    {
+
+    if(currBtn1Status != prevBtn1Status) {
         printf("Button_1 status: %u\r\n", currBtn1Status);
         sprintf(outputString,"  Button_1 status: %u   ", currBtn1Status);
         GUI_SetTextAlign(GUI_TA_HCENTER);
         GUI_DispStringAt(outputString, 160, 80);
+        btn1ToggleStatus = !btn1ToggleStatus;
+        if (currBtn1Status) {
+            if(btn1ToggleStatus) {
+                btn1ToggleStatus = false;
+                /* Turn The Red RGB LED off */
+                ledRed2 = LED_OFF;
+                /* turn virtual led off */
+                GUI_SetColor(0x320000);
+                GUI_FillCircle(240,90,8);
+            } else {
+                btn1ToggleStatus = true;
+                /* Turn The Red RGB LED on */
+                ledRed2 = LED_ON;
+                /* turn virtual led on */
+                GUI_SetColor(0xff0000);
+                GUI_FillCircle(240,90,8);
+            }
+        }
+        GUI_SetColor(GUI_WHITE);
         prevBtn1Status = currBtn1Status;
-    } 
+    }
     if(sw2Pressed != prevSw2Pressed) {
+        printf("Button sw2 status: %u\r\n", sw2Pressed);
         sprintf(outputString,"  Button_2 status: %u   ", sw2Pressed);
         GUI_SetTextAlign(GUI_TA_HCENTER);
         GUI_DispStringAt(outputString, 160, 100);
+        sw2ToggleStatus = !sw2ToggleStatus;
+        if (sw2Pressed) {
+            if(sw2ToggleStatus) {
+                sw2ToggleStatus = false;
+                /* Turn The Green RGB LED off */
+                ledGreen2 = LED_OFF;
+                /* turn virtual Green led off */
+                GUI_SetColor(0x3200);
+                GUI_FillCircle(240,110,8);
+            } else {
+                sw2ToggleStatus = true;
+                /* Turn The Green RGB LED on */
+                ledGreen2 = LED_ON;
+                /* turn virtual Green led on */
+                GUI_SetColor(0xff00);
+                GUI_FillCircle(240,110,8);
+            }
+        }
+        GUI_SetColor(GUI_WHITE);
         prevSw2Pressed = sw2Pressed;
     }
-    if (sldrTouch->numPosition == SLIDER_NUM_TOUCH)
-    {       
+    if (sldrTouch->numPosition == SLIDER_NUM_TOUCH) {
         currSliderPos = sldrTouch->ptrPosition->x;
 
-        if(currSliderPos != prevSliderPos)
-        {
+        if(currSliderPos != prevSliderPos) {
             printf("Slider position: %u\r\n", currSliderPos);
             sprintf(outputString,"  Slider position: %u   ", currSliderPos);
             GUI_SetTextAlign(GUI_TA_HCENTER);
             GUI_DispStringAt(outputString, 160, 120);
+            myPwm.pulsewidth_ms((100-currSliderPos)/10);
+            GUI_SetColor(GUI_BLACK);
+            GUI_SetPenSize(10);
+            GUI_DrawLine((61 + (currSliderPos * 2)), 150, 260, 150);
+            GUI_SetColor(GUI_MAGENTA);
+            GUI_SetPenSize(10);
+            GUI_DrawLine(60, 150, (60 + (currSliderPos * 2)), 150);
+            GUI_SetColor(GUI_WHITE);
             prevSliderPos = currSliderPos;
         }
     }
-
-    ledRed = (sw2Pressed || currBtn0Status || currBtn1Status || (sldrTouch->numPosition == SLIDER_NUM_TOUCH)) ? LED_ON : LED_OFF;
+    /* flash a LED when a key press is detected */
+    userLed = (sw2Pressed || currBtn0Status || currBtn1Status || (sldrTouch->numPosition == SLIDER_NUM_TOUCH)) ? nLED_ON : nLED_OFF;
 }
 
 
@@ -243,7 +319,7 @@
 * Function Name: EZI2C_InterruptHandler
 ********************************************************************************
 * Summary:
-*   Wrapper function for handling interrupts from EZI2C block. 
+*   Wrapper function for handling interrupts from EZI2C block.
 *
 *******************************************************************************/
 void EZI2C_InterruptHandler(void)
@@ -284,7 +360,7 @@
 * Function Name: InitCapSenseClock()
 ******************************************************************************
 * Summary:
-*  This function configures the peripheral clock for CapSense.  
+*  This function configures the peripheral clock for CapSense.
 *
 *****************************************************************************/
 void InitCapSenseClock(void)
@@ -294,33 +370,35 @@
     Cy_SysClk_PeriphSetDivider(CYBSP_CSD_CLK_DIV_HW, CYBSP_CSD_CLK_DIV_NUM, 0u);
     Cy_SysClk_PeriphEnableDivider(CYBSP_CSD_CLK_DIV_HW, CYBSP_CSD_CLK_DIV_NUM);
 }
-
-/*****************************************************************************
-* Function Name: main()
-******************************************************************************
-* Summary:
-*   Main function that starts a thread for CapSense scan and enters a forever
-*   wait state. 
-*
-*****************************************************************************/
-int main(void)
+void LED_Init(void)
 {
-    /* Turn off both red and green LEDs */
-    ledGreen = LED_OFF;
-    ledRed = LED_OFF;
-    ledBlue = LED_OFF; 
-    ledGreen2 = 0; /* 1 for on 0 for off */
-    ledRed2 = 0;
-    ledBlue2 = 0; 
+    /* Turn off all LEDs */
+    ledGreen = nLED_OFF;
+    ledRed = nLED_OFF;
+    ledBlue = nLED_OFF;
+    userLed = nLED_OFF;
+    ledGreen2 = LED_OFF; /* 1 for on 0 for off */
+    ledRed2 = LED_OFF;
+    ledBlue2 = LED_OFF;
+
+    /* Setup pwm output initially at 50% */
+    myPwm.period_ms(10);
+    myPwm.pulsewidth_ms(5);
+
+}
+
+void Display_Init(void)
+{
+
+    /* memory buffer for sprintf */
     char outputString[80];
-   
-    /* Initialize EmWin driver*/
-    GUI_Init();
+
     /* Set font size, foreground and background Colours */
     GUI_SetFont(GUI_FONT_16B_1);
     GUI_SetColor(GUI_WHITE);
     GUI_SetBkColor(GUI_BLACK);
 
+    /* Clear screen and print splash screen */
     GUI_Clear();
     GUI_SetTextAlign(GUI_TA_HCENTER);
     GUI_DispStringAt("Capsense Demo", 160, 20);
@@ -329,25 +407,31 @@
     GUI_SetTextAlign(GUI_TA_HCENTER);
     GUI_DispStringAt(outputString, 160, 180);
     wait(0.10);
- /* Configure AMUX bus for CapSense */
+}
+
+void CapSense_Init(void)
+{
+
+    /* memory buffer for sprintf */
+    char outputString[80];
+
+    /* Configure AMUX bus for CapSense */
     init_cycfg_routing();
-    
+
     /* Configure PERI clocks for CapSense */
-    InitCapSenseClock(); 
-    
+    InitCapSenseClock();
+
     InitTunerCommunication();
-    
+
     /* Initialize the CSD HW block to the default state. */
     cy_status status = Cy_CapSense_Init(&cy_capsense_context);
-    if(CY_RET_SUCCESS != status)
-    {
+    if(CY_RET_SUCCESS != status) {
         printf("CapSense initialization failed. Status code: %u\r\n", status);
         sprintf(outputString,"CapSense initialization failed. Status code: %u", status);
         GUI_SetTextAlign(GUI_TA_HCENTER);
         GUI_DispStringAt(outputString, 160, 40);
         wait(osWaitForever);
     }
-    
     /* Initialize CapSense interrupt */
     Cy_SysInt_Init(&CapSense_ISR_cfg, &CapSense_InterruptHandler);
     NVIC_ClearPendingIRQ(CapSense_ISR_cfg.intrSrc);
@@ -356,23 +440,15 @@
     /* Initialize the CapSense firmware modules. */
     Cy_CapSense_Enable(&cy_capsense_context);
     Cy_CapSense_RegisterCallback(CY_CAPSENSE_END_OF_SCAN_E, CapSenseEndOfScanCallback, &cy_capsense_context);
-    
-    /* Create a thread to run CapSense scan periodically using an event queue
-     * dispatcher.
-     */
-    Thread thread(osPriorityNormal, OS_STACK_SIZE, NULL, "CapSense Scan Thread");
-    thread.start(callback(&queue, &EventQueue::dispatch_forever));
-    queue.call_every(CAPSENSE_SCAN_PERIOD_MS, RunCapSenseScan);
+
+}
 
-    /* Initiate scan immediately since the first call of RunCapSenseScan()
-     * happens CAPSENSE_SCAN_PERIOD_MS after the event queue dispatcher has
-     * started. 
-     */
-    Cy_CapSense_ScanAllWidgets(&cy_capsense_context); 
-    
+/* Setup debounced mechanical buttons and callbacks*/
+void Button_Init(void)
+{
 
-   // Use internal pullups for pushbutton
-    pb2.mode(PullUp);    
+    /* Use internal pullups for pushbutton */
+    pb2.mode(PullUp);
 //    pb2.mode(PullUp);
     // Delay for initial pullup to take effect
     wait(.01);
@@ -383,7 +459,51 @@
     pb2.setSampleFrequency();
 
     pb2.attach_asserted( &pb2_released_callback );
-    wait(osWaitForever);
-    
 }
 
+/*****************************************************************************
+* Function Name: main()
+******************************************************************************
+* Summary:
+*   Main function that starts a thread for CapSense scan, initialises the
+*   tft screen, debounce buttons, turns off LEDs and enters a forever
+*   wait state.
+*
+*****************************************************************************/
+int main(void)
+{
+
+    /* Initialise EmWin driver*/
+    GUI_Init();
+
+    /* Initialise display */
+    Display_Init();
+
+    /* Set up CapSense paramteters */
+    CapSense_Init();
+
+    /* Create a thread to run CapSense scan periodically using an event queue
+     * dispatcher.
+     */
+    Thread thread(osPriorityNormal, OS_STACK_SIZE, NULL, "CapSense Scan Thread");
+    thread.start(callback(&queue, &EventQueue::dispatch_forever));
+    queue.call_every(CAPSENSE_SCAN_PERIOD_MS, RunCapSenseScan);
+
+    /* Initiate scan immediately since the first call of RunCapSenseScan()
+     * happens CAPSENSE_SCAN_PERIOD_MS after the event queue dispatcher has
+     * started.
+     */
+    Cy_CapSense_ScanAllWidgets(&cy_capsense_context);
+
+    /* Setup debounced mechanical buttons and callbacks*/
+    Button_Init();
+
+    /* Turn off all LEDs, set up pwm drive */
+    LED_Init();
+
+    /* everything is started so goto sleep forever while events control the hardware */
+    wait(osWaitForever);
+
+}
+
+