Nico Bollen / LIN

Dependents:   MBED_LIN_RGB_Master_Example

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers LinMaster.h Source File

LinMaster.h

00001 /*
00002  * A master device LIN communication library for mbed
00003  * 
00004  * Copyright (C) 2015 Bollen Nico
00005  * 
00006  * Released under GPL v2
00007  *
00008  * Other licensing models might apply at the sole discretion of the copyright holders.
00009  *
00010  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
00011  * and associated documentation files (the "Software"), to deal in the Software without restriction,
00012  * including without limitation the rights to use, copy, modify, merge, publish, distribute,
00013  * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
00014  * furnished to do so, subject to the following conditions:
00015  *
00016  * The above copyright notice and this permission notice shall be included in all copies or
00017  * substantial portions of the Software.
00018  *
00019  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
00020  * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00021  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
00022  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00023  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00024  */
00025 
00026 #ifndef MBED_LIN_MASTER_H
00027 #define MBED_LIN_MASTER_H
00028  
00029 #include "mbed.h"
00030 
00031 /**  A master device LIN communication library for mbed
00032  *
00033  * @code
00034  * #include "mbed.h"
00035  * #include "LinMaster.h"
00036  * 
00037  * LinMaster lin(p10, p9);
00038  * 
00039  * int main() {
00040  *     (void)lin.init();
00041  *
00042  *     (void)MyLinMaster.send_frame(&M2Sframe);
00043  *     while(MyLinMaster.status() != LinMaster::IDLE);
00044  *
00045  *     (void)MyLinMaster.send_frame(&S2Mframe);
00046  *     while(MyLinMaster.status() != LinMaster::IDLE);
00047  *     if (MyLinMaster.get_rx_data(S2Mframe) == true)
00048  *     {
00049  *     }
00050  *     else { }
00051  * }
00052  * @endcode
00053  */
00054 class LinMaster
00055 {
00056 public:
00057     /** LIN master constructor
00058      *
00059      * @param Pin The pinname to be used for LIN communication
00060      */
00061     LinMaster(PinName InPin, PinName OutPin);
00062 
00063     /** LIN master destructor */
00064     ~LinMaster();
00065 
00066     /** Initialise the LIN module
00067      * - configure IO
00068      * - configure Timer
00069      *
00070      * @return
00071      *   true on succes,
00072      *   false on fail
00073      */
00074     bool init(void);
00075 
00076     /** Set the LIN baudrate
00077      *
00078      * @param uBaud baudrate value in kbps (1..20000)
00079      * @return
00080      *   true on succes,
00081      *   false on fail
00082      */
00083     bool baudrate(uint16_t uBaud);
00084 
00085     /** Get the LIN baudrate
00086      *
00087      * @return
00088      *   The current configured LIN baudrate
00089      */
00090     uint16_t baudrate(void);
00091 
00092     /** Bus status */
00093     enum DriverStatus_t {
00094         INIT,           /**< initializing */
00095         IDLE,           /**< idle */
00096         RXWAKEUP,       /**< wake up pulses detected since the last request */
00097         DOMINANT,       /**< dominant level detected, longer than a wake up pulse */
00098         TRANSMIT,       /**< busy receiving data */
00099         RECEIVE,        /**< busy receiving data */
00100         TXWAKEUP        /**< busy sending a wake up pulse */
00101     };
00102 
00103     /** Get the current LIN driver status
00104      *
00105      * @return
00106      *   The current LIN driver status
00107      */
00108     DriverStatus_t status(void) {return ( DriverState );};
00109 
00110     /** Error code type */
00111     enum FrameError_t {
00112         NoError,                                        /* No error */
00113         NoSlaveResp,                                    /* No slave response, LIN message has timed out */
00114         FramingErr,                                     /* Framing error */
00115         CollisionErr,                                   /* Collision error */
00116         BusVoltage                                      /* Bus voltage to low */
00117     };
00118 
00119     /** Get the last error detected
00120      *
00121      * @return
00122      *   The last error detected
00123      */
00124     FrameError_t last_error(void) {return ( LastError );};
00125 
00126     /** Frame Direction Type */
00127     enum FrameType_t {
00128         S2M,
00129         M2S
00130     };
00131 
00132     /** CRC Type */
00133     enum CrcType_t {
00134         Classic,
00135         Enhanced
00136     };
00137 
00138     /** Brake Type */
00139     enum BrakeType_t {
00140         Normal,
00141         AutoConfig
00142     };
00143 
00144     /** Frame */
00145     struct Frame_t {
00146         FrameType_t FrameType;
00147         CrcType_t CrcType;
00148         BrakeType_t Brake;
00149         uint8_t DataLen;
00150         uint8_t FrameID;
00151         uint8_t Data[8];
00152     };
00153 
00154     /** Send a frame on the LIN bus
00155      *
00156      * @param ptrFrame pointer to the frame to transmit
00157      * @return
00158      *   true on succes,
00159      *   false on fail
00160      */
00161     bool send_frame(Frame_t * ptrFrame);
00162 
00163     /** Receive a frame on the LIN bus
00164      *
00165      * @param ptrFrame pointer to the frame to receive
00166      * @return
00167      *   true on succes,
00168      *   false on fail
00169      */
00170     bool get_rx_data(Frame_t & ptrFrame);
00171 
00172     void TickEventHndl(void);
00173 
00174     void RXtimeoutEventHndl(void);
00175 
00176     void PinEventHndl(void);
00177 
00178 private:
00179     enum FrameStatus_t {
00180         FStart,
00181         Break_OK,
00182         Sync_OK,
00183         ID_OK,
00184         Data0,
00185         Data1,
00186         Data2,
00187         Data3,
00188         Data4,
00189         Data5,
00190         Data6,
00191         Data7,
00192         CRC
00193     };
00194 
00195     enum ByteStatus_t {
00196         BStart,
00197         StartbitEdge,               /* Begin of startbit received */
00198         StartbitSample,             /* Startbit sample */
00199         Databit0Edge,               /* Databit edge */
00200         Databit0Sample,             /* Databit sample */
00201         Databit1Edge,               /* Databit edge */
00202         Databit1Sample,             /* Databit sample */
00203         Databit2Edge,               /* Databit edge */
00204         Databit2Sample,             /* Databit sample */
00205         Databit3Edge,               /* Databit edge */
00206         Databit3Sample,             /* Databit sample */
00207         Databit4Edge,               /* Databit edge */
00208         Databit4Sample,             /* Databit sample */
00209         Databit5Edge,               /* Databit edge */
00210         Databit5Sample,             /* Databit sample */
00211         Databit6Edge,               /* Databit edge */
00212         Databit6Sample,             /* Databit sample */
00213         Databit7Edge,               /* Databit edge */
00214         Databit7Sample,             /* Databit sample */
00215         StopbitEdge,                /* Stopbit edge */
00216         StopbitSample,              /* Stopbit sample */
00217         BDone
00218     };
00219 
00220     volatile DriverStatus_t DriverState;
00221     volatile FrameError_t LastError;
00222     volatile FrameStatus_t FrameStatus;
00223     volatile ByteStatus_t ByteStatus;
00224     volatile FrameType_t linMessageType;
00225 
00226     uint8_t  breakLength;
00227     uint8_t  FrameLength;
00228 
00229     uint8_t  TXbuf[11];
00230     uint8_t  TXbufIndex;
00231     uint8_t  RXbuf[11];
00232     uint8_t  RXbufIndex;
00233     std::chrono::microseconds u16HalfBitPeriod;
00234 
00235     DigitalOut LinOutPin;
00236     InterruptIn LinInPin;
00237     std::chrono::microseconds FrameTimeout;
00238     Ticker HalfbitTicker;
00239     Ticker TimeoutTicker;
00240 
00241     uint8_t parity(uint8_t u8BYTE);
00242 
00243 };
00244 
00245 #endif /* MBED_LIN_MASTER_H */