- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I like to implement the double click function with a timer. But it seems not working. And I am not sure it is the good way to implement the function. Please advise.
#define BUTTON_CLICKTIME_MS_MAX (3000u) //3 sec
#define DOUBLE_CLICKTIME_MS_MAX (500u) //0.5 sec
CY_ISR(CCChangeIsrHandler)
{
if (!clickCount) // ==0u
{
Timer_Start();
clickCount = 1u;
}
else //!=0u
{
clickTime = Timer_ReadCapture();
Timer_Stop();
clickCount = 2u;
}
Wakeup_SW_ClearInterrupt();
Wakeup_Interrupt_ClearPending();
}
int main(void)
{
Wakeup_Interrupt_StartEx(CCChangeIsrHandler);
while (1) {
/* DOUBLE CLICK */
if (clickCount == 2u && clickTime < DOUBLE_CLICKTIME_MS_MAX)
{
changeCC();
}
/* LONG PRESS */
while(Wakeup_SW_Read() == 0)
{
CyDelay(1u);
btnHoldTime++;
}
/* Enter STOP mode when the button is pressed longer than 3 sec */
if(btnHoldTime >= BUTTON_CLICKTIME_MS_MAX)
{
applicationPower = HIBERNATE;
}
}
}
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I tried this with CY8CKIT-044.
When started LED turns to GREEN.
If SW2 is pushed LED turns to YELLOW.
If you keep pushing SW2 for 3 seconds, PSoC enters to DeepSleep (LED off)
and with a push of SW2 again will make it wake up.
Or the LED color returns to the previous color (= current_color).
In each double click LED changes color to GREEN -> CYAN -> MAZENTA -> GREEN ...
I used systick to detect double click and a Timer for 3 seconds push.
Needless to say, there must be many more method(s) to do this,
but I hope at least this one is working (as I expected.)
schematic
pins
main.c
==================
#include "project.h"
#define LED_WHITE 7
#define LED_YELLOW 6
#define LED_MAZENTA 5
#define LED_RED 4
#define LED_CYAN 3
#define LED_GREEN 2
#define LED_BLUE 1
#define LED_BLACK 0
volatile int hibernate_flag = 0 ;
volatile int switch_flag = 0 ;
volatile uint32_t tick_count = 0 ;
volatile int double_click_flag = 0 ;
uint8_t current_color = LED_BLACK ;
void set_led(uint8_t color)
{
if (color & 0x01) { LED_B_Write(0) ; } else { LED_B_Write(1) ; }
if (color & 0x02) { LED_G_Write(0) ; } else { LED_G_Write(1) ; }
if (color & 0x04) { LED_R_Write(0) ; } else { LED_R_Write(1) ; }
}
CY_ISR(tick_isr)
{
tick_count++ ;
}
CY_ISR(sw2_pushed_isr)
{
push_int_ClearPending() ;
SW2_ClearInterrupt() ;
Timer_WriteCounter(0) ;
Timer_Enable() ;
switch_flag = 1 ;
set_led(LED_YELLOW) ;
}
CY_ISR(sw2_released_isr)
{
release_int_ClearPending() ;
Timer_Stop() ;
if (tick_count < 1000) {
double_click_flag = 1 ;
}
tick_count = 0 ;
set_led(current_color) ;
}
CY_ISR(hibernate_isr)
{
Timer_ClearInterrupt(Timer_INTR_MASK_TC) ;
Timer_Stop() ;
Timer_WriteCounter(0) ;
hibernate_flag = 1 ;
}
void do_double_click(void)
{
switch(current_color) {
case LED_GREEN: current_color = LED_CYAN ; break ;
case LED_CYAN: current_color = LED_MAZENTA ; break ;
default: current_color = LED_GREEN ; break ;
}
}
void init_hardware(void)
{
CyGlobalIntEnable; /* Enable global interrupts. */
Timer_Init() ;
Timer_ClearInterrupt(Timer_INTR_MASK_TC) ;
Timer_Int_StartEx(hibernate_isr) ;
CySysTickStart() ;
CySysTickSetCallback(0, tick_isr) ;
push_int_ClearPending() ;
push_int_StartEx(sw2_pushed_isr) ;
release_int_ClearPending() ;
release_int_StartEx(sw2_released_isr) ;
current_color = LED_GREEN ;
set_led(current_color) ;
}
void prepare_to_sleep(void)
{
CySysTickDisableInterrupt() ;
release_int_Disable() ;
}
void recover_from_sleep(void)
{
CySysTickEnableInterrupt() ;
release_int_ClearPending() ;
release_int_Enable() ;
}
int main(void)
{
init_hardware() ;
for(;;)
{
if (double_click_flag) {
double_click_flag = 0 ;
do_double_click() ;
}
if (hibernate_flag) {
hibernate_flag = 0 ;
set_led(LED_BLACK) ; /* turn LED off */
prepare_to_sleep() ;
CySysPmDeepSleep() ;
recover_from_sleep() ;
set_led(current_color) ;
}
}
}
==================
moto
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I tried this with CY8CKIT-044.
When started LED turns to GREEN.
If SW2 is pushed LED turns to YELLOW.
If you keep pushing SW2 for 3 seconds, PSoC enters to DeepSleep (LED off)
and with a push of SW2 again will make it wake up.
Or the LED color returns to the previous color (= current_color).
In each double click LED changes color to GREEN -> CYAN -> MAZENTA -> GREEN ...
I used systick to detect double click and a Timer for 3 seconds push.
Needless to say, there must be many more method(s) to do this,
but I hope at least this one is working (as I expected.)
schematic
pins
main.c
==================
#include "project.h"
#define LED_WHITE 7
#define LED_YELLOW 6
#define LED_MAZENTA 5
#define LED_RED 4
#define LED_CYAN 3
#define LED_GREEN 2
#define LED_BLUE 1
#define LED_BLACK 0
volatile int hibernate_flag = 0 ;
volatile int switch_flag = 0 ;
volatile uint32_t tick_count = 0 ;
volatile int double_click_flag = 0 ;
uint8_t current_color = LED_BLACK ;
void set_led(uint8_t color)
{
if (color & 0x01) { LED_B_Write(0) ; } else { LED_B_Write(1) ; }
if (color & 0x02) { LED_G_Write(0) ; } else { LED_G_Write(1) ; }
if (color & 0x04) { LED_R_Write(0) ; } else { LED_R_Write(1) ; }
}
CY_ISR(tick_isr)
{
tick_count++ ;
}
CY_ISR(sw2_pushed_isr)
{
push_int_ClearPending() ;
SW2_ClearInterrupt() ;
Timer_WriteCounter(0) ;
Timer_Enable() ;
switch_flag = 1 ;
set_led(LED_YELLOW) ;
}
CY_ISR(sw2_released_isr)
{
release_int_ClearPending() ;
Timer_Stop() ;
if (tick_count < 1000) {
double_click_flag = 1 ;
}
tick_count = 0 ;
set_led(current_color) ;
}
CY_ISR(hibernate_isr)
{
Timer_ClearInterrupt(Timer_INTR_MASK_TC) ;
Timer_Stop() ;
Timer_WriteCounter(0) ;
hibernate_flag = 1 ;
}
void do_double_click(void)
{
switch(current_color) {
case LED_GREEN: current_color = LED_CYAN ; break ;
case LED_CYAN: current_color = LED_MAZENTA ; break ;
default: current_color = LED_GREEN ; break ;
}
}
void init_hardware(void)
{
CyGlobalIntEnable; /* Enable global interrupts. */
Timer_Init() ;
Timer_ClearInterrupt(Timer_INTR_MASK_TC) ;
Timer_Int_StartEx(hibernate_isr) ;
CySysTickStart() ;
CySysTickSetCallback(0, tick_isr) ;
push_int_ClearPending() ;
push_int_StartEx(sw2_pushed_isr) ;
release_int_ClearPending() ;
release_int_StartEx(sw2_released_isr) ;
current_color = LED_GREEN ;
set_led(current_color) ;
}
void prepare_to_sleep(void)
{
CySysTickDisableInterrupt() ;
release_int_Disable() ;
}
void recover_from_sleep(void)
{
CySysTickEnableInterrupt() ;
release_int_ClearPending() ;
release_int_Enable() ;
}
int main(void)
{
init_hardware() ;
for(;;)
{
if (double_click_flag) {
double_click_flag = 0 ;
do_double_click() ;
}
if (hibernate_flag) {
hibernate_flag = 0 ;
set_led(LED_BLACK) ; /* turn LED off */
prepare_to_sleep() ;
CySysPmDeepSleep() ;
recover_from_sleep() ;
set_led(current_color) ;
}
}
}
==================
moto
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you so much for giving me such a good tip to use Systick and the two interrupts in a pin, which I never imagined.
My project is based on CYBLE-022001-00, which is PRoC with BLE. Your way works good as it is but not with my application.
When I apply your way my device does not sleep at all. My application is supposed to sleep with stop mode after x amount of time of inactivity.
It seems the interrupt of systick wakes it up all the time. I changed the systick to PWM timer with changing a few code, which works well. Thanks again!