1 /*
2  * Copyright (c) 2019 Alexander Wachter
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/drivers/can.h>
8 #include <zephyr/kernel.h>
9 #include <zephyr/sys/util.h>
10 #include <zephyr/logging/log.h>
11 
12 LOG_MODULE_REGISTER(can_common, CONFIG_CAN_LOG_LEVEL);
13 
14 /* Maximum acceptable deviation in sample point location (permille) */
15 #define SAMPLE_POINT_MARGIN 50
16 
17 /* CAN sync segment is always one time quantum */
18 #define CAN_SYNC_SEG 1
19 
20 struct can_tx_default_cb_ctx {
21 	struct k_sem done;
22 	int status;
23 };
24 
can_tx_default_cb(const struct device * dev,int error,void * user_data)25 static void can_tx_default_cb(const struct device *dev, int error, void *user_data)
26 {
27 	struct can_tx_default_cb_ctx *ctx = user_data;
28 
29 	ctx->status = error;
30 	k_sem_give(&ctx->done);
31 }
32 
z_impl_can_send(const struct device * dev,const struct can_frame * frame,k_timeout_t timeout,can_tx_callback_t callback,void * user_data)33 int z_impl_can_send(const struct device *dev, const struct can_frame *frame,
34 		    k_timeout_t timeout, can_tx_callback_t callback,
35 		    void *user_data)
36 {
37 	const struct can_driver_api *api = (const struct can_driver_api *)dev->api;
38 
39 	if (callback == NULL) {
40 		struct can_tx_default_cb_ctx ctx;
41 		int err;
42 
43 		k_sem_init(&ctx.done, 0, 1);
44 
45 		err = api->send(dev, frame, timeout, can_tx_default_cb, &ctx);
46 		if (err != 0) {
47 			return err;
48 		}
49 
50 		k_sem_take(&ctx.done, K_FOREVER);
51 
52 		return ctx.status;
53 	}
54 
55 	return api->send(dev, frame, timeout, callback, user_data);
56 }
57 
can_msgq_put(const struct device * dev,struct can_frame * frame,void * user_data)58 static void can_msgq_put(const struct device *dev, struct can_frame *frame, void *user_data)
59 {
60 	struct k_msgq *msgq = (struct k_msgq *)user_data;
61 	int ret;
62 
63 	ARG_UNUSED(dev);
64 
65 	__ASSERT_NO_MSG(msgq);
66 
67 	ret = k_msgq_put(msgq, frame, K_NO_WAIT);
68 	if (ret) {
69 		LOG_ERR("Msgq %p overflowed. Frame ID: 0x%x", msgq, frame->id);
70 	}
71 }
72 
z_impl_can_add_rx_filter_msgq(const struct device * dev,struct k_msgq * msgq,const struct can_filter * filter)73 int z_impl_can_add_rx_filter_msgq(const struct device *dev, struct k_msgq *msgq,
74 				  const struct can_filter *filter)
75 {
76 	const struct can_driver_api *api = dev->api;
77 
78 	return api->add_rx_filter(dev, can_msgq_put, msgq, filter);
79 }
80 
81 /**
82  * @brief Update the timing given a total number of time quanta and a sample point.
83  *
84  * @code{.text}
85  *
86  * +---------------------------------------------------+
87  * |     Nominal bit time in time quanta (total_tq)    |
88  * +--------------+----------+------------+------------+
89  * |   sync_seg   | prop_seg | phase_seg1 | phase_seg2 |
90  * +--------------+----------+------------+------------+
91  * | CAN_SYNG_SEG |        tseg1          |   tseg2    |
92  * +--------------+-----------------------+------------+
93  *                                        ^
94  *                                   sample_pnt
95  * @endcode
96  *
97  * @see @a can_timing
98  *
99  * @param total_tq   Total number of time quanta.
100  * @param sample_pnt Sampling point in permill of the entire bit time.
101  * @param[out] res   Result is written into the @a can_timing struct provided.
102  * @param max        Maximum timing parameters values.
103  * @param min        Minimum timing parameters values.
104  * @return           Absolute sample point error.
105  */
update_sampling_pnt(uint32_t total_tq,uint32_t sample_pnt,struct can_timing * res,const struct can_timing * max,const struct can_timing * min)106 static int update_sampling_pnt(uint32_t total_tq, uint32_t sample_pnt,
107 			       struct can_timing *res,
108 			       const struct can_timing *max,
109 			       const struct can_timing *min)
110 {
111 	uint16_t tseg1_max = max->phase_seg1 + max->prop_seg;
112 	uint16_t tseg1_min = min->phase_seg1 + min->prop_seg;
113 	uint32_t sample_pnt_res;
114 	uint16_t tseg1, tseg2;
115 
116 	/* Calculate number of time quanta in tseg2 for given sample point */
117 	tseg2 = total_tq - (total_tq * sample_pnt) / 1000;
118 	tseg2 = CLAMP(tseg2, min->phase_seg2, max->phase_seg2);
119 
120 	/* Calculate number of time quanta in tseg1 */
121 	tseg1 = total_tq - CAN_SYNC_SEG - tseg2;
122 	if (tseg1 > tseg1_max) {
123 		/* Sample point location must be decreased */
124 		tseg1 = tseg1_max;
125 		tseg2 = total_tq - CAN_SYNC_SEG - tseg1;
126 		if (tseg2 > max->phase_seg2) {
127 			return -1;
128 		}
129 	} else if (tseg1 < tseg1_min) {
130 		/* Sample point location must be increased */
131 		tseg1 = tseg1_min;
132 		tseg2 = total_tq - CAN_SYNC_SEG - tseg1;
133 		if (tseg2 < min->phase_seg2) {
134 			return -1;
135 		}
136 	}
137 
138 	res->phase_seg2 = tseg2;
139 
140 	/* Attempt to distribute tseg1 evenly between prop_seq and phase_seg1 */
141 	res->prop_seg = CLAMP(tseg1 / 2, min->prop_seg, max->prop_seg);
142 	res->phase_seg1 = tseg1 - res->prop_seg;
143 
144 	if (res->phase_seg1 > max->phase_seg1) {
145 		/* Even tseg1 distribution not possible, decrease phase_seg1 */
146 		res->phase_seg1 = max->phase_seg1;
147 		res->prop_seg = tseg1 - res->phase_seg1;
148 	} else if (res->phase_seg1 < min->phase_seg1) {
149 		/* Even tseg1 distribution not possible, increase phase_seg1 */
150 		res->phase_seg1 = min->phase_seg1;
151 		res->prop_seg = tseg1 - res->phase_seg1;
152 	}
153 
154 	/* Calculate the resulting sample point */
155 	sample_pnt_res = (CAN_SYNC_SEG + tseg1) * 1000 / total_tq;
156 
157 	/* Return the absolute sample point error */
158 	return sample_pnt_res > sample_pnt ?
159 		sample_pnt_res - sample_pnt :
160 		sample_pnt - sample_pnt_res;
161 }
162 
163 /* Internal function to do the actual calculation */
can_calc_timing_int(uint32_t core_clock,struct can_timing * res,const struct can_timing * min,const struct can_timing * max,uint32_t bitrate,uint16_t sp)164 static int can_calc_timing_int(uint32_t core_clock, struct can_timing *res,
165 			       const struct can_timing *min,
166 			       const struct can_timing *max,
167 			       uint32_t bitrate, uint16_t sp)
168 {
169 	uint32_t ts = max->prop_seg + max->phase_seg1 + max->phase_seg2 +
170 		   CAN_SYNC_SEG;
171 	uint16_t sp_err_min = UINT16_MAX;
172 	int sp_err;
173 	struct can_timing tmp_res = { 0 };
174 
175 	if (bitrate == 0 || sp >= 1000) {
176 		return -EINVAL;
177 	}
178 
179 	for (int prescaler = MAX(core_clock / (ts * bitrate), 1);
180 	     prescaler <= max->prescaler; ++prescaler) {
181 		if (core_clock % (prescaler * bitrate)) {
182 			/* No integer ts */
183 			continue;
184 		}
185 
186 		ts = core_clock / (prescaler * bitrate);
187 
188 		sp_err = update_sampling_pnt(ts, sp, &tmp_res,
189 					     max, min);
190 		if (sp_err < 0) {
191 			/* No prop_seg, seg1, seg2 combination possible */
192 			continue;
193 		}
194 
195 		if (sp_err < sp_err_min) {
196 			sp_err_min = sp_err;
197 			res->prop_seg = tmp_res.prop_seg;
198 			res->phase_seg1 = tmp_res.phase_seg1;
199 			res->phase_seg2 = tmp_res.phase_seg2;
200 			res->prescaler = (uint16_t)prescaler;
201 			if (sp_err == 0) {
202 				/* No better result than a perfect match*/
203 				break;
204 			}
205 		}
206 	}
207 
208 	if (sp_err_min) {
209 		LOG_DBG("SP error: %d 1/1000", sp_err_min);
210 	}
211 
212 	/* Calculate default sjw as phase_seg2 / 2 and clamp the result */
213 	res->sjw = MIN(res->phase_seg1, res->phase_seg2 / 2);
214 	res->sjw = CLAMP(res->sjw, min->sjw, max->sjw);
215 
216 	return sp_err_min == UINT16_MAX ? -ENOTSUP : (int)sp_err_min;
217 }
218 
z_impl_can_calc_timing(const struct device * dev,struct can_timing * res,uint32_t bitrate,uint16_t sample_pnt)219 int z_impl_can_calc_timing(const struct device *dev, struct can_timing *res,
220 			   uint32_t bitrate, uint16_t sample_pnt)
221 {
222 	const struct can_timing *min = can_get_timing_min(dev);
223 	const struct can_timing *max = can_get_timing_max(dev);
224 	uint32_t core_clock;
225 	int ret;
226 
227 	if (bitrate > 1000000) {
228 		return -EINVAL;
229 	}
230 
231 	ret = can_get_core_clock(dev, &core_clock);
232 	if (ret != 0) {
233 		return ret;
234 	}
235 
236 	return can_calc_timing_int(core_clock, res, min, max, bitrate, sample_pnt);
237 }
238 
239 #ifdef CONFIG_CAN_FD_MODE
z_impl_can_calc_timing_data(const struct device * dev,struct can_timing * res,uint32_t bitrate,uint16_t sample_pnt)240 int z_impl_can_calc_timing_data(const struct device *dev, struct can_timing *res,
241 				uint32_t bitrate, uint16_t sample_pnt)
242 {
243 	const struct can_timing *min = can_get_timing_data_min(dev);
244 	const struct can_timing *max = can_get_timing_data_max(dev);
245 	uint32_t core_clock;
246 	int ret;
247 
248 	if (bitrate > 8000000) {
249 		return -EINVAL;
250 	}
251 
252 	ret = can_get_core_clock(dev, &core_clock);
253 	if (ret != 0) {
254 		return ret;
255 	}
256 
257 	return can_calc_timing_int(core_clock, res, min, max, bitrate, sample_pnt);
258 }
259 #endif /* CONFIG_CAN_FD_MODE */
260 
can_calc_prescaler(const struct device * dev,struct can_timing * timing,uint32_t bitrate)261 int can_calc_prescaler(const struct device *dev, struct can_timing *timing,
262 		       uint32_t bitrate)
263 {
264 	uint32_t ts = timing->prop_seg + timing->phase_seg1 + timing->phase_seg2 +
265 		   CAN_SYNC_SEG;
266 	uint32_t core_clock;
267 	int ret;
268 
269 	ret = can_get_core_clock(dev, &core_clock);
270 	if (ret != 0) {
271 		return ret;
272 	}
273 
274 	timing->prescaler = core_clock / (bitrate * ts);
275 
276 	return core_clock % (ts * timing->prescaler);
277 }
278 
279 /**
280  * @brief Get the sample point location for a given bitrate
281  *
282  * @param  bitrate The bitrate in bits/second.
283  * @return The sample point in permille.
284  */
sample_point_for_bitrate(uint32_t bitrate)285 static uint16_t sample_point_for_bitrate(uint32_t bitrate)
286 {
287 	uint16_t sample_pnt;
288 
289 	if (bitrate > 800000) {
290 		/* 75.0% */
291 		sample_pnt = 750;
292 	} else if (bitrate > 500000) {
293 		/* 80.0% */
294 		sample_pnt = 800;
295 	} else {
296 		/* 87.5% */
297 		sample_pnt = 875;
298 	}
299 
300 	return sample_pnt;
301 }
302 
check_timing_in_range(const struct can_timing * timing,const struct can_timing * min,const struct can_timing * max)303 static int check_timing_in_range(const struct can_timing *timing,
304 				 const struct can_timing *min,
305 				 const struct can_timing *max)
306 {
307 	if (!IN_RANGE(timing->sjw, min->sjw, max->sjw) ||
308 	    !IN_RANGE(timing->prop_seg, min->prop_seg, max->prop_seg) ||
309 	    !IN_RANGE(timing->phase_seg1, min->phase_seg1, max->phase_seg1) ||
310 	    !IN_RANGE(timing->phase_seg2, min->phase_seg2, max->phase_seg2) ||
311 	    !IN_RANGE(timing->prescaler, min->prescaler, max->prescaler)) {
312 		return -ENOTSUP;
313 	}
314 
315 	if ((timing->sjw > timing->phase_seg1) || (timing->sjw > timing->phase_seg2)) {
316 		return -ENOTSUP;
317 	}
318 
319 	return 0;
320 }
321 
z_impl_can_set_timing(const struct device * dev,const struct can_timing * timing)322 int z_impl_can_set_timing(const struct device *dev,
323 			  const struct can_timing *timing)
324 {
325 	const struct can_driver_api *api = (const struct can_driver_api *)dev->api;
326 	const struct can_timing *min = can_get_timing_min(dev);
327 	const struct can_timing *max = can_get_timing_max(dev);
328 	int err;
329 
330 	err = check_timing_in_range(timing, min, max);
331 	if (err != 0) {
332 		return err;
333 	}
334 
335 	return api->set_timing(dev, timing);
336 }
337 
z_impl_can_set_bitrate(const struct device * dev,uint32_t bitrate)338 int z_impl_can_set_bitrate(const struct device *dev, uint32_t bitrate)
339 {
340 	struct can_timing timing = { 0 };
341 	uint32_t max_bitrate;
342 	uint16_t sample_pnt;
343 	int ret;
344 
345 	ret = can_get_max_bitrate(dev, &max_bitrate);
346 	if (ret == -ENOSYS) {
347 		/* Maximum bitrate unknown */
348 		max_bitrate = 0;
349 	} else if (ret < 0) {
350 		return ret;
351 	}
352 
353 	if ((max_bitrate > 0) && (bitrate > max_bitrate)) {
354 		return -ENOTSUP;
355 	}
356 
357 	sample_pnt = sample_point_for_bitrate(bitrate);
358 	ret = can_calc_timing(dev, &timing, bitrate, sample_pnt);
359 	if (ret < 0) {
360 		return ret;
361 	}
362 
363 	if (ret > SAMPLE_POINT_MARGIN) {
364 		return -ERANGE;
365 	}
366 
367 	return can_set_timing(dev, &timing);
368 }
369 
370 #ifdef CONFIG_CAN_FD_MODE
z_impl_can_set_timing_data(const struct device * dev,const struct can_timing * timing_data)371 int z_impl_can_set_timing_data(const struct device *dev,
372 			       const struct can_timing *timing_data)
373 {
374 	const struct can_driver_api *api = (const struct can_driver_api *)dev->api;
375 	const struct can_timing *min = can_get_timing_data_min(dev);
376 	const struct can_timing *max = can_get_timing_data_max(dev);
377 	int err;
378 
379 	if (api->set_timing_data == NULL) {
380 		return -ENOSYS;
381 	}
382 
383 	err = check_timing_in_range(timing_data, min, max);
384 	if (err != 0) {
385 		return err;
386 	}
387 
388 	return api->set_timing_data(dev, timing_data);
389 }
390 
z_impl_can_set_bitrate_data(const struct device * dev,uint32_t bitrate_data)391 int z_impl_can_set_bitrate_data(const struct device *dev, uint32_t bitrate_data)
392 {
393 	struct can_timing timing_data = { 0 };
394 	uint32_t max_bitrate;
395 	uint16_t sample_pnt;
396 	int ret;
397 
398 	ret = can_get_max_bitrate(dev, &max_bitrate);
399 	if (ret == -ENOSYS) {
400 		/* Maximum bitrate unknown */
401 		max_bitrate = 0;
402 	} else if (ret < 0) {
403 		return ret;
404 	}
405 
406 	if ((max_bitrate > 0) && (bitrate_data > max_bitrate)) {
407 		return -ENOTSUP;
408 	}
409 
410 	sample_pnt = sample_point_for_bitrate(bitrate_data);
411 	ret = can_calc_timing_data(dev, &timing_data, bitrate_data, sample_pnt);
412 	if (ret < 0) {
413 		return ret;
414 	}
415 
416 	if (ret > SAMPLE_POINT_MARGIN) {
417 		return -ERANGE;
418 	}
419 
420 	return can_set_timing_data(dev, &timing_data);
421 }
422 #endif /* CONFIG_CAN_FD_MODE */
423