MCU driver/HAL for the Picocell Gateway concentrator board. The firmware implements either a USB CDC protocol or a UART protocol to bridge commands coming from host to the SX1308 SPI interface.

Committer:
dgabino
Date:
Wed Apr 11 14:42:47 2018 +0000
Revision:
0:c76361bd82e8
Initial commit

Who changed what in which revision?

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