Andrew Reed / Mbed OS CITY1082-capsense-tft
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 
00009 DigitalOut ledGreen(LED_GREEN);
00010 DigitalOut ledRed(LED_RED);
00011 DigitalOut ledBlue(LED_BLUE);
00012 
00013 
00014 /* Macros for switch press status */
00015 #define BTN_PRESSED        (0u)
00016 #define BTN_RELEASED       (1u)
00017 
00018 /***************************************************************************
00019 * Global constants
00020 ***************************************************************************/
00021 #define SLIDER_NUM_TOUCH                        (1u)    /* Number of touches on the slider */
00022 #define LED_OFF                                 (1u) 
00023 #define LED_ON                                  (0u)
00024 #define CAPSENSE_SCAN_PERIOD_MS                 (20u)   /* milliseconds */
00025 
00026 
00027 /***************************************
00028 * Function Prototypes
00029 **************************************/
00030 void RunCapSenseScan(void);
00031 void InitTunerCommunication(void);
00032 void ProcessTouchStatus(void);
00033 void EZI2C_InterruptHandler(void);
00034 void CapSense_InterruptHandler(void);
00035 void CapSenseEndOfScanCallback(cy_stc_active_scan_sns_t * ptrActiveScan);
00036 void InitCapSenseClock(void);
00037 
00038 
00039 /*******************************************************************************
00040 * Interrupt configuration
00041 *******************************************************************************/
00042 const cy_stc_sysint_t CapSense_ISR_cfg =
00043 {
00044     .intrSrc = CYBSP_CSD_IRQ,
00045     .intrPriority = 4u
00046 };
00047 
00048 const cy_stc_sysint_t EZI2C_ISR_cfg = {
00049     .intrSrc = CYBSP_CSD_COMM_IRQ,
00050     .intrPriority = 3u
00051 };
00052 
00053 
00054 /*******************************************************************************
00055 * Global variables
00056 *******************************************************************************/
00057 Semaphore capsense_sem;
00058 EventQueue queue;
00059 cy_stc_scb_ezi2c_context_t EZI2C_context;
00060 uint32_t prevBtn0Status = 0u; 
00061 uint32_t prevBtn1Status = 0u;
00062 uint32_t prevSliderPos = 0u;
00063 
00064 /*****************************************************************************
00065 * Function Name: RunCapSenseScan()
00066 ******************************************************************************
00067 * Summary:
00068 *   This function starts the scan, and processes the touch status. It is
00069 * periodically called by an event dispatcher. 
00070 *
00071 *****************************************************************************/
00072 void RunCapSenseScan(void)
00073 {
00074     Cy_CapSense_ScanAllWidgets(&cy_capsense_context);
00075     capsense_sem.acquire();          
00076     Cy_CapSense_ProcessAllWidgets(&cy_capsense_context);
00077     Cy_CapSense_RunTuner(&cy_capsense_context);
00078     ProcessTouchStatus();     
00079 }
00080 
00081 
00082 /*******************************************************************************
00083 * Function Name: InitTunerCommunication
00084 ********************************************************************************
00085 *
00086 * Summary:
00087 *   This function performs the following functions:
00088 *       - Initializes SCB block for operation in EZI2C mode
00089 *       - Configures EZI2C pins
00090 *       - Configures EZI2C clock
00091 *       - Sets communication data buffer to CapSense data structure
00092 *
00093 *******************************************************************************/
00094 void InitTunerCommunication(void)
00095 {
00096     /* Initialize EZI2C pins */
00097     Cy_GPIO_Pin_Init(CYBSP_EZI2C_SCL_PORT, CYBSP_EZI2C_SCL_PIN, &CYBSP_EZI2C_SCL_config);
00098     Cy_GPIO_Pin_Init(CYBSP_EZI2C_SDA_PORT, CYBSP_EZI2C_SDA_PIN, &CYBSP_EZI2C_SDA_config);
00099     
00100     /* Configure the peripheral clock for EZI2C */
00101     Cy_SysClk_PeriphAssignDivider(PCLK_SCB3_CLOCK, CY_SYSCLK_DIV_8_BIT, 1U);
00102     Cy_SysClk_PeriphDisableDivider(CY_SYSCLK_DIV_8_BIT, 1U);
00103     Cy_SysClk_PeriphSetDivider(CY_SYSCLK_DIV_8_BIT, 1U, 7U);
00104     Cy_SysClk_PeriphEnableDivider(CY_SYSCLK_DIV_8_BIT, 1U);
00105     
00106     Cy_SCB_EZI2C_Init(CYBSP_CSD_COMM_HW, &CYBSP_CSD_COMM_config, &EZI2C_context);
00107 
00108     /* Initialize and enable EZI2C interrupts */
00109     Cy_SysInt_Init(&EZI2C_ISR_cfg, &EZI2C_InterruptHandler);
00110     NVIC_EnableIRQ(EZI2C_ISR_cfg.intrSrc);
00111 
00112     /* Set up communication data buffer to CapSense data structure to be exposed
00113      * to I2C master at primary slave address request.
00114      */
00115     Cy_SCB_EZI2C_SetBuffer1(CYBSP_CSD_COMM_HW, (uint8 *)&cy_capsense_tuner,
00116         sizeof(cy_capsense_tuner), sizeof(cy_capsense_tuner), &EZI2C_context);
00117 
00118     /* Enable EZI2C block */
00119     Cy_SCB_EZI2C_Enable(CYBSP_CSD_COMM_HW);
00120 }
00121 
00122 
00123 /*******************************************************************************
00124 * Function Name: ProcessTouchStatus
00125 ********************************************************************************
00126 *
00127 * Summary:
00128 *   Controls the LED status according to the status of CapSense widgets and
00129 *   prints the status to serial terminal.
00130 *
00131 *******************************************************************************/
00132 void ProcessTouchStatus(void)
00133 {
00134     uint32_t currSliderPos;    
00135     uint32_t currBtn0Status = Cy_CapSense_IsSensorActive(CY_CAPSENSE_BUTTON0_WDGT_ID, CY_CAPSENSE_BUTTON0_SNS0_ID, &cy_capsense_context);        
00136     uint32_t currBtn1Status = Cy_CapSense_IsSensorActive(CY_CAPSENSE_BUTTON1_WDGT_ID, CY_CAPSENSE_BUTTON1_SNS0_ID, &cy_capsense_context);       
00137     cy_stc_capsense_touch_t *sldrTouch = Cy_CapSense_GetTouchInfo(CY_CAPSENSE_LINEARSLIDER0_WDGT_ID, &cy_capsense_context);
00138     char outputString[80];
00139     if(currBtn0Status != prevBtn0Status)
00140     {
00141         printf("Button_0 status: %u\r\n", currBtn0Status);
00142         sprintf(outputString,"  Button_0 status: %u   ", currBtn0Status);
00143         GUI_SetTextAlign(GUI_TA_HCENTER);
00144         GUI_DispStringAt(outputString, 160, 60);
00145         prevBtn0Status = currBtn0Status;
00146     }
00147     
00148     if(currBtn1Status != prevBtn1Status)
00149     {
00150         printf("Button_1 status: %u\r\n", currBtn1Status);
00151         sprintf(outputString,"  Button_1 status: %u   ", currBtn1Status);
00152         GUI_SetTextAlign(GUI_TA_HCENTER);
00153         GUI_DispStringAt(outputString, 160, 80);
00154         prevBtn1Status = currBtn1Status;
00155     } 
00156 
00157     if (sldrTouch->numPosition == SLIDER_NUM_TOUCH)
00158     {       
00159         currSliderPos = sldrTouch->ptrPosition->x;
00160 
00161         if(currSliderPos != prevSliderPos)
00162         {
00163             printf("Slider position: %u\r\n", currSliderPos);
00164             sprintf(outputString,"  Slider position: %u   ", currSliderPos);
00165             GUI_SetTextAlign(GUI_TA_HCENTER);
00166             GUI_DispStringAt(outputString, 160, 100);
00167             prevSliderPos = currSliderPos;
00168         }
00169     }
00170 
00171     ledRed = (currBtn0Status || currBtn1Status || (sldrTouch->numPosition == SLIDER_NUM_TOUCH)) ? LED_ON : LED_OFF;
00172 }
00173 
00174 
00175 /*******************************************************************************
00176 * Function Name: EZI2C_InterruptHandler
00177 ********************************************************************************
00178 * Summary:
00179 *   Wrapper function for handling interrupts from EZI2C block. 
00180 *
00181 *******************************************************************************/
00182 void EZI2C_InterruptHandler(void)
00183 {
00184     Cy_SCB_EZI2C_Interrupt(CYBSP_CSD_COMM_HW, &EZI2C_context);
00185 }
00186 
00187 /*****************************************************************************
00188 * Function Name: CapSense_InterruptHandler()
00189 ******************************************************************************
00190 * Summary:
00191 *  Wrapper function for handling interrupts from CSD block.
00192 *
00193 *****************************************************************************/
00194 void CapSense_InterruptHandler(void)
00195 {
00196     Cy_CapSense_InterruptHandler(CYBSP_CSD_HW, &cy_capsense_context);
00197 }
00198 
00199 
00200 /*****************************************************************************
00201 * Function Name: CapSenseEndOfScanCallback()
00202 ******************************************************************************
00203 * Summary:
00204 *  This function releases a semaphore to indicate end of a CapSense scan.
00205 *
00206 * Parameters:
00207 *  cy_stc_active_scan_sns_t* : pointer to active sensor details.
00208 *
00209 *****************************************************************************/
00210 void CapSenseEndOfScanCallback(cy_stc_active_scan_sns_t * ptrActiveScan)
00211 {
00212     capsense_sem.release();
00213 }
00214 
00215 
00216 /*****************************************************************************
00217 * Function Name: InitCapSenseClock()
00218 ******************************************************************************
00219 * Summary:
00220 *  This function configures the peripheral clock for CapSense.  
00221 *
00222 *****************************************************************************/
00223 void InitCapSenseClock(void)
00224 {
00225     Cy_SysClk_PeriphAssignDivider(PCLK_CSD_CLOCK, CYBSP_CSD_CLK_DIV_HW, CYBSP_CSD_CLK_DIV_NUM);
00226     Cy_SysClk_PeriphDisableDivider(CYBSP_CSD_CLK_DIV_HW, CYBSP_CSD_CLK_DIV_NUM);
00227     Cy_SysClk_PeriphSetDivider(CYBSP_CSD_CLK_DIV_HW, CYBSP_CSD_CLK_DIV_NUM, 0u);
00228     Cy_SysClk_PeriphEnableDivider(CYBSP_CSD_CLK_DIV_HW, CYBSP_CSD_CLK_DIV_NUM);
00229 }
00230 
00231 /*****************************************************************************
00232 * Function Name: main()
00233 ******************************************************************************
00234 * Summary:
00235 *   Main function that starts a thread for CapSense scan and enters a forever
00236 *   wait state. 
00237 *
00238 *****************************************************************************/
00239 int main(void)
00240 {
00241     /* Turn off both red and green LEDs */
00242     ledGreen = LED_OFF;
00243     ledRed = LED_OFF;
00244     ledBlue = LED_OFF; 
00245     char outputString[80];
00246     
00247     /* Initialize EmWin driver*/
00248     GUI_Init();
00249     /* Set font size, foreground and background Colours */
00250     GUI_SetFont(GUI_FONT_16B_1);
00251     GUI_SetColor(GUI_WHITE);
00252     GUI_SetBkColor(GUI_BLACK);
00253 
00254     GUI_Clear();
00255     GUI_SetTextAlign(GUI_TA_HCENTER);
00256     GUI_DispStringAt("Capsense Demo", 160, 20);
00257 
00258  /* Configure AMUX bus for CapSense */
00259     init_cycfg_routing();
00260     
00261     /* Configure PERI clocks for CapSense */
00262     InitCapSenseClock(); 
00263     
00264     InitTunerCommunication();
00265     
00266     /* Initialize the CSD HW block to the default state. */
00267     cy_status status = Cy_CapSense_Init(&cy_capsense_context);
00268     if(CY_RET_SUCCESS != status)
00269     {
00270         printf("CapSense initialization failed. Status code: %u\r\n", status);
00271         sprintf(outputString,"CapSense initialization failed. Status code: %u", status);
00272         GUI_SetTextAlign(GUI_TA_HCENTER);
00273         GUI_DispStringAt(outputString, 160, 40);
00274         wait(osWaitForever);
00275     }
00276     
00277     /* Initialize CapSense interrupt */
00278     Cy_SysInt_Init(&CapSense_ISR_cfg, &CapSense_InterruptHandler);
00279     NVIC_ClearPendingIRQ(CapSense_ISR_cfg.intrSrc);
00280     NVIC_EnableIRQ(CapSense_ISR_cfg.intrSrc);
00281 
00282     /* Initialize the CapSense firmware modules. */
00283     Cy_CapSense_Enable(&cy_capsense_context);
00284     Cy_CapSense_RegisterCallback(CY_CAPSENSE_END_OF_SCAN_E, CapSenseEndOfScanCallback, &cy_capsense_context);
00285     
00286     /* Create a thread to run CapSense scan periodically using an event queue
00287      * dispatcher.
00288      */
00289     Thread thread(osPriorityNormal, OS_STACK_SIZE, NULL, "CapSense Scan Thread");
00290     thread.start(callback(&queue, &EventQueue::dispatch_forever));
00291     queue.call_every(CAPSENSE_SCAN_PERIOD_MS, RunCapSenseScan);
00292 
00293     /* Initiate scan immediately since the first call of RunCapSenseScan()
00294      * happens CAPSENSE_SCAN_PERIOD_MS after the event queue dispatcher has
00295      * started. 
00296      */
00297     Cy_CapSense_ScanAllWidgets(&cy_capsense_context); 
00298     
00299     printf("\r\nApplication has started. Touch any CapSense button or slider.\r\n");
00300     sprintf(outputString,"\r\nApplication has started.\r\n Touch any CapSense button or slider.");
00301     GUI_SetTextAlign(GUI_TA_HCENTER);
00302     GUI_DispStringAt(outputString, 160, 180);
00303     wait(osWaitForever);
00304     
00305 }
00306