test

Fork of CANnucleo by Zoltan Hudak

Committer:
hudakz
Date:
Sun Jul 19 09:06:26 2015 +0000
Revision:
0:e29bc8e0dddd
Child:
4:38403b42718b
rev 00

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 0:e29bc8e0dddd 28 #define DEBUG 1
hudakz 0:e29bc8e0dddd 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 /** Copy constructor.
hudakz 0:e29bc8e0dddd 54 */
hudakz 0:e29bc8e0dddd 55 CANMessage(const CANMessage& canMessage) {
hudakz 0:e29bc8e0dddd 56 len = canMessage.len;
hudakz 0:e29bc8e0dddd 57 type = canMessage.type;
hudakz 0:e29bc8e0dddd 58 format = canMessage.format;
hudakz 0:e29bc8e0dddd 59 id = canMessage.id;
hudakz 0:e29bc8e0dddd 60 memcpy(data, canMessage.data, canMessage.len);
hudakz 0:e29bc8e0dddd 61 }
hudakz 0:e29bc8e0dddd 62
hudakz 0:e29bc8e0dddd 63 /** Creates CAN message with specific content.
hudakz 0:e29bc8e0dddd 64 */
hudakz 0:e29bc8e0dddd 65 CANMessage(int _id, const char *_data, char _len = 8, CANType _type = CANData, CANFormat _format = CANStandard) {
hudakz 0:e29bc8e0dddd 66 len = _len & 0xF;
hudakz 0:e29bc8e0dddd 67 type = _type;
hudakz 0:e29bc8e0dddd 68 format = _format;
hudakz 0:e29bc8e0dddd 69 id = _id;
hudakz 0:e29bc8e0dddd 70 memcpy(data, _data, _len);
hudakz 0:e29bc8e0dddd 71 }
hudakz 0:e29bc8e0dddd 72
hudakz 0:e29bc8e0dddd 73 /** Creates CAN remote message.
hudakz 0:e29bc8e0dddd 74 */
hudakz 0:e29bc8e0dddd 75 CANMessage(int _id, CANFormat _format = CANStandard) {
hudakz 0:e29bc8e0dddd 76 len = 0;
hudakz 0:e29bc8e0dddd 77 type = CANRemote;
hudakz 0:e29bc8e0dddd 78 format = _format;
hudakz 0:e29bc8e0dddd 79 id = _id;
hudakz 0:e29bc8e0dddd 80 memset(data, 0, 8);
hudakz 0:e29bc8e0dddd 81 }
hudakz 0:e29bc8e0dddd 82
hudakz 0:e29bc8e0dddd 83 /*********************************************************************/
hudakz 0:e29bc8e0dddd 84 /*********************************************************************/
hudakz 0:e29bc8e0dddd 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 0:e29bc8e0dddd 174 CAN(PinName rd, PinName td);
hudakz 0:e29bc8e0dddd 175 virtual ~CAN();
hudakz 0:e29bc8e0dddd 176
hudakz 0:e29bc8e0dddd 177 /** Set the frequency of the CAN interface
hudakz 0:e29bc8e0dddd 178 *
hudakz 0:e29bc8e0dddd 179 * @param hz The bus frequency in hertz
hudakz 0:e29bc8e0dddd 180 *
hudakz 0:e29bc8e0dddd 181 * @returns
hudakz 0:e29bc8e0dddd 182 * 1 if successful,
hudakz 0:e29bc8e0dddd 183 * 0 otherwise
hudakz 0:e29bc8e0dddd 184 */
hudakz 0:e29bc8e0dddd 185 int frequency(int hz);
hudakz 0:e29bc8e0dddd 186
hudakz 0:e29bc8e0dddd 187 /** Write a CANMessage to the bus.
hudakz 0:e29bc8e0dddd 188 *
hudakz 0:e29bc8e0dddd 189 * @param msg The CANMessage to write.
hudakz 0:e29bc8e0dddd 190 *
hudakz 0:e29bc8e0dddd 191 * @returns
hudakz 0:e29bc8e0dddd 192 * 0 if write failed,
hudakz 0:e29bc8e0dddd 193 * 1 if write was successful
hudakz 0:e29bc8e0dddd 194 */
hudakz 0:e29bc8e0dddd 195 int write(CANMessage msg);
hudakz 0:e29bc8e0dddd 196
hudakz 0:e29bc8e0dddd 197 /** Read a CANMessage from the bus.
hudakz 0:e29bc8e0dddd 198 *
hudakz 0:e29bc8e0dddd 199 * @param msg A CANMessage to read to.
hudakz 0:e29bc8e0dddd 200 * @param handle message filter handle (0 for any message)
hudakz 0:e29bc8e0dddd 201 *
hudakz 0:e29bc8e0dddd 202 * @returns
hudakz 0:e29bc8e0dddd 203 * 0 if no message arrived,
hudakz 0:e29bc8e0dddd 204 * 1 if message arrived
hudakz 0:e29bc8e0dddd 205 */
hudakz 0:e29bc8e0dddd 206 int read(CANMessage &msg, int handle = 0);
hudakz 0:e29bc8e0dddd 207
hudakz 0:e29bc8e0dddd 208 /** Reset CAN interface.
hudakz 0:e29bc8e0dddd 209 *
hudakz 0:e29bc8e0dddd 210 * To use after error overflow.
hudakz 0:e29bc8e0dddd 211 */
hudakz 0:e29bc8e0dddd 212 void reset();
hudakz 0:e29bc8e0dddd 213
hudakz 0:e29bc8e0dddd 214 /** Puts or removes the CAN interface into silent monitoring mode
hudakz 0:e29bc8e0dddd 215 *
hudakz 0:e29bc8e0dddd 216 * @param silent boolean indicating whether to go into silent mode or not
hudakz 0:e29bc8e0dddd 217 */
hudakz 0:e29bc8e0dddd 218 void monitor(bool silent);
hudakz 0:e29bc8e0dddd 219
hudakz 0:e29bc8e0dddd 220 enum Mode {
hudakz 0:e29bc8e0dddd 221 Reset = 0,
hudakz 0:e29bc8e0dddd 222 Normal,
hudakz 0:e29bc8e0dddd 223 Silent,
hudakz 0:e29bc8e0dddd 224 LocalTest,
hudakz 0:e29bc8e0dddd 225 GlobalTest,
hudakz 0:e29bc8e0dddd 226 SilentTest
hudakz 0:e29bc8e0dddd 227 };
hudakz 0:e29bc8e0dddd 228
hudakz 0:e29bc8e0dddd 229 /** Change CAN operation to the specified mode
hudakz 0:e29bc8e0dddd 230 *
hudakz 0:e29bc8e0dddd 231 * @param mode The new operation mode (CAN::Normal, CAN::Silent, CAN::LocalTest, CAN::GlobalTest, CAN::SilentTest)
hudakz 0:e29bc8e0dddd 232 *
hudakz 0:e29bc8e0dddd 233 * @returns
hudakz 0:e29bc8e0dddd 234 * 0 if mode change failed or unsupported,
hudakz 0:e29bc8e0dddd 235 * 1 if mode change was successful
hudakz 0:e29bc8e0dddd 236 */
hudakz 0:e29bc8e0dddd 237 int mode(Mode mode);
hudakz 0:e29bc8e0dddd 238
hudakz 0:e29bc8e0dddd 239 /** Filter out incomming messages
hudakz 0:e29bc8e0dddd 240 *
hudakz 0:e29bc8e0dddd 241 * @param id the id to filter on
hudakz 0:e29bc8e0dddd 242 * @param mask the mask applied to the id
hudakz 0:e29bc8e0dddd 243 * @param format format to filter on (Default CANAny)
hudakz 0:e29bc8e0dddd 244 * @param handle message filter handle (Optional)
hudakz 0:e29bc8e0dddd 245 *
hudakz 0:e29bc8e0dddd 246 * @returns
hudakz 0:e29bc8e0dddd 247 * 0 if filter change failed or unsupported,
hudakz 0:e29bc8e0dddd 248 * new filter handle if successful
hudakz 0:e29bc8e0dddd 249 */
hudakz 0:e29bc8e0dddd 250 int filter(unsigned int id, unsigned int mask, CANFormat format = CANAny, int handle = 0);
hudakz 0:e29bc8e0dddd 251
hudakz 0:e29bc8e0dddd 252 /** Returns number of read errors to detect read overflow errors.
hudakz 0:e29bc8e0dddd 253 */
hudakz 0:e29bc8e0dddd 254 unsigned char rderror();
hudakz 0:e29bc8e0dddd 255
hudakz 0:e29bc8e0dddd 256 /** Returns number of write errors to detect write overflow errors.
hudakz 0:e29bc8e0dddd 257 */
hudakz 0:e29bc8e0dddd 258 unsigned char tderror();
hudakz 0:e29bc8e0dddd 259
hudakz 0:e29bc8e0dddd 260 enum IrqType {
hudakz 0:e29bc8e0dddd 261 RxIrq = 0,
hudakz 0:e29bc8e0dddd 262 TxIrq,
hudakz 0:e29bc8e0dddd 263 EwIrq,
hudakz 0:e29bc8e0dddd 264 DoIrq,
hudakz 0:e29bc8e0dddd 265 WuIrq,
hudakz 0:e29bc8e0dddd 266 EpIrq,
hudakz 0:e29bc8e0dddd 267 AlIrq,
hudakz 0:e29bc8e0dddd 268 BeIrq,
hudakz 0:e29bc8e0dddd 269 IdIrq
hudakz 0:e29bc8e0dddd 270 };
hudakz 0:e29bc8e0dddd 271
hudakz 0:e29bc8e0dddd 272 /** Attach a function to call whenever a CAN frame received interrupt is
hudakz 0:e29bc8e0dddd 273 * generated.
hudakz 0:e29bc8e0dddd 274 *
hudakz 0:e29bc8e0dddd 275 * @param fptr A pointer to a void function, or 0 to set as none
hudakz 0:e29bc8e0dddd 276 * @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 277 */
hudakz 0:e29bc8e0dddd 278 void attach(void (*fptr)(void), IrqType type=RxIrq);
hudakz 0:e29bc8e0dddd 279
hudakz 0:e29bc8e0dddd 280 /** Attach a member function to call whenever a CAN frame received interrupt
hudakz 0:e29bc8e0dddd 281 * is generated.
hudakz 0:e29bc8e0dddd 282 *
hudakz 0:e29bc8e0dddd 283 * @param tptr pointer to the object to call the member function on
hudakz 0:e29bc8e0dddd 284 * @param mptr pointer to the member function to be called
hudakz 0:e29bc8e0dddd 285 * @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 286 */
hudakz 0:e29bc8e0dddd 287 template<typename T>
hudakz 0:e29bc8e0dddd 288 void attach(T* tptr, void (T::*mptr)(void), IrqType type=RxIrq) {
hudakz 0:e29bc8e0dddd 289 if((mptr != NULL) && (tptr != NULL)) {
hudakz 0:e29bc8e0dddd 290 _irq[type].attach(tptr, mptr);
hudakz 0:e29bc8e0dddd 291 // can_irq_set(&_can, (CanIrqType)type, 1);
hudakz 0:e29bc8e0dddd 292 }
hudakz 0:e29bc8e0dddd 293 // else {
hudakz 0:e29bc8e0dddd 294 // can_irq_set(&_can, (CanIrqType)type, 0);
hudakz 0:e29bc8e0dddd 295 // }
hudakz 0:e29bc8e0dddd 296 }
hudakz 0:e29bc8e0dddd 297
hudakz 0:e29bc8e0dddd 298 static void _irq_handler(uint32_t id, CanIrqType type);
hudakz 0:e29bc8e0dddd 299
hudakz 0:e29bc8e0dddd 300 protected:
hudakz 0:e29bc8e0dddd 301 can_t _can;
hudakz 0:e29bc8e0dddd 302 FunctionPointer _irq[9];
hudakz 0:e29bc8e0dddd 303 };
hudakz 0:e29bc8e0dddd 304
hudakz 0:e29bc8e0dddd 305 } // namespace mbed
hudakz 0:e29bc8e0dddd 306
hudakz 0:e29bc8e0dddd 307 #endif
hudakz 0:e29bc8e0dddd 308
hudakz 0:e29bc8e0dddd 309 #endif // MBED_CAN_H
hudakz 0:e29bc8e0dddd 310
hudakz 0:e29bc8e0dddd 311