2 * Copyright (c) 2015-2016 ARM Limited. All rights reserved.
\r
4 * SPDX-License-Identifier: Apache-2.0
\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
10 * http://www.apache.org/licenses/LICENSE-2.0
\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
19 #include "Driver_CAN.h"
\r
21 #define ARM_CAN_DRV_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(1,0) // CAN driver version
\r
24 static const ARM_DRIVER_VERSION can_driver_version = { ARM_CAN_API_VERSION, ARM_CAN_DRV_VERSION };
\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
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
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
59 static ARM_DRIVER_VERSION CAN_GetVersion (void) {
\r
60 // Return driver version
\r
61 return can_driver_version;
\r
64 static ARM_CAN_CAPABILITIES CAN_GetCapabilities (void) {
\r
65 // Return driver capabilities
\r
66 return can_driver_capabilities;
\r
69 static int32_t CAN_Initialize (ARM_CAN_SignalUnitEvent_t cb_unit_event,
\r
70 ARM_CAN_SignalObjectEvent_t cb_object_event) {
\r
72 if (can_driver_initialized != 0U) { return ARM_DRIVER_OK; }
\r
74 CAN_SignalUnitEvent = cb_unit_event;
\r
75 CAN_SignalObjectEvent = cb_object_event;
\r
77 // Add code for pin, memory, RTX objects initialization
\r
80 can_driver_initialized = 1U;
\r
82 return ARM_DRIVER_OK;
\r
85 static int32_t CAN_Uninitialize (void) {
\r
87 // Add code for pin, memory, RTX objects de-initialization
\r
90 can_driver_initialized = 0U;
\r
92 return ARM_DRIVER_OK;
\r
95 static int32_t CAN_PowerControl (ARM_POWER_STATE state) {
\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
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
107 // Add code to enable clocks, reset variables enable interrupts
\r
108 // and put peripheral into operational
\r
111 can_driver_powered = 1U;
\r
115 // Other states are not supported
\r
116 return ARM_DRIVER_ERROR_UNSUPPORTED;
\r
119 return ARM_DRIVER_OK;
\r
122 uint32_t CAN_GetClock (void) {
\r
124 // Add code to return peripheral clock frequency
\r
128 static int32_t CAN_SetBitrate (ARM_CAN_BITRATE_SELECT select, uint32_t bitrate, uint32_t bit_segments) {
\r
130 if (can_driver_powered == 0U) { return ARM_DRIVER_ERROR; }
\r
132 // Add code to setup peripheral parameters to generate specified bitrate
\r
133 // with specified bit segments
\r
136 return ARM_DRIVER_OK;
\r
139 static int32_t CAN_SetMode (ARM_CAN_MODE mode) {
\r
141 if (can_driver_powered == 0U) { return ARM_DRIVER_ERROR; }
\r
144 case ARM_CAN_MODE_INITIALIZATION:
\r
145 // Add code to put peripheral into initialization mode
\r
148 case ARM_CAN_MODE_NORMAL:
\r
149 // Add code to put peripheral into normal operation mode
\r
152 case ARM_CAN_MODE_RESTRICTED:
\r
153 // Add code to put peripheral into restricted operation mode
\r
156 case ARM_CAN_MODE_MONITOR:
\r
157 // Add code to put peripheral into bus monitoring mode
\r
160 case ARM_CAN_MODE_LOOPBACK_INTERNAL:
\r
161 // Add code to put peripheral into internal loopback mode
\r
164 case ARM_CAN_MODE_LOOPBACK_EXTERNAL:
\r
165 // Add code to put peripheral into external loopback mode
\r
169 // Handle unknown mode code
\r
170 return ARM_DRIVER_ERROR_UNSUPPORTED;
\r
173 return ARM_DRIVER_OK;
\r
176 ARM_CAN_OBJ_CAPABILITIES CAN_ObjectGetCapabilities (uint32_t obj_idx) {
\r
177 // Return object capabilities
\r
178 return can_object_capabilities;
\r
181 static int32_t CAN_ObjectSetFilter (uint32_t obj_idx, ARM_CAN_FILTER_OPERATION operation, uint32_t id, uint32_t arg) {
\r
183 if (can_driver_powered == 0U) { return ARM_DRIVER_ERROR; }
\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
189 case ARM_CAN_FILTER_ID_MASKABLE_ADD:
\r
190 // Add code to setup peripheral to receive messages with specified maskable ID
\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
195 case ARM_CAN_FILTER_ID_EXACT_REMOVE:
\r
196 // Add code to remove specified exact ID from being received by peripheral
\r
198 case ARM_CAN_FILTER_ID_MASKABLE_REMOVE:
\r
199 // Add code to remove specified maskable ID from being received by peripheral
\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
205 // Handle unknown operation code
\r
206 return ARM_DRIVER_ERROR_UNSUPPORTED;
\r
209 return ARM_DRIVER_OK;
\r
212 static int32_t CAN_ObjectConfigure (uint32_t obj_idx, ARM_CAN_OBJ_CONFIG obj_cfg) {
\r
214 if (can_driver_powered == 0U) { return ARM_DRIVER_ERROR; }
\r
217 case ARM_CAN_OBJ_INACTIVE:
\r
218 // Deactivate object
\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
225 case ARM_CAN_OBJ_TX_RTR_RX_DATA:
\r
226 // Setup object to send RTR and receive data response
\r
229 case ARM_CAN_OBJ_TX:
\r
230 // Setup object to be used for sending messages
\r
233 case ARM_CAN_OBJ_RX:
\r
234 // Setup object to be used for receiving messages
\r
238 // Handle unknown object configuration code
\r
239 return ARM_DRIVER_ERROR_UNSUPPORTED;
\r
242 return ARM_DRIVER_OK;
\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
247 if (can_driver_powered == 0U) { return ARM_DRIVER_ERROR; }
\r
249 // Add code to send requested message
\r
252 return ((int32_t)size);
\r
255 static int32_t CAN_MessageRead (uint32_t obj_idx, ARM_CAN_MSG_INFO *msg_info, uint8_t *data, uint8_t size) {
\r
257 if (can_driver_powered == 0U) { return ARM_DRIVER_ERROR; }
\r
259 // Add code to read previously received message
\r
260 // (reception was started when object was configured for reception)
\r
263 return ((int32_t)size);
\r
266 static int32_t CAN_Control (uint32_t control, uint32_t arg) {
\r
268 if (can_driver_powered == 0U) { return ARM_DRIVER_ERROR; }
\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
275 case ARM_CAN_SET_FD_MODE:
\r
276 // Add code to enable Flexible Data-rate mode
\r
279 case ARM_CAN_SET_TRANSCEIVER_DELAY:
\r
280 // Add code to set transceiver delay
\r
284 // Handle unknown control code
\r
285 return ARM_DRIVER_ERROR_UNSUPPORTED;
\r
288 return ARM_DRIVER_OK;
\r
291 static ARM_CAN_STATUS CAN_GetStatus (void) {
\r
293 // Add code to return device bus and error status
\r
299 // Add interrupt routines to handle transmission, reception, error and status interrupts
\r
302 // CAN driver functions structure
\r
304 ARM_DRIVER_CAN Driver_CAN = {
\r
306 CAN_GetCapabilities,
\r
313 CAN_ObjectGetCapabilities,
\r
314 CAN_ObjectSetFilter,
\r
315 CAN_ObjectConfigure,
\r