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