| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321 |
- /*
- * Copyright (c) 2015-2018 Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the License); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
- #include "Driver_CAN.h"
- #define ARM_CAN_DRV_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(1,0) // CAN driver version
- // Driver Version
- static const ARM_DRIVER_VERSION can_driver_version = { ARM_CAN_API_VERSION, ARM_CAN_DRV_VERSION };
- // Driver Capabilities
- static const ARM_CAN_CAPABILITIES can_driver_capabilities = {
- 32U, // Number of CAN Objects available
- 1U, // Supports reentrant calls to ARM_CAN_MessageSend, ARM_CAN_MessageRead, ARM_CAN_ObjectConfigure and abort message sending used by ARM_CAN_Control.
- 0U, // Does not support CAN with Flexible Data-rate mode (CAN_FD)
- 0U, // Does not support restricted operation mode
- 1U, // Supports bus monitoring mode
- 1U, // Supports internal loopback mode
- 1U, // Supports external loopback mode
- };
- // Object Capabilities
- static const ARM_CAN_OBJ_CAPABILITIES can_object_capabilities = {
- 1U, // Object supports transmission
- 1U, // Object supports reception
- 0U, // Object does not support RTR reception and automatic Data transmission
- 0U, // Object does not support RTR transmission and automatic Data reception
- 1U, // Object allows assignment of multiple filters to it
- 1U, // Object supports exact identifier filtering
- 0U, // Object does not support range identifier filtering
- 1U, // Object supports mask identifier filtering
- 3U // Object can buffer 3 messages
- };
- static uint8_t can_driver_powered = 0U;
- static uint8_t can_driver_initialized = 0U;
- static ARM_CAN_SignalUnitEvent_t CAN_SignalUnitEvent = NULL;
- static ARM_CAN_SignalObjectEvent_t CAN_SignalObjectEvent = NULL;
- //
- // Functions
- //
- static ARM_DRIVER_VERSION CAN_GetVersion (void) {
- // Return driver version
- return can_driver_version;
- }
- static ARM_CAN_CAPABILITIES CAN_GetCapabilities (void) {
- // Return driver capabilities
- return can_driver_capabilities;
- }
- static int32_t CAN_Initialize (ARM_CAN_SignalUnitEvent_t cb_unit_event,
- ARM_CAN_SignalObjectEvent_t cb_object_event) {
- if (can_driver_initialized != 0U) { return ARM_DRIVER_OK; }
- CAN_SignalUnitEvent = cb_unit_event;
- CAN_SignalObjectEvent = cb_object_event;
- // Add code for pin, memory, RTX objects initialization
- // ..
- can_driver_initialized = 1U;
- return ARM_DRIVER_OK;
- }
- static int32_t CAN_Uninitialize (void) {
- // Add code for pin, memory, RTX objects de-initialization
- // ..
- can_driver_initialized = 0U;
- return ARM_DRIVER_OK;
- }
- static int32_t CAN_PowerControl (ARM_POWER_STATE state) {
- switch (state) {
- case ARM_POWER_OFF:
- can_driver_powered = 0U;
- // Add code to disable interrupts and put peripheral into reset mode,
- // and if possible disable clock
- // ..
- case ARM_POWER_FULL:
- if (can_driver_initialized == 0U) { return ARM_DRIVER_ERROR; }
- if (can_driver_powered != 0U) { return ARM_DRIVER_OK; }
- // Add code to enable clocks, reset variables enable interrupts
- // and put peripheral into operational
- // ..
- can_driver_powered = 1U;
- break;
- default:
- // Other states are not supported
- return ARM_DRIVER_ERROR_UNSUPPORTED;
- }
- return ARM_DRIVER_OK;
- }
- uint32_t CAN_GetClock (void) {
- // Add code to return peripheral clock frequency
- // ..
- }
- static int32_t CAN_SetBitrate (ARM_CAN_BITRATE_SELECT select, uint32_t bitrate, uint32_t bit_segments) {
- if (can_driver_powered == 0U) { return ARM_DRIVER_ERROR; }
- // Add code to setup peripheral parameters to generate specified bitrate
- // with specified bit segments
- // ..
- return ARM_DRIVER_OK;
- }
- static int32_t CAN_SetMode (ARM_CAN_MODE mode) {
- if (can_driver_powered == 0U) { return ARM_DRIVER_ERROR; }
- switch (mode) {
- case ARM_CAN_MODE_INITIALIZATION:
- // Add code to put peripheral into initialization mode
- // ..
- break;
- case ARM_CAN_MODE_NORMAL:
- // Add code to put peripheral into normal operation mode
- // ..
- break;
- case ARM_CAN_MODE_RESTRICTED:
- // Add code to put peripheral into restricted operation mode
- // ..
- break;
- case ARM_CAN_MODE_MONITOR:
- // Add code to put peripheral into bus monitoring mode
- // ..
- break;
- case ARM_CAN_MODE_LOOPBACK_INTERNAL:
- // Add code to put peripheral into internal loopback mode
- // ..
- break;
- case ARM_CAN_MODE_LOOPBACK_EXTERNAL:
- // Add code to put peripheral into external loopback mode
- // ..
- break;
- default:
- // Handle unknown mode code
- return ARM_DRIVER_ERROR_UNSUPPORTED;
- }
- return ARM_DRIVER_OK;
- }
- ARM_CAN_OBJ_CAPABILITIES CAN_ObjectGetCapabilities (uint32_t obj_idx) {
- // Return object capabilities
- return can_object_capabilities;
- }
- static int32_t CAN_ObjectSetFilter (uint32_t obj_idx, ARM_CAN_FILTER_OPERATION operation, uint32_t id, uint32_t arg) {
- if (can_driver_powered == 0U) { return ARM_DRIVER_ERROR; }
- switch (operation) {
- case ARM_CAN_FILTER_ID_EXACT_ADD:
- // Add code to setup peripheral to receive messages with specified exact ID
- break;
- case ARM_CAN_FILTER_ID_MASKABLE_ADD:
- // Add code to setup peripheral to receive messages with specified maskable ID
- break;
- case ARM_CAN_FILTER_ID_RANGE_ADD:
- // Add code to setup peripheral to receive messages within specified range of IDs
- break;
- case ARM_CAN_FILTER_ID_EXACT_REMOVE:
- // Add code to remove specified exact ID from being received by peripheral
- break;
- case ARM_CAN_FILTER_ID_MASKABLE_REMOVE:
- // Add code to remove specified maskable ID from being received by peripheral
- break;
- case ARM_CAN_FILTER_ID_RANGE_REMOVE:
- // Add code to remove specified range of IDs from being received by peripheral
- break;
- default:
- // Handle unknown operation code
- return ARM_DRIVER_ERROR_UNSUPPORTED;
- }
- return ARM_DRIVER_OK;
- }
- static int32_t CAN_ObjectConfigure (uint32_t obj_idx, ARM_CAN_OBJ_CONFIG obj_cfg) {
- if (can_driver_powered == 0U) { return ARM_DRIVER_ERROR; }
- switch (obj_cfg) {
- case ARM_CAN_OBJ_INACTIVE:
- // Deactivate object
- // ..
- break;
- case ARM_CAN_OBJ_RX_RTR_TX_DATA:
- // Setup object to automatically return data when RTR with it's ID is received
- // ..
- break;
- case ARM_CAN_OBJ_TX_RTR_RX_DATA:
- // Setup object to send RTR and receive data response
- // ..
- break;
- case ARM_CAN_OBJ_TX:
- // Setup object to be used for sending messages
- // ..
- break;
- case ARM_CAN_OBJ_RX:
- // Setup object to be used for receiving messages
- // ..
- break;
- default:
- // Handle unknown object configuration code
- return ARM_DRIVER_ERROR_UNSUPPORTED;
- }
- return ARM_DRIVER_OK;
- }
- static int32_t CAN_MessageSend (uint32_t obj_idx, ARM_CAN_MSG_INFO *msg_info, const uint8_t *data, uint8_t size) {
- if (can_driver_powered == 0U) { return ARM_DRIVER_ERROR; }
- // Add code to send requested message
- // ..
- return ((int32_t)size);
- }
- static int32_t CAN_MessageRead (uint32_t obj_idx, ARM_CAN_MSG_INFO *msg_info, uint8_t *data, uint8_t size) {
- if (can_driver_powered == 0U) { return ARM_DRIVER_ERROR; }
- // Add code to read previously received message
- // (reception was started when object was configured for reception)
- // ..
- return ((int32_t)size);
- }
- static int32_t CAN_Control (uint32_t control, uint32_t arg) {
- if (can_driver_powered == 0U) { return ARM_DRIVER_ERROR; }
- switch (control & ARM_CAN_CONTROL_Msk) {
- case ARM_CAN_ABORT_MESSAGE_SEND:
- // Add code to abort message pending to be sent
- // ..
- break;
- case ARM_CAN_SET_FD_MODE:
- // Add code to enable Flexible Data-rate mode
- // ..
- break;
- case ARM_CAN_SET_TRANSCEIVER_DELAY:
- // Add code to set transceiver delay
- // ..
- break;
- default:
- // Handle unknown control code
- return ARM_DRIVER_ERROR_UNSUPPORTED;
- }
- return ARM_DRIVER_OK;
- }
- static ARM_CAN_STATUS CAN_GetStatus (void) {
- // Add code to return device bus and error status
- // ..
- }
- // IRQ handlers
- // Add interrupt routines to handle transmission, reception, error and status interrupts
- // ..
- // CAN driver functions structure
- ARM_DRIVER_CAN Driver_CAN = {
- CAN_GetVersion,
- CAN_GetCapabilities,
- CAN_Initialize,
- CAN_Uninitialize,
- CAN_PowerControl,
- CAN_GetClock,
- CAN_SetBitrate,
- CAN_SetMode,
- CAN_ObjectGetCapabilities,
- CAN_ObjectSetFilter,
- CAN_ObjectConfigure,
- CAN_MessageSend,
- CAN_MessageRead,
- CAN_Control,
- CAN_GetStatus
- };
|