1 /*
2 * Copyright (c) 2006-2023, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2022-07-28 Rbb666 first version
9 */
10
11 #include <rtthread.h>
12 #include "drv_common.h"
13
14 #ifdef BSP_USING_SLIDER
15 #include "cycfg_capsense.h"
16
17 #define CAPSENSE_INTR_PRIORITY (7u)
18 #define EZI2C_INTR_PRIORITY (6u)
19
20 /* Allowed duty cycle for maximum brightness */
21 #define LED_MAX_BRIGHTNESS (100u)
22
23 /* Allowed duty cycle for minimum brightness*/
24 #define LED_MIN_BRIGHTNESS (0u)
25
26 #define GET_DUTY_CYCLE(x) (1 * 1000 * 1000 - x * 10 * 1000)
27
28 typedef enum
29 {
30 LED_OFF,
31 LED_ON
32 } led_state_t;
33
34 typedef struct
35 {
36 led_state_t state;
37 uint32_t brightness;
38 } led_data_t;
39
40 static rt_sem_t trans_done_semphr = RT_NULL;
41
42 #ifndef RT_USING_PWM
43 #error You need enable PWM to use this sample
44 #else
45 #define PWM_DEV_NAME "pwm0"
46 #define PWM_DEV_CHANNEL 3
47 static struct rt_device_pwm *pwm_dev;
48 #endif
49
capsense_isr(void)50 static void capsense_isr(void)
51 {
52 /* enter interrupt */
53 rt_interrupt_enter();
54
55 Cy_CapSense_InterruptHandler(CYBSP_CSD_HW, &cy_capsense_context);
56
57 /* leave interrupt */
58 rt_interrupt_leave();
59 }
60
capsense_callback(cy_stc_active_scan_sns_t * ptrActiveScan)61 void capsense_callback(cy_stc_active_scan_sns_t *ptrActiveScan)
62 {
63 rt_sem_release(trans_done_semphr);
64 }
65
initialize_capsense(void)66 static uint32_t initialize_capsense(void)
67 {
68 uint32_t status = CYRET_SUCCESS;
69
70 /* CapSense interrupt configuration parameters */
71 static const cy_stc_sysint_t capSense_intr_config =
72 {
73 .intrSrc = csd_interrupt_IRQn,
74 .intrPriority = CAPSENSE_INTR_PRIORITY,
75 };
76
77 /* Capture the CSD HW block and initialize it to the default state. */
78 status = Cy_CapSense_Init(&cy_capsense_context);
79 if (CYRET_SUCCESS != status)
80 {
81 return status;
82 }
83
84 /* Initialize CapSense interrupt */
85 cyhal_system_set_isr(csd_interrupt_IRQn, csd_interrupt_IRQn, CAPSENSE_INTR_PRIORITY, &capsense_isr);
86 NVIC_ClearPendingIRQ(capSense_intr_config.intrSrc);
87 NVIC_EnableIRQ(capSense_intr_config.intrSrc);
88
89 /* Initialize the CapSense firmware modules. */
90 status = Cy_CapSense_Enable(&cy_capsense_context);
91 if (CYRET_SUCCESS != status)
92 {
93 return status;
94 }
95
96 /* Assign a callback function to indicate end of CapSense scan. */
97 status = Cy_CapSense_RegisterCallback(CY_CAPSENSE_END_OF_SCAN_E,
98 capsense_callback, &cy_capsense_context);
99 if (CYRET_SUCCESS != status)
100 {
101 return status;
102 }
103
104 return status;
105 }
106
Slider_Init(void)107 void Slider_Init(void)
108 {
109 cy_rslt_t result;
110
111 result = initialize_capsense();
112
113 if (CYRET_SUCCESS != result)
114 {
115 /* Halt the CPU if CapSense initialization failed */
116 RT_ASSERT(0);
117 }
118
119 /* Initiate first scan */
120 Cy_CapSense_ScanAllWidgets(&cy_capsense_context);
121
122 trans_done_semphr = rt_sem_create("slider_sem", 1, RT_IPC_FLAG_PRIO);
123 if (trans_done_semphr == RT_NULL)
124 {
125 rt_kprintf("create transform done semphr failed.\n");
126 RT_ASSERT(0);
127 return;
128 }
129
130 #ifdef BSP_USING_PWM0_PORT13
131 /* Initiate PWM*/
132 pwm_dev = (struct rt_device_pwm *)rt_device_find(PWM_DEV_NAME);
133
134 if (pwm_dev == RT_NULL)
135 {
136 rt_kprintf("PWM init failed! can't find %s device!\n", PWM_DEV_NAME);
137 RT_ASSERT(0);
138 }
139
140 /*default period:1ms pulse:0*/
141 rt_pwm_set(pwm_dev, PWM_DEV_CHANNEL, 1 * 1000 * 1000, 1 * 1000 * 1000);
142 rt_pwm_enable(pwm_dev, PWM_DEV_CHANNEL);
143 #endif
144 }
145
update_led_state(led_data_t * ledData)146 void update_led_state(led_data_t *ledData)
147 {
148 if (ledData->brightness >= 0)
149 {
150 uint32_t brightness = (ledData->brightness < LED_MIN_BRIGHTNESS) ? LED_MIN_BRIGHTNESS : ledData->brightness;
151
152 /* Drive the LED with brightness */
153 rt_pwm_set(pwm_dev, PWM_DEV_CHANNEL, 1 * 1000 * 1000, GET_DUTY_CYCLE(brightness));
154 }
155 }
156
process_touch(void)157 static void process_touch(void)
158 {
159 cy_stc_capsense_touch_t *slider_touch_info;
160 uint16_t slider_pos;
161 uint8_t slider_touch_status;
162 bool led_update_req = false;
163
164 static uint16_t slider_pos_prev;
165 static led_data_t led_data = {LED_ON, LED_MAX_BRIGHTNESS};
166
167 /* Get slider status */
168 slider_touch_info = Cy_CapSense_GetTouchInfo(
169 CY_CAPSENSE_LINEARSLIDER0_WDGT_ID, &cy_capsense_context);
170 slider_touch_status = slider_touch_info->numPosition;
171 slider_pos = slider_touch_info->ptrPosition->x;
172
173 /* Detect the new touch on slider */
174 if ((RT_NULL != slider_touch_status) &&
175 (slider_pos != slider_pos_prev))
176 {
177 led_data.brightness = (slider_pos * 100)
178 / cy_capsense_context.ptrWdConfig[CY_CAPSENSE_LINEARSLIDER0_WDGT_ID].xResolution;
179
180 led_update_req = true;
181 }
182
183 #ifndef RT_USING_PWM
184 #error You need enable PWM to use this sample
185 #else
186 /* Update the LED state if requested */
187 if (led_update_req)
188 {
189 update_led_state(&led_data);
190 }
191 #endif
192 slider_pos_prev = slider_pos;
193 }
194
Slider_thread_entry(void * parameter)195 static void Slider_thread_entry(void *parameter)
196 {
197 Slider_Init();
198
199 for (;;)
200 {
201 rt_sem_take(trans_done_semphr, RT_WAITING_FOREVER);
202
203 /* Process all widgets */
204 Cy_CapSense_ProcessAllWidgets(&cy_capsense_context);
205
206 /* Process touch input */
207 process_touch();
208
209 /* Establishes synchronized operation between the CapSense
210 * middleware and the CapSense Tuner tool.
211 */
212 Cy_CapSense_RunTuner(&cy_capsense_context);
213
214 /* Initiate next scan */
215 Cy_CapSense_ScanAllWidgets(&cy_capsense_context);
216
217 rt_thread_mdelay(50);
218 }
219 }
220
Slider_ctrl_sample(void)221 int Slider_ctrl_sample(void)
222 {
223 rt_err_t ret = RT_EOK;
224
225 rt_thread_t thread = rt_thread_create("slider_th",
226 Slider_thread_entry,
227 RT_NULL,
228 1024,
229 25,
230 10);
231 if (thread != RT_NULL)
232 {
233 rt_thread_startup(thread);
234 }
235 else
236 {
237 ret = -RT_ERROR;
238 }
239
240 return ret;
241 }
242 MSH_CMD_EXPORT(Slider_ctrl_sample, Slider sample to ctrl led);
243 #endif
244