Andrew Reed
/
city1082-capsense-sw2-tft-leds
PSoC 6 pioneer kit multi library code for emwin driven tft display, capsense and mechanical button input.
main.cpp
- Committer:
- reedas
- Date:
- 2019-10-18
- Revision:
- 3:1edcda6af8df
- Parent:
- 2:02954bc28fc5
File content as of revision 3:1edcda6af8df:
#include "mbed.h" #include "GUI.h" #include "cy8ckit_028_tft.h" #define Cy_SysLib_Delay wait_ms #include "cy_pdl.h" #include "cycfg_capsense.h" #include "cycfg.h" #include "PinDetect.h" 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); /* Macros for switch press status */ #define BTN_PRESSED (0u) #define BTN_RELEASED (1u) /*************************************************************************** * Global constants ***************************************************************************/ #define SLIDER_NUM_TOUCH (1u) /* Number of touches on the slider */ #define nLED_OFF (1u) #define nLED_ON (0u) #define LED_OFF (0u) #define LED_ON (1u) #define CAPSENSE_SCAN_PERIOD_MS (20u) /* milliseconds */ /*************************************** * Function Prototypes **************************************/ void RunCapSenseScan(void); void InitTunerCommunication(void); void ProcessTouchStatus(void); void EZI2C_InterruptHandler(void); 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 = { .intrSrc = CYBSP_CSD_IRQ, .intrPriority = 4u }; const cy_stc_sysint_t EZI2C_ISR_cfg = { .intrSrc = CYBSP_CSD_COMM_IRQ, .intrPriority = 3u }; /******************************************************************************* * Global variables *******************************************************************************/ //DigitalOut ledRed(LED_RED); Semaphore capsense_sem; EventQueue queue; cy_stc_scb_ezi2c_context_t EZI2C_context; 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 bmCypressLogo; // Callback routine is interrupt activated by a debounced pb1 hit 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) { // printf("Count is %d\n", ++countit); sw2Pressed = false; } /******************************************************************************* * Function Name: bool IsBtnClicked ******************************************************************************** * * Summary: This non-blocking function implements SW2 button click check. * * Parameters: * None * * Return: * Status of the SW2 button: * 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; * } */ /***************************************************************************** * Function Name: RunCapSenseScan() ****************************************************************************** * Summary: * This function starts the scan, and processes the touch status. It is * periodically called by an event dispatcher. * *****************************************************************************/ void RunCapSenseScan(void) { Cy_CapSense_ScanAllWidgets(&cy_capsense_context); capsense_sem.acquire(); Cy_CapSense_ProcessAllWidgets(&cy_capsense_context); Cy_CapSense_RunTuner(&cy_capsense_context); ProcessTouchStatus(); } /******************************************************************************* * Function Name: InitTunerCommunication ******************************************************************************** * * Summary: * This function performs the following functions: * - Initializes SCB block for operation in EZI2C mode * - Configures EZI2C pins * - Configures EZI2C clock * - Sets communication data buffer to CapSense data structure * *******************************************************************************/ void InitTunerCommunication(void) { /* 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 */ Cy_SysInt_Init(&EZI2C_ISR_cfg, &EZI2C_InterruptHandler); NVIC_EnableIRQ(EZI2C_ISR_cfg.intrSrc); /* Set up communication data buffer to CapSense data structure to be exposed * 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); /* Enable EZI2C block */ Cy_SCB_EZI2C_Enable(CYBSP_CSD_COMM_HW); } /******************************************************************************* * Function Name: ProcessTouchStatus ******************************************************************************** * * Summary: * Controls the LED status according to the status of CapSense widgets and * prints the status to serial terminal. * *******************************************************************************/ 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); cy_stc_capsense_touch_t *sldrTouch = Cy_CapSense_GetTouchInfo(CY_CAPSENSE_LINEARSLIDER0_WDGT_ID, &cy_capsense_context); char outputString[80]; 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) { 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) { currSliderPos = sldrTouch->ptrPosition->x; 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; } } /* flash a LED when a key press is detected */ userLed = (sw2Pressed || currBtn0Status || currBtn1Status || (sldrTouch->numPosition == SLIDER_NUM_TOUCH)) ? nLED_ON : nLED_OFF; } /******************************************************************************* * Function Name: EZI2C_InterruptHandler ******************************************************************************** * Summary: * Wrapper function for handling interrupts from EZI2C block. * *******************************************************************************/ void EZI2C_InterruptHandler(void) { Cy_SCB_EZI2C_Interrupt(CYBSP_CSD_COMM_HW, &EZI2C_context); } /***************************************************************************** * Function Name: CapSense_InterruptHandler() ****************************************************************************** * Summary: * Wrapper function for handling interrupts from CSD block. * *****************************************************************************/ void CapSense_InterruptHandler(void) { Cy_CapSense_InterruptHandler(CYBSP_CSD_HW, &cy_capsense_context); } /***************************************************************************** * Function Name: CapSenseEndOfScanCallback() ****************************************************************************** * Summary: * This function releases a semaphore to indicate end of a CapSense scan. * * Parameters: * cy_stc_active_scan_sns_t* : pointer to active sensor details. * *****************************************************************************/ void CapSenseEndOfScanCallback(cy_stc_active_scan_sns_t * ptrActiveScan) { capsense_sem.release(); } /***************************************************************************** * Function Name: InitCapSenseClock() ****************************************************************************** * Summary: * This function configures the peripheral clock for CapSense. * *****************************************************************************/ void InitCapSenseClock(void) { Cy_SysClk_PeriphAssignDivider(PCLK_CSD_CLOCK, CYBSP_CSD_CLK_DIV_HW, CYBSP_CSD_CLK_DIV_NUM); Cy_SysClk_PeriphDisableDivider(CYBSP_CSD_CLK_DIV_HW, CYBSP_CSD_CLK_DIV_NUM); 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); } void LED_Init(void) { /* 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]; /* 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); printf("\r\nApplication has started. Touch any CapSense button or slider.\r\n"); sprintf(outputString,"\r\nApplication has started.\r\n Touch any CapSense button or slider."); GUI_SetTextAlign(GUI_TA_HCENTER); GUI_DispStringAt(outputString, 160, 180); wait(0.10); } 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(); InitTunerCommunication(); /* Initialize the CSD HW block to the default state. */ cy_status status = Cy_CapSense_Init(&cy_capsense_context); 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); NVIC_EnableIRQ(CapSense_ISR_cfg.intrSrc); /* Initialize the CapSense firmware modules. */ Cy_CapSense_Enable(&cy_capsense_context); Cy_CapSense_RegisterCallback(CY_CAPSENSE_END_OF_SCAN_E, CapSenseEndOfScanCallback, &cy_capsense_context); } /* Setup debounced mechanical buttons and callbacks*/ void Button_Init(void) { /* Use internal pullups for pushbutton */ pb2.mode(PullUp); // pb2.mode(PullUp); // Delay for initial pullup to take effect wait(.01); // Setup Interrupt callback functions for a pb hit pb2.attach_deasserted(&pb2_hit_callback); // pb2.attach_deasserted(&pb2_hit_callback); // Start sampling pb inputs using interrupts pb2.setSampleFrequency(); pb2.attach_asserted( &pb2_released_callback ); } /***************************************************************************** * 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); }