This is a demonstration of using the tft display of the Cypress PSoC 6 WiFi-BT Pioneer kit. The demo displays the status of the capsense buttons, slider and user button on the tft display. Makes use of emwin, capsense and PinDetect libraries.

Dependencies:   PinDetect

main.cpp

Committer:
reedas
Date:
2019-10-11
Revision:
1:f8f4e789361f
Parent:
0:4ad2c16b6e43

File content as of revision 1:f8f4e789361f:

#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 ledBlue(LED_BLUE);
DigitalOut ledBlue2(P13_4);
DigitalOut ledGreen2(P13_3);
DigitalOut ledRed2(P13_2);

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 LED_OFF                                 (1u) 
#define LED_ON                                  (0u)
#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);


/*******************************************************************************
* 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;


/* 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
*
*******************************************************************************/
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);
        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);
        prevBtn1Status = currBtn1Status;
    } 
    if(sw2Pressed != prevSw2Pressed) {
        sprintf(outputString,"  Button_2 status: %u   ", sw2Pressed);
        GUI_SetTextAlign(GUI_TA_HCENTER);
        GUI_DispStringAt(outputString, 160, 100);
        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);
            prevSliderPos = currSliderPos;
        }
    }

    ledRed = (sw2Pressed || currBtn0Status || currBtn1Status || (sldrTouch->numPosition == SLIDER_NUM_TOUCH)) ? LED_ON : LED_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);
}

/*****************************************************************************
* Function Name: main()
******************************************************************************
* Summary:
*   Main function that starts a thread for CapSense scan and enters a forever
*   wait state. 
*
*****************************************************************************/
int main(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; 
    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);

    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);
 /* 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);
    
    /* 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); 
    

   // 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 );
    wait(osWaitForever);
    
}