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 18:19:16 2015 +0000
Revision:
11:439f3a34c42e
Parent:
9:e9224f2c6d37
Child:
14:0344705e6fb8
Support for NUCLEO-F303RE added.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
hudakz 0:e29bc8e0dddd 1 /* mbed Microcontroller Library
hudakz 0:e29bc8e0dddd 2 * Copyright (c) 2006-2013 ARM Limited
hudakz 0:e29bc8e0dddd 3 *
hudakz 0:e29bc8e0dddd 4 * Licensed under the Apache License, Version 2.0 (the "License");
hudakz 0:e29bc8e0dddd 5 * you may not use this file except in compliance with the License.
hudakz 0:e29bc8e0dddd 6 * You may obtain a copy of the License at
hudakz 0:e29bc8e0dddd 7 *
hudakz 0:e29bc8e0dddd 8 * http://www.apache.org/licenses/LICENSE-2.0
hudakz 0:e29bc8e0dddd 9 *
hudakz 0:e29bc8e0dddd 10 * Unless required by applicable law or agreed to in writing, software
hudakz 0:e29bc8e0dddd 11 * distributed under the License is distributed on an "AS IS" BASIS,
hudakz 0:e29bc8e0dddd 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
hudakz 0:e29bc8e0dddd 13 * See the License for the specific language governing permissions and
hudakz 0:e29bc8e0dddd 14 * limitations under the License.
hudakz 0:e29bc8e0dddd 15 *
hudakz 0:e29bc8e0dddd 16 * Modified by Zoltan Hudak <hudakz@inbox.com>
hudakz 0:e29bc8e0dddd 17 *
hudakz 0:e29bc8e0dddd 18 */
hudakz 0:e29bc8e0dddd 19 #ifndef CAN_H
hudakz 0:e29bc8e0dddd 20 #define CAN_H
hudakz 0:e29bc8e0dddd 21
hudakz 0:e29bc8e0dddd 22 #include "platform.h"
hudakz 0:e29bc8e0dddd 23
hudakz 0:e29bc8e0dddd 24 #define DEVICE_CAN 1
hudakz 0:e29bc8e0dddd 25
hudakz 0:e29bc8e0dddd 26 #if DEVICE_CAN
hudakz 0:e29bc8e0dddd 27
hudakz 11:439f3a34c42e 28 #undef CAN
hudakz 11:439f3a34c42e 29
hudakz 0:e29bc8e0dddd 30 #include "can_api.h"
hudakz 0:e29bc8e0dddd 31 #include "can_helper.h"
hudakz 0:e29bc8e0dddd 32 #include "FunctionPointer.h"
hudakz 0:e29bc8e0dddd 33
hudakz 0:e29bc8e0dddd 34 namespace mbed
hudakz 0:e29bc8e0dddd 35 {
hudakz 0:e29bc8e0dddd 36
hudakz 0:e29bc8e0dddd 37 /** CANMessage class
hudakz 0:e29bc8e0dddd 38 */
hudakz 0:e29bc8e0dddd 39 class CANMessage : public CAN_Message
hudakz 0:e29bc8e0dddd 40 {
hudakz 0:e29bc8e0dddd 41
hudakz 0:e29bc8e0dddd 42 public:
hudakz 0:e29bc8e0dddd 43 /** Creates empty CAN message.
hudakz 0:e29bc8e0dddd 44 */
hudakz 0:e29bc8e0dddd 45 CANMessage() : CAN_Message() {
hudakz 0:e29bc8e0dddd 46 len = 8;
hudakz 0:e29bc8e0dddd 47 type = CANData;
hudakz 0:e29bc8e0dddd 48 format = CANStandard;
hudakz 0:e29bc8e0dddd 49 id = 0;
hudakz 0:e29bc8e0dddd 50 memset(data, 0, 8);
hudakz 0:e29bc8e0dddd 51 }
hudakz 0:e29bc8e0dddd 52
hudakz 0:e29bc8e0dddd 53 /** Creates CAN message with specific content.
hudakz 0:e29bc8e0dddd 54 */
hudakz 0:e29bc8e0dddd 55 CANMessage(int _id, const char *_data, char _len = 8, CANType _type = CANData, CANFormat _format = CANStandard) {
hudakz 0:e29bc8e0dddd 56 len = _len & 0xF;
hudakz 0:e29bc8e0dddd 57 type = _type;
hudakz 0:e29bc8e0dddd 58 format = _format;
hudakz 0:e29bc8e0dddd 59 id = _id;
hudakz 0:e29bc8e0dddd 60 memcpy(data, _data, _len);
hudakz 0:e29bc8e0dddd 61 }
hudakz 0:e29bc8e0dddd 62
hudakz 0:e29bc8e0dddd 63 /** Creates CAN remote message.
hudakz 0:e29bc8e0dddd 64 */
hudakz 0:e29bc8e0dddd 65 CANMessage(int _id, CANFormat _format = CANStandard) {
hudakz 0:e29bc8e0dddd 66 len = 0;
hudakz 0:e29bc8e0dddd 67 type = CANRemote;
hudakz 0:e29bc8e0dddd 68 format = _format;
hudakz 0:e29bc8e0dddd 69 id = _id;
hudakz 0:e29bc8e0dddd 70 memset(data, 0, 8);
hudakz 0:e29bc8e0dddd 71 }
hudakz 0:e29bc8e0dddd 72
hudakz 0:e29bc8e0dddd 73 /*********************************************************************/
hudakz 0:e29bc8e0dddd 74 /*********************************************************************/
hudakz 0:e29bc8e0dddd 75 /*********************************************************************/
hudakz 4:38403b42718b 76 /** Copy constructor.
hudakz 4:38403b42718b 77 */
hudakz 4:38403b42718b 78 CANMessage(const CANMessage& canMessage) {
hudakz 4:38403b42718b 79 len = canMessage.len;
hudakz 4:38403b42718b 80 type = canMessage.type;
hudakz 4:38403b42718b 81 format = canMessage.format;
hudakz 4:38403b42718b 82 id = canMessage.id;
hudakz 4:38403b42718b 83 memcpy(data, canMessage.data, canMessage.len);
hudakz 4:38403b42718b 84 }
hudakz 4:38403b42718b 85
hudakz 0:e29bc8e0dddd 86 /** Clears CAN message content
hudakz 0:e29bc8e0dddd 87 */
hudakz 0:e29bc8e0dddd 88 void clear(void) {
hudakz 0:e29bc8e0dddd 89 len = 0;
hudakz 0:e29bc8e0dddd 90 type = CANData;
hudakz 0:e29bc8e0dddd 91 format = CANStandard;
hudakz 0:e29bc8e0dddd 92 id = 0;
hudakz 0:e29bc8e0dddd 93 memset(data, 0, 8);
hudakz 0:e29bc8e0dddd 94 };
hudakz 0:e29bc8e0dddd 95
hudakz 0:e29bc8e0dddd 96 /** Inserter operator: Appends data (value) to CAN message
hudakz 0:e29bc8e0dddd 97 */
hudakz 0:e29bc8e0dddd 98 template<class T>
hudakz 0:e29bc8e0dddd 99 CANMessage &operator<<(const T val) {
hudakz 0:e29bc8e0dddd 100 if(len + sizeof(T) <= 8) {
hudakz 0:e29bc8e0dddd 101 *reinterpret_cast < T * > (&data[len]) = val;
hudakz 0:e29bc8e0dddd 102 len += sizeof(T);
hudakz 0:e29bc8e0dddd 103 }
hudakz 0:e29bc8e0dddd 104 #if DEBUG
hudakz 0:e29bc8e0dddd 105 else {
hudakz 0:e29bc8e0dddd 106 printf("Error: Cannot append data because it exceeds CAN data length!\r\n");
hudakz 0:e29bc8e0dddd 107 }
hudakz 0:e29bc8e0dddd 108 #endif
hudakz 0:e29bc8e0dddd 109 return *this;
hudakz 0:e29bc8e0dddd 110 }
hudakz 0:e29bc8e0dddd 111
hudakz 0:e29bc8e0dddd 112 /** Extractor operator: Extracts data (value) from CAN message
hudakz 0:e29bc8e0dddd 113 */
hudakz 0:e29bc8e0dddd 114 template<class T>
hudakz 0:e29bc8e0dddd 115 CANMessage &operator>>(T& val) {
hudakz 0:e29bc8e0dddd 116 if(sizeof(T) <= len) {
hudakz 0:e29bc8e0dddd 117 val = *reinterpret_cast < T * > (&data[0]);
hudakz 0:e29bc8e0dddd 118 len -= sizeof(T);
hudakz 0:e29bc8e0dddd 119 memcpy(data, data + sizeof(T), len);
hudakz 0:e29bc8e0dddd 120 }
hudakz 0:e29bc8e0dddd 121 #if DEBUG
hudakz 0:e29bc8e0dddd 122 else {
hudakz 0:e29bc8e0dddd 123 printf("Error: Cannot extract data because it exceeds CAN data length!\r\n");
hudakz 0:e29bc8e0dddd 124 }
hudakz 0:e29bc8e0dddd 125 #endif
hudakz 0:e29bc8e0dddd 126 return *this;
hudakz 0:e29bc8e0dddd 127 }
hudakz 0:e29bc8e0dddd 128
hudakz 0:e29bc8e0dddd 129 };
hudakz 0:e29bc8e0dddd 130
hudakz 0:e29bc8e0dddd 131 /** A can bus client, used for communicating with can devices
hudakz 0:e29bc8e0dddd 132 */
hudakz 0:e29bc8e0dddd 133 class CAN
hudakz 0:e29bc8e0dddd 134 {
hudakz 0:e29bc8e0dddd 135
hudakz 0:e29bc8e0dddd 136 public:
hudakz 0:e29bc8e0dddd 137 /** Creates an CAN interface connected to specific pins.
hudakz 0:e29bc8e0dddd 138 *
hudakz 0:e29bc8e0dddd 139 * @param rd read from transmitter
hudakz 0:e29bc8e0dddd 140 * @param td transmit to transmitter
hudakz 0:e29bc8e0dddd 141 *
hudakz 0:e29bc8e0dddd 142 * Example:
hudakz 0:e29bc8e0dddd 143 * @code
hudakz 0:e29bc8e0dddd 144 * #include "mbed.h"
hudakz 0:e29bc8e0dddd 145 * #include "CAN.h"
hudakz 0:e29bc8e0dddd 146 *
hudakz 0:e29bc8e0dddd 147 * Ticker ticker;
hudakz 0:e29bc8e0dddd 148 * DigitalOut led1(LED1);
hudakz 0:e29bc8e0dddd 149 * CAN can(PA_11, PA_12);
hudakz 0:e29bc8e0dddd 150 *
hudakz 0:e29bc8e0dddd 151 * char counter = 0;
hudakz 0:e29bc8e0dddd 152 *
hudakz 0:e29bc8e0dddd 153 * void send() {
hudakz 0:e29bc8e0dddd 154 * if(can.write(CANMessage(1337, &counter, 1))) {
hudakz 0:e29bc8e0dddd 155 * printf("Message sent: %d\n", counter);
hudakz 0:e29bc8e0dddd 156 * counter++;
hudakz 0:e29bc8e0dddd 157 * }
hudakz 0:e29bc8e0dddd 158 * led1 = !led1;
hudakz 0:e29bc8e0dddd 159 * }
hudakz 0:e29bc8e0dddd 160 *
hudakz 0:e29bc8e0dddd 161 * int main() {
hudakz 0:e29bc8e0dddd 162 * ticker.attach(&send, 1);
hudakz 0:e29bc8e0dddd 163 * CANMessage msg;
hudakz 0:e29bc8e0dddd 164 * while(1) {
hudakz 0:e29bc8e0dddd 165 * if(can.read(msg)) {
hudakz 0:e29bc8e0dddd 166 * printf("Message received: %d\n\n", msg.data[0]);
hudakz 0:e29bc8e0dddd 167 * led1 = !led1;
hudakz 0:e29bc8e0dddd 168 * }
hudakz 0:e29bc8e0dddd 169 * wait(0.2);
hudakz 0:e29bc8e0dddd 170 * }
hudakz 0:e29bc8e0dddd 171 * }
hudakz 0:e29bc8e0dddd 172 * @endcode
hudakz 0:e29bc8e0dddd 173 */
hudakz 6:c5a40d5fd9f1 174
hudakz 6:c5a40d5fd9f1 175 /** Constructor
hudakz 6:c5a40d5fd9f1 176 *
hudakz 6:c5a40d5fd9f1 177 * @param rd CAN receiver pin name
hudakz 6:c5a40d5fd9f1 178 * @param td CAN transmitter pin name
hudakz 6:c5a40d5fd9f1 179 * @param abom Automatic recovery from bus-off state (default value set to enabled)
hudakz 6:c5a40d5fd9f1 180 *
hudakz 6:c5a40d5fd9f1 181 */
hudakz 6:c5a40d5fd9f1 182 CAN(PinName rd, PinName td, FunctionalState abom = ENABLE);
hudakz 6:c5a40d5fd9f1 183
hudakz 0:e29bc8e0dddd 184 virtual ~CAN();
hudakz 0:e29bc8e0dddd 185
hudakz 0:e29bc8e0dddd 186 /** Set the frequency of the CAN interface
hudakz 0:e29bc8e0dddd 187 *
hudakz 0:e29bc8e0dddd 188 * @param hz The bus frequency in hertz
hudakz 0:e29bc8e0dddd 189 *
hudakz 0:e29bc8e0dddd 190 * @returns
hudakz 0:e29bc8e0dddd 191 * 1 if successful,
hudakz 0:e29bc8e0dddd 192 * 0 otherwise
hudakz 0:e29bc8e0dddd 193 */
hudakz 0:e29bc8e0dddd 194 int frequency(int hz);
hudakz 0:e29bc8e0dddd 195
hudakz 0:e29bc8e0dddd 196 /** Write a CANMessage to the bus.
hudakz 0:e29bc8e0dddd 197 *
hudakz 0:e29bc8e0dddd 198 * @param msg The CANMessage to write.
hudakz 0:e29bc8e0dddd 199 *
hudakz 0:e29bc8e0dddd 200 * @returns
hudakz 0:e29bc8e0dddd 201 * 0 if write failed,
hudakz 0:e29bc8e0dddd 202 * 1 if write was successful
hudakz 0:e29bc8e0dddd 203 */
hudakz 0:e29bc8e0dddd 204 int write(CANMessage msg);
hudakz 0:e29bc8e0dddd 205
hudakz 0:e29bc8e0dddd 206 /** Read a CANMessage from the bus.
hudakz 0:e29bc8e0dddd 207 *
hudakz 0:e29bc8e0dddd 208 * @param msg A CANMessage to read to.
hudakz 0:e29bc8e0dddd 209 * @param handle message filter handle (0 for any message)
hudakz 0:e29bc8e0dddd 210 *
hudakz 0:e29bc8e0dddd 211 * @returns
hudakz 0:e29bc8e0dddd 212 * 0 if no message arrived,
hudakz 0:e29bc8e0dddd 213 * 1 if message arrived
hudakz 0:e29bc8e0dddd 214 */
hudakz 0:e29bc8e0dddd 215 int read(CANMessage &msg, int handle = 0);
hudakz 0:e29bc8e0dddd 216
hudakz 0:e29bc8e0dddd 217 /** Reset CAN interface.
hudakz 0:e29bc8e0dddd 218 *
hudakz 0:e29bc8e0dddd 219 * To use after error overflow.
hudakz 0:e29bc8e0dddd 220 */
hudakz 0:e29bc8e0dddd 221 void reset();
hudakz 0:e29bc8e0dddd 222
hudakz 0:e29bc8e0dddd 223 /** Puts or removes the CAN interface into silent monitoring mode
hudakz 0:e29bc8e0dddd 224 *
hudakz 0:e29bc8e0dddd 225 * @param silent boolean indicating whether to go into silent mode or not
hudakz 0:e29bc8e0dddd 226 */
hudakz 0:e29bc8e0dddd 227 void monitor(bool silent);
hudakz 0:e29bc8e0dddd 228
hudakz 0:e29bc8e0dddd 229 enum Mode {
hudakz 0:e29bc8e0dddd 230 Reset = 0,
hudakz 0:e29bc8e0dddd 231 Normal,
hudakz 0:e29bc8e0dddd 232 Silent,
hudakz 0:e29bc8e0dddd 233 LocalTest,
hudakz 0:e29bc8e0dddd 234 GlobalTest,
hudakz 0:e29bc8e0dddd 235 SilentTest
hudakz 0:e29bc8e0dddd 236 };
hudakz 0:e29bc8e0dddd 237
hudakz 0:e29bc8e0dddd 238 /** Change CAN operation to the specified mode
hudakz 0:e29bc8e0dddd 239 *
hudakz 0:e29bc8e0dddd 240 * @param mode The new operation mode (CAN::Normal, CAN::Silent, CAN::LocalTest, CAN::GlobalTest, CAN::SilentTest)
hudakz 0:e29bc8e0dddd 241 *
hudakz 0:e29bc8e0dddd 242 * @returns
hudakz 0:e29bc8e0dddd 243 * 0 if mode change failed or unsupported,
hudakz 0:e29bc8e0dddd 244 * 1 if mode change was successful
hudakz 0:e29bc8e0dddd 245 */
hudakz 0:e29bc8e0dddd 246 int mode(Mode mode);
hudakz 0:e29bc8e0dddd 247
hudakz 0:e29bc8e0dddd 248 /** Filter out incomming messages
hudakz 0:e29bc8e0dddd 249 *
hudakz 0:e29bc8e0dddd 250 * @param id the id to filter on
hudakz 0:e29bc8e0dddd 251 * @param mask the mask applied to the id
hudakz 0:e29bc8e0dddd 252 * @param format format to filter on (Default CANAny)
hudakz 0:e29bc8e0dddd 253 * @param handle message filter handle (Optional)
hudakz 0:e29bc8e0dddd 254 *
hudakz 8:5c90d6b9a382 255 * @returns 0 - successful
hudakz 8:5c90d6b9a382 256 * 1 - error
hudakz 8:5c90d6b9a382 257 * 2 - busy
hudakz 9:e9224f2c6d37 258 * 3 - time out
hudakz 0:e29bc8e0dddd 259 */
hudakz 0:e29bc8e0dddd 260 int filter(unsigned int id, unsigned int mask, CANFormat format = CANAny, int handle = 0);
hudakz 0:e29bc8e0dddd 261
hudakz 0:e29bc8e0dddd 262 /** Returns number of read errors to detect read overflow errors.
hudakz 0:e29bc8e0dddd 263 */
hudakz 0:e29bc8e0dddd 264 unsigned char rderror();
hudakz 0:e29bc8e0dddd 265
hudakz 0:e29bc8e0dddd 266 /** Returns number of write errors to detect write overflow errors.
hudakz 0:e29bc8e0dddd 267 */
hudakz 0:e29bc8e0dddd 268 unsigned char tderror();
hudakz 0:e29bc8e0dddd 269
hudakz 0:e29bc8e0dddd 270 enum IrqType {
hudakz 0:e29bc8e0dddd 271 RxIrq = 0,
hudakz 0:e29bc8e0dddd 272 TxIrq,
hudakz 0:e29bc8e0dddd 273 EwIrq,
hudakz 0:e29bc8e0dddd 274 DoIrq,
hudakz 0:e29bc8e0dddd 275 WuIrq,
hudakz 0:e29bc8e0dddd 276 EpIrq,
hudakz 0:e29bc8e0dddd 277 AlIrq,
hudakz 0:e29bc8e0dddd 278 BeIrq,
hudakz 0:e29bc8e0dddd 279 IdIrq
hudakz 0:e29bc8e0dddd 280 };
hudakz 0:e29bc8e0dddd 281
hudakz 0:e29bc8e0dddd 282 /** Attach a function to call whenever a CAN frame received interrupt is
hudakz 0:e29bc8e0dddd 283 * generated.
hudakz 0:e29bc8e0dddd 284 *
hudakz 0:e29bc8e0dddd 285 * @param fptr A pointer to a void function, or 0 to set as none
hudakz 0:e29bc8e0dddd 286 * @param event Which CAN interrupt to attach the member function to (CAN::RxIrq for message received, CAN::TxIrq for transmitted or aborted, CAN::EwIrq for error warning, CAN::DoIrq for data overrun, CAN::WuIrq for wake-up, CAN::EpIrq for error passive, CAN::AlIrq for arbitration lost, CAN::BeIrq for bus error)
hudakz 0:e29bc8e0dddd 287 */
hudakz 0:e29bc8e0dddd 288 void attach(void (*fptr)(void), IrqType type=RxIrq);
hudakz 0:e29bc8e0dddd 289
hudakz 0:e29bc8e0dddd 290 /** Attach a member function to call whenever a CAN frame received interrupt
hudakz 0:e29bc8e0dddd 291 * is generated.
hudakz 0:e29bc8e0dddd 292 *
hudakz 0:e29bc8e0dddd 293 * @param tptr pointer to the object to call the member function on
hudakz 0:e29bc8e0dddd 294 * @param mptr pointer to the member function to be called
hudakz 0:e29bc8e0dddd 295 * @param event Which CAN interrupt to attach the member function to (CAN::RxIrq for message received, TxIrq for transmitted or aborted, EwIrq for error warning, DoIrq for data overrun, WuIrq for wake-up, EpIrq for error passive, AlIrq for arbitration lost, BeIrq for bus error)
hudakz 0:e29bc8e0dddd 296 */
hudakz 0:e29bc8e0dddd 297 template<typename T>
hudakz 0:e29bc8e0dddd 298 void attach(T* tptr, void (T::*mptr)(void), IrqType type=RxIrq) {
hudakz 0:e29bc8e0dddd 299 if((mptr != NULL) && (tptr != NULL)) {
hudakz 0:e29bc8e0dddd 300 _irq[type].attach(tptr, mptr);
hudakz 0:e29bc8e0dddd 301 // can_irq_set(&_can, (CanIrqType)type, 1);
hudakz 0:e29bc8e0dddd 302 }
hudakz 0:e29bc8e0dddd 303 // else {
hudakz 0:e29bc8e0dddd 304 // can_irq_set(&_can, (CanIrqType)type, 0);
hudakz 0:e29bc8e0dddd 305 // }
hudakz 0:e29bc8e0dddd 306 }
hudakz 0:e29bc8e0dddd 307
hudakz 0:e29bc8e0dddd 308 static void _irq_handler(uint32_t id, CanIrqType type);
hudakz 0:e29bc8e0dddd 309
hudakz 0:e29bc8e0dddd 310 protected:
hudakz 0:e29bc8e0dddd 311 can_t _can;
hudakz 0:e29bc8e0dddd 312 FunctionPointer _irq[9];
hudakz 0:e29bc8e0dddd 313 };
hudakz 0:e29bc8e0dddd 314
hudakz 0:e29bc8e0dddd 315 } // namespace mbed
hudakz 0:e29bc8e0dddd 316
hudakz 0:e29bc8e0dddd 317 #endif
hudakz 0:e29bc8e0dddd 318
hudakz 0:e29bc8e0dddd 319 #endif // MBED_CAN_H
hudakz 0:e29bc8e0dddd 320
hudakz 0:e29bc8e0dddd 321
hudakz 6:c5a40d5fd9f1 322
hudakz 8:5c90d6b9a382 323
hudakz 11:439f3a34c42e 324