244 lines
6.0 KiB
C
244 lines
6.0 KiB
C
/*
|
|
* 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 <rtthread.h>
|
|
#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;
|
|
|
|
#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;
|
|
|
|
rt_thread_t thread = rt_thread_create("slider_th",
|
|
Slider_thread_entry,
|
|
RT_NULL,
|
|
1024,
|
|
25,
|
|
10);
|
|
if (thread != RT_NULL)
|
|
{
|
|
rt_thread_startup(thread);
|
|
}
|
|
else
|
|
{
|
|
ret = -RT_ERROR;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
MSH_CMD_EXPORT(Slider_ctrl_sample, Slider sample to ctrl led);
|
|
#endif
|