Nico Bollen / LIN

Dependents:   MBED_LIN_RGB_Master_Example

LinMaster.h

Committer:
bollenn
Date:
2015-06-25
Revision:
6:0827e5003e17
Parent:
5:b42737f5dabc
Child:
7:53b2cded83f3

File content as of revision 6:0827e5003e17:

/*
 * A master device LIN communication library for mbed
 * 
 * Copyright (C) 2015 Bollen Nico
 * 
 * Released under GPL v2
 *
 * Other licensing models might apply at the sole discretion of the copyright holders.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
 * and associated documentation files (the "Software"), to deal in the Software without restriction,
 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or
 * substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
 
#include "mbed.h"

#ifndef MBED_LIN_MASTER_H
#define MBED_LIN_MASTER_H

/**  A master device LIN communication library for mbed
 *
 * @code
 * #include "mbed.h"
 * #include "LinMaster.h"
 * 
 * LinMaster lin(p10, p9);
 * 
 * int main() {
 *     (void)lin.init();
 *     (void)MyLinMaster.tx_frame(&M2Sframe);
 *     while(MyLinMaster.status() != LinMaster::IDLE);
 *     void)MyLinMaster.rx_frame(&S2Mframe);
 * }
 * @endcode
 */
class LinMaster
{
public:
    /** LIN master constructor
     *
     * @param Pin The pinname to be used for LIN communication
     */
    LinMaster(PinName InPin, PinName OutPin);

    /** LIN master destructor */
    ~LinMaster();

    /** Initialise the LIN module
     * - configure IO
     * - configure Timer
     *
     * @return
     *   true on succes,
     *   false on fail
     */
    bool init(void);

    /** Set the LIN baudrate
     *
     * @param uBaud baudrate value in kbps (1..20000)
     * @return
     *   true on succes,
     *   false on fail
     */
    bool baudrate(uint16_t uBaud);

    /** Get the LIN baudrate
     *
     * @return
     *   The current configured LIN baudrate
     */
    uint16_t baudrate(void);
    
    /** Bus status */
    enum DriverStatus_t {
        INIT,           /**< initializing */
        IDLE,           /**< idle */
        RXWAKEUP,       /**< wake up pulses detected since the last request */
        DOMINANT,       /**< dominant level detected, longer than a wake up pulse */
        TRANSMIT,       /**< busy receiving data */
        RECEIVE,        /**< busy receiving data */
        TXWAKEUP        /**< busy sending a wake up pulse */
    };

    /** Get the current LIN driver status
     *
     * @return
     *   The current LIN driver status
     */
    DriverStatus_t status(void) {return ( DriverState );};
    
    /** Frame Direction Type */
    enum FrameType_t {
        S2M,
        M2S
    };
    
    /** CRC Type */
    enum CrcType_t {
        Classic,
        Enhanced
    };
    
    /** Brake Type */
    enum BrakeType_t {
        Normal,
        AutoConfig
    };
    
    /** Frame */
    struct Frame_t {
        FrameType_t FrameType;
        CrcType_t CrcType;
        BrakeType_t Brake;
        uint8_t DataLen;
        uint8_t FrameID;
        uint8_t Data[8];
    };
    
    /** Send a frame on the LIN bus
     *
     * @param ptrFrame pointer to the frame to transmit
     * @return
     *   true on succes,
     *   false on fail
     */
    bool send_frame(Frame_t * ptrFrame);
    
    /** Receive a frame on the LIN bus
     *
     * @param ptrFrame pointer to the frame to receive
     * @return
     *   true on succes,
     *   false on fail
     */
    bool get_rx_data(Frame_t & ptrFrame);
    
    void TickEventHndl(void);
    
    void PinEventHndl(void);

private:
    enum FrameError_t {
        NoError,                                        /* No error */
        NoSlaveResp,                                    /* No slave response, LIN message has timed out */
        FramingErr,                                     /* Framing error */
        CollisionErr,                                   /* Collision error */
        BusVoltage                                      /* Bus voltage to low */
    };
    
    enum FrameStatus_t {
        FStart,
        Break_OK,
        Sync_OK,
        ID_OK,
        Data0,
        Data1,
        Data2,
        Data3,
        Data4,
        Data5,
        Data6,
        Data7,
        CRC
    };
    
    enum ByteStatus_t {
        BStart,
        StartbitEdge,               /* Begin of startbit received */
        StartbitSample,             /* Startbit sample */
        Databit0Edge,               /* Databit edge */
        Databit0Sample,             /* Databit sample */
        Databit1Edge,               /* Databit edge */
        Databit1Sample,             /* Databit sample */
        Databit2Edge,               /* Databit edge */
        Databit2Sample,             /* Databit sample */
        Databit3Edge,               /* Databit edge */
        Databit3Sample,             /* Databit sample */
        Databit4Edge,               /* Databit edge */
        Databit4Sample,             /* Databit sample */
        Databit5Edge,               /* Databit edge */
        Databit5Sample,             /* Databit sample */
        Databit6Edge,               /* Databit edge */
        Databit6Sample,             /* Databit sample */
        Databit7Edge,               /* Databit edge */
        Databit7Sample,             /* Databit sample */
        StopbitEdge,                /* Stopbit edge */
        StopbitSample,              /* Stopbit sample */
        BDone
    };

    volatile DriverStatus_t DriverState;
    volatile FrameError_t LastError;
    volatile FrameStatus_t FrameStatus;
    volatile ByteStatus_t ByteStatus;
    volatile FrameType_t linMessageType;

    uint8_t  breakLength;
    uint8_t  FrameLength;
    
    uint8_t  TXbuf[11];
    uint8_t  TXbufIndex;
    uint8_t  RXbuf[11];
    uint8_t  RXbufIndex;
    uint8_t  RXtimeout;
    uint16_t RXtimeoutSubCTR;
    uint16_t u16HalfBitPeriod;

    DigitalOut  LinOutPin;
    DigitalIn   LinInPin;
    InterruptIn LinIntPin;
    Ticker   MyTicker;
    Timer    MyTimer;
    
    uint8_t parity(uint8_t u8BYTE);

};

#endif /* MBED_LIN_MASTER_H */