1 /*
2 * Copyright (c) 2006-2022, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2018-12-04 Sundm75 the first version
9 */
10 #include <stdint.h>
11 #include <string.h>
12 #include <stdlib.h>
13
14 #include <rtthread.h>
15 #include <rtdevice.h>
16
17 #include "ls1c.h"
18 #include "../libraries/ls1c_public.h"
19 #include "../libraries/ls1c_regs.h"
20 #include "../libraries/ls1c_clock.h"
21 #include "../libraries/ls1c_pwm.h"
22 #include "../libraries/ls1c_pin.h"
23
24 #define PWM_CHANNEL_MAX (4) /* 0-3*/
25
26 #ifdef RT_USING_PWM
27
28 struct rt_ls1c_pwm
29 {
30 struct rt_device_pwm parent;
31
32 rt_uint32_t period[PWM_CHANNEL_MAX];
33 rt_uint32_t pulse[PWM_CHANNEL_MAX];
34 };
35
36 static struct rt_ls1c_pwm _ls1c_pwm_device;
37
set(struct rt_device_pwm * device,struct rt_pwm_configuration * configuration)38 static rt_err_t set(struct rt_device_pwm *device, struct rt_pwm_configuration *configuration)
39 {
40 rt_err_t result = RT_EOK;
41 struct rt_ls1c_pwm *ls1c_pwm_device = (struct rt_ls1c_pwm *)device;
42
43 if (configuration->channel > (PWM_CHANNEL_MAX - 1))
44 {
45 result = -RT_EIO;
46 goto _exit;
47 }
48
49 rt_kprintf("drv_pwm.c set channel %d: period: %d, pulse: %d\n", configuration->channel, configuration->period, configuration->pulse);
50
51 ls1c_pwm_device->period[configuration->channel] = configuration->period;
52 ls1c_pwm_device->pulse[configuration->channel] = configuration->pulse;
53
54 _exit:
55 return result;
56 }
57
get(struct rt_device_pwm * device,struct rt_pwm_configuration * configuration)58 static rt_err_t get(struct rt_device_pwm *device, struct rt_pwm_configuration *configuration)
59 {
60 rt_err_t result = RT_EOK;
61 struct rt_ls1c_pwm *ls1c_pwm_device = (struct rt_ls1c_pwm *)device;
62
63 if (configuration->channel > (PWM_CHANNEL_MAX - 1))
64 {
65 result = -RT_EIO;
66 goto _exit;
67 }
68
69 configuration->period = ls1c_pwm_device->period[configuration->channel];
70 configuration->pulse = ls1c_pwm_device->pulse[configuration->channel];
71 rt_kprintf("drv_pwm.c get channel %d: period: %d, pulse: %d\n", configuration->channel, configuration->period, configuration->pulse);
72
73 _exit:
74 return result;
75 }
76
control(struct rt_device_pwm * device,int cmd,void * arg)77 static rt_err_t control(struct rt_device_pwm *device, int cmd, void *arg)
78 {
79 rt_err_t result = RT_EOK;
80 struct rt_pwm_configuration * configuration = (struct rt_pwm_configuration *)arg;
81
82 rt_kprintf("drv_pwm.c control cmd: %d. \n", cmd);
83
84 if (cmd == PWM_CMD_ENABLE)
85 {
86 rt_kprintf("PWM_CMD_ENABLE\n");
87
88 pwm_info_t pwm_info;
89 switch ( configuration->channel)
90 {
91 case 0:
92 pwm_info.gpio = LS1C_PWM0_GPIO06;
93 //pwm_info.gpio = LS1C_PWM0_GPIO04;
94 break;
95 case 1:
96 pwm_info.gpio = LS1C_PWM1_GPIO92;
97 //pwm_info.gpio = LS1C_PWM1_GPIO05;
98 break;
99 case 2:
100 pwm_info.gpio = LS1C_PWM2_GPIO52;
101 //pwm_info.gpio = LS1C_PWM2_GPIO46;
102 break;
103 case 3:
104 pwm_info.gpio = LS1C_PWM3_GPIO47;
105 //pwm_info.gpio = LS1C_PWM3_GPIO53;
106 break;
107 default:
108 break;
109 }
110 pwm_info.mode = PWM_MODE_NORMAL;
111 pwm_info.duty = ( (float)configuration->pulse ) / ((float)configuration->period );
112 pwm_info.period_ns = configuration->period;
113 pwm_init(&pwm_info);
114 pwm_enable(&pwm_info);
115 }
116 else if (cmd == PWM_CMD_DISABLE)
117 {
118 rt_kprintf("PWM_CMD_DISABLE\n");
119 pwm_info_t pwm_info;
120 switch ( configuration->channel)
121 {
122 case 0:
123 pwm_info.gpio = LS1C_PWM0_GPIO06;
124 //pwm_info.gpio = LS1C_PWM0_GPIO04;
125 break;
126 case 1:
127 pwm_info.gpio = LS1C_PWM1_GPIO92;
128 //pwm_info.gpio = LS1C_PWM1_GPIO05;
129 break;
130 case 2:
131 pwm_info.gpio = LS1C_PWM2_GPIO52;
132 //pwm_info.gpio = LS1C_PWM2_GPIO46;
133 break;
134 case 3:
135 pwm_info.gpio = LS1C_PWM3_GPIO47;
136 //pwm_info.gpio = LS1C_PWM3_GPIO53;
137 break;
138 default:
139 break;
140 }
141 pwm_info.mode = PWM_MODE_NORMAL;
142 pwm_info.duty = ( (float)configuration->pulse ) / ((float)configuration->period );
143 pwm_info.period_ns = configuration->period;
144 pwm_init(&pwm_info);
145 pwm_disable(&pwm_info);
146 }
147 else if (cmd == PWM_CMD_SET)
148 {
149 rt_kprintf("PWM_CMD_SET\n");
150 result = set(device, (struct rt_pwm_configuration *)arg);
151 }
152 else if (cmd == PWM_CMD_GET)
153 {
154 rt_kprintf("PWM_CMD_GET\n");
155 result = get(device, (struct rt_pwm_configuration *)arg);
156 }
157
158 return result;
159 }
160
161 static const struct rt_pwm_ops pwm_ops =
162 {
163 control,
164 };
165
rt_hw_pwm_init(void)166 int rt_hw_pwm_init(void)
167 {
168 int ret = RT_EOK;
169
170 /* add pwm initial. */
171
172 ret = rt_device_pwm_register(&_ls1c_pwm_device.parent, "pwm", &pwm_ops, RT_NULL);
173
174 return ret;
175 }
176 INIT_DEVICE_EXPORT(rt_hw_pwm_init);
177
178 #endif /*RT_USING_PWM*/
179