Capsense buttons and Slider, output to Serial over i2c and tft display

Committer:
reedas
Date:
Mon Dec 02 22:55:59 2019 +0000
Revision:
1:cf461b359823
Parent:
0:4ad2c16b6e43
Example of Capacitive Sensitive Buttons and slider from MBED example

Who changed what in which revision?

UserRevisionLine numberNew contents of line
reedas 0:4ad2c16b6e43 1 #include "mbed.h"
reedas 0:4ad2c16b6e43 2 #include "GUI.h"
reedas 0:4ad2c16b6e43 3 #include "cy8ckit_028_tft.h"
reedas 0:4ad2c16b6e43 4 #define Cy_SysLib_Delay wait_ms
reedas 1:cf461b359823 5 #include "cy_pdl.h"
reedas 1:cf461b359823 6 #include "cycfg_capsense.h"
reedas 1:cf461b359823 7 #include "cycfg.h"
reedas 0:4ad2c16b6e43 8
reedas 0:4ad2c16b6e43 9 DigitalOut ledGreen(LED_GREEN);
reedas 0:4ad2c16b6e43 10 DigitalOut ledRed(LED_RED);
reedas 0:4ad2c16b6e43 11 DigitalOut ledBlue(LED_BLUE);
reedas 0:4ad2c16b6e43 12
reedas 0:4ad2c16b6e43 13
reedas 0:4ad2c16b6e43 14 /* Macros for switch press status */
reedas 0:4ad2c16b6e43 15 #define BTN_PRESSED (0u)
reedas 0:4ad2c16b6e43 16 #define BTN_RELEASED (1u)
reedas 0:4ad2c16b6e43 17
reedas 1:cf461b359823 18 /***************************************************************************
reedas 1:cf461b359823 19 * Global constants
reedas 1:cf461b359823 20 ***************************************************************************/
reedas 1:cf461b359823 21 #define SLIDER_NUM_TOUCH (1u) /* Number of touches on the slider */
reedas 1:cf461b359823 22 #define LED_OFF (1u)
reedas 1:cf461b359823 23 #define LED_ON (0u)
reedas 1:cf461b359823 24 #define CAPSENSE_SCAN_PERIOD_MS (20u) /* milliseconds */
reedas 0:4ad2c16b6e43 25
reedas 0:4ad2c16b6e43 26
reedas 1:cf461b359823 27 /***************************************
reedas 1:cf461b359823 28 * Function Prototypes
reedas 1:cf461b359823 29 **************************************/
reedas 1:cf461b359823 30 void RunCapSenseScan(void);
reedas 1:cf461b359823 31 void InitTunerCommunication(void);
reedas 1:cf461b359823 32 void ProcessTouchStatus(void);
reedas 1:cf461b359823 33 void EZI2C_InterruptHandler(void);
reedas 1:cf461b359823 34 void CapSense_InterruptHandler(void);
reedas 1:cf461b359823 35 void CapSenseEndOfScanCallback(cy_stc_active_scan_sns_t * ptrActiveScan);
reedas 1:cf461b359823 36 void InitCapSenseClock(void);
reedas 0:4ad2c16b6e43 37
reedas 0:4ad2c16b6e43 38
reedas 1:cf461b359823 39 /*******************************************************************************
reedas 1:cf461b359823 40 * Interrupt configuration
reedas 1:cf461b359823 41 *******************************************************************************/
reedas 1:cf461b359823 42 const cy_stc_sysint_t CapSense_ISR_cfg =
reedas 1:cf461b359823 43 {
reedas 1:cf461b359823 44 .intrSrc = CYBSP_CSD_IRQ,
reedas 1:cf461b359823 45 .intrPriority = 4u
reedas 1:cf461b359823 46 };
reedas 0:4ad2c16b6e43 47
reedas 1:cf461b359823 48 const cy_stc_sysint_t EZI2C_ISR_cfg = {
reedas 1:cf461b359823 49 .intrSrc = CYBSP_CSD_COMM_IRQ,
reedas 1:cf461b359823 50 .intrPriority = 3u
reedas 0:4ad2c16b6e43 51 };
reedas 0:4ad2c16b6e43 52
reedas 0:4ad2c16b6e43 53
reedas 0:4ad2c16b6e43 54 /*******************************************************************************
reedas 1:cf461b359823 55 * Global variables
reedas 1:cf461b359823 56 *******************************************************************************/
reedas 1:cf461b359823 57 Semaphore capsense_sem;
reedas 1:cf461b359823 58 EventQueue queue;
reedas 1:cf461b359823 59 cy_stc_scb_ezi2c_context_t EZI2C_context;
reedas 1:cf461b359823 60 uint32_t prevBtn0Status = 0u;
reedas 1:cf461b359823 61 uint32_t prevBtn1Status = 0u;
reedas 1:cf461b359823 62 uint32_t prevSliderPos = 0u;
reedas 1:cf461b359823 63
reedas 1:cf461b359823 64 /*****************************************************************************
reedas 1:cf461b359823 65 * Function Name: RunCapSenseScan()
reedas 1:cf461b359823 66 ******************************************************************************
reedas 1:cf461b359823 67 * Summary:
reedas 1:cf461b359823 68 * This function starts the scan, and processes the touch status. It is
reedas 1:cf461b359823 69 * periodically called by an event dispatcher.
reedas 1:cf461b359823 70 *
reedas 1:cf461b359823 71 *****************************************************************************/
reedas 1:cf461b359823 72 void RunCapSenseScan(void)
reedas 1:cf461b359823 73 {
reedas 1:cf461b359823 74 Cy_CapSense_ScanAllWidgets(&cy_capsense_context);
reedas 1:cf461b359823 75 capsense_sem.acquire();
reedas 1:cf461b359823 76 Cy_CapSense_ProcessAllWidgets(&cy_capsense_context);
reedas 1:cf461b359823 77 Cy_CapSense_RunTuner(&cy_capsense_context);
reedas 1:cf461b359823 78 ProcessTouchStatus();
reedas 1:cf461b359823 79 }
reedas 1:cf461b359823 80
reedas 1:cf461b359823 81
reedas 1:cf461b359823 82 /*******************************************************************************
reedas 1:cf461b359823 83 * Function Name: InitTunerCommunication
reedas 1:cf461b359823 84 ********************************************************************************
reedas 1:cf461b359823 85 *
reedas 1:cf461b359823 86 * Summary:
reedas 1:cf461b359823 87 * This function performs the following functions:
reedas 1:cf461b359823 88 * - Initializes SCB block for operation in EZI2C mode
reedas 1:cf461b359823 89 * - Configures EZI2C pins
reedas 1:cf461b359823 90 * - Configures EZI2C clock
reedas 1:cf461b359823 91 * - Sets communication data buffer to CapSense data structure
reedas 1:cf461b359823 92 *
reedas 1:cf461b359823 93 *******************************************************************************/
reedas 1:cf461b359823 94 void InitTunerCommunication(void)
reedas 1:cf461b359823 95 {
reedas 1:cf461b359823 96 /* Initialize EZI2C pins */
reedas 1:cf461b359823 97 Cy_GPIO_Pin_Init(CYBSP_EZI2C_SCL_PORT, CYBSP_EZI2C_SCL_PIN, &CYBSP_EZI2C_SCL_config);
reedas 1:cf461b359823 98 Cy_GPIO_Pin_Init(CYBSP_EZI2C_SDA_PORT, CYBSP_EZI2C_SDA_PIN, &CYBSP_EZI2C_SDA_config);
reedas 1:cf461b359823 99
reedas 1:cf461b359823 100 /* Configure the peripheral clock for EZI2C */
reedas 1:cf461b359823 101 Cy_SysClk_PeriphAssignDivider(PCLK_SCB3_CLOCK, CY_SYSCLK_DIV_8_BIT, 1U);
reedas 1:cf461b359823 102 Cy_SysClk_PeriphDisableDivider(CY_SYSCLK_DIV_8_BIT, 1U);
reedas 1:cf461b359823 103 Cy_SysClk_PeriphSetDivider(CY_SYSCLK_DIV_8_BIT, 1U, 7U);
reedas 1:cf461b359823 104 Cy_SysClk_PeriphEnableDivider(CY_SYSCLK_DIV_8_BIT, 1U);
reedas 1:cf461b359823 105
reedas 1:cf461b359823 106 Cy_SCB_EZI2C_Init(CYBSP_CSD_COMM_HW, &CYBSP_CSD_COMM_config, &EZI2C_context);
reedas 1:cf461b359823 107
reedas 1:cf461b359823 108 /* Initialize and enable EZI2C interrupts */
reedas 1:cf461b359823 109 Cy_SysInt_Init(&EZI2C_ISR_cfg, &EZI2C_InterruptHandler);
reedas 1:cf461b359823 110 NVIC_EnableIRQ(EZI2C_ISR_cfg.intrSrc);
reedas 1:cf461b359823 111
reedas 1:cf461b359823 112 /* Set up communication data buffer to CapSense data structure to be exposed
reedas 1:cf461b359823 113 * to I2C master at primary slave address request.
reedas 1:cf461b359823 114 */
reedas 1:cf461b359823 115 Cy_SCB_EZI2C_SetBuffer1(CYBSP_CSD_COMM_HW, (uint8 *)&cy_capsense_tuner,
reedas 1:cf461b359823 116 sizeof(cy_capsense_tuner), sizeof(cy_capsense_tuner), &EZI2C_context);
reedas 1:cf461b359823 117
reedas 1:cf461b359823 118 /* Enable EZI2C block */
reedas 1:cf461b359823 119 Cy_SCB_EZI2C_Enable(CYBSP_CSD_COMM_HW);
reedas 1:cf461b359823 120 }
reedas 1:cf461b359823 121
reedas 1:cf461b359823 122
reedas 1:cf461b359823 123 /*******************************************************************************
reedas 1:cf461b359823 124 * Function Name: ProcessTouchStatus
reedas 0:4ad2c16b6e43 125 ********************************************************************************
reedas 0:4ad2c16b6e43 126 *
reedas 1:cf461b359823 127 * Summary:
reedas 1:cf461b359823 128 * Controls the LED status according to the status of CapSense widgets and
reedas 1:cf461b359823 129 * prints the status to serial terminal.
reedas 1:cf461b359823 130 *
reedas 1:cf461b359823 131 *******************************************************************************/
reedas 1:cf461b359823 132 void ProcessTouchStatus(void)
reedas 1:cf461b359823 133 {
reedas 1:cf461b359823 134 uint32_t currSliderPos;
reedas 1:cf461b359823 135 uint32_t currBtn0Status = Cy_CapSense_IsSensorActive(CY_CAPSENSE_BUTTON0_WDGT_ID, CY_CAPSENSE_BUTTON0_SNS0_ID, &cy_capsense_context);
reedas 1:cf461b359823 136 uint32_t currBtn1Status = Cy_CapSense_IsSensorActive(CY_CAPSENSE_BUTTON1_WDGT_ID, CY_CAPSENSE_BUTTON1_SNS0_ID, &cy_capsense_context);
reedas 1:cf461b359823 137 cy_stc_capsense_touch_t *sldrTouch = Cy_CapSense_GetTouchInfo(CY_CAPSENSE_LINEARSLIDER0_WDGT_ID, &cy_capsense_context);
reedas 1:cf461b359823 138 char outputString[80];
reedas 1:cf461b359823 139 if(currBtn0Status != prevBtn0Status)
reedas 1:cf461b359823 140 {
reedas 1:cf461b359823 141 printf("Button_0 status: %u\r\n", currBtn0Status);
reedas 1:cf461b359823 142 sprintf(outputString," Button_0 status: %u ", currBtn0Status);
reedas 1:cf461b359823 143 GUI_SetTextAlign(GUI_TA_HCENTER);
reedas 1:cf461b359823 144 GUI_DispStringAt(outputString, 160, 60);
reedas 1:cf461b359823 145 prevBtn0Status = currBtn0Status;
reedas 1:cf461b359823 146 }
reedas 1:cf461b359823 147
reedas 1:cf461b359823 148 if(currBtn1Status != prevBtn1Status)
reedas 1:cf461b359823 149 {
reedas 1:cf461b359823 150 printf("Button_1 status: %u\r\n", currBtn1Status);
reedas 1:cf461b359823 151 sprintf(outputString," Button_1 status: %u ", currBtn1Status);
reedas 1:cf461b359823 152 GUI_SetTextAlign(GUI_TA_HCENTER);
reedas 1:cf461b359823 153 GUI_DispStringAt(outputString, 160, 80);
reedas 1:cf461b359823 154 prevBtn1Status = currBtn1Status;
reedas 1:cf461b359823 155 }
reedas 1:cf461b359823 156
reedas 1:cf461b359823 157 if (sldrTouch->numPosition == SLIDER_NUM_TOUCH)
reedas 1:cf461b359823 158 {
reedas 1:cf461b359823 159 currSliderPos = sldrTouch->ptrPosition->x;
reedas 1:cf461b359823 160
reedas 1:cf461b359823 161 if(currSliderPos != prevSliderPos)
reedas 1:cf461b359823 162 {
reedas 1:cf461b359823 163 printf("Slider position: %u\r\n", currSliderPos);
reedas 1:cf461b359823 164 sprintf(outputString," Slider position: %u ", currSliderPos);
reedas 1:cf461b359823 165 GUI_SetTextAlign(GUI_TA_HCENTER);
reedas 1:cf461b359823 166 GUI_DispStringAt(outputString, 160, 100);
reedas 1:cf461b359823 167 prevSliderPos = currSliderPos;
reedas 1:cf461b359823 168 }
reedas 1:cf461b359823 169 }
reedas 1:cf461b359823 170
reedas 1:cf461b359823 171 ledRed = (currBtn0Status || currBtn1Status || (sldrTouch->numPosition == SLIDER_NUM_TOUCH)) ? LED_ON : LED_OFF;
reedas 1:cf461b359823 172 }
reedas 1:cf461b359823 173
reedas 1:cf461b359823 174
reedas 1:cf461b359823 175 /*******************************************************************************
reedas 1:cf461b359823 176 * Function Name: EZI2C_InterruptHandler
reedas 1:cf461b359823 177 ********************************************************************************
reedas 1:cf461b359823 178 * Summary:
reedas 1:cf461b359823 179 * Wrapper function for handling interrupts from EZI2C block.
reedas 1:cf461b359823 180 *
reedas 1:cf461b359823 181 *******************************************************************************/
reedas 1:cf461b359823 182 void EZI2C_InterruptHandler(void)
reedas 1:cf461b359823 183 {
reedas 1:cf461b359823 184 Cy_SCB_EZI2C_Interrupt(CYBSP_CSD_COMM_HW, &EZI2C_context);
reedas 1:cf461b359823 185 }
reedas 1:cf461b359823 186
reedas 1:cf461b359823 187 /*****************************************************************************
reedas 1:cf461b359823 188 * Function Name: CapSense_InterruptHandler()
reedas 1:cf461b359823 189 ******************************************************************************
reedas 1:cf461b359823 190 * Summary:
reedas 1:cf461b359823 191 * Wrapper function for handling interrupts from CSD block.
reedas 1:cf461b359823 192 *
reedas 1:cf461b359823 193 *****************************************************************************/
reedas 1:cf461b359823 194 void CapSense_InterruptHandler(void)
reedas 1:cf461b359823 195 {
reedas 1:cf461b359823 196 Cy_CapSense_InterruptHandler(CYBSP_CSD_HW, &cy_capsense_context);
reedas 1:cf461b359823 197 }
reedas 1:cf461b359823 198
reedas 1:cf461b359823 199
reedas 1:cf461b359823 200 /*****************************************************************************
reedas 1:cf461b359823 201 * Function Name: CapSenseEndOfScanCallback()
reedas 1:cf461b359823 202 ******************************************************************************
reedas 1:cf461b359823 203 * Summary:
reedas 1:cf461b359823 204 * This function releases a semaphore to indicate end of a CapSense scan.
reedas 0:4ad2c16b6e43 205 *
reedas 0:4ad2c16b6e43 206 * Parameters:
reedas 1:cf461b359823 207 * cy_stc_active_scan_sns_t* : pointer to active sensor details.
reedas 1:cf461b359823 208 *
reedas 1:cf461b359823 209 *****************************************************************************/
reedas 1:cf461b359823 210 void CapSenseEndOfScanCallback(cy_stc_active_scan_sns_t * ptrActiveScan)
reedas 1:cf461b359823 211 {
reedas 1:cf461b359823 212 capsense_sem.release();
reedas 1:cf461b359823 213 }
reedas 1:cf461b359823 214
reedas 1:cf461b359823 215
reedas 1:cf461b359823 216 /*****************************************************************************
reedas 1:cf461b359823 217 * Function Name: InitCapSenseClock()
reedas 1:cf461b359823 218 ******************************************************************************
reedas 1:cf461b359823 219 * Summary:
reedas 1:cf461b359823 220 * This function configures the peripheral clock for CapSense.
reedas 0:4ad2c16b6e43 221 *
reedas 1:cf461b359823 222 *****************************************************************************/
reedas 1:cf461b359823 223 void InitCapSenseClock(void)
reedas 1:cf461b359823 224 {
reedas 1:cf461b359823 225 Cy_SysClk_PeriphAssignDivider(PCLK_CSD_CLOCK, CYBSP_CSD_CLK_DIV_HW, CYBSP_CSD_CLK_DIV_NUM);
reedas 1:cf461b359823 226 Cy_SysClk_PeriphDisableDivider(CYBSP_CSD_CLK_DIV_HW, CYBSP_CSD_CLK_DIV_NUM);
reedas 1:cf461b359823 227 Cy_SysClk_PeriphSetDivider(CYBSP_CSD_CLK_DIV_HW, CYBSP_CSD_CLK_DIV_NUM, 0u);
reedas 1:cf461b359823 228 Cy_SysClk_PeriphEnableDivider(CYBSP_CSD_CLK_DIV_HW, CYBSP_CSD_CLK_DIV_NUM);
reedas 1:cf461b359823 229 }
reedas 1:cf461b359823 230
reedas 1:cf461b359823 231 /*****************************************************************************
reedas 1:cf461b359823 232 * Function Name: main()
reedas 1:cf461b359823 233 ******************************************************************************
reedas 1:cf461b359823 234 * Summary:
reedas 1:cf461b359823 235 * Main function that starts a thread for CapSense scan and enters a forever
reedas 1:cf461b359823 236 * wait state.
reedas 0:4ad2c16b6e43 237 *
reedas 1:cf461b359823 238 *****************************************************************************/
reedas 1:cf461b359823 239 int main(void)
reedas 0:4ad2c16b6e43 240 {
reedas 1:cf461b359823 241 /* Turn off both red and green LEDs */
reedas 1:cf461b359823 242 ledGreen = LED_OFF;
reedas 1:cf461b359823 243 ledRed = LED_OFF;
reedas 1:cf461b359823 244 ledBlue = LED_OFF;
reedas 1:cf461b359823 245 char outputString[80];
reedas 1:cf461b359823 246
reedas 1:cf461b359823 247 /* Initialize EmWin driver*/
reedas 1:cf461b359823 248 GUI_Init();
reedas 0:4ad2c16b6e43 249 /* Set font size, foreground and background Colours */
reedas 0:4ad2c16b6e43 250 GUI_SetFont(GUI_FONT_16B_1);
reedas 0:4ad2c16b6e43 251 GUI_SetColor(GUI_WHITE);
reedas 0:4ad2c16b6e43 252 GUI_SetBkColor(GUI_BLACK);
reedas 0:4ad2c16b6e43 253
reedas 0:4ad2c16b6e43 254 GUI_Clear();
reedas 0:4ad2c16b6e43 255 GUI_SetTextAlign(GUI_TA_HCENTER);
reedas 1:cf461b359823 256 GUI_DispStringAt("Capsense Demo", 160, 20);
reedas 0:4ad2c16b6e43 257
reedas 1:cf461b359823 258 /* Configure AMUX bus for CapSense */
reedas 1:cf461b359823 259 init_cycfg_routing();
reedas 1:cf461b359823 260
reedas 1:cf461b359823 261 /* Configure PERI clocks for CapSense */
reedas 1:cf461b359823 262 InitCapSenseClock();
reedas 1:cf461b359823 263
reedas 1:cf461b359823 264 InitTunerCommunication();
reedas 0:4ad2c16b6e43 265
reedas 1:cf461b359823 266 /* Initialize the CSD HW block to the default state. */
reedas 1:cf461b359823 267 cy_status status = Cy_CapSense_Init(&cy_capsense_context);
reedas 1:cf461b359823 268 if(CY_RET_SUCCESS != status)
reedas 1:cf461b359823 269 {
reedas 1:cf461b359823 270 printf("CapSense initialization failed. Status code: %u\r\n", status);
reedas 1:cf461b359823 271 sprintf(outputString,"CapSense initialization failed. Status code: %u", status);
reedas 1:cf461b359823 272 GUI_SetTextAlign(GUI_TA_HCENTER);
reedas 1:cf461b359823 273 GUI_DispStringAt(outputString, 160, 40);
reedas 1:cf461b359823 274 wait(osWaitForever);
reedas 1:cf461b359823 275 }
reedas 1:cf461b359823 276
reedas 1:cf461b359823 277 /* Initialize CapSense interrupt */
reedas 1:cf461b359823 278 Cy_SysInt_Init(&CapSense_ISR_cfg, &CapSense_InterruptHandler);
reedas 1:cf461b359823 279 NVIC_ClearPendingIRQ(CapSense_ISR_cfg.intrSrc);
reedas 1:cf461b359823 280 NVIC_EnableIRQ(CapSense_ISR_cfg.intrSrc);
reedas 0:4ad2c16b6e43 281
reedas 1:cf461b359823 282 /* Initialize the CapSense firmware modules. */
reedas 1:cf461b359823 283 Cy_CapSense_Enable(&cy_capsense_context);
reedas 1:cf461b359823 284 Cy_CapSense_RegisterCallback(CY_CAPSENSE_END_OF_SCAN_E, CapSenseEndOfScanCallback, &cy_capsense_context);
reedas 1:cf461b359823 285
reedas 1:cf461b359823 286 /* Create a thread to run CapSense scan periodically using an event queue
reedas 1:cf461b359823 287 * dispatcher.
reedas 1:cf461b359823 288 */
reedas 1:cf461b359823 289 Thread thread(osPriorityNormal, OS_STACK_SIZE, NULL, "CapSense Scan Thread");
reedas 1:cf461b359823 290 thread.start(callback(&queue, &EventQueue::dispatch_forever));
reedas 1:cf461b359823 291 queue.call_every(CAPSENSE_SCAN_PERIOD_MS, RunCapSenseScan);
reedas 0:4ad2c16b6e43 292
reedas 1:cf461b359823 293 /* Initiate scan immediately since the first call of RunCapSenseScan()
reedas 1:cf461b359823 294 * happens CAPSENSE_SCAN_PERIOD_MS after the event queue dispatcher has
reedas 1:cf461b359823 295 * started.
reedas 1:cf461b359823 296 */
reedas 1:cf461b359823 297 Cy_CapSense_ScanAllWidgets(&cy_capsense_context);
reedas 1:cf461b359823 298
reedas 1:cf461b359823 299 printf("\r\nApplication has started. Touch any CapSense button or slider.\r\n");
reedas 1:cf461b359823 300 sprintf(outputString,"\r\nApplication has started.\r\n Touch any CapSense button or slider.");
reedas 1:cf461b359823 301 GUI_SetTextAlign(GUI_TA_HCENTER);
reedas 1:cf461b359823 302 GUI_DispStringAt(outputString, 160, 180);
reedas 1:cf461b359823 303 wait(osWaitForever);
reedas 1:cf461b359823 304
reedas 0:4ad2c16b6e43 305 }
reedas 0:4ad2c16b6e43 306