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