]> begriffs open source - cmsis/blob - CMSIS/Driver/DriverTemplates/Driver_CAN.c
CMSIS_Core:
[cmsis] / CMSIS / Driver / DriverTemplates / Driver_CAN.c
1 /*\r
2  * Copyright (c) 2015-2016 ARM Limited. All rights reserved.\r
3  *\r
4  * SPDX-License-Identifier: Apache-2.0\r
5  *\r
6  * Licensed under the Apache License, Version 2.0 (the License); you may\r
7  * not use this file except in compliance with the License.\r
8  * You may obtain a copy of the License at\r
9  *\r
10  * http://www.apache.org/licenses/LICENSE-2.0\r
11  *\r
12  * Unless required by applicable law or agreed to in writing, software\r
13  * distributed under the License is distributed on an AS IS BASIS, WITHOUT\r
14  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
15  * See the License for the specific language governing permissions and\r
16  * limitations under the License.\r
17  */\r
18  \r
19 #include "Driver_CAN.h"\r
20 \r
21 #define ARM_CAN_DRV_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(1,0) // CAN driver version\r
22 \r
23 // Driver Version\r
24 static const ARM_DRIVER_VERSION can_driver_version = { ARM_CAN_API_VERSION, ARM_CAN_DRV_VERSION };\r
25 \r
26 // Driver Capabilities\r
27 static const ARM_CAN_CAPABILITIES can_driver_capabilities = {\r
28   32U,  // Number of CAN Objects available\r
29   1U,   // Supports reentrant calls to ARM_CAN_MessageSend, ARM_CAN_MessageRead, ARM_CAN_ObjectConfigure and abort message sending used by ARM_CAN_Control.\r
30   0U,   // Does not support CAN with Flexible Data-rate mode (CAN_FD)\r
31   0U,   // Does not support restricted operation mode\r
32   1U,   // Supports bus monitoring mode\r
33   1U,   // Supports internal loopback mode\r
34   1U,   // Supports external loopback mode\r
35 };\r
36 \r
37 // Object Capabilities\r
38 static const ARM_CAN_OBJ_CAPABILITIES can_object_capabilities = {\r
39   1U,   // Object supports transmission\r
40   1U,   // Object supports reception\r
41   0U,   // Object does not support RTR reception and automatic Data transmission\r
42   0U,   // Object does not support RTR transmission and automatic Data reception\r
43   1U,   // Object allows assignment of multiple filters to it\r
44   1U,   // Object supports exact identifier filtering\r
45   0U,   // Object does not support range identifier filtering\r
46   1U,   // Object supports mask identifier filtering\r
47   3U    // Object can buffer 3 messages\r
48 };\r
49 \r
50 static uint8_t                     can_driver_powered     = 0U;\r
51 static uint8_t                     can_driver_initialized = 0U;\r
52 static ARM_CAN_SignalUnitEvent_t   CAN_SignalUnitEvent    = NULL;\r
53 static ARM_CAN_SignalObjectEvent_t CAN_SignalObjectEvent  = NULL;\r
54 \r
55 //\r
56 //   Functions\r
57 //\r
58 \r
59 static ARM_DRIVER_VERSION CAN_GetVersion (void) {\r
60   // Return driver version\r
61   return can_driver_version;\r
62 }\r
63 \r
64 static ARM_CAN_CAPABILITIES CAN_GetCapabilities (void) {\r
65   // Return driver capabilities\r
66   return can_driver_capabilities;\r
67 }\r
68 \r
69 static int32_t CAN_Initialize (ARM_CAN_SignalUnitEvent_t   cb_unit_event,\r
70                                ARM_CAN_SignalObjectEvent_t cb_object_event) {\r
71 \r
72   if (can_driver_initialized != 0U) { return ARM_DRIVER_OK; }\r
73 \r
74   CAN_SignalUnitEvent   = cb_unit_event;\r
75   CAN_SignalObjectEvent = cb_object_event;\r
76 \r
77   // Add code for pin, memory, RTX objects initialization\r
78   // ..\r
79 \r
80   can_driver_initialized = 1U;\r
81 \r
82   return ARM_DRIVER_OK;\r
83 }\r
84 \r
85 static int32_t CAN_Uninitialize (void) {\r
86 \r
87   // Add code for pin, memory, RTX objects de-initialization\r
88   // ..\r
89 \r
90   can_driver_initialized = 0U;\r
91 \r
92   return ARM_DRIVER_OK;\r
93 }\r
94 \r
95 static int32_t CAN_PowerControl (ARM_POWER_STATE state) {\r
96   switch (state) {\r
97     case ARM_POWER_OFF:\r
98       can_driver_powered = 0U;\r
99       // Add code to disable interrupts and put peripheral into reset mode,\r
100       // and if possible disable clock\r
101       // ..\r
102 \r
103     case ARM_POWER_FULL:\r
104       if (can_driver_initialized == 0U) { return ARM_DRIVER_ERROR; }\r
105       if (can_driver_powered     != 0U) { return ARM_DRIVER_OK;    }\r
106 \r
107       // Add code to enable clocks, reset variables enable interrupts\r
108       // and put peripheral into operational\r
109       // ..\r
110 \r
111       can_driver_powered = 1U;\r
112       break;\r
113 \r
114     default:\r
115       // Other states are not supported\r
116       return ARM_DRIVER_ERROR_UNSUPPORTED;\r
117   }\r
118 \r
119   return ARM_DRIVER_OK;\r
120 }\r
121 \r
122 uint32_t CAN_GetClock (void) {\r
123 \r
124   // Add code to return peripheral clock frequency\r
125   // ..\r
126 }\r
127 \r
128 static int32_t CAN_SetBitrate (ARM_CAN_BITRATE_SELECT select, uint32_t bitrate, uint32_t bit_segments) {\r
129 \r
130   if (can_driver_powered == 0U) { return ARM_DRIVER_ERROR; }\r
131 \r
132   // Add code to setup peripheral parameters to generate specified bitrate\r
133   // with specified bit segments\r
134   // ..\r
135 \r
136   return ARM_DRIVER_OK;\r
137 }\r
138 \r
139 static int32_t CAN_SetMode (ARM_CAN_MODE mode) {\r
140 \r
141   if (can_driver_powered == 0U) { return ARM_DRIVER_ERROR; }\r
142 \r
143   switch (mode) {\r
144     case ARM_CAN_MODE_INITIALIZATION:\r
145       // Add code to put peripheral into initialization mode\r
146       // ..\r
147       break;\r
148     case ARM_CAN_MODE_NORMAL:\r
149       // Add code to put peripheral into normal operation mode\r
150       // ..\r
151       break;\r
152     case ARM_CAN_MODE_RESTRICTED:\r
153       // Add code to put peripheral into restricted operation mode\r
154       // ..\r
155       break;\r
156     case ARM_CAN_MODE_MONITOR:\r
157       // Add code to put peripheral into bus monitoring mode\r
158       // ..\r
159       break;\r
160     case ARM_CAN_MODE_LOOPBACK_INTERNAL:\r
161       // Add code to put peripheral into internal loopback mode\r
162       // ..\r
163       break;\r
164     case ARM_CAN_MODE_LOOPBACK_EXTERNAL:\r
165       // Add code to put peripheral into external loopback mode\r
166       // ..\r
167       break;\r
168     default:\r
169       // Handle unknown mode code\r
170       return ARM_DRIVER_ERROR_UNSUPPORTED;\r
171   }\r
172 \r
173   return ARM_DRIVER_OK;\r
174 }\r
175 \r
176 ARM_CAN_OBJ_CAPABILITIES CAN_ObjectGetCapabilities (uint32_t obj_idx) {\r
177   // Return object capabilities\r
178   return can_object_capabilities;\r
179 }\r
180 \r
181 static int32_t CAN_ObjectSetFilter (uint32_t obj_idx, ARM_CAN_FILTER_OPERATION operation, uint32_t id, uint32_t arg) {\r
182 \r
183   if (can_driver_powered == 0U) { return ARM_DRIVER_ERROR; }\r
184 \r
185   switch (operation) {\r
186     case ARM_CAN_FILTER_ID_EXACT_ADD:\r
187       // Add code to setup peripheral to receive messages with specified exact ID\r
188       break;\r
189     case ARM_CAN_FILTER_ID_MASKABLE_ADD:\r
190       // Add code to setup peripheral to receive messages with specified maskable ID\r
191       break;\r
192     case ARM_CAN_FILTER_ID_RANGE_ADD:\r
193       // Add code to setup peripheral to receive messages within specified range of IDs\r
194       break;\r
195     case ARM_CAN_FILTER_ID_EXACT_REMOVE:\r
196       // Add code to remove specified exact ID from being received by peripheral\r
197       break;\r
198     case ARM_CAN_FILTER_ID_MASKABLE_REMOVE:\r
199       // Add code to remove specified maskable ID from being received by peripheral\r
200       break;\r
201     case ARM_CAN_FILTER_ID_RANGE_REMOVE:\r
202       // Add code to remove specified range of IDs from being received by peripheral\r
203       break;\r
204     default:\r
205       // Handle unknown operation code\r
206       return ARM_DRIVER_ERROR_UNSUPPORTED;\r
207   }\r
208 \r
209   return ARM_DRIVER_OK;\r
210 }\r
211 \r
212 static int32_t CAN_ObjectConfigure (uint32_t obj_idx, ARM_CAN_OBJ_CONFIG obj_cfg) {\r
213 \r
214   if (can_driver_powered == 0U) { return ARM_DRIVER_ERROR; }\r
215 \r
216   switch (obj_cfg) {\r
217     case ARM_CAN_OBJ_INACTIVE:\r
218       // Deactivate object\r
219       // ..\r
220       break;\r
221     case ARM_CAN_OBJ_RX_RTR_TX_DATA:\r
222       // Setup object to automatically return data when RTR with it's ID is received\r
223       // ..\r
224       break;\r
225     case ARM_CAN_OBJ_TX_RTR_RX_DATA:\r
226       // Setup object to send RTR and receive data response\r
227       // ..\r
228       break;\r
229     case ARM_CAN_OBJ_TX:\r
230       // Setup object to be used for sending messages\r
231       // ..\r
232       break;\r
233     case ARM_CAN_OBJ_RX:\r
234       // Setup object to be used for receiving messages\r
235       // ..\r
236       break;\r
237     default:\r
238       // Handle unknown object configuration code\r
239       return ARM_DRIVER_ERROR_UNSUPPORTED;\r
240   }\r
241 \r
242   return ARM_DRIVER_OK;\r
243 }\r
244 \r
245 static int32_t CAN_MessageSend (uint32_t obj_idx, ARM_CAN_MSG_INFO *msg_info, const uint8_t *data, uint8_t size) {\r
246 \r
247   if (can_driver_powered == 0U) { return ARM_DRIVER_ERROR; }\r
248 \r
249   // Add code to send requested message\r
250   // ..\r
251 \r
252   return ((int32_t)size);\r
253 }\r
254 \r
255 static int32_t CAN_MessageRead (uint32_t obj_idx, ARM_CAN_MSG_INFO *msg_info, uint8_t *data, uint8_t size) {\r
256 \r
257   if (can_driver_powered == 0U) { return ARM_DRIVER_ERROR;  }\r
258 \r
259   // Add code to read previously received message\r
260   // (reception was started when object was configured for reception)\r
261   // ..\r
262 \r
263   return ((int32_t)size);\r
264 }\r
265 \r
266 static int32_t CAN_Control (uint32_t control, uint32_t arg) {\r
267 \r
268   if (can_driver_powered == 0U) { return ARM_DRIVER_ERROR; }\r
269 \r
270   switch (control & ARM_CAN_CONTROL_Msk) {\r
271     case ARM_CAN_ABORT_MESSAGE_SEND:\r
272       // Add code to abort message pending to be sent\r
273       // ..\r
274       break;\r
275     case ARM_CAN_SET_FD_MODE:\r
276       // Add code to enable Flexible Data-rate mode\r
277       // ..\r
278       break;\r
279     case ARM_CAN_SET_TRANSCEIVER_DELAY:\r
280       // Add code to set transceiver delay\r
281       // ..\r
282       break;\r
283     default:\r
284       // Handle unknown control code\r
285       return ARM_DRIVER_ERROR_UNSUPPORTED;\r
286   }\r
287 \r
288   return ARM_DRIVER_OK;\r
289 }\r
290 \r
291 static ARM_CAN_STATUS CAN_GetStatus (void) {\r
292 \r
293   // Add code to return device bus and error status\r
294   // ..\r
295 }\r
296 \r
297 \r
298 // IRQ handlers\r
299 // Add interrupt routines to handle transmission, reception, error and status interrupts\r
300 // ..\r
301 \r
302 // CAN driver functions structure\r
303 \r
304 ARM_DRIVER_CAN Driver_CAN = {\r
305   CAN_GetVersion,\r
306   CAN_GetCapabilities,\r
307   CAN_Initialize,\r
308   CAN_Uninitialize,\r
309   CAN_PowerControl,\r
310   CAN_GetClock,\r
311   CAN_SetBitrate,\r
312   CAN_SetMode,\r
313   CAN_ObjectGetCapabilities,\r
314   CAN_ObjectSetFilter,\r
315   CAN_ObjectConfigure,\r
316   CAN_MessageSend,\r
317   CAN_MessageRead,\r
318   CAN_Control,\r
319   CAN_GetStatus\r
320 };\r
321 \r