Controller Area Network library for NUCLEO boards equipped with CAN peripheral.

Dependents:   Nucleo-Courtois CANBLE CANnucleo_Hello3 Nucleo_Serialprintf ... more

Controller Area Network library for the NUCLEO and DISCOVERY boards equipped with CAN peripheral


Information

Because CAN support has been finally implemented into the mbed library also for the ST boards there is no need to use the CANnucleo library anymore (however you may if you want). The CAN_Hello example is trying to demonstrate the mbed built-in CAN API with NUCLEO boards.


Provides CAN support for the following boards:

with the following features:

  • Easy to use. Delete the mbed library from your project and import the latest mbed-dev and CANnucleo libraries. In the mbed-dev library open the device.h file associated with the selected target board and add #undef DEVICE_CAN as follows:

device.h

#ifndef MBED_DEVICE_H
#define MBED_DEVICE_H

//=======================================
#define DEVICE_ID_LENGTH       24

#undef DEVICE_CAN

#include "objects.h"

#endif

See the CANnucleo_Hello demo for more details.

  • Automatic recovery from bus-off state can be enabled/disabled in the constructor (defaults to ENABLE).
  • Up to 14 filters (0 - 13) are available for the application to set up for message filtering performed by hardware.
    For more details see below or have a look at the comments in CANnucleo.cpp.
  • One CAN channel per NUCLEO board is supported. The CAN peripheral can be connected either to pins PA_11, PA_12 (Receiver, Transmitter) or to pins PB_8, PB_9 (Receiver, Transmitter). This is configured when creating a CAN instance.
  • Simplifies adding/getting data to/from a CAN message by using the << (append) and the >> (extract) operators.

Import programCANnucleo_Hello

Using CAN bus with NUCLEO boards (Demo for the CANnucleo library).



Filtering performed by the built-in CAN controller without disturbing the CPU

CANnucleo supports only mask mode and 32-bit filter scale. Identifier list mode filtering and 16-bit filter scale are not supported. There are 14 filters available (0 - 13) for the application to set up. Each filter is a 32-bit filter defined by a filter ID and a filter mask. If no filter is set up then no CAN message is accepted! That's why filter #0 is set up in the constructor to accept all CAN messages by default. On reception of a message it is compared with filter #0. If there is a match, the message is accepted and stored. If there is no match, the incoming identifier is then compared with the next filter. If the received identifier does not match any of the identifiers configured in the filters, the message is discarded by hardware without disturbing the software.

CAN filter function - designed to setup a CAN filter

int CAN::filter(unsigned int id, unsigned int mask, CANFormat format, int handle)

Parameters

id - 'Filter ID' defines the bit values to be compared with the corresponding received bits.

Mapping of 32-bits (4-bytes) :

STID[10:3]STID[2:0] EXID[17:13]EXID[12:5]EXID[4:0] IDE RTR 0
  • STID - Stardard Identifier bits
  • EXID - Extended Identifier bits
  • [x:y]- bit range
  • IDE - Identifier Extension bit (0 -> Standard Identifier, 1 -> Extended Identifier)
  • RTR - Remote Transmission Request bit (0 -> Remote Transmission Request, 1 -> Standard message)

mask - 'Filter mask' defines which bits of the 'Filter ID' are compared with the received bits and which are disregarded.
Mapping of 32-bits (4-bytes) :

STID[10:3]STID[2:0] EXID[17:13]EXID[12:5]EXID[4:0] IDE RTR 0
  • STID - Stardard Identifier bits
  • EXID - Extended Identifier bits
  • [x:y]- bit range
  • IDE - Identifier Extension bit
  • RTR - Remote Transmission Request bit
  • 1 -> bit is considered
  • 0 -> bit is disregarded

format - This parameter must be CANAny
handle - Selects the filter. This parameter must be a number between 0 and 13.
retval - 0 - successful, 1 - error, 2 - busy, 3 - time out

Example of filter set up and filtering

Let's assume we would like to accept only messages with standard identifier 0x207:

STID[15:0] = 0x207 = 00000010 00000111


We map the STID to filter ID by shifting the bits adequately:

Filter ID = STID << (16 + (15 - 10)) = STID << 21 = 01000000 11100000 00000000 00000000


To compare only the bits representing STID we set the filter mask appropriately:

Filter mask = 11111111 11100000 00000000 00000100 = 0xFFE00004
              |||||||| |||                    |
              -------- ---                    |
                  |     |                     |
           STID[10:3]  STID[2:0]             IDE


Recall that filter #0 has been set up in the constructor to accept all CAN messages by default. So we have to reconfigure it. If we were set up filter #1 here then filter #0 would accept all the messages and no message would reach filter #1!
To reconfigure (set up) filter #0 we call:

can.filter(0x207 << 21, 0xFFE00004, CANAny, 0);


            Only these bits of 'Filter id' (set to 1 here in 'Filter mask') are compared 
            with the corresponding bits of received message (the others are disregarded)
                                |
                 ---------------------------------
                 |||||||| |||                    |
   Filter mask = 11111111 11100000 00000000 00000100 (= 0xFFE00004)
   Filter id   = 01000000 11100000 00000000 00000000 (= 0x40E00000)
                 |||||||| |||                    |
                 ---------------------------------
                                |
            To accept the message the values of these bits must match.
            Otherwise the message is passed to the next filter or
            discarded if this was the last active filter.
                                |
                 ---------------------------------
                 |||||||| |||                    |
   Received id = 01000000 11100000 00000000 00000010 (= 0x40E00002)
                             ||||| |||||||| ||||| ||
                             -----------------------
                                         |
                          These bits (set to 0 in 'Filter mask') are disregarded (masked).
                          They can have arbitrary values.


NOTE: For the meaning of individual bits see the mapping of 32-bits explained above.

We can use the filter function to setup more (up to 14) CAN filters for example as follows:

can.filter(0x207 << 21, 0xFFE00004, CANAny, 0);    // filter #0
can.filter(0x251 << 21, 0xFFE00004, CANAny, 1);    // filter #1
can.filter(0x304 << 21, 0xFFE00004, CANAny, 2);    // filter #2
...
Committer:
hudakz
Date:
Tue Dec 22 20:46:47 2015 +0000
Revision:
12:c45310ff2233
Parent:
11:439f3a34c42e
Child:
14:0344705e6fb8
Support for NUCLEO-F302R8, NUCLEO-F303K8, NUCLEO-F334R8 and DISCO-F334C8 added.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
hudakz 0:e29bc8e0dddd 1 /*
hudakz 5:b53e5ee15315 2 ******************************************************************************
hudakz 5:b53e5ee15315 3 * @file can_api.c
hudakz 5:b53e5ee15315 4 * @author Zoltan Hudak
hudakz 5:b53e5ee15315 5 * @version
hudakz 5:b53e5ee15315 6 * @date 04-August-2015
hudakz 5:b53e5ee15315 7 * @brief CAN api for NUCLEO-F103RB platform
hudakz 5:b53e5ee15315 8 ******************************************************************************
hudakz 5:b53e5ee15315 9 * @attention
hudakz 5:b53e5ee15315 10 *
hudakz 5:b53e5ee15315 11 * <h2><center>&copy; COPYRIGHT(c) 2015 Zoltan Hudak <hudakz@inbox.com>
hudakz 5:b53e5ee15315 12 *
hudakz 5:b53e5ee15315 13 * All rights reserved.
hudakz 0:e29bc8e0dddd 14
hudakz 0:e29bc8e0dddd 15 This program is free software: you can redistribute it and/or modify
hudakz 0:e29bc8e0dddd 16 it under the terms of the GNU General Public License as published by
hudakz 0:e29bc8e0dddd 17 the Free Software Foundation, either version 3 of the License, or
hudakz 0:e29bc8e0dddd 18 (at your option) any later version.
hudakz 0:e29bc8e0dddd 19
hudakz 0:e29bc8e0dddd 20 This program is distributed in the hope that it will be useful,
hudakz 0:e29bc8e0dddd 21 but WITHOUT ANY WARRANTY; without even the implied warranty of
hudakz 0:e29bc8e0dddd 22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
hudakz 0:e29bc8e0dddd 23 GNU General Public License for more details.
hudakz 0:e29bc8e0dddd 24
hudakz 0:e29bc8e0dddd 25 You should have received a copy of the GNU General Public License
hudakz 0:e29bc8e0dddd 26 along with this program. If not, see <http://www.gnu.org/licenses/>.
hudakz 0:e29bc8e0dddd 27 */
hudakz 11:439f3a34c42e 28 #if defined(TARGET_NUCLEO_F103RB)
hudakz 11:439f3a34c42e 29 #include "stm32f1xx_hal.h"
hudakz 12:c45310ff2233 30 #elif defined(TARGET_NUCLEO_F302R8) || \
hudakz 12:c45310ff2233 31 defined(TARGET_NUCLEO_F303RE) || \
hudakz 12:c45310ff2233 32 defined(TARGET_NUCLEO_F303K8) || \
hudakz 12:c45310ff2233 33 defined(TARGET_NUCLEO_F334R8) || \
hudakz 12:c45310ff2233 34 defined(TARGET_DISCO_F334C8)
hudakz 11:439f3a34c42e 35 #include "stm32f3xx_hal.h"
hudakz 11:439f3a34c42e 36 #endif
hudakz 0:e29bc8e0dddd 37 #include "can_api.h"
hudakz 0:e29bc8e0dddd 38 #include "can_helper.h"
hudakz 0:e29bc8e0dddd 39 #include "pinmap.h"
hudakz 0:e29bc8e0dddd 40
hudakz 0:e29bc8e0dddd 41 extern void (*rxCompleteCallback) (void);
hudakz 0:e29bc8e0dddd 42 extern CAN_HandleTypeDef _canHandle;
hudakz 0:e29bc8e0dddd 43
hudakz 0:e29bc8e0dddd 44 /**
hudakz 0:e29bc8e0dddd 45 * @brief
hudakz 0:e29bc8e0dddd 46 * @note
hudakz 0:e29bc8e0dddd 47 * @param
hudakz 0:e29bc8e0dddd 48 * @retval
hudakz 0:e29bc8e0dddd 49 */
hudakz 6:c5a40d5fd9f1 50 void can_init(can_t* obj, PinName rd, PinName td, FunctionalState abom) {
hudakz 6:c5a40d5fd9f1 51 initCAN(obj, rd, td, abom);
hudakz 0:e29bc8e0dddd 52 can_filter(obj, 0, 0, CANAny, 0);
hudakz 0:e29bc8e0dddd 53 }
hudakz 0:e29bc8e0dddd 54
hudakz 0:e29bc8e0dddd 55 /**
hudakz 0:e29bc8e0dddd 56 * @brief
hudakz 0:e29bc8e0dddd 57 * @note
hudakz 0:e29bc8e0dddd 58 * @param
hudakz 0:e29bc8e0dddd 59 * @retval
hudakz 0:e29bc8e0dddd 60 */
hudakz 0:e29bc8e0dddd 61 void can_free(can_t* obj) {
hudakz 0:e29bc8e0dddd 62 HAL_CAN_MspDeInit(obj);
hudakz 0:e29bc8e0dddd 63 }
hudakz 0:e29bc8e0dddd 64
hudakz 0:e29bc8e0dddd 65 /**
hudakz 0:e29bc8e0dddd 66 * @brief
hudakz 0:e29bc8e0dddd 67 * @note
hudakz 0:e29bc8e0dddd 68 * @param
hudakz 0:e29bc8e0dddd 69 * @retval
hudakz 0:e29bc8e0dddd 70 */
hudakz 0:e29bc8e0dddd 71 int can_frequency(can_t* obj, int hz) {
hudakz 11:439f3a34c42e 72 #if defined(TARGET_NUCLEO_F103RB)
hudakz 0:e29bc8e0dddd 73 HAL_NVIC_DisableIRQ(USB_LP_CAN1_RX0_IRQn);
hudakz 12:c45310ff2233 74 #elif defined(TARGET_NUCLEO_F302R8) || \
hudakz 12:c45310ff2233 75 defined(TARGET_NUCLEO_F303RE) || \
hudakz 12:c45310ff2233 76 defined(TARGET_NUCLEO_F303K8) || \
hudakz 12:c45310ff2233 77 defined(TARGET_NUCLEO_F334R8) || \
hudakz 12:c45310ff2233 78 defined(TARGET_DISCO_F334C8)
hudakz 11:439f3a34c42e 79 HAL_NVIC_DisableIRQ(CAN_RX1_IRQn);
hudakz 11:439f3a34c42e 80 #endif
hudakz 0:e29bc8e0dddd 81
hudakz 5:b53e5ee15315 82 // APB1 peripheral clock = 36000000Hz
hudakz 0:e29bc8e0dddd 83
hudakz 0:e29bc8e0dddd 84 switch(hz) {
hudakz 0:e29bc8e0dddd 85 case 1000000:
hudakz 0:e29bc8e0dddd 86 // 1000kbps bit rate
hudakz 0:e29bc8e0dddd 87 _canHandle.Init.Prescaler = 3; // number of time quanta = 36000000/3/1000000 = 12
hudakz 0:e29bc8e0dddd 88 _canHandle.Init.SJW = CAN_SJW_1TQ;
hudakz 0:e29bc8e0dddd 89 _canHandle.Init.BS1 = CAN_BS1_8TQ; // sample point at: (1 + 8) / 12 * 100 = 75%
hudakz 0:e29bc8e0dddd 90 _canHandle.Init.BS2 = CAN_BS2_3TQ;
hudakz 0:e29bc8e0dddd 91 break;
hudakz 0:e29bc8e0dddd 92
hudakz 0:e29bc8e0dddd 93 case 500000:
hudakz 0:e29bc8e0dddd 94 // 500kbps bit rate
hudakz 0:e29bc8e0dddd 95 _canHandle.Init.Prescaler = 6; // number of time quanta = 36000000/6/500000 = 12
hudakz 0:e29bc8e0dddd 96 _canHandle.Init.SJW = CAN_SJW_1TQ;
hudakz 0:e29bc8e0dddd 97 _canHandle.Init.BS1 = CAN_BS1_8TQ; // sample point at: (1 + 8) / 12 * 100 = 75%
hudakz 0:e29bc8e0dddd 98 _canHandle.Init.BS2 = CAN_BS2_3TQ;
hudakz 0:e29bc8e0dddd 99 break;
hudakz 0:e29bc8e0dddd 100
hudakz 0:e29bc8e0dddd 101 case 250000:
hudakz 0:e29bc8e0dddd 102 // 250kbps
hudakz 0:e29bc8e0dddd 103 _canHandle.Init.Prescaler = 9; // number of time quanta = 36000000/9/250000 = 16
hudakz 0:e29bc8e0dddd 104 _canHandle.Init.SJW = CAN_SJW_1TQ;
hudakz 0:e29bc8e0dddd 105 _canHandle.Init.BS1 = CAN_BS1_11TQ; // sample point at: (1 + 11) / 16 * 100 = 75%
hudakz 0:e29bc8e0dddd 106 _canHandle.Init.BS2 = CAN_BS2_4TQ;
hudakz 0:e29bc8e0dddd 107 break;
hudakz 0:e29bc8e0dddd 108
hudakz 0:e29bc8e0dddd 109 case 125000:
hudakz 0:e29bc8e0dddd 110 // 125kbps
hudakz 0:e29bc8e0dddd 111 _canHandle.Init.Prescaler = 18; // number of time quanta = 36000000/18/125000 = 16
hudakz 0:e29bc8e0dddd 112 _canHandle.Init.SJW = CAN_SJW_1TQ;
hudakz 0:e29bc8e0dddd 113 _canHandle.Init.BS1 = CAN_BS1_11TQ; // sample point at: (1 + 11) / 16 * 100 = 75%
hudakz 0:e29bc8e0dddd 114 _canHandle.Init.BS2 = CAN_BS2_4TQ;
hudakz 0:e29bc8e0dddd 115 break;
hudakz 0:e29bc8e0dddd 116
hudakz 0:e29bc8e0dddd 117 default:
hudakz 0:e29bc8e0dddd 118 // 125kbps (default)
hudakz 5:b53e5ee15315 119 #if DEBUG
hudakz 0:e29bc8e0dddd 120 printf("Unknown frequency specified!\r\n");
hudakz 0:e29bc8e0dddd 121 printf("Using default 125kbps\r\n");
hudakz 5:b53e5ee15315 122 #endif
hudakz 0:e29bc8e0dddd 123 _canHandle.Init.Prescaler = 18; // number of time quanta = 36000000/18/125000 = 16
hudakz 0:e29bc8e0dddd 124 _canHandle.Init.SJW = CAN_SJW_1TQ;
hudakz 0:e29bc8e0dddd 125 _canHandle.Init.BS1 = CAN_BS1_11TQ; // sample point at: (1 + 11) / 16 * 100 = 75%
hudakz 0:e29bc8e0dddd 126 _canHandle.Init.BS2 = CAN_BS2_4TQ;
hudakz 0:e29bc8e0dddd 127 }
hudakz 0:e29bc8e0dddd 128
hudakz 0:e29bc8e0dddd 129 HAL_CAN_Init(&_canHandle);
hudakz 11:439f3a34c42e 130 #if defined(TARGET_NUCLEO_F103RB)
hudakz 12:c45310ff2233 131 HAL_NVIC_EnableIRQ(USB_LP_CAN1_RX0_IRQn);
hudakz 12:c45310ff2233 132 #elif defined(TARGET_NUCLEO_F302R8) || \
hudakz 12:c45310ff2233 133 defined(TARGET_NUCLEO_F303RE) || \
hudakz 12:c45310ff2233 134 defined(TARGET_NUCLEO_F303K8) || \
hudakz 12:c45310ff2233 135 defined(TARGET_NUCLEO_F334R8) || \
hudakz 12:c45310ff2233 136 defined(TARGET_DISCO_F334C8)
hudakz 11:439f3a34c42e 137 HAL_NVIC_EnableIRQ(CAN_RX1_IRQn);
hudakz 11:439f3a34c42e 138 #endif
hudakz 11:439f3a34c42e 139
hudakz 5:b53e5ee15315 140 return 1;
hudakz 0:e29bc8e0dddd 141 }
hudakz 0:e29bc8e0dddd 142
hudakz 0:e29bc8e0dddd 143 /**
hudakz 0:e29bc8e0dddd 144 * @brief
hudakz 0:e29bc8e0dddd 145 * @note
hudakz 0:e29bc8e0dddd 146 * @param
hudakz 0:e29bc8e0dddd 147 * @retval
hudakz 0:e29bc8e0dddd 148 */
hudakz 0:e29bc8e0dddd 149 void can_irq_init(can_t* obj, can_irq_handler handler, uint32_t id) {
hudakz 0:e29bc8e0dddd 150 if(HAL_CAN_Receive_IT(&_canHandle, CAN_FIFO0) != HAL_OK) {
hudakz 5:b53e5ee15315 151 #ifdef DEBUG
hudakz 0:e29bc8e0dddd 152 printf("CAN reception initialization error\r\n");
hudakz 5:b53e5ee15315 153 #endif
hudakz 0:e29bc8e0dddd 154 }
hudakz 0:e29bc8e0dddd 155 }
hudakz 0:e29bc8e0dddd 156
hudakz 0:e29bc8e0dddd 157 /**
hudakz 0:e29bc8e0dddd 158 * @brief
hudakz 0:e29bc8e0dddd 159 * @note
hudakz 0:e29bc8e0dddd 160 * @param
hudakz 0:e29bc8e0dddd 161 * @retval
hudakz 0:e29bc8e0dddd 162 */
hudakz 0:e29bc8e0dddd 163 void can_irq_free(can_t* obj) {
hudakz 11:439f3a34c42e 164 rxCompleteCallback = 0;
hudakz 0:e29bc8e0dddd 165 }
hudakz 0:e29bc8e0dddd 166
hudakz 0:e29bc8e0dddd 167 /**
hudakz 0:e29bc8e0dddd 168 * @brief
hudakz 0:e29bc8e0dddd 169 * @note
hudakz 0:e29bc8e0dddd 170 * @param
hudakz 0:e29bc8e0dddd 171 * @retval
hudakz 0:e29bc8e0dddd 172 */
hudakz 0:e29bc8e0dddd 173 void can_irq_set(void (*fptr) (void)) {
hudakz 0:e29bc8e0dddd 174 rxCompleteCallback = fptr;
hudakz 0:e29bc8e0dddd 175 }
hudakz 0:e29bc8e0dddd 176
hudakz 0:e29bc8e0dddd 177 /**
hudakz 0:e29bc8e0dddd 178 * @brief
hudakz 0:e29bc8e0dddd 179 * @note
hudakz 0:e29bc8e0dddd 180 * @param
hudakz 0:e29bc8e0dddd 181 * @retval
hudakz 0:e29bc8e0dddd 182 */
hudakz 0:e29bc8e0dddd 183 int can_write(can_t* obj, CAN_Message msg, int cc) {
hudakz 0:e29bc8e0dddd 184 int i = 0;
hudakz 0:e29bc8e0dddd 185
hudakz 0:e29bc8e0dddd 186 if(msg.format == CANStandard) {
hudakz 0:e29bc8e0dddd 187 _canHandle.pTxMsg->StdId = msg.id;
hudakz 0:e29bc8e0dddd 188 _canHandle.pTxMsg->ExtId = 0x00;
hudakz 0:e29bc8e0dddd 189 }
hudakz 0:e29bc8e0dddd 190 else {
hudakz 0:e29bc8e0dddd 191 _canHandle.pTxMsg->StdId = 0x00;
hudakz 0:e29bc8e0dddd 192 _canHandle.pTxMsg->ExtId = msg.id;
hudakz 0:e29bc8e0dddd 193 }
hudakz 0:e29bc8e0dddd 194
hudakz 0:e29bc8e0dddd 195 _canHandle.pTxMsg->RTR = msg.type == CANData ? CAN_RTR_DATA : CAN_RTR_REMOTE;
hudakz 0:e29bc8e0dddd 196 _canHandle.pTxMsg->IDE = msg.format == CANStandard ? CAN_ID_STD : CAN_ID_EXT;
hudakz 0:e29bc8e0dddd 197 _canHandle.pTxMsg->DLC = msg.len;
hudakz 0:e29bc8e0dddd 198
hudakz 0:e29bc8e0dddd 199 for(i = 0; i < msg.len; i++)
hudakz 0:e29bc8e0dddd 200 _canHandle.pTxMsg->Data[i] = msg.data[i];
hudakz 0:e29bc8e0dddd 201
hudakz 0:e29bc8e0dddd 202 if(HAL_CAN_Transmit(&_canHandle, 10) != HAL_OK) {
hudakz 5:b53e5ee15315 203 #ifdef DEBUG
hudakz 0:e29bc8e0dddd 204 printf("Transmission error\r\n");
hudakz 5:b53e5ee15315 205 #endif
hudakz 5:b53e5ee15315 206 return 0;
hudakz 0:e29bc8e0dddd 207 }
hudakz 5:b53e5ee15315 208 else
hudakz 5:b53e5ee15315 209 return 1;
hudakz 0:e29bc8e0dddd 210 }
hudakz 0:e29bc8e0dddd 211
hudakz 0:e29bc8e0dddd 212 /**
hudakz 0:e29bc8e0dddd 213 * @brief
hudakz 0:e29bc8e0dddd 214 * @note
hudakz 0:e29bc8e0dddd 215 * @param
hudakz 0:e29bc8e0dddd 216 * @retval
hudakz 0:e29bc8e0dddd 217 */
hudakz 0:e29bc8e0dddd 218 int can_read(can_t* obj, CAN_Message* msg, int handle) {
hudakz 10:227a455d0f9f 219 int i;
hudakz 0:e29bc8e0dddd 220 msg->id = _canHandle.pRxMsg->IDE == CAN_ID_STD ? _canHandle.pRxMsg->StdId : _canHandle.pRxMsg->ExtId;
hudakz 0:e29bc8e0dddd 221 msg->type = _canHandle.pRxMsg->RTR == CAN_RTR_DATA ? CANData : CANRemote;
hudakz 0:e29bc8e0dddd 222 msg->format = _canHandle.pRxMsg->IDE == CAN_ID_STD ? CANStandard : CANExtended;
hudakz 0:e29bc8e0dddd 223 msg->len = _canHandle.pRxMsg->DLC;
hudakz 10:227a455d0f9f 224 for(i = 0; i < msg->len; i++)
hudakz 0:e29bc8e0dddd 225 msg->data[i] = _canHandle.pRxMsg->Data[i];
hudakz 5:b53e5ee15315 226
hudakz 5:b53e5ee15315 227 return msg->len;
hudakz 0:e29bc8e0dddd 228 }
hudakz 0:e29bc8e0dddd 229
hudakz 0:e29bc8e0dddd 230 /**
hudakz 0:e29bc8e0dddd 231 * @brief
hudakz 0:e29bc8e0dddd 232 * @note
hudakz 0:e29bc8e0dddd 233 * @param
hudakz 0:e29bc8e0dddd 234 * @retval
hudakz 0:e29bc8e0dddd 235 */
hudakz 0:e29bc8e0dddd 236 int can_mode(can_t* obj, CanMode mode) {
hudakz 0:e29bc8e0dddd 237 switch(mode) {
hudakz 0:e29bc8e0dddd 238 case MODE_RESET:
hudakz 0:e29bc8e0dddd 239 return HAL_ERROR;
hudakz 0:e29bc8e0dddd 240
hudakz 0:e29bc8e0dddd 241 case MODE_NORMAL:
hudakz 0:e29bc8e0dddd 242 _canHandle.Init.Mode = CAN_MODE_NORMAL;
hudakz 0:e29bc8e0dddd 243 break;
hudakz 0:e29bc8e0dddd 244
hudakz 0:e29bc8e0dddd 245 case MODE_SILENT:
hudakz 0:e29bc8e0dddd 246 _canHandle.Init.Mode = CAN_MODE_SILENT;
hudakz 0:e29bc8e0dddd 247 break;
hudakz 0:e29bc8e0dddd 248
hudakz 0:e29bc8e0dddd 249 case MODE_TEST_GLOBAL:
hudakz 0:e29bc8e0dddd 250 _canHandle.Init.Mode = CAN_MODE_LOOPBACK;
hudakz 0:e29bc8e0dddd 251 break;
hudakz 0:e29bc8e0dddd 252
hudakz 0:e29bc8e0dddd 253 case MODE_TEST_LOCAL:
hudakz 0:e29bc8e0dddd 254 _canHandle.Init.Mode = CAN_MODE_LOOPBACK;
hudakz 0:e29bc8e0dddd 255 break;
hudakz 0:e29bc8e0dddd 256
hudakz 0:e29bc8e0dddd 257 case MODE_TEST_SILENT:
hudakz 0:e29bc8e0dddd 258 _canHandle.Init.Mode = CAN_MODE_SILENT_LOOPBACK;
hudakz 0:e29bc8e0dddd 259 break;
hudakz 0:e29bc8e0dddd 260 }
hudakz 0:e29bc8e0dddd 261
hudakz 3:0fae6b54a2ee 262 return HAL_CAN_Init(&_canHandle);
hudakz 0:e29bc8e0dddd 263 }
hudakz 0:e29bc8e0dddd 264
hudakz 0:e29bc8e0dddd 265 /**
hudakz 0:e29bc8e0dddd 266 * @brief
hudakz 0:e29bc8e0dddd 267 * @note
hudakz 0:e29bc8e0dddd 268 * @param
hudakz 0:e29bc8e0dddd 269 * @retval
hudakz 0:e29bc8e0dddd 270 */
hudakz 0:e29bc8e0dddd 271 int can_filter(can_t* obj, uint32_t id, uint32_t mask, CANFormat format /*=CANAny*/, int32_t handle /*=0*/ ) {
hudakz 0:e29bc8e0dddd 272 CAN_FilterConfTypeDef sFilterConfig;
hudakz 0:e29bc8e0dddd 273
hudakz 8:5c90d6b9a382 274 sFilterConfig.FilterNumber = handle; // Specifies the filter number (must be a number between 0 and 13 at 32-bit filter scale)
hudakz 0:e29bc8e0dddd 275 sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
hudakz 0:e29bc8e0dddd 276 sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
hudakz 0:e29bc8e0dddd 277 sFilterConfig.FilterIdHigh = (((id) >> 16) & 0xFFFF);
hudakz 0:e29bc8e0dddd 278 sFilterConfig.FilterIdLow = ((id) & 0xFFFF);
hudakz 0:e29bc8e0dddd 279 sFilterConfig.FilterMaskIdHigh = (((mask) >> 16) & 0xFFFF);
hudakz 0:e29bc8e0dddd 280 sFilterConfig.FilterMaskIdLow = ((mask) & 0xFFFF);
hudakz 0:e29bc8e0dddd 281 sFilterConfig.FilterFIFOAssignment = 0;
hudakz 0:e29bc8e0dddd 282 sFilterConfig.FilterActivation = ENABLE;
hudakz 8:5c90d6b9a382 283 sFilterConfig.BankNumber = 0; // Selects the start bank filter
hudakz 8:5c90d6b9a382 284 return HAL_CAN_ConfigFilter(&_canHandle, &sFilterConfig);
hudakz 0:e29bc8e0dddd 285 }
hudakz 0:e29bc8e0dddd 286
hudakz 0:e29bc8e0dddd 287 /**
hudakz 0:e29bc8e0dddd 288 * @brief
hudakz 0:e29bc8e0dddd 289 * @note
hudakz 0:e29bc8e0dddd 290 * @param
hudakz 0:e29bc8e0dddd 291 * @retval
hudakz 0:e29bc8e0dddd 292 */
hudakz 0:e29bc8e0dddd 293 void can_reset(can_t* obj) {
hudakz 0:e29bc8e0dddd 294 __HAL_CAN_RESET_HANDLE_STATE(&_canHandle);
hudakz 0:e29bc8e0dddd 295 }
hudakz 0:e29bc8e0dddd 296
hudakz 0:e29bc8e0dddd 297 /**
hudakz 0:e29bc8e0dddd 298 * @brief
hudakz 0:e29bc8e0dddd 299 * @note
hudakz 0:e29bc8e0dddd 300 * @param
hudakz 0:e29bc8e0dddd 301 * @retval
hudakz 0:e29bc8e0dddd 302 */
hudakz 0:e29bc8e0dddd 303 unsigned char can_rderror(can_t* obj) {
hudakz 0:e29bc8e0dddd 304 return HAL_CAN_GetError(&_canHandle);
hudakz 0:e29bc8e0dddd 305 }
hudakz 0:e29bc8e0dddd 306
hudakz 0:e29bc8e0dddd 307 /**
hudakz 0:e29bc8e0dddd 308 * @brief
hudakz 0:e29bc8e0dddd 309 * @note
hudakz 0:e29bc8e0dddd 310 * @param
hudakz 0:e29bc8e0dddd 311 * @retval
hudakz 0:e29bc8e0dddd 312 */
hudakz 0:e29bc8e0dddd 313 unsigned char can_tderror(can_t* obj) {
hudakz 0:e29bc8e0dddd 314 return HAL_CAN_GetError(&_canHandle);
hudakz 0:e29bc8e0dddd 315 }
hudakz 0:e29bc8e0dddd 316
hudakz 0:e29bc8e0dddd 317 /**
hudakz 0:e29bc8e0dddd 318 * @brief
hudakz 0:e29bc8e0dddd 319 * @note
hudakz 0:e29bc8e0dddd 320 * @param
hudakz 0:e29bc8e0dddd 321 * @retval
hudakz 0:e29bc8e0dddd 322 */
hudakz 0:e29bc8e0dddd 323 void can_monitor(can_t* obj, int silent) {
hudakz 0:e29bc8e0dddd 324
hudakz 0:e29bc8e0dddd 325 // not implemented
hudakz 0:e29bc8e0dddd 326 }
hudakz 1:eb04f7f0478d 327
hudakz 5:b53e5ee15315 328
hudakz 6:c5a40d5fd9f1 329
hudakz 11:439f3a34c42e 330
hudakz 12:c45310ff2233 331