I2CRTOS Driver by Helmut Schmücker. Removed included mbed-rtos library to prevent multiple definition. Make sure to include mbed-rtos library in your program!

Fork of I2cRtosDriver by Helmut Schmücker

I2CDriver.h

Committer:
humlet
Date:
2013-04-14
Revision:
1:90455d5bdd8c
Parent:
0:13c962fecb13
Child:
2:514105beb343

File content as of revision 1:90455d5bdd8c:

#ifndef I2CDRIVER_H
#define I2CDRIVER_H

#include "stdint.h"

#include "I2C.h"

#include "Thread.h"
#include "Semaphore.h"
#include "Mutex.h"

namespace mbed
{

class I2CDriver : protected I2C
{
public:
    using I2C::RxStatus;
    using I2C::Acknowledge;
    using I2C::frequency;

    /** Create an I2C Master interface, connected to the specified pins
     *
     *  @param sda I2C data line pin
     *  @param scl I2C clock line pin
     */
    I2CDriver(PinName sda, PinName scl);

    /** Read from an I2C slave
     *
     * Performs a complete read transaction. The bottom bit of
     * the address is forced to 1 to indicate a read.
     *
     *  @param address 8-bit I2C slave address [ addr | 1 ]
     *  @param data Pointer to the byte-array to read data in to
     *  @param length Number of bytes to read
     *  @param repeated Repeated start, true - don't send stop at end
     *
     *  @returns
     *       0 on success (ack),
     *   non-0 on failure (nack)
     */
    int read(int address, char *data, int length, bool repeated = false);

    int read(int address, uint8_t regist, char *data, int length, bool repeated = false);

    /** Read a single byte from the I2C bus
     *
     *  @param ack indicates if the byte is to be acknowledged (1 = acknowledge)
     *
     *  @returns
     *    the byte read
     */
    int read(int ack);

    /** Write to an I2C slave
     *
     * Performs a complete write transaction. The bottom bit of
     * the address is forced to 0 to indicate a write.
     *
     *  @param address 8-bit I2C slave address [ addr | 0 ]
     *  @param data Pointer to the byte-array data to send
     *  @param length Number of bytes to send
     *  @param repeated Repeated start, true - do not send stop at end
     *
     *  @returns
     *       0 on success (ack),
     *   non-0 on failure (nack)
     */
    int write(int address, const char *data, int length, bool repeated = false);

    /** Write single byte out on the I2C bus
     *
     *  @param data data to write out on bus
     *
     *  @returns
     *    '1' if an ACK was received,
     *    '0' otherwise
     */
    int write(int data);

    /// Creates a start condition on the I2C bus
    void start(void);

    ///Creates a stop condition on the I2C bus
    void stop(void);

    /// Wait until the i2c driver becomes available.
     void lock()  {
        // if one and the same thread can lock twice, but then it needs also to unlock twice.
        // exactly what we need here
        m_channel->mutex.lock(osWaitForever);
    }

    /// Unlock the driver that has previously been locked by the same thread
     void unlock() {
        m_channel->mutex.unlock();
    }


protected:

    enum Command {
        START,
        STOP,
        WRITE_BYTE,
        WRITE,
        READ_BYTE,
        READ,
        READ_FROM_REGISTER
    };

    struct Transfer {
        osThreadId caller;
        Command cmd;
        int freq;
        int adr;
        uint8_t reg;
        char* dta;
        const char* wdta;
        int len;
        int ack;
        bool rep;
        int ret;
    };

    struct Channel {
        volatile osThreadId driver;
        rtos::Mutex  mutex;
        volatile Transfer transfer;
        volatile int freq;
    };

    static const PinName c_sdas[2];
    static const PinName c_scls[2];

     static Channel* s_channels[2];

     Channel* m_channel;

    static void channel_0_ISR();
    static void channel_1_ISR();

    static void threadFun(void const *args);

    void sendNwait();

};
}
#endif