1 /******************************************************************************
2 *
3 * Copyright (C) 2022-2023 Maxim Integrated Products, Inc. (now owned by
4 * Analog Devices, Inc.),
5 * Copyright (C) 2023-2024 Analog Devices, Inc.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 ******************************************************************************/
20
21 #include "mxc_device.h"
22 #include "mxc_errors.h"
23 #include "mxc_pins.h"
24 #include "can.h"
25 #include "can_reva.h"
26
27 #define MXC_CAN_OBJCAPABILITIES_ERROR \
28 { \
29 -1, -1, -1, -1, -1, -1, -1, -1, -1 \
30 }
31
32 /**********************************************************************************************************************************************************************/
MXC_CAN_GetVersion(void)33 mxc_can_drv_version_t MXC_CAN_GetVersion(void)
34 {
35 return MXC_CAN_RevA_GetVersion();
36 }
37
38 /**********************************************************************************************************************************************************************/
MXC_CAN_GetCapabilities(void)39 mxc_can_capabilities_t MXC_CAN_GetCapabilities(void)
40 {
41 mxc_can_capabilities_t ret = MXC_CAN_RevA_GetCapabilities();
42 ret.fd_mode = 0;
43 return ret;
44 }
45
46 /**********************************************************************************************************************************************************************/
MXC_CAN_Init(uint32_t can_idx,mxc_can_obj_cfg_t cfg,mxc_can_unit_event_cb_t unit_cb,mxc_can_object_event_cb_t obj_cb,uint8_t map)47 int MXC_CAN_Init(uint32_t can_idx, mxc_can_obj_cfg_t cfg, mxc_can_unit_event_cb_t unit_cb,
48 mxc_can_object_event_cb_t obj_cb, uint8_t map)
49 {
50 mxc_can_regs_t *can = MXC_CAN_GET_CAN(can_idx);
51 if (can == 0) {
52 return E_BAD_PARAM;
53 }
54
55 MXC_CAN_RevA_Init((mxc_can_reva_regs_t *)can, unit_cb, obj_cb);
56
57 return MXC_CAN_ObjectConfigure(can_idx, cfg, map);
58 }
59
60 /**********************************************************************************************************************************************************************/
MXC_CAN_UnInit(uint32_t can_idx)61 int MXC_CAN_UnInit(uint32_t can_idx)
62 {
63 switch (can_idx) {
64 case 0:
65 MXC_SYS_Reset_Periph(MXC_SYS_RESET0_CAN);
66 #ifndef MSDK_NO_GPIO_CLK_INIT
67 MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_CAN);
68 #endif // MSDK_NO_GPIO_CLK_INIT
69 break;
70 default:
71 return E_BAD_PARAM;
72 }
73
74 return MXC_CAN_RevA_UnInit((mxc_can_reva_regs_t *)MXC_CAN_GET_CAN(can_idx));
75 }
76
77 /**********************************************************************************************************************************************************************/
MXC_CAN_PowerControl(uint32_t can_idx,mxc_can_pwr_ctrl_t pwr)78 int MXC_CAN_PowerControl(uint32_t can_idx, mxc_can_pwr_ctrl_t pwr)
79 {
80 mxc_sys_periph_clock_t periph_clk;
81 if (can_idx == 0) {
82 periph_clk = MXC_SYS_PERIPH_CLOCK_CAN;
83 } else {
84 return E_BAD_PARAM;
85 }
86
87 switch (pwr) {
88 case MXC_CAN_PWR_CTRL_OFF:
89 #ifndef MSDK_NO_GPIO_CLK_INIT
90 MXC_SYS_ClockDisable(periph_clk);
91 #endif // MSDK_NO_GPIO_CLK_INIT
92 return E_NO_ERROR;
93 case MXC_CAN_PWR_CTRL_SLEEP: //Fall through
94 case MXC_CAN_PWR_CTRL_FULL:
95 #ifndef MSDK_NO_GPIO_CLK_INIT
96 MXC_SYS_ClockEnable(periph_clk);
97 #endif // MSDK_NO_GPIO_CLK_INIT
98 break;
99 default:
100 return E_BAD_PARAM;
101 }
102
103 return MXC_CAN_RevA_PowerControl((mxc_can_reva_regs_t *)MXC_CAN_GET_CAN(can_idx), pwr);
104 }
105
106 /**********************************************************************************************************************************************************************/
MXC_CAN_EnableInt(uint32_t can_idx,uint8_t en,uint8_t ext_en)107 int MXC_CAN_EnableInt(uint32_t can_idx, uint8_t en, uint8_t ext_en)
108 {
109 mxc_can_regs_t *can = MXC_CAN_GET_CAN(can_idx);
110 if (can == 0) {
111 return E_BAD_PARAM;
112 }
113
114 return MXC_CAN_RevA_EnableInt((mxc_can_reva_regs_t *)can, en, ext_en);
115 }
116
117 /**********************************************************************************************************************************************************************/
MXC_CAN_DisableInt(uint32_t can_idx,uint8_t dis,uint8_t ext_dis)118 int MXC_CAN_DisableInt(uint32_t can_idx, uint8_t dis, uint8_t ext_dis)
119 {
120 mxc_can_regs_t *can = MXC_CAN_GET_CAN(can_idx);
121 if (can == 0) {
122 return E_BAD_PARAM;
123 }
124
125 return MXC_CAN_RevA_DisableInt((mxc_can_reva_regs_t *)can, dis, ext_dis);
126 }
127
128 /**********************************************************************************************************************************************************************/
MXC_CAN_GetFlags(uint32_t can_idx,uint8_t * flags,uint8_t * ext_flags)129 int MXC_CAN_GetFlags(uint32_t can_idx, uint8_t *flags, uint8_t *ext_flags)
130 {
131 mxc_can_regs_t *can = MXC_CAN_GET_CAN(can_idx);
132 if (can == 0) {
133 return E_BAD_PARAM;
134 }
135
136 return MXC_CAN_RevA_GetFlags((mxc_can_reva_regs_t *)can, flags, ext_flags);
137 }
138
139 /**********************************************************************************************************************************************************************/
MXC_CAN_ClearFlags(uint32_t can_idx,uint8_t flags,uint8_t ext_flags)140 int MXC_CAN_ClearFlags(uint32_t can_idx, uint8_t flags, uint8_t ext_flags)
141 {
142 mxc_can_regs_t *can = MXC_CAN_GET_CAN(can_idx);
143 if (can == 0) {
144 return E_BAD_PARAM;
145 }
146
147 return MXC_CAN_RevA_ClearFlags((mxc_can_reva_regs_t *)can, flags, ext_flags);
148 }
149
150 /**********************************************************************************************************************************************************************/
MXC_CAN_GetClock(uint32_t can_idx)151 int MXC_CAN_GetClock(uint32_t can_idx)
152 {
153 return PeripheralClock;
154 }
155
156 /**********************************************************************************************************************************************************************/
MXC_CAN_GetBitRate(uint32_t can_idx,mxc_can_bitrate_sel_t sel)157 int MXC_CAN_GetBitRate(uint32_t can_idx, mxc_can_bitrate_sel_t sel)
158 {
159 mxc_can_regs_t *can = MXC_CAN_GET_CAN(can_idx);
160 if (can == 0) {
161 return E_BAD_PARAM;
162 } else if (sel == MXC_CAN_BITRATE_SEL_FD_DATA) {
163 return E_NOT_SUPPORTED;
164 }
165
166 return MXC_CAN_RevA_GetBitRate((mxc_can_reva_regs_t *)can, sel, MXC_CAN_GetClock(can_idx));
167 }
168
169 /**********************************************************************************************************************************************************************/
MXC_CAN_SetBitRate(uint32_t can_idx,mxc_can_bitrate_sel_t sel,uint32_t bitrate,uint32_t bit_segments)170 int MXC_CAN_SetBitRate(uint32_t can_idx, mxc_can_bitrate_sel_t sel, uint32_t bitrate,
171 uint32_t bit_segments)
172 {
173 mxc_can_regs_t *can = MXC_CAN_GET_CAN(can_idx);
174 if (can == 0) {
175 return E_BAD_PARAM;
176 } else if (sel == MXC_CAN_BITRATE_SEL_FD_DATA) {
177 return E_NOT_SUPPORTED;
178 }
179
180 uint8_t seg1 = (bit_segments & (0xFF << MXC_CAN_SEG1_SHIFT)) >> MXC_CAN_SEG1_SHIFT;
181 uint8_t seg2 = (bit_segments & (0xFF << MXC_CAN_SEG2_SHIFT)) >> MXC_CAN_SEG2_SHIFT;
182 uint8_t sjw = (bit_segments & (0xFF << MXC_CAN_SJW_SHIFT)) >> MXC_CAN_SJW_SHIFT;
183
184 return MXC_CAN_RevA_SetBitRate((mxc_can_reva_regs_t *)can, MXC_CAN_GetClock(can_idx), sel,
185 bitrate, seg1, seg2, sjw);
186 }
187
188 /**********************************************************************************************************************************************************************/
MXC_CAN_SetMode(uint32_t can_idx,mxc_can_mode_t mode)189 int MXC_CAN_SetMode(uint32_t can_idx, mxc_can_mode_t mode)
190 {
191 mxc_can_regs_t *can = MXC_CAN_GET_CAN(can_idx);
192 if (can == 0) {
193 return E_BAD_PARAM;
194 }
195
196 return MXC_CAN_RevA_SetMode((mxc_can_reva_regs_t *)can, mode);
197 }
198
199 /**********************************************************************************************************************************************************************/
MXC_CAN_ObjectGetCapabilities(uint32_t can_idx)200 mxc_can_obj_capabilities_t MXC_CAN_ObjectGetCapabilities(uint32_t can_idx)
201 {
202 mxc_can_regs_t *can = MXC_CAN_GET_CAN(can_idx);
203 if (can == 0) {
204 return (mxc_can_obj_capabilities_t)MXC_CAN_OBJCAPABILITIES_ERROR;
205 }
206
207 return MXC_CAN_RevA_ObjectGetCapabilities((mxc_can_reva_regs_t *)can);
208 }
209
210 /**********************************************************************************************************************************************************************/
MXC_CAN_ObjectSetFilter(uint32_t can_idx,mxc_can_filt_cfg_t cfg,uint32_t id,uint32_t arg)211 int MXC_CAN_ObjectSetFilter(uint32_t can_idx, mxc_can_filt_cfg_t cfg, uint32_t id, uint32_t arg)
212 {
213 mxc_can_regs_t *can = MXC_CAN_GET_CAN(can_idx);
214 if (can == 0) {
215 return E_BAD_PARAM;
216 }
217
218 return MXC_CAN_RevA_ObjectSetFilter((mxc_can_reva_regs_t *)can, cfg, id, arg);
219 }
220
221 /**********************************************************************************************************************************************************************/
MXC_CAN_ObjectConfigure(uint32_t can_idx,mxc_can_obj_cfg_t cfg,uint8_t map)222 int MXC_CAN_ObjectConfigure(uint32_t can_idx, mxc_can_obj_cfg_t cfg, uint8_t map)
223 {
224 mxc_can_regs_t *can = MXC_CAN_GET_CAN(can_idx);
225 if (can == 0) {
226 return E_BAD_PARAM;
227 }
228
229 #ifndef MSDK_NO_GPIO_CLK_INIT
230 switch (map) {
231 case 0:
232 MXC_GPIO_Config(&gpio_cfg_can);
233 break;
234 case 1:
235 MXC_GPIO_Config(&gpio_cfg_canb);
236 break;
237 }
238 #endif // MSDK_NO_GPIO_CLK_INIT
239
240 return MXC_CAN_RevA_ObjectConfigure((mxc_can_reva_regs_t *)can, cfg);
241 }
242
243 /**********************************************************************************************************************************************************************/
MXC_CAN_WriteTXFIFO(uint32_t can_idx,mxc_can_msg_info_t * info,const uint8_t * data,uint8_t size)244 int MXC_CAN_WriteTXFIFO(uint32_t can_idx, mxc_can_msg_info_t *info, const uint8_t *data,
245 uint8_t size)
246 {
247 mxc_can_regs_t *can = MXC_CAN_GET_CAN(can_idx);
248 if (can == 0) {
249 return E_BAD_PARAM;
250 } else if (info->fdf != 0) {
251 return E_NOT_SUPPORTED;
252 }
253
254 return MXC_CAN_RevA_WriteTXFIFO((mxc_can_reva_regs_t *)can, info, data, size);
255 }
256
257 /**********************************************************************************************************************************************************************/
MXC_CAN_ReadRXFIFO(uint32_t can_idx,mxc_can_msg_info_t * info,uint8_t * data,uint8_t size)258 int MXC_CAN_ReadRXFIFO(uint32_t can_idx, mxc_can_msg_info_t *info, uint8_t *data, uint8_t size)
259 {
260 mxc_can_regs_t *can = MXC_CAN_GET_CAN(can_idx);
261 if (can == 0) {
262 return E_BAD_PARAM;
263 } else if (info->fdf != 0) {
264 return E_NOT_SUPPORTED;
265 }
266
267 return MXC_CAN_RevA_ReadRXFIFO((mxc_can_reva_regs_t *)can, info, data, size, false);
268 }
269
270 /**********************************************************************************************************************************************************************/
MXC_CAN_MessageSend(uint32_t can_idx,mxc_can_req_t * req)271 int MXC_CAN_MessageSend(uint32_t can_idx, mxc_can_req_t *req)
272 {
273 mxc_can_regs_t *can = MXC_CAN_GET_CAN(can_idx);
274 if (can == 0) {
275 return E_BAD_PARAM;
276 } else if (req->msg_info->fdf != 0) {
277 return E_NOT_SUPPORTED;
278 }
279
280 return MXC_CAN_RevA_MessageSend((mxc_can_reva_regs_t *)can, req);
281 }
282
283 /**********************************************************************************************************************************************************************/
MXC_CAN_MessageSendAsync(uint32_t can_idx,mxc_can_req_t * req)284 int MXC_CAN_MessageSendAsync(uint32_t can_idx, mxc_can_req_t *req)
285 {
286 mxc_can_regs_t *can = MXC_CAN_GET_CAN(can_idx);
287 if (can == 0) {
288 return E_BAD_PARAM;
289 } else if (req->msg_info->fdf != 0) {
290 return E_NOT_SUPPORTED;
291 }
292
293 return MXC_CAN_RevA_MessageSendAsync((mxc_can_reva_regs_t *)can, req);
294 }
295
296 /**********************************************************************************************************************************************************************/
MXC_CAN_MessageSendDMA(uint32_t can_idx,mxc_can_req_t * req)297 int MXC_CAN_MessageSendDMA(uint32_t can_idx, mxc_can_req_t *req)
298 {
299 mxc_can_regs_t *can = MXC_CAN_GET_CAN(can_idx);
300 if (can == 0) {
301 return E_BAD_PARAM;
302 } else if (req->msg_info->fdf != 0) {
303 return E_NOT_SUPPORTED;
304 }
305
306 return MXC_CAN_RevA_MessageSendDMA((mxc_can_reva_regs_t *)can, req);
307 }
308
309 /**********************************************************************************************************************************************************************/
MXC_CAN_MessageRead(uint32_t can_idx,mxc_can_req_t * req)310 int MXC_CAN_MessageRead(uint32_t can_idx, mxc_can_req_t *req)
311 {
312 mxc_can_regs_t *can = MXC_CAN_GET_CAN(can_idx);
313 if (can == 0) {
314 return E_BAD_PARAM;
315 }
316
317 return MXC_CAN_RevA_MessageRead((mxc_can_reva_regs_t *)can, req);
318 }
319
320 /**********************************************************************************************************************************************************************/
MXC_CAN_MessageReadAsync(uint32_t can_idx,mxc_can_req_t * req)321 int MXC_CAN_MessageReadAsync(uint32_t can_idx, mxc_can_req_t *req)
322 {
323 mxc_can_regs_t *can = MXC_CAN_GET_CAN(can_idx);
324 if (can == 0) {
325 return E_BAD_PARAM;
326 }
327
328 return MXC_CAN_RevA_MessageReadAsync((mxc_can_reva_regs_t *)can, req);
329 }
330
331 /**********************************************************************************************************************************************************************/
MXC_CAN_MessageReadDMA(uint32_t can_idx,mxc_can_req_t * req,void (* dma_cb)(int,int))332 int MXC_CAN_MessageReadDMA(uint32_t can_idx, mxc_can_req_t *req, void (*dma_cb)(int, int))
333 {
334 mxc_dma_reqsel_t reqsel;
335
336 mxc_can_regs_t *can = MXC_CAN_GET_CAN(can_idx);
337 if (can == 0) {
338 return E_BAD_PARAM;
339 } else if (req->msg_info->fdf != 0) {
340 return E_NOT_SUPPORTED;
341 }
342
343 // Set Appropriate DMA Request Select
344 if (can_idx == 0) {
345 reqsel = MXC_DMA_REQUEST_CANRX;
346 } else {
347 return E_BAD_PARAM;
348 }
349
350 return MXC_CAN_RevA_MessageReadDMA((mxc_can_reva_regs_t *)can, req, reqsel, dma_cb);
351 }
352
353 /**********************************************************************************************************************************************************************/
MXC_CAN_Handler(uint32_t can_idx)354 int MXC_CAN_Handler(uint32_t can_idx)
355 {
356 mxc_can_regs_t *can = MXC_CAN_GET_CAN(can_idx);
357 if (can == 0) {
358 return E_BAD_PARAM;
359 }
360
361 return MXC_CAN_RevA_Handler((mxc_can_reva_regs_t *)can, NULL, NULL);
362 }
363
364 /**********************************************************************************************************************************************************************/
MXC_CAN_Control(uint32_t can_idx,mxc_can_ctrl_t ctrl,uint32_t ctrl_arg)365 int MXC_CAN_Control(uint32_t can_idx, mxc_can_ctrl_t ctrl, uint32_t ctrl_arg)
366 {
367 mxc_can_regs_t *can = MXC_CAN_GET_CAN(can_idx);
368 if (can == 0) {
369 return E_BAD_PARAM;
370 } else if (ctrl == MXC_CAN_CTRL_SET_FD_MODE) {
371 return E_NOT_SUPPORTED;
372 }
373
374 return MXC_CAN_RevA_Control((mxc_can_reva_regs_t *)can, ctrl, ctrl_arg);
375 }
376
377 /**********************************************************************************************************************************************************************/
MXC_CAN_SetWakeupTimer(uint32_t can_idx,uint8_t prescaler,uint16_t wup_filter_tm,uint32_t wup_expire_tm)378 int MXC_CAN_SetWakeupTimer(uint32_t can_idx, uint8_t prescaler, uint16_t wup_filter_tm,
379 uint32_t wup_expire_tm)
380 {
381 mxc_can_regs_t *can = MXC_CAN_GET_CAN(can_idx);
382 if (can == 0) {
383 return E_BAD_PARAM;
384 }
385
386 return MXC_CAN_RevA_SetWakeupTimer((mxc_can_reva_regs_t *)can, prescaler, wup_filter_tm,
387 wup_expire_tm);
388 }
389
390 /**********************************************************************************************************************************************************************/
MXC_CAN_GetStatus(uint32_t can_idx)391 mxc_can_stat_t MXC_CAN_GetStatus(uint32_t can_idx)
392 {
393 mxc_can_stat_t obj_stat;
394 obj_stat = MXC_CAN_RevA_GetStatus((mxc_can_reva_regs_t *)MXC_CAN_GET_CAN(can_idx));
395 obj_stat.can_idx = can_idx;
396
397 return obj_stat;
398 }
399
400 /**********************************************************************************************************************************************************************/
MXC_CAN_SignalUnitEvent(uint32_t can_idx,mxc_can_unit_evt_t event)401 void MXC_CAN_SignalUnitEvent(uint32_t can_idx, mxc_can_unit_evt_t event)
402 {
403 if (can_idx >= MXC_CAN_INSTANCES) {
404 return;
405 } else if (event < MXC_CAN_UNIT_EVT_INACTIVE || event > MXC_CAN_UNIT_EVT_BUS_OFF) {
406 return;
407 }
408
409 MXC_CAN_RevA_SignalUnitEvent(can_idx, event);
410 }
411
412 /**********************************************************************************************************************************************************************/
MXC_CAN_SignalObjectEvent(uint32_t can_idx,mxc_can_obj_evt_t event)413 void MXC_CAN_SignalObjectEvent(uint32_t can_idx, mxc_can_obj_evt_t event)
414 {
415 if (can_idx >= MXC_CAN_INSTANCES) {
416 return;
417 } else if (event < MXC_CAN_OBJ_EVT_TX_COMPLETE || event > MXC_CAN_OBJ_EVT_RX_OVERRUN) {
418 return;
419 }
420
421 MXC_CAN_RevA_SignalObjectEvent(can_idx, event);
422 }
423