Andrew Reed / Mbed OS city1082-capsense-sw2-tft-leds

Dependencies:   PinDetect

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include "GUI.h"
00003 #include "cy8ckit_028_tft.h"
00004 #define Cy_SysLib_Delay wait_ms
00005 #include "cy_pdl.h"
00006 #include "cycfg_capsense.h"
00007 #include "cycfg.h"
00008 #include "PinDetect.h"
00009 
00010 DigitalOut ledGreen(LED_GREEN);
00011 DigitalIn  sw2(SWITCH2, PullUp);
00012 DigitalOut ledRed(LED_RED);
00013 DigitalOut userLed(LED4); /* Amber LED */
00014 DigitalOut ledBlue(LED_BLUE);
00015 DigitalOut ledBlue2(P13_4);
00016 DigitalOut ledGreen2(P13_3);
00017 DigitalOut ledRed2(P13_2);
00018 PwmOut myPwm(LED5); /* Red Ststus LED */
00019 
00020 PinDetect pb2(P0_4);
00021 
00022 /* Macros for switch press status */
00023 #define BTN_PRESSED        (0u)
00024 #define BTN_RELEASED       (1u)
00025 
00026 /***************************************************************************
00027 * Global constants
00028 ***************************************************************************/
00029 #define SLIDER_NUM_TOUCH                        (1u)    /* Number of touches on the slider */
00030 #define nLED_OFF                                (1u)
00031 #define nLED_ON                                 (0u)
00032 #define LED_OFF                                 (0u)
00033 #define LED_ON                                  (1u)
00034 #define CAPSENSE_SCAN_PERIOD_MS                 (20u)   /* milliseconds */
00035 
00036 
00037 /***************************************
00038 * Function Prototypes
00039 **************************************/
00040 void RunCapSenseScan(void);
00041 void InitTunerCommunication(void);
00042 void ProcessTouchStatus(void);
00043 void EZI2C_InterruptHandler(void);
00044 void CapSense_InterruptHandler(void);
00045 void CapSenseEndOfScanCallback(cy_stc_active_scan_sns_t * ptrActiveScan);
00046 void InitCapSenseClock(void);
00047 void LED_Init(void);
00048 void Display_Init(void);
00049 void CapSense_Init(void);
00050 void Button_Init(void);
00051 
00052 /*******************************************************************************
00053 * Interrupt configuration
00054 *******************************************************************************/
00055 const cy_stc_sysint_t CapSense_ISR_cfg = {
00056     .intrSrc = CYBSP_CSD_IRQ,
00057     .intrPriority = 4u
00058 };
00059 
00060 const cy_stc_sysint_t EZI2C_ISR_cfg = {
00061     .intrSrc = CYBSP_CSD_COMM_IRQ,
00062     .intrPriority = 3u
00063 };
00064 
00065 
00066 /*******************************************************************************
00067 * Global variables
00068 *******************************************************************************/
00069 //DigitalOut ledRed(LED_RED);
00070 Semaphore capsense_sem;
00071 EventQueue queue;
00072 cy_stc_scb_ezi2c_context_t EZI2C_context;
00073 uint32_t prevBtn0Status = 0u;
00074 uint32_t prevBtn1Status = 0u;
00075 uint32_t prevSliderPos = 0u;
00076 bool    sw2Pressed = false;
00077 bool    prevSw2Pressed = false;
00078 bool    sw2ToggleStatus = false;
00079 bool    btn0ToggleStatus = false;
00080 bool    btn1ToggleStatus = false;
00081 
00082 
00083 /* External global references */
00084 //extern GUI_CONST_STORAGE GUI_BITMAP bmCypressLogo_1bpp;
00085 
00086 extern GUI_CONST_STORAGE GUI_BITMAP bmExampleImage;
00087 extern GUI_CONST_STORAGE GUI_BITMAP bmCypressLogo;
00088 
00089 // Callback routine is interrupt activated by a debounced pb1 hit
00090 void pb2_hit_callback (void)
00091 {
00092 //   printf("Count is %d\n", ++countit);
00093     sw2Pressed = true;
00094 }
00095 // Callback routine is interrupt activated by a debounced pb1 hit
00096 void pb2_released_callback (void)
00097 {
00098 //   printf("Count is %d\n", ++countit);
00099     sw2Pressed = false;
00100 }
00101 /*******************************************************************************
00102 * Function Name: bool IsBtnClicked
00103 ********************************************************************************
00104 *
00105 * Summary: This non-blocking function implements SW2 button click check.
00106 *
00107 * Parameters:
00108 *  None
00109 *
00110 * Return:
00111 *  Status of the SW2 button:
00112 *  true when button was pressed and then released and
00113 *  false in other cases
00114 *
00115 * This code is not used in this version of the program as PinDetect Library
00116 * is employed to debounce the switch.
00117 *
00118 *******************************************************************************/
00119 /*
00120  * bool IsBtnClicked(void)
00121  * {
00122  *     int currBtnState;
00123  *     static int prevBtnState  = BTN_RELEASED;
00124  * 
00125  *     bool result = false;
00126  * 
00127  *     currBtnState = sw2;
00128  * 
00129  *     if((prevBtnState == BTN_RELEASED) && (currBtnState == BTN_PRESSED)) {
00130  *         result = true;
00131  *     }
00132  * 
00133  *     prevBtnState = currBtnState;
00134  * 
00135  *     wait_ms(5);
00136  * 
00137  *     return result;
00138  * }
00139  */
00140 /*****************************************************************************
00141 * Function Name: RunCapSenseScan()
00142 ******************************************************************************
00143 * Summary:
00144 *   This function starts the scan, and processes the touch status. It is
00145 * periodically called by an event dispatcher.
00146 *
00147 *****************************************************************************/
00148 void RunCapSenseScan(void)
00149 {
00150     Cy_CapSense_ScanAllWidgets(&cy_capsense_context);
00151     capsense_sem.acquire();
00152     Cy_CapSense_ProcessAllWidgets(&cy_capsense_context);
00153     Cy_CapSense_RunTuner(&cy_capsense_context);
00154     ProcessTouchStatus();
00155 }
00156 
00157 
00158 /*******************************************************************************
00159 * Function Name: InitTunerCommunication
00160 ********************************************************************************
00161 *
00162 * Summary:
00163 *   This function performs the following functions:
00164 *       - Initializes SCB block for operation in EZI2C mode
00165 *       - Configures EZI2C pins
00166 *       - Configures EZI2C clock
00167 *       - Sets communication data buffer to CapSense data structure
00168 *
00169 *******************************************************************************/
00170 void InitTunerCommunication(void)
00171 {
00172     /* Initialize EZI2C pins */
00173     Cy_GPIO_Pin_Init(CYBSP_EZI2C_SCL_PORT, CYBSP_EZI2C_SCL_PIN, &CYBSP_EZI2C_SCL_config);
00174     Cy_GPIO_Pin_Init(CYBSP_EZI2C_SDA_PORT, CYBSP_EZI2C_SDA_PIN, &CYBSP_EZI2C_SDA_config);
00175 
00176     /* Configure the peripheral clock for EZI2C */
00177     Cy_SysClk_PeriphAssignDivider(PCLK_SCB3_CLOCK, CY_SYSCLK_DIV_8_BIT, 1U);
00178     Cy_SysClk_PeriphDisableDivider(CY_SYSCLK_DIV_8_BIT, 1U);
00179     Cy_SysClk_PeriphSetDivider(CY_SYSCLK_DIV_8_BIT, 1U, 7U);
00180     Cy_SysClk_PeriphEnableDivider(CY_SYSCLK_DIV_8_BIT, 1U);
00181 
00182     Cy_SCB_EZI2C_Init(CYBSP_CSD_COMM_HW, &CYBSP_CSD_COMM_config, &EZI2C_context);
00183 
00184     /* Initialize and enable EZI2C interrupts */
00185     Cy_SysInt_Init(&EZI2C_ISR_cfg, &EZI2C_InterruptHandler);
00186     NVIC_EnableIRQ(EZI2C_ISR_cfg.intrSrc);
00187 
00188     /* Set up communication data buffer to CapSense data structure to be exposed
00189      * to I2C master at primary slave address request.
00190      */
00191     Cy_SCB_EZI2C_SetBuffer1(CYBSP_CSD_COMM_HW, (uint8 *)&cy_capsense_tuner,
00192                             sizeof(cy_capsense_tuner), sizeof(cy_capsense_tuner), &EZI2C_context);
00193 
00194     /* Enable EZI2C block */
00195     Cy_SCB_EZI2C_Enable(CYBSP_CSD_COMM_HW);
00196 }
00197 
00198 
00199 /*******************************************************************************
00200 * Function Name: ProcessTouchStatus
00201 ********************************************************************************
00202 *
00203 * Summary:
00204 *   Controls the LED status according to the status of CapSense widgets and
00205 *   prints the status to serial terminal.
00206 *
00207 *******************************************************************************/
00208 void ProcessTouchStatus(void)
00209 {
00210     uint32_t currSliderPos;
00211     uint32_t currBtn0Status = Cy_CapSense_IsSensorActive(CY_CAPSENSE_BUTTON0_WDGT_ID, CY_CAPSENSE_BUTTON0_SNS0_ID, &cy_capsense_context);
00212     uint32_t currBtn1Status = Cy_CapSense_IsSensorActive(CY_CAPSENSE_BUTTON1_WDGT_ID, CY_CAPSENSE_BUTTON1_SNS0_ID, &cy_capsense_context);
00213     cy_stc_capsense_touch_t *sldrTouch = Cy_CapSense_GetTouchInfo(CY_CAPSENSE_LINEARSLIDER0_WDGT_ID, &cy_capsense_context);
00214     char outputString[80];
00215     if(currBtn0Status != prevBtn0Status) {
00216         printf("Button_0 status: %u\r\n", currBtn0Status);
00217         sprintf(outputString,"  Button_0 status: %u   ", currBtn0Status);
00218         GUI_SetTextAlign(GUI_TA_HCENTER);
00219         GUI_DispStringAt(outputString, 160, 60);
00220         if (currBtn0Status) {
00221             if(btn0ToggleStatus) {
00222                 btn0ToggleStatus = false;
00223                 /* Turn The Blue RGB LED off */
00224                 ledBlue2 = LED_OFF;
00225                  /* turn virtual Blue led off */
00226                 GUI_SetColor(50);
00227                 GUI_FillCircle(240,70,8);
00228             } else {
00229                 btn0ToggleStatus = true;
00230                 /* Turn The Blue RGB LED on */
00231                 ledBlue2 = LED_ON;
00232                 /* turn virtual led on */
00233                 GUI_SetColor(255);
00234                 GUI_FillCircle(240,70,8);
00235             }
00236         }
00237         GUI_SetColor(GUI_WHITE);
00238 
00239         prevBtn0Status = currBtn0Status;
00240     }
00241 
00242     if(currBtn1Status != prevBtn1Status) {
00243         printf("Button_1 status: %u\r\n", currBtn1Status);
00244         sprintf(outputString,"  Button_1 status: %u   ", currBtn1Status);
00245         GUI_SetTextAlign(GUI_TA_HCENTER);
00246         GUI_DispStringAt(outputString, 160, 80);
00247         btn1ToggleStatus = !btn1ToggleStatus;
00248         if (currBtn1Status) {
00249             if(btn1ToggleStatus) {
00250                 btn1ToggleStatus = false;
00251                 /* Turn The Red RGB LED off */
00252                 ledRed2 = LED_OFF;
00253                 /* turn virtual led off */
00254                 GUI_SetColor(0x320000);
00255                 GUI_FillCircle(240,90,8);
00256             } else {
00257                 btn1ToggleStatus = true;
00258                 /* Turn The Red RGB LED on */
00259                 ledRed2 = LED_ON;
00260                 /* turn virtual led on */
00261                 GUI_SetColor(0xff0000);
00262                 GUI_FillCircle(240,90,8);
00263             }
00264         }
00265         GUI_SetColor(GUI_WHITE);
00266         prevBtn1Status = currBtn1Status;
00267     }
00268     if(sw2Pressed != prevSw2Pressed) {
00269         printf("Button sw2 status: %u\r\n", sw2Pressed);
00270         sprintf(outputString,"  Button_2 status: %u   ", sw2Pressed);
00271         GUI_SetTextAlign(GUI_TA_HCENTER);
00272         GUI_DispStringAt(outputString, 160, 100);
00273         sw2ToggleStatus = !sw2ToggleStatus;
00274         if (sw2Pressed) {
00275             if(sw2ToggleStatus) {
00276                 sw2ToggleStatus = false;
00277                 /* Turn The Green RGB LED off */
00278                 ledGreen2 = LED_OFF;
00279                 /* turn virtual Green led off */
00280                 GUI_SetColor(0x3200);
00281                 GUI_FillCircle(240,110,8);
00282             } else {
00283                 sw2ToggleStatus = true;
00284                 /* Turn The Green RGB LED on */
00285                 ledGreen2 = LED_ON;
00286                 /* turn virtual Green led on */
00287                 GUI_SetColor(0xff00);
00288                 GUI_FillCircle(240,110,8);
00289             }
00290         }
00291         GUI_SetColor(GUI_WHITE);
00292         prevSw2Pressed = sw2Pressed;
00293     }
00294     if (sldrTouch->numPosition == SLIDER_NUM_TOUCH) {
00295         currSliderPos = sldrTouch->ptrPosition->x;
00296 
00297         if(currSliderPos != prevSliderPos) {
00298             printf("Slider position: %u\r\n", currSliderPos);
00299             sprintf(outputString,"  Slider position: %u   ", currSliderPos);
00300             GUI_SetTextAlign(GUI_TA_HCENTER);
00301             GUI_DispStringAt(outputString, 160, 120);
00302             myPwm.pulsewidth_ms((100-currSliderPos)/10);
00303             GUI_SetColor(GUI_BLACK);
00304             GUI_SetPenSize(10);
00305             GUI_DrawLine((61 + (currSliderPos * 2)), 150, 260, 150);
00306             GUI_SetColor(GUI_MAGENTA);
00307             GUI_SetPenSize(10);
00308             GUI_DrawLine(60, 150, (60 + (currSliderPos * 2)), 150);
00309             GUI_SetColor(GUI_WHITE);
00310             prevSliderPos = currSliderPos;
00311         }
00312     }
00313     /* flash a LED when a key press is detected */
00314     userLed = (sw2Pressed || currBtn0Status || currBtn1Status || (sldrTouch->numPosition == SLIDER_NUM_TOUCH)) ? nLED_ON : nLED_OFF;
00315 }
00316 
00317 
00318 /*******************************************************************************
00319 * Function Name: EZI2C_InterruptHandler
00320 ********************************************************************************
00321 * Summary:
00322 *   Wrapper function for handling interrupts from EZI2C block.
00323 *
00324 *******************************************************************************/
00325 void EZI2C_InterruptHandler(void)
00326 {
00327     Cy_SCB_EZI2C_Interrupt(CYBSP_CSD_COMM_HW, &EZI2C_context);
00328 }
00329 
00330 /*****************************************************************************
00331 * Function Name: CapSense_InterruptHandler()
00332 ******************************************************************************
00333 * Summary:
00334 *  Wrapper function for handling interrupts from CSD block.
00335 *
00336 *****************************************************************************/
00337 void CapSense_InterruptHandler(void)
00338 {
00339     Cy_CapSense_InterruptHandler(CYBSP_CSD_HW, &cy_capsense_context);
00340 }
00341 
00342 
00343 /*****************************************************************************
00344 * Function Name: CapSenseEndOfScanCallback()
00345 ******************************************************************************
00346 * Summary:
00347 *  This function releases a semaphore to indicate end of a CapSense scan.
00348 *
00349 * Parameters:
00350 *  cy_stc_active_scan_sns_t* : pointer to active sensor details.
00351 *
00352 *****************************************************************************/
00353 void CapSenseEndOfScanCallback(cy_stc_active_scan_sns_t * ptrActiveScan)
00354 {
00355     capsense_sem.release();
00356 }
00357 
00358 
00359 /*****************************************************************************
00360 * Function Name: InitCapSenseClock()
00361 ******************************************************************************
00362 * Summary:
00363 *  This function configures the peripheral clock for CapSense.
00364 *
00365 *****************************************************************************/
00366 void InitCapSenseClock(void)
00367 {
00368     Cy_SysClk_PeriphAssignDivider(PCLK_CSD_CLOCK, CYBSP_CSD_CLK_DIV_HW, CYBSP_CSD_CLK_DIV_NUM);
00369     Cy_SysClk_PeriphDisableDivider(CYBSP_CSD_CLK_DIV_HW, CYBSP_CSD_CLK_DIV_NUM);
00370     Cy_SysClk_PeriphSetDivider(CYBSP_CSD_CLK_DIV_HW, CYBSP_CSD_CLK_DIV_NUM, 0u);
00371     Cy_SysClk_PeriphEnableDivider(CYBSP_CSD_CLK_DIV_HW, CYBSP_CSD_CLK_DIV_NUM);
00372 }
00373 void LED_Init(void)
00374 {
00375     /* Turn off all LEDs */
00376     ledGreen = nLED_OFF;
00377     ledRed = nLED_OFF;
00378     ledBlue = nLED_OFF;
00379     userLed = nLED_OFF;
00380     ledGreen2 = LED_OFF; /* 1 for on 0 for off */
00381     ledRed2 = LED_OFF;
00382     ledBlue2 = LED_OFF;
00383 
00384     /* Setup pwm output initially at 50% */
00385     myPwm.period_ms(10);
00386     myPwm.pulsewidth_ms(5);
00387 
00388 }
00389 
00390 void Display_Init(void)
00391 {
00392 
00393     /* memory buffer for sprintf */
00394     char outputString[80];
00395 
00396     /* Set font size, foreground and background Colours */
00397     GUI_SetFont(GUI_FONT_16B_1);
00398     GUI_SetColor(GUI_WHITE);
00399     GUI_SetBkColor(GUI_BLACK);
00400 
00401     /* Clear screen and print splash screen */
00402     GUI_Clear();
00403     GUI_SetTextAlign(GUI_TA_HCENTER);
00404     GUI_DispStringAt("Capsense Demo", 160, 20);
00405     printf("\r\nApplication has started. Touch any CapSense button or slider.\r\n");
00406     sprintf(outputString,"\r\nApplication has started.\r\n Touch any CapSense button or slider.");
00407     GUI_SetTextAlign(GUI_TA_HCENTER);
00408     GUI_DispStringAt(outputString, 160, 180);
00409     wait(0.10);
00410 }
00411 
00412 void CapSense_Init(void)
00413 {
00414 
00415     /* memory buffer for sprintf */
00416     char outputString[80];
00417 
00418     /* Configure AMUX bus for CapSense */
00419     init_cycfg_routing();
00420 
00421     /* Configure PERI clocks for CapSense */
00422     InitCapSenseClock();
00423 
00424     InitTunerCommunication();
00425 
00426     /* Initialize the CSD HW block to the default state. */
00427     cy_status status = Cy_CapSense_Init(&cy_capsense_context);
00428     if(CY_RET_SUCCESS != status) {
00429         printf("CapSense initialization failed. Status code: %u\r\n", status);
00430         sprintf(outputString,"CapSense initialization failed. Status code: %u", status);
00431         GUI_SetTextAlign(GUI_TA_HCENTER);
00432         GUI_DispStringAt(outputString, 160, 40);
00433         wait(osWaitForever);
00434     }
00435     /* Initialize CapSense interrupt */
00436     Cy_SysInt_Init(&CapSense_ISR_cfg, &CapSense_InterruptHandler);
00437     NVIC_ClearPendingIRQ(CapSense_ISR_cfg.intrSrc);
00438     NVIC_EnableIRQ(CapSense_ISR_cfg.intrSrc);
00439 
00440     /* Initialize the CapSense firmware modules. */
00441     Cy_CapSense_Enable(&cy_capsense_context);
00442     Cy_CapSense_RegisterCallback(CY_CAPSENSE_END_OF_SCAN_E, CapSenseEndOfScanCallback, &cy_capsense_context);
00443 
00444 }
00445 
00446 /* Setup debounced mechanical buttons and callbacks*/
00447 void Button_Init(void)
00448 {
00449 
00450     /* Use internal pullups for pushbutton */
00451     pb2.mode(PullUp);
00452 //    pb2.mode(PullUp);
00453     // Delay for initial pullup to take effect
00454     wait(.01);
00455     // Setup Interrupt callback functions for a pb hit
00456     pb2.attach_deasserted(&pb2_hit_callback);
00457 //    pb2.attach_deasserted(&pb2_hit_callback);
00458     // Start sampling pb inputs using interrupts
00459     pb2.setSampleFrequency();
00460 
00461     pb2.attach_asserted( &pb2_released_callback );
00462 }
00463 
00464 /*****************************************************************************
00465 * Function Name: main()
00466 ******************************************************************************
00467 * Summary:
00468 *   Main function that starts a thread for CapSense scan, initialises the
00469 *   tft screen, debounce buttons, turns off LEDs and enters a forever
00470 *   wait state.
00471 *
00472 *****************************************************************************/
00473 int main(void)
00474 {
00475 
00476     /* Initialise EmWin driver*/
00477     GUI_Init();
00478 
00479     /* Initialise display */
00480     Display_Init();
00481 
00482     /* Set up CapSense paramteters */
00483     CapSense_Init();
00484 
00485     /* Create a thread to run CapSense scan periodically using an event queue
00486      * dispatcher.
00487      */
00488     Thread thread(osPriorityNormal, OS_STACK_SIZE, NULL, "CapSense Scan Thread");
00489     thread.start(callback(&queue, &EventQueue::dispatch_forever));
00490     queue.call_every(CAPSENSE_SCAN_PERIOD_MS, RunCapSenseScan);
00491 
00492     /* Initiate scan immediately since the first call of RunCapSenseScan()
00493      * happens CAPSENSE_SCAN_PERIOD_MS after the event queue dispatcher has
00494      * started.
00495      */
00496     Cy_CapSense_ScanAllWidgets(&cy_capsense_context);
00497 
00498     /* Setup debounced mechanical buttons and callbacks*/
00499     Button_Init();
00500 
00501     /* Turn off all LEDs, set up pwm drive */
00502     LED_Init();
00503 
00504     /* everything is started so goto sleep forever while events control the hardware */
00505     wait(osWaitForever);
00506 
00507 }
00508 
00509