Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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);
}