test

Dependencies:   mbed Watchdog

Dependents:   STM32-MC_node

Committer:
ommpy
Date:
Mon Jul 06 17:18:59 2020 +0530
Revision:
0:d383e2dee0f7
first commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ommpy 0:d383e2dee0f7 1 /* mbed Microcontroller Library
ommpy 0:d383e2dee0f7 2 * Copyright (c) 2006-2013 ARM Limited
ommpy 0:d383e2dee0f7 3 * SPDX-License-Identifier: Apache-2.0
ommpy 0:d383e2dee0f7 4 *
ommpy 0:d383e2dee0f7 5 * Licensed under the Apache License, Version 2.0 (the "License");
ommpy 0:d383e2dee0f7 6 * you may not use this file except in compliance with the License.
ommpy 0:d383e2dee0f7 7 * You may obtain a copy of the License at
ommpy 0:d383e2dee0f7 8 *
ommpy 0:d383e2dee0f7 9 * http://www.apache.org/licenses/LICENSE-2.0
ommpy 0:d383e2dee0f7 10 *
ommpy 0:d383e2dee0f7 11 * Unless required by applicable law or agreed to in writing, software
ommpy 0:d383e2dee0f7 12 * distributed under the License is distributed on an "AS IS" BASIS,
ommpy 0:d383e2dee0f7 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
ommpy 0:d383e2dee0f7 14 * See the License for the specific language governing permissions and
ommpy 0:d383e2dee0f7 15 * limitations under the License.
ommpy 0:d383e2dee0f7 16 */
ommpy 0:d383e2dee0f7 17 #ifndef MBED_CAN_H
ommpy 0:d383e2dee0f7 18 #define MBED_CAN_H
ommpy 0:d383e2dee0f7 19
ommpy 0:d383e2dee0f7 20 #include "platform/platform.h"
ommpy 0:d383e2dee0f7 21
ommpy 0:d383e2dee0f7 22 #if DEVICE_CAN || defined(DOXYGEN_ONLY)
ommpy 0:d383e2dee0f7 23
ommpy 0:d383e2dee0f7 24 #include "hal/can_api.h"
ommpy 0:d383e2dee0f7 25 #include "platform/Callback.h"
ommpy 0:d383e2dee0f7 26 #include "platform/PlatformMutex.h"
ommpy 0:d383e2dee0f7 27 #include "platform/NonCopyable.h"
ommpy 0:d383e2dee0f7 28
ommpy 0:d383e2dee0f7 29 namespace mbed {
ommpy 0:d383e2dee0f7 30 /** \addtogroup drivers */
ommpy 0:d383e2dee0f7 31
ommpy 0:d383e2dee0f7 32 /** CANMessage class
ommpy 0:d383e2dee0f7 33 *
ommpy 0:d383e2dee0f7 34 * @note Synchronization level: Thread safe
ommpy 0:d383e2dee0f7 35 * @ingroup drivers
ommpy 0:d383e2dee0f7 36 */
ommpy 0:d383e2dee0f7 37 class CANMessage : public CAN_Message {
ommpy 0:d383e2dee0f7 38
ommpy 0:d383e2dee0f7 39 public:
ommpy 0:d383e2dee0f7 40 /** Creates empty CAN message.
ommpy 0:d383e2dee0f7 41 */
ommpy 0:d383e2dee0f7 42 CANMessage() : CAN_Message()
ommpy 0:d383e2dee0f7 43 {
ommpy 0:d383e2dee0f7 44 len = 8;
ommpy 0:d383e2dee0f7 45 type = CANData;
ommpy 0:d383e2dee0f7 46 format = CANStandard;
ommpy 0:d383e2dee0f7 47 id = 0;
ommpy 0:d383e2dee0f7 48 memset(data, 0, 8);
ommpy 0:d383e2dee0f7 49 }
ommpy 0:d383e2dee0f7 50
ommpy 0:d383e2dee0f7 51 /** Creates CAN message with specific content.
ommpy 0:d383e2dee0f7 52 *
ommpy 0:d383e2dee0f7 53 * @param _id Message ID
ommpy 0:d383e2dee0f7 54 * @param _data Mesaage Data
ommpy 0:d383e2dee0f7 55 * @param _len Message Data length
ommpy 0:d383e2dee0f7 56 * @param _type Type of Data: Use enum CANType for valid parameter values
ommpy 0:d383e2dee0f7 57 * @param _format Data Format: Use enum CANFormat for valid parameter values
ommpy 0:d383e2dee0f7 58 */
ommpy 0:d383e2dee0f7 59 CANMessage(unsigned _id, const char *_data, char _len = 8, CANType _type = CANData, CANFormat _format = CANStandard)
ommpy 0:d383e2dee0f7 60 {
ommpy 0:d383e2dee0f7 61 len = _len & 0xF;
ommpy 0:d383e2dee0f7 62 type = _type;
ommpy 0:d383e2dee0f7 63 format = _format;
ommpy 0:d383e2dee0f7 64 id = _id;
ommpy 0:d383e2dee0f7 65 memcpy(data, _data, _len);
ommpy 0:d383e2dee0f7 66 }
ommpy 0:d383e2dee0f7 67
ommpy 0:d383e2dee0f7 68 /** Creates CAN remote message.
ommpy 0:d383e2dee0f7 69 *
ommpy 0:d383e2dee0f7 70 * @param _id Message ID
ommpy 0:d383e2dee0f7 71 * @param _format Data Format: Use enum CANType for valid parameter values
ommpy 0:d383e2dee0f7 72 */
ommpy 0:d383e2dee0f7 73 CANMessage(unsigned _id, CANFormat _format = CANStandard)
ommpy 0:d383e2dee0f7 74 {
ommpy 0:d383e2dee0f7 75 len = 0;
ommpy 0:d383e2dee0f7 76 type = CANRemote;
ommpy 0:d383e2dee0f7 77 format = _format;
ommpy 0:d383e2dee0f7 78 id = _id;
ommpy 0:d383e2dee0f7 79 memset(data, 0, 8);
ommpy 0:d383e2dee0f7 80 }
ommpy 0:d383e2dee0f7 81 };
ommpy 0:d383e2dee0f7 82
ommpy 0:d383e2dee0f7 83 /** A can bus client, used for communicating with can devices
ommpy 0:d383e2dee0f7 84 * @ingroup drivers
ommpy 0:d383e2dee0f7 85 */
ommpy 0:d383e2dee0f7 86 class CAN : private NonCopyable<CAN> {
ommpy 0:d383e2dee0f7 87
ommpy 0:d383e2dee0f7 88 public:
ommpy 0:d383e2dee0f7 89 /** Creates a CAN interface connected to specific pins.
ommpy 0:d383e2dee0f7 90 *
ommpy 0:d383e2dee0f7 91 * @param rd read from transmitter
ommpy 0:d383e2dee0f7 92 * @param td transmit to transmitter
ommpy 0:d383e2dee0f7 93 *
ommpy 0:d383e2dee0f7 94 * Example:
ommpy 0:d383e2dee0f7 95 * @code
ommpy 0:d383e2dee0f7 96 * #include "mbed.h"
ommpy 0:d383e2dee0f7 97 *
ommpy 0:d383e2dee0f7 98 *
ommpy 0:d383e2dee0f7 99 * Ticker ticker;
ommpy 0:d383e2dee0f7 100 * DigitalOut led1(LED1);
ommpy 0:d383e2dee0f7 101 * DigitalOut led2(LED2);
ommpy 0:d383e2dee0f7 102 * //The constructor takes in RX, and TX pin respectively.
ommpy 0:d383e2dee0f7 103 * //These pins, for this example, are defined in mbed_app.json
ommpy 0:d383e2dee0f7 104 * CAN can1(MBED_CONF_APP_CAN1_RD, MBED_CONF_APP_CAN1_TD);
ommpy 0:d383e2dee0f7 105 * CAN can2(MBED_CONF_APP_CAN2_RD, MBED_CONF_APP_CAN2_TD);
ommpy 0:d383e2dee0f7 106 *
ommpy 0:d383e2dee0f7 107 * char counter = 0;
ommpy 0:d383e2dee0f7 108 *
ommpy 0:d383e2dee0f7 109 * void send() {
ommpy 0:d383e2dee0f7 110 * if(can1.write(CANMessage(1337, &counter, 1))) {
ommpy 0:d383e2dee0f7 111 * printf("Message sent: %d\n", counter);
ommpy 0:d383e2dee0f7 112 * counter++;
ommpy 0:d383e2dee0f7 113 * }
ommpy 0:d383e2dee0f7 114 * led1 = !led1;
ommpy 0:d383e2dee0f7 115 * }
ommpy 0:d383e2dee0f7 116 *
ommpy 0:d383e2dee0f7 117 * int main() {
ommpy 0:d383e2dee0f7 118 * ticker.attach(&send, 1);
ommpy 0:d383e2dee0f7 119 * CANMessage msg;
ommpy 0:d383e2dee0f7 120 * while(1) {
ommpy 0:d383e2dee0f7 121 * if(can2.read(msg)) {
ommpy 0:d383e2dee0f7 122 * printf("Message received: %d\n\n", msg.data[0]);
ommpy 0:d383e2dee0f7 123 * led2 = !led2;
ommpy 0:d383e2dee0f7 124 * }
ommpy 0:d383e2dee0f7 125 * wait(0.2);
ommpy 0:d383e2dee0f7 126 * }
ommpy 0:d383e2dee0f7 127 * }
ommpy 0:d383e2dee0f7 128 *
ommpy 0:d383e2dee0f7 129 * @endcode
ommpy 0:d383e2dee0f7 130 */
ommpy 0:d383e2dee0f7 131 CAN(PinName rd, PinName td);
ommpy 0:d383e2dee0f7 132
ommpy 0:d383e2dee0f7 133 /** Initialize CAN interface and set the frequency
ommpy 0:d383e2dee0f7 134 *
ommpy 0:d383e2dee0f7 135 * @param rd the read pin
ommpy 0:d383e2dee0f7 136 * @param td the transmit pin
ommpy 0:d383e2dee0f7 137 * @param hz the bus frequency in hertz
ommpy 0:d383e2dee0f7 138 */
ommpy 0:d383e2dee0f7 139 CAN(PinName rd, PinName td, int hz);
ommpy 0:d383e2dee0f7 140
ommpy 0:d383e2dee0f7 141 virtual ~CAN();
ommpy 0:d383e2dee0f7 142
ommpy 0:d383e2dee0f7 143 /** Set the frequency of the CAN interface
ommpy 0:d383e2dee0f7 144 *
ommpy 0:d383e2dee0f7 145 * @param hz The bus frequency in hertz
ommpy 0:d383e2dee0f7 146 *
ommpy 0:d383e2dee0f7 147 * @returns
ommpy 0:d383e2dee0f7 148 * 1 if successful,
ommpy 0:d383e2dee0f7 149 * 0 otherwise
ommpy 0:d383e2dee0f7 150 */
ommpy 0:d383e2dee0f7 151 int frequency(int hz);
ommpy 0:d383e2dee0f7 152
ommpy 0:d383e2dee0f7 153 /** Write a CANMessage to the bus.
ommpy 0:d383e2dee0f7 154 *
ommpy 0:d383e2dee0f7 155 * @param msg The CANMessage to write.
ommpy 0:d383e2dee0f7 156 *
ommpy 0:d383e2dee0f7 157 * @returns
ommpy 0:d383e2dee0f7 158 * 0 if write failed,
ommpy 0:d383e2dee0f7 159 * 1 if write was successful
ommpy 0:d383e2dee0f7 160 */
ommpy 0:d383e2dee0f7 161 int write(CANMessage msg);
ommpy 0:d383e2dee0f7 162
ommpy 0:d383e2dee0f7 163 /** Read a CANMessage from the bus.
ommpy 0:d383e2dee0f7 164 *
ommpy 0:d383e2dee0f7 165 * @param msg A CANMessage to read to.
ommpy 0:d383e2dee0f7 166 * @param handle message filter handle (0 for any message)
ommpy 0:d383e2dee0f7 167 *
ommpy 0:d383e2dee0f7 168 * @returns
ommpy 0:d383e2dee0f7 169 * 0 if no message arrived,
ommpy 0:d383e2dee0f7 170 * 1 if message arrived
ommpy 0:d383e2dee0f7 171 */
ommpy 0:d383e2dee0f7 172 int read(CANMessage &msg, int handle = 0);
ommpy 0:d383e2dee0f7 173
ommpy 0:d383e2dee0f7 174 /** Reset CAN interface.
ommpy 0:d383e2dee0f7 175 *
ommpy 0:d383e2dee0f7 176 * To use after error overflow.
ommpy 0:d383e2dee0f7 177 */
ommpy 0:d383e2dee0f7 178 void reset();
ommpy 0:d383e2dee0f7 179
ommpy 0:d383e2dee0f7 180 /** Puts or removes the CAN interface into silent monitoring mode
ommpy 0:d383e2dee0f7 181 *
ommpy 0:d383e2dee0f7 182 * @param silent boolean indicating whether to go into silent mode or not
ommpy 0:d383e2dee0f7 183 */
ommpy 0:d383e2dee0f7 184 void monitor(bool silent);
ommpy 0:d383e2dee0f7 185
ommpy 0:d383e2dee0f7 186 enum Mode {
ommpy 0:d383e2dee0f7 187 Reset = 0,
ommpy 0:d383e2dee0f7 188 Normal,
ommpy 0:d383e2dee0f7 189 Silent,
ommpy 0:d383e2dee0f7 190 LocalTest,
ommpy 0:d383e2dee0f7 191 GlobalTest,
ommpy 0:d383e2dee0f7 192 SilentTest
ommpy 0:d383e2dee0f7 193 };
ommpy 0:d383e2dee0f7 194
ommpy 0:d383e2dee0f7 195 /** Change CAN operation to the specified mode
ommpy 0:d383e2dee0f7 196 *
ommpy 0:d383e2dee0f7 197 * @param mode The new operation mode (CAN::Normal, CAN::Silent, CAN::LocalTest, CAN::GlobalTest, CAN::SilentTest)
ommpy 0:d383e2dee0f7 198 *
ommpy 0:d383e2dee0f7 199 * @returns
ommpy 0:d383e2dee0f7 200 * 0 if mode change failed or unsupported,
ommpy 0:d383e2dee0f7 201 * 1 if mode change was successful
ommpy 0:d383e2dee0f7 202 */
ommpy 0:d383e2dee0f7 203 int mode(Mode mode);
ommpy 0:d383e2dee0f7 204
ommpy 0:d383e2dee0f7 205 /** Filter out incoming messages
ommpy 0:d383e2dee0f7 206 *
ommpy 0:d383e2dee0f7 207 * @param id the id to filter on
ommpy 0:d383e2dee0f7 208 * @param mask the mask applied to the id
ommpy 0:d383e2dee0f7 209 * @param format format to filter on (Default CANAny)
ommpy 0:d383e2dee0f7 210 * @param handle message filter handle (Optional)
ommpy 0:d383e2dee0f7 211 *
ommpy 0:d383e2dee0f7 212 * @returns
ommpy 0:d383e2dee0f7 213 * 0 if filter change failed or unsupported,
ommpy 0:d383e2dee0f7 214 * new filter handle if successful
ommpy 0:d383e2dee0f7 215 */
ommpy 0:d383e2dee0f7 216 int filter(unsigned int id, unsigned int mask, CANFormat format = CANAny, int handle = 0);
ommpy 0:d383e2dee0f7 217
ommpy 0:d383e2dee0f7 218 /** Detects read errors - Used to detect read overflow errors.
ommpy 0:d383e2dee0f7 219 *
ommpy 0:d383e2dee0f7 220 * @returns number of read errors
ommpy 0:d383e2dee0f7 221 */
ommpy 0:d383e2dee0f7 222 unsigned char rderror();
ommpy 0:d383e2dee0f7 223
ommpy 0:d383e2dee0f7 224 /** Detects write errors - Used to detect write overflow errors.
ommpy 0:d383e2dee0f7 225 *
ommpy 0:d383e2dee0f7 226 * @returns number of write errors
ommpy 0:d383e2dee0f7 227 */
ommpy 0:d383e2dee0f7 228 unsigned char tderror();
ommpy 0:d383e2dee0f7 229
ommpy 0:d383e2dee0f7 230 enum IrqType {
ommpy 0:d383e2dee0f7 231 RxIrq = 0,
ommpy 0:d383e2dee0f7 232 TxIrq,
ommpy 0:d383e2dee0f7 233 EwIrq,
ommpy 0:d383e2dee0f7 234 DoIrq,
ommpy 0:d383e2dee0f7 235 WuIrq,
ommpy 0:d383e2dee0f7 236 EpIrq,
ommpy 0:d383e2dee0f7 237 AlIrq,
ommpy 0:d383e2dee0f7 238 BeIrq,
ommpy 0:d383e2dee0f7 239 IdIrq,
ommpy 0:d383e2dee0f7 240
ommpy 0:d383e2dee0f7 241 IrqCnt
ommpy 0:d383e2dee0f7 242 };
ommpy 0:d383e2dee0f7 243
ommpy 0:d383e2dee0f7 244 /** Attach a function to call whenever a CAN frame received interrupt is
ommpy 0:d383e2dee0f7 245 * generated.
ommpy 0:d383e2dee0f7 246 *
ommpy 0:d383e2dee0f7 247 * This function locks the deep sleep while a callback is attached
ommpy 0:d383e2dee0f7 248 *
ommpy 0:d383e2dee0f7 249 * @param func A pointer to a void function, or 0 to set as none
ommpy 0:d383e2dee0f7 250 * @param type 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)
ommpy 0:d383e2dee0f7 251 */
ommpy 0:d383e2dee0f7 252 void attach(Callback<void()> func, IrqType type = RxIrq);
ommpy 0:d383e2dee0f7 253
ommpy 0:d383e2dee0f7 254 /** Attach a member function to call whenever a CAN frame received interrupt
ommpy 0:d383e2dee0f7 255 * is generated.
ommpy 0:d383e2dee0f7 256 *
ommpy 0:d383e2dee0f7 257 * @param obj pointer to the object to call the member function on
ommpy 0:d383e2dee0f7 258 * @param method pointer to the member function to be called
ommpy 0:d383e2dee0f7 259 * @param type 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)
ommpy 0:d383e2dee0f7 260 * @deprecated
ommpy 0:d383e2dee0f7 261 * The attach function does not support cv-qualifiers. Replaced by
ommpy 0:d383e2dee0f7 262 * attach(callback(obj, method), type).
ommpy 0:d383e2dee0f7 263 */
ommpy 0:d383e2dee0f7 264 template<typename T>
ommpy 0:d383e2dee0f7 265 MBED_DEPRECATED_SINCE("mbed-os-5.1",
ommpy 0:d383e2dee0f7 266 "The attach function does not support cv-qualifiers. Replaced by "
ommpy 0:d383e2dee0f7 267 "attach(callback(obj, method), type).")
ommpy 0:d383e2dee0f7 268 void attach(T *obj, void (T::*method)(), IrqType type = RxIrq)
ommpy 0:d383e2dee0f7 269 {
ommpy 0:d383e2dee0f7 270 // Underlying call thread safe
ommpy 0:d383e2dee0f7 271 attach(callback(obj, method), type);
ommpy 0:d383e2dee0f7 272 }
ommpy 0:d383e2dee0f7 273
ommpy 0:d383e2dee0f7 274 /** Attach a member function to call whenever a CAN frame received interrupt
ommpy 0:d383e2dee0f7 275 * is generated.
ommpy 0:d383e2dee0f7 276 *
ommpy 0:d383e2dee0f7 277 * @param obj pointer to the object to call the member function on
ommpy 0:d383e2dee0f7 278 * @param method pointer to the member function to be called
ommpy 0:d383e2dee0f7 279 * @param type 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)
ommpy 0:d383e2dee0f7 280 * @deprecated
ommpy 0:d383e2dee0f7 281 * The attach function does not support cv-qualifiers. Replaced by
ommpy 0:d383e2dee0f7 282 * attach(callback(obj, method), type).
ommpy 0:d383e2dee0f7 283 */
ommpy 0:d383e2dee0f7 284 template<typename T>
ommpy 0:d383e2dee0f7 285 MBED_DEPRECATED_SINCE("mbed-os-5.1",
ommpy 0:d383e2dee0f7 286 "The attach function does not support cv-qualifiers. Replaced by "
ommpy 0:d383e2dee0f7 287 "attach(callback(obj, method), type).")
ommpy 0:d383e2dee0f7 288 void attach(T *obj, void (*method)(T *), IrqType type = RxIrq)
ommpy 0:d383e2dee0f7 289 {
ommpy 0:d383e2dee0f7 290 // Underlying call thread safe
ommpy 0:d383e2dee0f7 291 attach(callback(obj, method), type);
ommpy 0:d383e2dee0f7 292 }
ommpy 0:d383e2dee0f7 293
ommpy 0:d383e2dee0f7 294 static void _irq_handler(uint32_t id, CanIrqType type);
ommpy 0:d383e2dee0f7 295
ommpy 0:d383e2dee0f7 296 #if !defined(DOXYGEN_ONLY)
ommpy 0:d383e2dee0f7 297 protected:
ommpy 0:d383e2dee0f7 298 virtual void lock();
ommpy 0:d383e2dee0f7 299 virtual void unlock();
ommpy 0:d383e2dee0f7 300 can_t _can;
ommpy 0:d383e2dee0f7 301 Callback<void()> _irq[IrqCnt];
ommpy 0:d383e2dee0f7 302 PlatformMutex _mutex;
ommpy 0:d383e2dee0f7 303 #endif
ommpy 0:d383e2dee0f7 304 };
ommpy 0:d383e2dee0f7 305
ommpy 0:d383e2dee0f7 306 } // namespace mbed
ommpy 0:d383e2dee0f7 307
ommpy 0:d383e2dee0f7 308 #endif
ommpy 0:d383e2dee0f7 309
ommpy 0:d383e2dee0f7 310 #endif // MBED_CAN_H
ommpy 0:d383e2dee0f7 311