Working fork to test F0 application

Dependents:   ppCANOpen_Example

Fork of CANnucleo by Zoltan Hudak

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers CAN.h Source File

CAN.h

00001 /* mbed Microcontroller Library
00002  * Copyright (c) 2006-2013 ARM Limited
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  *
00016  * Modified by Zoltan Hudak    <hudakz@inbox.com>
00017  *
00018  */
00019 #ifndef CAN_H
00020 #define CAN_H
00021 
00022 #include "platform.h"
00023 
00024 #define DEVICE_CAN 1
00025 
00026 #if DEVICE_CAN
00027 
00028 #include "can_api.h"
00029 #include "can_helper.h"
00030 #include "FunctionPointer.h"
00031     
00032 namespace mbed
00033 {
00034     
00035 /** CANMessage class
00036  */
00037 class CANMessage : public CAN_Message
00038 {
00039 
00040 public:
00041     /** Creates empty CAN message.
00042      */
00043     CANMessage() : CAN_Message() {
00044         len    = 8;
00045         type   = CANData;
00046         format = CANStandard;
00047         id     = 0;
00048         memset(data, 0, 8);
00049     }
00050 
00051     /** Creates CAN message with specific content.
00052      */
00053     CANMessage(int _id, const char *_data, char _len = 8, CANType _type = CANData, CANFormat _format = CANStandard) {
00054         len    = _len & 0xF;
00055         type   = _type;
00056         format = _format;
00057         id     = _id;
00058         memcpy(data, _data, _len);
00059     }
00060 
00061     /** Creates CAN remote message.
00062      */
00063     CANMessage(int _id, CANFormat _format = CANStandard) {
00064         len    = 0;
00065         type   = CANRemote;
00066         format = _format;
00067         id     = _id;
00068         memset(data, 0, 8);
00069     }
00070 
00071     /*********************************************************************/
00072     /*********************************************************************/
00073     /*********************************************************************/
00074     /** Copy constructor.
00075      */
00076     CANMessage(const CANMessage& canMessage) {
00077         len     = canMessage.len;
00078         type    = canMessage.type;
00079         format  = canMessage.format;
00080         id      = canMessage.id;
00081         memcpy(data, canMessage.data, canMessage.len);
00082     }
00083 
00084     /** Clears CAN message content
00085      */
00086     void clear(void) {
00087         len    = 0;
00088         type   = CANData;
00089         format = CANStandard;
00090         id     = 0;
00091         memset(data, 0, 8);
00092     };
00093 
00094     /** Inserter operator: Appends data (value) to CAN message
00095      */
00096     template<class T>
00097     CANMessage &operator<<(const T val) {
00098         if(len + sizeof(T) <= 8) {
00099             *reinterpret_cast < T * > (&data[len]) = val;
00100             len += sizeof(T);
00101         } 
00102 #if DEBUG
00103         else {
00104             printf("Error: Cannot append data because it exceeds CAN data length!\r\n");
00105         }
00106 #endif
00107        return *this;
00108     }
00109 
00110     /** Extractor operator: Extracts data (value) from CAN message
00111      */
00112     template<class T>
00113     CANMessage &operator>>(T& val) {
00114         if(sizeof(T) <= len) {
00115             val = *reinterpret_cast < T * > (&data[0]);
00116             len -= sizeof(T);
00117             memcpy(data, data + sizeof(T), len);
00118         } 
00119 #if DEBUG
00120         else {
00121             printf("Error: Cannot extract data because it exceeds CAN data length!\r\n");
00122         }
00123 #endif
00124         return *this;
00125     }
00126 
00127 };
00128 
00129 /** A can bus client, used for communicating with can devices
00130  */
00131 class CAN
00132 {
00133 
00134 public:
00135     /** Creates an CAN interface connected to specific pins.
00136      *
00137      *  @param rd read from transmitter
00138      *  @param td transmit to transmitter
00139      *
00140      * Example:
00141      * @code
00142      * #include "mbed.h"
00143      * #include "CAN.h"
00144      *
00145      * Ticker ticker;
00146      * DigitalOut led1(LED1);
00147      * CAN can(PA_11, PA_12);
00148      *
00149      * char counter = 0;
00150      *
00151      * void send() {
00152      *     if(can.write(CANMessage(1337, &counter, 1))) {
00153      *         printf("Message sent: %d\n", counter);
00154      *         counter++;
00155      *     }
00156      *     led1 = !led1;
00157      * }
00158      *
00159      * int main() {
00160      *     ticker.attach(&send, 1);
00161      *     CANMessage msg;
00162      *     while(1) {
00163      *         if(can.read(msg)) {
00164      *             printf("Message received: %d\n\n", msg.data[0]);
00165      *             led1 = !led1;
00166      *         }
00167      *         wait(0.2);
00168      *     }
00169      * }
00170      * @endcode
00171      */
00172      
00173     /** Constructor
00174      *
00175      * @param rd CAN receiver pin name
00176      * @param td CAN transmitter pin name
00177      * @param abom Automatic recovery from bus-off state (default value set to enabled)
00178      *
00179      */
00180     CAN(PinName rd, PinName td, FunctionalState abom = ENABLE);
00181 
00182     virtual ~CAN ();
00183 
00184     /** Set the frequency of the CAN interface
00185      *
00186      *  @param hz The bus frequency in hertz
00187      *
00188      *  @returns
00189      *    1 if successful,
00190      *    0 otherwise
00191      */
00192     int frequency(int hz);
00193 
00194     /** Write a CANMessage to the bus.
00195      *
00196      *  @param msg The CANMessage to write.
00197      *
00198      *  @returns
00199      *    0 if write failed,
00200      *    1 if write was successful
00201      */
00202     int write(CANMessage msg);
00203 
00204     /** Read a CANMessage from the bus.
00205      *
00206      *  @param msg A CANMessage to read to.
00207      *  @param handle message filter handle (0 for any message)
00208      *
00209      *  @returns
00210      *    0 if no message arrived,
00211      *    1 if message arrived
00212      */
00213     int read(CANMessage &msg, int handle = 0);
00214 
00215     /** Reset CAN interface.
00216      *
00217      * To use after error overflow.
00218      */
00219     void reset();
00220 
00221     /** Puts or removes the CAN interface into silent monitoring mode
00222      *
00223      *  @param silent boolean indicating whether to go into silent mode or not
00224      */
00225     void monitor(bool silent);
00226 
00227     enum Mode {
00228         Reset = 0,
00229         Normal,
00230         Silent,
00231         LocalTest,
00232         GlobalTest,
00233         SilentTest
00234     };
00235 
00236     /** Change CAN operation to the specified mode
00237      *
00238      *  @param mode The new operation mode (CAN::Normal, CAN::Silent, CAN::LocalTest, CAN::GlobalTest, CAN::SilentTest)
00239      *
00240      *  @returns
00241      *    0 if mode change failed or unsupported,
00242      *    1 if mode change was successful
00243      */
00244     int mode(Mode mode);
00245 
00246     /** Filter out incomming messages
00247      *
00248      *  @param id the id to filter on
00249      *  @param mask the mask applied to the id
00250      *  @param format format to filter on (Default CANAny)
00251      *  @param handle message filter handle (Optional)
00252      *
00253      *  @returns 0 - successful
00254      *           1 - error
00255      *           2 - busy
00256      *           3 - time out 
00257      */
00258     int filter(unsigned int id, unsigned int mask, CANFormat format = CANAny, int handle = 0);
00259 
00260     /** Returns number of read errors to detect read overflow errors.
00261      */
00262     unsigned char rderror();
00263 
00264     /** Returns number of write errors to detect write overflow errors.
00265      */
00266     unsigned char tderror();
00267 
00268     enum IrqType {
00269         RxIrq = 0,
00270         TxIrq,
00271         EwIrq,
00272         DoIrq,
00273         WuIrq,
00274         EpIrq,
00275         AlIrq,
00276         BeIrq,
00277         IdIrq
00278     };
00279 
00280     /** Attach a function to call whenever a CAN frame received interrupt is
00281      *  generated.
00282      *
00283      *  @param fptr A pointer to a void function, or 0 to set as none
00284      *  @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)
00285      */
00286     void attach(void (*fptr)(void), IrqType type=RxIrq);
00287 
00288     /** Attach a member function to call whenever a CAN frame received interrupt
00289      *  is generated.
00290      *
00291      *  @param tptr pointer to the object to call the member function on
00292      *  @param mptr pointer to the member function to be called
00293      *  @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)
00294      */
00295     template<typename T>
00296     void attach(T* tptr, void (T::*mptr)(void), IrqType type=RxIrq) {
00297         if((mptr != NULL) && (tptr != NULL)) {
00298             _irq[type].attach(tptr, mptr);
00299 //            can_irq_set(&_can, (CanIrqType)type, 1);
00300         }
00301 //        else {
00302 //            can_irq_set(&_can, (CanIrqType)type, 0);
00303 //        }
00304     }
00305 
00306     static void _irq_handler (uint32_t id, CanIrqType type);
00307 
00308 protected:
00309     can_t           _can;
00310     FunctionPointer _irq[9];
00311 };
00312 
00313 } // namespace mbed
00314 
00315 #endif
00316 
00317 #endif    // MBED_CAN_H
00318 
00319 
00320 
00321 
00322 
00323