1 /*
2 * Copyright (c) 2015-2020 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 0U, // Does not support 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 0U, // Does not support bus monitoring mode
33 0U, // Does not support internal loopback mode
34 0U, // Does not support external loopback mode
35 0U // Reserved (must be zero)
36 };
37
38 // Object Capabilities
39 static const ARM_CAN_OBJ_CAPABILITIES can_object_capabilities = {
40 1U, // Object supports transmission
41 1U, // Object supports reception
42 0U, // Object does not support RTR reception and automatic Data transmission
43 0U, // Object does not support RTR transmission and automatic Data reception
44 0U, // Object does not allow assignment of multiple filters to it
45 0U, // Object does not support exact identifier filtering
46 0U, // Object does not support range identifier filtering
47 0U, // Object does not support mask identifier filtering
48 0U, // Object can not buffer messages
49 0U // Reserved (must be zero)
50 };
51
52 static uint8_t can_driver_powered = 0U;
53 static uint8_t can_driver_initialized = 0U;
54 static ARM_CAN_SignalUnitEvent_t CAN_SignalUnitEvent = NULL;
55 static ARM_CAN_SignalObjectEvent_t CAN_SignalObjectEvent = NULL;
56
57 //
58 // Functions
59 //
60
ARM_CAN_GetVersion(void)61 static ARM_DRIVER_VERSION ARM_CAN_GetVersion (void) {
62 // Return driver version
63 return can_driver_version;
64 }
65
ARM_CAN_GetCapabilities(void)66 static ARM_CAN_CAPABILITIES ARM_CAN_GetCapabilities (void) {
67 // Return driver capabilities
68 return can_driver_capabilities;
69 }
70
ARM_CAN_Initialize(ARM_CAN_SignalUnitEvent_t cb_unit_event,ARM_CAN_SignalObjectEvent_t cb_object_event)71 static int32_t ARM_CAN_Initialize (ARM_CAN_SignalUnitEvent_t cb_unit_event,
72 ARM_CAN_SignalObjectEvent_t cb_object_event) {
73
74 if (can_driver_initialized != 0U) { return ARM_DRIVER_OK; }
75
76 CAN_SignalUnitEvent = cb_unit_event;
77 CAN_SignalObjectEvent = cb_object_event;
78
79 // Add code for pin, memory, RTX objects initialization
80 // ..
81
82 can_driver_initialized = 1U;
83
84 return ARM_DRIVER_OK;
85 }
86
ARM_CAN_Uninitialize(void)87 static int32_t ARM_CAN_Uninitialize (void) {
88
89 // Add code for pin, memory, RTX objects de-initialization
90 // ..
91
92 can_driver_initialized = 0U;
93
94 return ARM_DRIVER_OK;
95 }
96
ARM_CAN_PowerControl(ARM_POWER_STATE state)97 static int32_t ARM_CAN_PowerControl (ARM_POWER_STATE state) {
98 switch (state) {
99 case ARM_POWER_OFF:
100 can_driver_powered = 0U;
101 // Add code to disable interrupts and put peripheral into reset mode,
102 // and if possible disable clock
103 // ..
104
105 break;
106
107 case ARM_POWER_FULL:
108 if (can_driver_initialized == 0U) { return ARM_DRIVER_ERROR; }
109 if (can_driver_powered != 0U) { return ARM_DRIVER_OK; }
110
111 // Add code to enable clocks, reset variables enable interrupts
112 // and put peripheral into operational
113 // ..
114
115 can_driver_powered = 1U;
116 break;
117
118 case ARM_POWER_LOW:
119 return ARM_DRIVER_ERROR_UNSUPPORTED;
120 }
121
122 return ARM_DRIVER_OK;
123 }
124
ARM_CAN_GetClock(void)125 static uint32_t ARM_CAN_GetClock (void) {
126
127 // Add code to return peripheral clock frequency
128 // ..
129 }
130
ARM_CAN_SetBitrate(ARM_CAN_BITRATE_SELECT select,uint32_t bitrate,uint32_t bit_segments)131 static int32_t ARM_CAN_SetBitrate (ARM_CAN_BITRATE_SELECT select, uint32_t bitrate, uint32_t bit_segments) {
132
133 if (can_driver_powered == 0U) { return ARM_DRIVER_ERROR; }
134
135 // Add code to setup peripheral parameters to generate specified bitrate
136 // with specified bit segments
137 // ..
138
139 return ARM_DRIVER_OK;
140 }
141
ARM_CAN_SetMode(ARM_CAN_MODE mode)142 static int32_t ARM_CAN_SetMode (ARM_CAN_MODE mode) {
143
144 if (can_driver_powered == 0U) { return ARM_DRIVER_ERROR; }
145
146 switch (mode) {
147 case ARM_CAN_MODE_INITIALIZATION:
148 // Add code to put peripheral into initialization mode
149 // ..
150 break;
151 case ARM_CAN_MODE_NORMAL:
152 // Add code to put peripheral into normal operation mode
153 // ..
154 break;
155 case ARM_CAN_MODE_RESTRICTED:
156 // Add code to put peripheral into restricted operation mode
157 // ..
158 break;
159 case ARM_CAN_MODE_MONITOR:
160 // Add code to put peripheral into bus monitoring mode
161 // ..
162 break;
163 case ARM_CAN_MODE_LOOPBACK_INTERNAL:
164 // Add code to put peripheral into internal loopback mode
165 // ..
166 break;
167 case ARM_CAN_MODE_LOOPBACK_EXTERNAL:
168 // Add code to put peripheral into external loopback mode
169 // ..
170 break;
171 }
172
173 return ARM_DRIVER_OK;
174 }
175
ARM_CAN_ObjectGetCapabilities(uint32_t obj_idx)176 static ARM_CAN_OBJ_CAPABILITIES ARM_CAN_ObjectGetCapabilities (uint32_t obj_idx) {
177 // Return object capabilities
178 return can_object_capabilities;
179 }
180
ARM_CAN_ObjectSetFilter(uint32_t obj_idx,ARM_CAN_FILTER_OPERATION operation,uint32_t id,uint32_t arg)181 static int32_t ARM_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 }
205
206 return ARM_DRIVER_OK;
207 }
208
ARM_CAN_ObjectConfigure(uint32_t obj_idx,ARM_CAN_OBJ_CONFIG obj_cfg)209 static int32_t ARM_CAN_ObjectConfigure (uint32_t obj_idx, ARM_CAN_OBJ_CONFIG obj_cfg) {
210
211 if (can_driver_powered == 0U) { return ARM_DRIVER_ERROR; }
212
213 switch (obj_cfg) {
214 case ARM_CAN_OBJ_INACTIVE:
215 // Deactivate object
216 // ..
217 break;
218 case ARM_CAN_OBJ_RX_RTR_TX_DATA:
219 // Setup object to automatically return data when RTR with it's ID is received
220 // ..
221 break;
222 case ARM_CAN_OBJ_TX_RTR_RX_DATA:
223 // Setup object to send RTR and receive data response
224 // ..
225 break;
226 case ARM_CAN_OBJ_TX:
227 // Setup object to be used for sending messages
228 // ..
229 break;
230 case ARM_CAN_OBJ_RX:
231 // Setup object to be used for receiving messages
232 // ..
233 break;
234 }
235
236 return ARM_DRIVER_OK;
237 }
238
ARM_CAN_MessageSend(uint32_t obj_idx,ARM_CAN_MSG_INFO * msg_info,const uint8_t * data,uint8_t size)239 static int32_t ARM_CAN_MessageSend (uint32_t obj_idx, ARM_CAN_MSG_INFO *msg_info, const uint8_t *data, uint8_t size) {
240
241 if (can_driver_powered == 0U) { return ARM_DRIVER_ERROR; }
242
243 // Add code to send requested message
244 // ..
245
246 return ((int32_t)size);
247 }
248
ARM_CAN_MessageRead(uint32_t obj_idx,ARM_CAN_MSG_INFO * msg_info,uint8_t * data,uint8_t size)249 static int32_t ARM_CAN_MessageRead (uint32_t obj_idx, ARM_CAN_MSG_INFO *msg_info, uint8_t *data, uint8_t size) {
250
251 if (can_driver_powered == 0U) { return ARM_DRIVER_ERROR; }
252
253 // Add code to read previously received message
254 // (reception was started when object was configured for reception)
255 // ..
256
257 return ((int32_t)size);
258 }
259
ARM_CAN_Control(uint32_t control,uint32_t arg)260 static int32_t ARM_CAN_Control (uint32_t control, uint32_t arg) {
261
262 if (can_driver_powered == 0U) { return ARM_DRIVER_ERROR; }
263
264 switch (control & ARM_CAN_CONTROL_Msk) {
265 case ARM_CAN_ABORT_MESSAGE_SEND:
266 // Add code to abort message pending to be sent
267 // ..
268 break;
269 case ARM_CAN_SET_FD_MODE:
270 // Add code to enable Flexible Data-rate mode
271 // ..
272 break;
273 case ARM_CAN_SET_TRANSCEIVER_DELAY:
274 // Add code to set transceiver delay
275 // ..
276 break;
277 default:
278 // Handle unknown control code
279 return ARM_DRIVER_ERROR_UNSUPPORTED;
280 }
281
282 return ARM_DRIVER_OK;
283 }
284
ARM_CAN_GetStatus(void)285 static ARM_CAN_STATUS ARM_CAN_GetStatus (void) {
286
287 // Add code to return device bus and error status
288 // ..
289 }
290
291
292 // IRQ handlers
293 // Add interrupt routines to handle transmission, reception, error and status interrupts
294 // ..
295
296 // CAN driver functions structure
297
298 extern \
299 ARM_DRIVER_CAN Driver_CAN0;
300 ARM_DRIVER_CAN Driver_CAN0 = {
301 ARM_CAN_GetVersion,
302 ARM_CAN_GetCapabilities,
303 ARM_CAN_Initialize,
304 ARM_CAN_Uninitialize,
305 ARM_CAN_PowerControl,
306 ARM_CAN_GetClock,
307 ARM_CAN_SetBitrate,
308 ARM_CAN_SetMode,
309 ARM_CAN_ObjectGetCapabilities,
310 ARM_CAN_ObjectSetFilter,
311 ARM_CAN_ObjectConfigure,
312 ARM_CAN_MessageSend,
313 ARM_CAN_MessageRead,
314 ARM_CAN_Control,
315 ARM_CAN_GetStatus
316 };
317
318