Andrew Reed
/
city1082-capsense-sw2-tft-leds
PSoC 6 pioneer kit multi library code for emwin driven tft display, capsense and mechanical button input.
Diff: main.cpp
- Revision:
- 2:02954bc28fc5
- Parent:
- 1:f8f4e789361f
diff -r f8f4e789361f -r 02954bc28fc5 main.cpp --- 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); + +} + +