this hurts

Dependencies:   FFT

Committer:
annieluo2
Date:
Wed Dec 02 18:02:03 2020 +0000
Revision:
0:d6c9b09b4042
boo

Who changed what in which revision?

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