1 /*
2 * Copyright (c) 2022 Nick Ward <nix.ward@gmail.com>
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #define DT_DRV_COMPAT nxp_pca9685_pwm
8
9 #include <zephyr/device.h>
10 #include <zephyr/drivers/i2c.h>
11 #include <zephyr/drivers/pwm.h>
12 #include <zephyr/sys/util_macro.h>
13 #include <zephyr/kernel.h>
14
15 #include <zephyr/logging/log.h>
16 LOG_MODULE_REGISTER(pwm_pca9685, CONFIG_PWM_LOG_LEVEL);
17
18 #define OSC_CLOCK_MAX 50000000
19 #define CHANNEL_CNT 16
20
21 #define ADDR_MODE1 0x00
22 #define SLEEP BIT(4)
23 #define AUTO_INC BIT(5)
24 #define RESTART BIT(7)
25
26 #define ADDR_MODE2 0x01
27 #define OUTDRV_TOTEM_POLE BIT(2)
28 #define OCH_ON_ACK BIT(3)
29
30 #define ADDR_LED0_ON_L 0x06
31 #define ADDR_LED_ON_L(n) (ADDR_LED0_ON_L + (4 * n))
32 #define LED_FULL_ON BIT(4)
33 #define LED_FULL_OFF BIT(4)
34 #define BYTE_N(word, n) ((word >> (8 * n)) & 0xFF)
35
36 #define ADDR_PRE_SCALE 0xFE
37
38
39 /* See PCA9585 datasheet Rev. 4 - 16 April 2015 section 7.3.5 */
40 #define OSC_CLOCK_INTERNAL 25000000
41
42 #define PWM_STEPS 4096
43
44 #define PRE_SCALE_MIN 0x03
45 #define PRE_SCALE_MAX 0xFF
46
47 #define PRE_SCALE_DEFAULT 0x1E
48
49 #define PWM_PERIOD_COUNT_PS(pre_scale) (PWM_STEPS * (pre_scale + 1))
50
51 /*
52 * When using the internal oscillator this corresponds to an
53 * update rate of 1526 Hz
54 */
55 #define PWM_PERIOD_COUNT_MIN PWM_PERIOD_COUNT_PS(PRE_SCALE_MIN)
56
57 /*
58 * When using the internal oscillator this corresponds to an
59 * update rate of 24 Hz
60 */
61 #define PWM_PERIOD_COUNT_MAX PWM_PERIOD_COUNT_PS(PRE_SCALE_MAX)
62
63 /*
64 * When using the internal oscillator this corresponds to an
65 * update rate of 200 Hz
66 */
67 #define PWM_PERIOD_COUNT_DEFAULT PWM_PERIOD_COUNT_PS(PRE_SCALE_DEFAULT)
68
69
70 /*
71 * Time allowed for the oscillator to stabilize after the PCA9685's
72 * RESTART mode is used to wake the chip from SLEEP.
73 * See PCA9685 datasheet section 7.3.1.1
74 */
75 #define OSCILLATOR_STABILIZE K_USEC(500)
76
77 struct pca9685_config {
78 struct i2c_dt_spec i2c;
79 bool outdrv_open_drain;
80 bool och_on_ack;
81 bool invrt;
82 };
83
84 struct pca9685_data {
85 struct k_mutex mutex;
86 uint8_t pre_scale;
87 };
88
set_reg(const struct device * dev,uint8_t addr,uint8_t value)89 static int set_reg(const struct device *dev, uint8_t addr, uint8_t value)
90 {
91 const struct pca9685_config *config = dev->config;
92 uint8_t buf[] = {addr, value};
93 int ret;
94
95 ret = i2c_write_dt(&config->i2c, buf, sizeof(buf));
96 if (ret != 0) {
97 LOG_ERR("I2C write [0x%02X]=0x%02X: %d", addr, value, ret);
98 } else {
99 LOG_DBG("[0x%02X]=0x%02X", addr, value);
100 }
101 return ret;
102 }
103
get_reg(const struct device * dev,uint8_t addr,uint8_t * value)104 static int get_reg(const struct device *dev, uint8_t addr, uint8_t *value)
105 {
106 const struct pca9685_config *config = dev->config;
107 int ret;
108
109 ret = i2c_write_read_dt(&config->i2c, &addr, sizeof(addr), value,
110 sizeof(*value));
111 if (ret != 0) {
112 LOG_ERR("I2C write [0x%02X]=0x%02X: %d", addr, *value, ret);
113 }
114 return ret;
115 }
116
set_pre_scale(const struct device * dev,uint8_t value)117 static int set_pre_scale(const struct device *dev, uint8_t value)
118 {
119 struct pca9685_data *data = dev->data;
120 uint8_t mode1;
121 int ret;
122 uint8_t restart = RESTART;
123
124 k_mutex_lock(&data->mutex, K_FOREVER);
125
126 /* Unblock write to PRE_SCALE by setting SLEEP bit to logic 1 */
127 ret = set_reg(dev, ADDR_MODE1, AUTO_INC | SLEEP);
128 if (ret != 0) {
129 goto out;
130 }
131
132 ret = get_reg(dev, ADDR_MODE1, &mode1);
133 if (ret != 0) {
134 goto out;
135 }
136
137 if ((mode1 & RESTART) == 0x00) {
138 restart = 0;
139 }
140
141 ret = set_reg(dev, ADDR_PRE_SCALE, value);
142 if (ret != 0) {
143 goto out;
144 }
145
146 /* Clear SLEEP bit - See datasheet section 7.3.1.1 */
147 ret = set_reg(dev, ADDR_MODE1, AUTO_INC);
148 if (ret != 0) {
149 goto out;
150 }
151
152 k_sleep(OSCILLATOR_STABILIZE);
153
154 ret = set_reg(dev, ADDR_MODE1, AUTO_INC | restart);
155 if (ret != 0) {
156 goto out;
157 }
158
159 out:
160 k_mutex_unlock(&data->mutex);
161
162 return ret;
163 }
164
pca9685_set_cycles(const struct device * dev,uint32_t channel,uint32_t period_count,uint32_t pulse_count,pwm_flags_t flags)165 static int pca9685_set_cycles(const struct device *dev,
166 uint32_t channel, uint32_t period_count,
167 uint32_t pulse_count, pwm_flags_t flags)
168 {
169 const struct pca9685_config *config = dev->config;
170 struct pca9685_data *data = dev->data;
171 uint8_t buf[5] = { 0 };
172 uint32_t led_off_count;
173 int32_t pre_scale;
174 int ret;
175
176 ARG_UNUSED(flags);
177
178 if (channel >= CHANNEL_CNT) {
179 LOG_WRN("channel out of range: %u", channel);
180 return -EINVAL;
181 }
182
183 pre_scale = DIV_ROUND_UP((int64_t)period_count, PWM_STEPS) - 1;
184
185 if (pre_scale < PRE_SCALE_MIN) {
186 LOG_ERR("period_count %u < %u (min)", period_count,
187 PWM_PERIOD_COUNT_MIN);
188 return -ENOTSUP;
189 } else if (pre_scale > PRE_SCALE_MAX) {
190 LOG_ERR("period_count %u > %u (max)", period_count,
191 PWM_PERIOD_COUNT_MAX);
192 return -ENOTSUP;
193 }
194
195 /* Only one output frequency - simple conversion to equivalent PWM */
196 if (pre_scale != data->pre_scale) {
197 data->pre_scale = pre_scale;
198 ret = set_pre_scale(dev, pre_scale);
199 if (ret != 0) {
200 return ret;
201 }
202 }
203
204 /* Adjust PWM output for the resolution of the PCA9685 */
205 led_off_count = DIV_ROUND_UP(pulse_count * PWM_STEPS, period_count);
206
207 buf[0] = ADDR_LED_ON_L(channel);
208 if (led_off_count == 0) {
209 buf[4] = LED_FULL_OFF;
210 } else if (led_off_count < PWM_STEPS) {
211 /* LED turns on at count 0 */
212 buf[3] = BYTE_N(led_off_count, 0);
213 buf[4] = BYTE_N(led_off_count, 1);
214 } else {
215 buf[2] = LED_FULL_ON;
216 }
217
218 return i2c_write_dt(&config->i2c, buf, sizeof(buf));
219 }
220
pca9685_get_cycles_per_sec(const struct device * dev,uint32_t channel,uint64_t * cycles)221 static int pca9685_get_cycles_per_sec(const struct device *dev,
222 uint32_t channel, uint64_t *cycles)
223 {
224 ARG_UNUSED(dev);
225 ARG_UNUSED(channel);
226
227 *cycles = OSC_CLOCK_INTERNAL;
228
229 return 0;
230 }
231
232 static DEVICE_API(pwm, pca9685_api) = {
233 .set_cycles = pca9685_set_cycles,
234 .get_cycles_per_sec = pca9685_get_cycles_per_sec,
235 };
236
pca9685_init(const struct device * dev)237 static int pca9685_init(const struct device *dev)
238 {
239 const struct pca9685_config *config = dev->config;
240 struct pca9685_data *data = dev->data;
241 uint8_t value;
242 int ret;
243
244 (void)k_mutex_init(&data->mutex);
245
246 if (!i2c_is_ready_dt(&config->i2c)) {
247 LOG_ERR("I2C device not ready");
248 return -ENODEV;
249 }
250
251 ret = set_reg(dev, ADDR_MODE1, AUTO_INC);
252 if (ret != 0) {
253 LOG_ERR("set_reg MODE1: %d", ret);
254 return ret;
255 }
256
257 value = 0x00;
258 if (!config->outdrv_open_drain) {
259 value |= OUTDRV_TOTEM_POLE;
260 }
261 if (config->och_on_ack) {
262 value |= OCH_ON_ACK;
263 }
264 ret = set_reg(dev, ADDR_MODE2, value);
265 if (ret != 0) {
266 LOG_ERR("set_reg MODE2: %d", ret);
267 return ret;
268 }
269
270 return 0;
271 }
272
273 #define PCA9685_INIT(inst) \
274 static const struct pca9685_config pca9685_##inst##_config = { \
275 .i2c = I2C_DT_SPEC_INST_GET(inst), \
276 .outdrv_open_drain = DT_INST_PROP(inst, open_drain), \
277 .och_on_ack = DT_INST_PROP(inst, och_on_ack), \
278 .invrt = DT_INST_PROP(inst, invert), \
279 }; \
280 \
281 static struct pca9685_data pca9685_##inst##_data; \
282 \
283 DEVICE_DT_INST_DEFINE(inst, pca9685_init, NULL, \
284 &pca9685_##inst##_data, \
285 &pca9685_##inst##_config, POST_KERNEL, \
286 CONFIG_PWM_INIT_PRIORITY, \
287 &pca9685_api);
288
289 DT_INST_FOREACH_STATUS_OKAY(PCA9685_INIT);
290