/* * Copyright (c) 2006-2023, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2022-07-28 Rbb666 first version */ #include #include "drv_common.h" #ifdef BSP_USING_SLIDER #include "cycfg_capsense.h" #define CAPSENSE_INTR_PRIORITY (7u) #define EZI2C_INTR_PRIORITY (6u) /* Allowed duty cycle for maximum brightness */ #define LED_MAX_BRIGHTNESS (100u) /* Allowed duty cycle for minimum brightness*/ #define LED_MIN_BRIGHTNESS (0u) #define GET_DUTY_CYCLE(x) (1 * 1000 * 1000 - x * 10 * 1000) typedef enum { LED_OFF, LED_ON } led_state_t; typedef struct { led_state_t state; uint32_t brightness; } led_data_t; static rt_sem_t trans_done_semphr = RT_NULL; static rt_thread_t sld_thread = RT_NULL; #ifndef RT_USING_PWM #error You need enable PWM to use this sample #else #define PWM_DEV_NAME "pwm0" #define PWM_DEV_CHANNEL 3 static struct rt_device_pwm *pwm_dev; #endif static void capsense_isr(void) { /* enter interrupt */ rt_interrupt_enter(); Cy_CapSense_InterruptHandler(CYBSP_CSD_HW, &cy_capsense_context); /* leave interrupt */ rt_interrupt_leave(); } void capsense_callback(cy_stc_active_scan_sns_t *ptrActiveScan) { rt_sem_release(trans_done_semphr); } static uint32_t initialize_capsense(void) { uint32_t status = CYRET_SUCCESS; /* CapSense interrupt configuration parameters */ static const cy_stc_sysint_t capSense_intr_config = { .intrSrc = csd_interrupt_IRQn, .intrPriority = CAPSENSE_INTR_PRIORITY, }; /* Capture the CSD HW block and initialize it to the default state. */ status = Cy_CapSense_Init(&cy_capsense_context); if (CYRET_SUCCESS != status) { return status; } /* Initialize CapSense interrupt */ cyhal_system_set_isr(csd_interrupt_IRQn, csd_interrupt_IRQn, CAPSENSE_INTR_PRIORITY, &capsense_isr); NVIC_ClearPendingIRQ(capSense_intr_config.intrSrc); NVIC_EnableIRQ(capSense_intr_config.intrSrc); /* Initialize the CapSense firmware modules. */ status = Cy_CapSense_Enable(&cy_capsense_context); if (CYRET_SUCCESS != status) { return status; } /* Assign a callback function to indicate end of CapSense scan. */ status = Cy_CapSense_RegisterCallback(CY_CAPSENSE_END_OF_SCAN_E, capsense_callback, &cy_capsense_context); if (CYRET_SUCCESS != status) { return status; } return status; } void Slider_Init(void) { cy_rslt_t result; result = initialize_capsense(); if (CYRET_SUCCESS != result) { /* Halt the CPU if CapSense initialization failed */ RT_ASSERT(0); } /* Initiate first scan */ Cy_CapSense_ScanAllWidgets(&cy_capsense_context); trans_done_semphr = rt_sem_create("slider_sem", 1, RT_IPC_FLAG_PRIO); if (trans_done_semphr == RT_NULL) { rt_kprintf("create transform done semphr failed.\n"); RT_ASSERT(0); return; } #ifdef BSP_USING_PWM0_PORT13 /* Initiate PWM*/ pwm_dev = (struct rt_device_pwm *)rt_device_find(PWM_DEV_NAME); if (pwm_dev == RT_NULL) { rt_kprintf("PWM init failed! can't find %s device!\n", PWM_DEV_NAME); RT_ASSERT(0); } /*default period:1ms pulse:0*/ rt_pwm_set(pwm_dev, PWM_DEV_CHANNEL, 1 * 1000 * 1000, 1 * 1000 * 1000); rt_pwm_enable(pwm_dev, PWM_DEV_CHANNEL); #endif } void update_led_state(led_data_t *ledData) { if (ledData->brightness >= 0) { uint32_t brightness = (ledData->brightness < LED_MIN_BRIGHTNESS) ? LED_MIN_BRIGHTNESS : ledData->brightness; /* Drive the LED with brightness */ rt_pwm_set(pwm_dev, PWM_DEV_CHANNEL, 1 * 1000 * 1000, GET_DUTY_CYCLE(brightness)); } } static void process_touch(void) { cy_stc_capsense_touch_t *slider_touch_info; uint16_t slider_pos; uint8_t slider_touch_status; bool led_update_req = false; static uint16_t slider_pos_prev; static led_data_t led_data = {LED_ON, LED_MAX_BRIGHTNESS}; /* Get slider status */ slider_touch_info = Cy_CapSense_GetTouchInfo( CY_CAPSENSE_LINEARSLIDER0_WDGT_ID, &cy_capsense_context); slider_touch_status = slider_touch_info->numPosition; slider_pos = slider_touch_info->ptrPosition->x; /* Detect the new touch on slider */ if ((RT_NULL != slider_touch_status) && (slider_pos != slider_pos_prev)) { led_data.brightness = (slider_pos * 100) / cy_capsense_context.ptrWdConfig[CY_CAPSENSE_LINEARSLIDER0_WDGT_ID].xResolution; led_update_req = true; } #ifndef RT_USING_PWM #error You need enable PWM to use this sample #else /* Update the LED state if requested */ if (led_update_req) { update_led_state(&led_data); } #endif slider_pos_prev = slider_pos; } static void Slider_thread_entry(void *parameter) { Slider_Init(); for (;;) { rt_sem_take(trans_done_semphr, RT_WAITING_FOREVER); /* Process all widgets */ Cy_CapSense_ProcessAllWidgets(&cy_capsense_context); /* Process touch input */ process_touch(); /* Establishes synchronized operation between the CapSense * middleware and the CapSense Tuner tool. */ Cy_CapSense_RunTuner(&cy_capsense_context); /* Initiate next scan */ Cy_CapSense_ScanAllWidgets(&cy_capsense_context); rt_thread_mdelay(50); } } int Slider_ctrl_sample(void) { rt_err_t ret = RT_EOK; sld_thread = rt_thread_create("slider_th", Slider_thread_entry, RT_NULL, 1024, 25, 10); if (sld_thread != RT_NULL) { rt_thread_startup(sld_thread); } else { ret = RT_ERROR; } return ret; } MSH_CMD_EXPORT(Slider_ctrl_sample, Slider sample to ctrl led); #endif