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