This library for Seeed Studio's CAN-BUS Shield has a similar API to mbed's LPC1768 CAN library making it easy to add CAN functionality to mbed systems that support Arduino type 'Shields. This Beta release of my CAN-BUS Library is largely working but lacks interrupt 'attach' functions.

Dependents:   Seeed_CAN_Hello_World ws-canrecv-1 CAN_SPI_modulo

Fork of SEEED_CAN by Sophie Dexter

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers seeed_can.h Source File

seeed_can.h

00001 /* seeed_can.h
00002  * Copyright (c) 2013 Sophie Dexter
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 #ifndef _SEEED_CAN_H_
00017 #define _SEEED_CAN_H_
00018 
00019 #include "seeed_can_api.h"
00020 
00021 // if print debug information
00022 #define DEBUG
00023 
00024 /** CANMessage class
00025  */
00026 class SEEED_CANMessage : public CAN_Message
00027 {
00028 
00029 public:
00030     /** Creates empty CAN message.
00031      */
00032     SEEED_CANMessage() {
00033         id     = 0;
00034         memset(data, 0, 8);
00035         len    = 8;
00036         type   = CANData;
00037         format = CANStandard;
00038     }
00039 
00040     /** Creates CAN message with specific content.
00041      */
00042     SEEED_CANMessage(int _id, const char *_data, char _len = 8, CANType _type = CANData, CANFormat _format = CANStandard) {
00043         id     = _id;
00044         memcpy(data, _data, _len);
00045         len    = _len & 0xF;
00046         type   = _type;
00047         format = _format;
00048     }
00049 
00050     /** Creates CAN remote message.
00051      */
00052     SEEED_CANMessage(int _id, CANFormat _format = CANStandard) {
00053         id     = _id;
00054         memset(data, 0, 8);
00055         len    = 0;
00056         type   = CANRemote;
00057         format = _format;
00058     }
00059 };
00060 
00061 
00062 /** A can bus client, used for communicating with Seeed Studios' CAN-BUS Arduino Shield.
00063  */
00064 class SEEED_CAN
00065 {
00066 public:
00067     /** Seeed Studios CAN-BUS Shield Constructor - Create a SEEED_CAN interface connected to the specified pins.
00068      *
00069      *  The Seeed Studio CAN-BUS shield is an Arduino compatible shield and connects to the FRDM-KL25Z SPI0 interface using pins PTD2 (mosi) PTD3 (miso) PTD1 (clk). The Active low chip select normally connects to the FRDM-KL25Z's PTD0 pin, but there is an option on the Seeed Studio CAN-BUS shield to connect to the PTD5 pin. The CAN-BUS shield uses the FRDM-KL25Z's PTD4 pin for its (active low) interrupt capability. The defaults allow you to plug the Seeed Studios' CAN-BUS Shield into a FRDM-KL25Z mbed and it to work without specifying any parameters.
00070      *
00071      *  @param ncs Active low chip select, @b default: @p SEEED_CAN_CS is FRDM-KL25Z PTD0 pin (p9 on LPC1768).
00072      *  @n If you change the link on the Seeed Studios CAN-BUS shield you should use a value of SEEED_CAN_IO9 or PTD5 instead.
00073      *  @param irq Active low interrupt pin, @b default: @p SEEED_CAN_IRQ is FRDM-KL25Z PTD4 pin (p10 on LPC1768).
00074      *  @param mosi SPI Master Out, Slave In pin, @b default: @p SEEED_CAN_MOSI is FRDM-KL25Z PTD2 pin (p11 on LPC1768).
00075      *  @param miso SPI Master In, Slave Out pin, @b default: :p SEEED_CAN_MISO is FRDM-KL25Z PTD3 pin (p12 on LPC1768).
00076      *  @param clk SPI Clock pin, @b default: @p SEEED_CAN_MISO is FRDM-KL25Z PTD1 pin (p13 on LPC1768).
00077      *  @param spiBitrate SPI Clock frequency, @b default: @p 1000000 (1 MHz).
00078      */
00079 #if defined MKL25Z4_H_                                                  // defined in MKL25Z4.h
00080     SEEED_CAN(PinName ncs=SEEED_CAN_CS, PinName irq=SEEED_CAN_IRQ, PinName mosi=SEEED_CAN_MOSI, PinName miso=SEEED_CAN_MISO, PinName clk=SEEED_CAN_CLK, int spiBitrate=1000000);
00081 #elif defined __LPC17xx_H__                                             // defined in LPC17xx.h
00082     SEEED_CAN(PinName ncs=p9, PinName irq=p10, PinName mosi=p11, PinName miso=p12, PinName clk=p13, int spiBitrate=1000000);
00083 #else                                                                   // No default constructor for other...
00084     SEEED_CAN(PinName ncs, PinName irq, PinName mosi, PinName miso, PinName clk, int spiBitrate=1000000);
00085 #endif
00086 //    virtual ~SEEED_CAN(); // !!! Need a de-constructor for the interrrupt pin !!!
00087 
00088     enum Mode {
00089         Normal = 0,
00090         Sleep,
00091         Loopback,
00092         Monitor,
00093         Config,
00094         Reset
00095     };
00096 
00097     /** Open initialises the Seeed Studios CAN-BUS Shield.
00098      *
00099      *  @param canBitrate CAN Bus Clock frequency, @b default: @p 100000 (100 kHz).
00100      *  @param mode The initial operation mode, @b default: @p Normal.
00101      *  @n @p SEEED_CAN::Normal - Normal mode is the standard operating mode,
00102      *  @n @p SEEED_CAN::Monitor - This mode can be used for bus monitor applications.
00103      *  @n @p SEEED_CAN::Sleep - This mode can be used to minimize the current consumption,
00104      *  @n @p SEEED_CAN::Loopback - This mode can be used in system development and testing.
00105      *  @n @p SEEED_CAN::Config - Open with this mode to prevent unwanted messages being received while you configure Filters.
00106      *
00107      *  @returns
00108      *     1 if successful,
00109      *  @n 0 otherwise
00110      */
00111     int open(int canBitrate=100000, Mode mode = Normal);
00112 
00113     /** Puts or removes the Seeed Studios CAN-BUS shield into or from silent monitoring mode.
00114      *
00115      *  @param silent boolean indicating whether to go into silent mode or not.
00116      */
00117     void monitor(bool silent);
00118 
00119     /** Change the Seeed Studios CAN-BUS shield CAN operation mode.
00120      *
00121      *  @param mode The new operation mode
00122      *  @n @p SEEED_CAN::Normal - Normal mode is the standard operating mode,
00123      *  @n @p SEEED_CAN::Monitor - This mode can be used for bus monitor applications.
00124      *  @n @p SEEED_CAN::Sleep - This mode can be used to minimize the current consumption,
00125      *  @n @p SEEED_CAN::Loopback - This mode can be used in system development and testing.
00126      *  @n @p SEEED_CAN::Reset - Reset the MCP2515 device and stay in Configuration mode.
00127      *
00128      *  @returns
00129      *     1 if mode change was successful
00130      *  @n 0 if mode change failed or unsupported,
00131      */
00132     int mode(Mode mode);
00133 
00134     /** Set the CAN bus frequency (Bit Rate)
00135      *
00136      *  @param hz The bus frequency in Hertz
00137      *
00138      *  @returns
00139      *     1 if successful,
00140      *  @n 0 otherwise
00141      */
00142     int frequency(int canBitRate);
00143 
00144     /** Read a CAN bus message from the MCP2515 (if one has been received)
00145      *
00146      *  @param msg A CANMessage to read to.
00147      *
00148      *  @returns
00149      *     1 if any messages have arrived
00150      *  @n 0 if no message arrived,
00151      */
00152     int read(SEEED_CANMessage &msg);
00153 
00154     /** Write a CAN bus message to the MCP2515 (if there is a free message buffer)
00155      *
00156      *  @param msg The CANMessage to write.
00157      *
00158      *  @returns
00159      *     1 if write was successful
00160      *  @n 0 if write failed,
00161      */
00162     int write(SEEED_CANMessage msg);
00163 
00164     /** Configure one of the Accpetance Masks (0 or 1)
00165      *
00166      *  @param maskNum The number of the Acceptance Mask to configure (Acceptance Mask 0 is associated with Filters 0 and 1, Acceptance Mask 1 is associated with Filters 2 through 5).
00167      *  @param canId CAN Id Mask bits (Acceptance Filters are only compared against bits that are set to '1' in an Acceptance Mask (e.g. mask 0x07F0 and filter 0x03F0 would allow through messages with CAN Id's 0x03F0 through 0x03FF because the 4 LSBs of the CAN Id are not filtered).
00168      *  @param format Describes if the Acceptance Mask is for a standard (CANStandard) or extended (CANExtended) CAN message frame format, @b default: @p CANStandard.
00169      *
00170      *  @returns
00171      *     1 if Acceptance Mask was set
00172      *  @n 0 if the Acceptance Mask could not be set
00173      */
00174     int mask(int maskNum, int canId, CANFormat format = CANStandard);
00175 
00176     /** Configure one of the Acceptance Filters (0 through 5)
00177      *
00178      *  @param filterNum The number of the Acceptance Filter to configure (Acceptance Filters 0 and 1 are associated with Mask 0, Acceptance Filters 2 through 5 are associated with Mask 1).
00179      *  @param canId CAN Id Filter bits (Acceptance Filters are only compared against bits that are set to '1' in an Acceptance Mask (e.g. mask 0x07F0 and filter 0x03F0 would allow through messages with CAN Id's 0x03F0 through 0x03FF because the 4 LSBs of the CAN Id are not filtered).
00180      *  @param format Describes if the Acceptance Filter is for a standard (CANStandard) or extended (CANExtended) CAN message frame format, @b default: @p CANStandard.
00181      *
00182      *  @returns
00183      *     1 if Acceptance Filter was set
00184      *  @n 0 if the Acceptance Filter could not be set
00185      */
00186     int filter(int filterNum, int canId, CANFormat format = CANStandard);
00187 
00188     /** Returns number of message reception (read) errors to detect read overflow errors.
00189      *
00190      *  @returns
00191      *    Number of reception errors
00192      */
00193     unsigned char rderror(void);
00194 
00195     /** Returns number of message transmission (write) errors to detect write overflow errors.
00196      *
00197      *  @returns
00198      *    Number of transmission errors
00199      */
00200     unsigned char tderror(void);
00201 
00202     enum ErrorType {
00203         AnyError = 0,
00204         Errors,
00205         Warnings,
00206         Rx1Ovr,
00207         Rx0Ovr,
00208         TxBOff,
00209         TxPasv,
00210         RxPasv,
00211         TxWarn,
00212         RxWarn,
00213         EWarn
00214     };
00215 
00216     /** Check if any type of error has been detected on the CAN bus
00217      *
00218      *  @param error Specify which type of error to report on, @b default: @p AnyError.
00219      *  @n @p SEEED_CAN::AnyError - Any one or more of the following errors and warnings:
00220      *  @n @p SEEED_CAN::Errors - Any one or more of the 5 errors:
00221      *  @n @p SEEED_CAN::Rx1Ovr - Receive Buffer 1 Overflow Flag bit,
00222      *  @n @p SEEED_CAN::Rx0Ovr - Receive Buffer 0 Overflow Flag bit,
00223      *  @n @p SEEED_CAN::TxBOff - Bus-Off Error Flag bit,
00224      *  @n @p SEEED_CAN::TxPasv - Transmit Error-Passive Flag bit,
00225      *  @n @p SEEED_CAN::RxPasv - Receive Error-Passive Flag bit,
00226      *  @n @p SEEED_CAN::Warnings - Any one or more of the 3 warnings:
00227      *  @n @p SEEED_CAN::TxWarn - Transmit Error Warning Flag bit,
00228      *  @n @p SEEED_CAN::RxWarn - Receive Error Warning Flag bit,
00229      *  @n @p SEEED_CAN::EWarn - Error Warning Flag bit.
00230      *
00231      *  @returns
00232      *     1 if specified type of error has been detected
00233      *  @n 0 if no errors
00234      */
00235     int errors(ErrorType type = AnyError);
00236 
00237     /** Returns the contents of the MCP2515's Error Flag register
00238      *
00239      *  @returns
00240      *     @b Bit_7 - RX1OVR: Receive Buffer 1 Overflow Flag bit - Set when a valid message is received for RXB1 and CANINTF.RX1IF = 1 - Must be reset by MCU,
00241      *  @n @b Bit_6 - RX0OVR: Receive Buffer 1 Overflow Flag bit - Set when a valid message is received for RXB0 and CANINTF.RX0IF = 1 - Must be reset by MCU,
00242      *  @n @b Bit_5 - TXBO: Bus-Off Error Flag bit - Bit set when TEC reaches 255 - Reset after a successful bus recovery sequence,
00243      *  @n @b Bit_4 - TXEP: Transmit Error-Passive Flag bit - Set when TEC is >= 128 - Reset when TEC is less than 128,
00244      *  @n @b Bit_3 - RXEP: Receive Error-Passive Flag bit - Set when REC is >= 128 - Reset when REC is less than 128,
00245      *  @n @b Bit_2 - TXWAR: Transmit Error Warning Flag bit - Set when TEC is >= 96 - Reset when TEC is less than 96,
00246      *  @n @b Bit_1 - RXWAR: Receive Error Warning Flag bit - Set when REC is >= 96 - Reset when REC is less than 96,
00247      *  @n @b Bit_0 - EWARN: Error Warning Flag bit - Set when TEC or REC is >= 96 (TXWAR or RXWAR = 1) - Reset when both REC and TEC are < 96.
00248      */
00249     unsigned char errorFlags(void);
00250 
00251     enum IrqType {
00252         None = 0,
00253         AnyIrq,
00254         RxAny,
00255         TxAny,
00256         Rx0Fill,
00257         Rx1Full,
00258         Tx0Free,
00259         Tx1Free,
00260         Tx2Free,
00261         Error,
00262         Wake,
00263         MsgError,
00264     };
00265 
00266     /** Attach a function to call whenever a CAN frame received interrupt is generated.
00267      *
00268      *  @param fptr A pointer to a void function, or 0 to set as none.
00269      *  @param event Which CAN interrupt to attach the member function to, @b default: @p RxAny
00270      *  @n @p SEEED_CAN::None - Disable all interrupt sources,
00271      *  @n @p SEEED_CAN::AnyIrq - Enable all interrupt sources,
00272      *  @n @p SEEED_CAN::RxAny - Any full RX buffer can generate an interrupt,
00273      *  @n @p SEEED_CAN::TxAny - Any empty TX buffer can generate an interrupt,
00274      *  @n @p SEEED_CAN::Rx0Full - Receive buffer 1 full,
00275      *  @n @p SEEED_CAN::Rx1Full - Receive buffer 1 full,
00276      *  @n @p SEEED_CAN::Tx0Free - Transmit buffer 2 empty,
00277      *  @n @p SEEED_CAN::Tx1Free - Transmit buffer 2 empty,
00278      *  @n @p SEEED_CAN::Tx2Free - Transmit buffer 2 empty,
00279      *  @n @p SEEED_CAN::Error - Error (multiple sources in EFLG register),
00280      *  @n @p SEEED_CAN::Wake - Wakeup,
00281      *  @n @p SEEED_CAN::MsgError - Message Error,
00282      */
00283     void attach(void (*fptr)(void), IrqType event=RxAny);
00284 
00285     /** Attach a member function to call whenever a CAN frame received interrupt is generated.
00286      *
00287      *  @param tptr pointer to the object to call the member function on.
00288      *  @param mptr pointer to the member function to be called.
00289      *  @param event Which CAN interrupt to attach the member function to, @b default: @p RxAny
00290      *  @n @p SEEED_CAN::None - Disable all interrupt sources,
00291      *  @n @p SEEED_CAN::AnyIrq - Enable all interrupt sources,
00292      *  @n @p SEEED_CAN::RxAny - Any full RX buffer can generate an interrupt,
00293      *  @n @p SEEED_CAN::TxAny - Any empty TX buffer can generate an interrupt,
00294      *  @n @p SEEED_CAN::Rx0Full - Receive buffer 1 full,
00295      *  @n @p SEEED_CAN::Rx1Full - Receive buffer 1 full,
00296      *  @n @p SEEED_CAN::Tx0Free - Transmit buffer 2 empty,
00297      *  @n @p SEEED_CAN::Tx1Free - Transmit buffer 2 empty,
00298      *  @n @p SEEED_CAN::Tx2Free - Transmit buffer 2 empty,
00299      *  @n @p SEEED_CAN::Error - Error (multiple sources in EFLG register),
00300      *  @n @p SEEED_CAN::Wake - Wakeup,
00301      *  @n @p SEEED_CAN::MsgError - Message Error,
00302      */
00303     template<typename T>
00304     void attach(T* tptr, void (T::*mptr)(void), IrqType event=RxAny) {
00305         _callback_irq.attach(tptr, mptr);
00306         mcpSetInterrupts(&_can, (CANIrqs)event);
00307         if((mptr != NULL) && (tptr != NULL)) {
00308             _callback_irq.attach(tptr, mptr);
00309             mcpSetInterrupts(&_can, (CANIrqs)event);
00310 //            _irq[type].attach(tptr, mptr);
00311 //            can_irq_set(&_can, (CanIrqType)type, 1);
00312         } else {
00313             mcpSetInterrupts(&_can, (CANIrqs)SEEED_CAN::None);
00314 //            can_irq_set(&_can, (CanIrqType)type, 0);
00315         }
00316     }
00317 
00318     void call_irq(void);
00319     
00320     /** Check if the specified interrupt event has occurred
00321      *
00322      *  @param event Which CAN interrupt to attach the member function to
00323      *  @n @p SEEED_CAN::RxAny - At least 1 RX buffer is full,
00324      *  @n @p SEEED_CAN::TxAny - At least 1 TX buffer is empty,
00325      *  @n @p SEEED_CAN::Rx0Full - Receive buffer 1 full,
00326      *  @n @p SEEED_CAN::Rx1Full - Receive buffer 1 full,
00327      *  @n @p SEEED_CAN::Tx0Free - Transmit buffer 2 empty,
00328      *  @n @p SEEED_CAN::Tx1Free - Transmit buffer 2 empty,
00329      *  @n @p SEEED_CAN::Tx2Free - Transmit buffer 2 empty,
00330      *  @n @p SEEED_CAN::Error - Error (multiple sources in EFLG register),
00331      *  @n @p SEEED_CAN::Wake - Wakeup,
00332      *  @n @p SEEED_CAN::MsgError - Message Error,
00333      *
00334      *  @returns
00335      *     1 if specified interrupt event has occurred
00336      *  @n 0 if no errors
00337      */
00338     int interrupts(IrqType type);
00339 
00340     /** Returns the contents of the MCP2515's Interrupt Flag register
00341      *
00342      *  @returns
00343      *     @b Bit_7 - MERRF: Message Error Interrupt Flag,
00344      *  @n @b Bit_6 - WAKIF: Wake-up Interrupt Flag,
00345      *  @n @b Bit_5 - ERRIF: Error Interrupt Flag (multiple sources in EFLG register, see errorFlags)
00346      *  @n @b Bit_4 - TX2IF: Transmit Buffer 2 Empty Interrupt Flag
00347      *  @n @b Bit_3 - TX1IF: Transmit Buffer 1 Empty Interrupt Flag
00348      *  @n @b Bit_2 - TX0IF: Transmit Buffer 0 Empty Interrupt Flag
00349      *  @n @b Bit_1 - RX1IF: Receive Buffer 1 Full Interrupt Flag
00350      *  @n @b Bit_0 - RX0IF: Receive Buffer 0 Full Interrupt Flag
00351      *  @n Bits are set (1) when interrupt pending, clear (0) when no interrupt pending.
00352      *  @n Bits must be cleared by MCU to reset interrupt condition.
00353      */
00354     unsigned char interruptFlags(void);
00355 
00356 protected:
00357     SPI             _spi;
00358     mcp_can_t       _can;
00359     InterruptIn     _irqpin;
00360     FunctionPointer _callback_irq;
00361 
00362 };
00363 
00364 #endif      // SEEED_CAN_H