CANPort provides a higher level interface to a CAN communication channel, and provides timestamping, servicing additional hardware interfaces (optional activity LED, CAN transceiver slope control)

Revision:
0:7b81b19d9b10
Child:
1:f0b4e47d948d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CANPort.h	Sun Jul 15 15:15:19 2012 +0000
@@ -0,0 +1,285 @@
+/// @file CANPort.h is where all the port level functionality is defined
+///
+/// This module creates the physical interface, services the hardware, and provides
+/// additional functionality on top of that (e.g. timestamp messages).
+///
+/// @todo Instead of providing a callback directly to the user code, all 
+///       callbacks should be handled in this class, and then the user 
+///       callback could be activated. In this way, the rxCounter, timestamps,
+///       and other features are preserved.
+///
+/// @note Copyright &copr; 2011 by Smartware Computing, all rights reserved.
+///     Individuals may use this application for evaluation or non-commercial
+///     purposes. Within this restriction, changes may be made to this application
+///     as long as this copyright notice is retained. The user shall make
+///     clear that their work is a derived work, and not the original.
+///     Users of this application and sources accept this application "as is" and
+///     shall hold harmless Smartware Computing, for any undesired results while
+///     using this application - whether real or imagined.
+///
+/// @author David Smart, Smartware Computing
+///
+/// History
+/// v1.01 20110608
+/// \li initial version numbered to match other CAN components
+///
+#ifndef CANPORT_H
+#define CANPORT_H
+#include "mbed.h"
+#include "CANMessage.h"
+#include "Utilities.h"      // mbed <-> Visual Studio
+
+
+typedef enum {
+    HIGHSPEED,
+    NORMALSPEED,
+    STANDBY
+} CANSlopeControl_T;
+
+typedef enum {
+    MONITOR,
+    ACTIVE
+} CANBusMode_T;
+
+/// This is the CANPort, which is the physical interface to CAN
+///
+/// This derived class has a number of additional capabilities:
+/// \li activity indicator to show receive and transmit activity per port
+/// \li slope control pin to permit controlling performance and power modes
+/// \li counters, to keep track of received and transmitted messages
+/// \li and more...
+///
+class CANPort {
+public:
+
+    /// The advanced form of the constructure to create a CANPort, name 
+    /// an activity indicator, and name a slope control pin
+    ///
+    /// This version lets you specify the receive and transmit pins
+    /// for a CANPort, indicate a pin which is used to indicate
+    /// CAN activity, both receive and transmit, and identify a slope
+    /// control pin.
+    ///
+    /// @param chNum is the user assigned channel number given to this port
+    /// @param rd is the receive pin
+    /// @param td is the transmit pin
+    /// @param activityPin is the PWM pin used to indicate CAN traffic
+    /// @param slopePin is the DigitalInOut pin used to control slope
+    /// @param slope is the initial slope setting
+    ///
+    CANPort(CANCHANNEL_T chNum, PinName rd, PinName td, PinName activityPin = NC, PinName slopePin = NC, CANSlopeControl_T slope = NORMALSPEED);
+    
+    /// Destroys the CANPort
+    virtual ~CANPort();
+
+    /// Transmit a message to the bus
+    ///
+    /// This method transmits a message to the bus.
+    ///
+    /// @param msg is a CANmsg
+    /// @returns true if the message was successfully written to CAN
+    ///
+    bool TransmitMsg(CANmsg msg);
+    
+    /// Read a message from the bus into a buffer
+    ///
+    /// This method will extract a message from the bus and put it 
+    /// in the message space provided
+    ///
+    /// @param msg is a reference to a CANmsg into which the msg is placed
+    /// @returns true if a message was received and processed
+    ///
+    bool ReceiveMsg(CANmsg &msg);
+    
+    /// This flashes the activity indicator associated with this CANPort
+    ///
+    /// If the activity indicator is configured.
+    ///
+    /// @param tx indiciates if the flash is to be a sign of xmt or rcv
+    ///        it will flash dimly for a transmit and bright for a receive
+    ///
+    void Flash(CANDIR_T tx);
+    
+    /// This extinguishes the activity indicator associated with this CANPort
+    ///
+    /// If the activity indicator is configured.
+    ///
+    void Extinguish(void);
+    
+    /// Attach a callback whenever a CAN receive interrupt is generated
+    ///
+    /// This attaches a simple callback to the CAN ISR
+    ///
+    /// @param fptr pointer to the function to be called 
+    ///
+    void Attach( void  (*fptr)(void) );
+    
+    /// Attach a callback whenever a CAN receive interrupt is generated
+    ///
+    /// This attaches a callback to the CAN ISR
+    ///
+    /// @param tptr pointer to the object to call the member function on 
+    /// @param mptr pointer to the member function to be called 
+    ///
+    template <typename T> void Attach(T * tptr, void (T::*mptr)(void)) {
+        can->attach(tptr, mptr);
+    }
+    
+    /// This provides control of the AutoReset feature
+    ///
+    /// AutoReset is a feature that permits automatically resetting the 
+    /// CAN chip when it is trapped in an error state (e.g. bus off).
+    /// The default is disabled.
+    ///
+    /// @param enable is used to enable or disable the auto reset feature
+    /// @returns true if the command was accepted
+    ///
+    bool SetAutoReset(bool enable);
+    
+    /// This returns the current state of the AutoReset feature
+    ///
+    /// Returns a value indicating the current state
+    ///
+    /// @returns true if AutoReset is enabled
+    /// @returns false if AutoReset is disabled
+    ///
+    bool GetAutoReset() { return autoReset; }
+    
+    /// This provides control to set the bus mode as active or listener only
+    ///
+    /// The CAN adapter can be placed into a monitor(LISTENER) mode (sometimes
+    /// called promiscuous mode) or into an active mode, in which case it
+    /// will send hardware acknowledge.
+    ///
+    /// @param mode is either MONITOR or ACTIVE
+    /// @returns true if the command was accepted
+    ///
+    bool SetBusMode(CANBusMode_T mode);
+    
+    /// This returns the current state of the bus mode
+    ///
+    /// @returns MONITOR if the chip is in the monitor (listen / promiscuous) mode
+    /// @returns ACTIVE if the chip is in the active mode
+    ///
+    CANBusMode_T GetBusMode();
+
+    /// This provides control to set the transceiver slope control mode
+    ///
+    /// Many CAN transceivers can be operated in one of several modes - 
+    /// \li HIGHSPEED - which supports the highest frequency of communication, but
+    ///     does tend to generate more EMI unless the cable is properly shielded
+    /// \li NORMALSPEED - which wave-shapes the rising and falling edge, and
+    ///     significantly reduces the EMI concerns, but may trade off the
+    ///     highest performance.
+    /// \li STANDBY - which puts the chip into the lowest power state, and prevents
+    ///     transmission of a message. It can typically still receive messages,
+    ///     but this mode may also be useful for other purposes (wake on CAN,
+    ///     autobaud w/o disrupting bus traffic, etc.)
+    ///
+    /// @param slope sets the slope control to one of the states HIGHSPEED, 
+    ///     NORMALSPEED, or STANDBY
+    /// @returns true if the command succeeded
+    /// @returns false if the command failed, which may be due to not having
+    ///     defined a slope control pin.
+    ///
+    bool SetSlopeControl(CANSlopeControl_T slope);
+    
+    /// This returns the current state of the slope control
+    /// 
+    /// The state is controlled by the SetSlopeControl command.
+    ///
+    /// @returns the current state; one of HIGHSPEED, NORMALSPEED, or STANDBY
+    ///
+    CANSlopeControl_T GetSlopeControl();
+
+    /// This sets the bitrate for the CAN channel
+    ///
+    /// This sets the bitrate for the CAN channel. The rate is in bits per
+    /// second. The actual bitrate and the sample point is automagically 
+    /// determined from the internal algorithms provided by the mbed library.
+    ///
+    /// This API appears redundant to the frequency api, however this one
+    /// will retain the rate setting and then permits the query of the bitrate.
+    /// 
+    /// @param rate is the desired bitrate in bits per second.
+    /// @returns true if teh command succeeded
+    ///
+    bool SetBitRate(int rate);
+    
+    /// This returns the current desired bitrate for the CAN channel
+    ///
+    /// This returns the previously set bitrate. Note that the actual bitrate
+    /// may be different, due to the internal calculations of the mbed library.
+    ///
+    /// @returns the bitrate in bits per second
+    ///
+    int GetBitRate();
+
+    /// This returns the number of messages that were sent by this CAN channel
+    ///
+    /// The counter is never reset.
+    ///
+    /// @returns the number of messages sent by this CAN channel
+    ///
+    int GetTxCounter();
+
+    /// This returns the number of messages that were received by this CAN channel
+    ///
+    /// The counter is never reset.
+    ///
+    /// @returns the number of messages received by this CAN channel
+    ///
+    int GetRxCounter();
+    
+    /// This returns the number of transmit errors
+    ///
+    /// As counted by the hardware
+    ///
+    /// @returns the number of transmit errors
+    int GetTxErrorCounter();
+    
+    /// This returns the number of receive errors
+    ///
+    /// As counted by the hardware
+    ///
+    /// @returns the number of receive errors
+    int GetRxErrorCounter();
+    
+    /// This resets the CAN interface
+    ///
+    /// Unconditionally.
+    ///
+    /// @returns true if success
+    ///
+    bool ResetChip();
+    
+    /// This writes various CAN info to the selected serial channel
+    ///
+    /// When supplied with a Serial port channel, this will output
+    /// some possibly interesting information about the CAN configuration.
+    /// It does not output details for only the active objects channel,
+    /// rather it outputs information about the CAN subsystem.
+    ///
+    /// @param stream is the handle of a serial channel
+    /// @returns nothing
+    ///
+    void PrintInfo(Serial * stream);
+
+private:
+    CANCHANNEL_T channel;       // user assigned port number of this port
+    CAN * can;                  // bind to a specific CAN
+    CANBusMode_T busMode;       // monitor or active mode
+    int bitRate;                // bit rate for this bus
+    PwmOut * activityPin;       // LED to indicate activity
+    Timeout activityTimeout;    // used to extinguish the LED
+
+    DigitalInOut * slopePin;    // pin used to control the transceiver slope modes
+    PinName slopePinName;
+    CANSlopeControl_T slopeMode;// current mode
+
+    bool autoReset;             // true when auto reset on error is enabled
+    uint32_t txCounter;
+    uint32_t rxCounter;
+};
+
+#endif // CANPORT_H