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

Files at this revision

API Documentation at this revision

Comitter:
humlet
Date:
Sat Apr 13 13:37:29 2013 +0000
Child:
1:90455d5bdd8c
Commit message:
intermediate;

Changed in this revision

I2CDriver.cpp Show annotated file Show diff for this revision Revisions of this file
I2CDriver.h Show annotated file Show diff for this revision Revisions of this file
mbed-NXP.lib Show annotated file Show diff for this revision Revisions of this file
mbed-rtos.lib Show annotated file Show diff for this revision Revisions of this file
mbed-src.lib Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/I2CDriver.cpp	Sat Apr 13 13:37:29 2013 +0000
@@ -0,0 +1,102 @@
+#include "I2CDriver.h"
+#include "error.h"
+
+#define ISR2DRV_SIG (1<<0);
+#define DRV_USR_SIG (1<<1);
+
+Channel I2CDriver::channels[2]= {0,0};
+
+
+void I2CDriver::channel_0_ISR()
+{
+    osSignalSet( channels[0].driver, ISR2DRV_SIG);
+    NVIC_DisableIRQ(I2C1_IRQn); //I2C_IRQn
+}
+
+
+void I2CDriver::channel_1_ISR()
+{
+    osSignalSet( channels[1].driver, ISR2DRV_SIG);
+    NVIC_DisableIRQ(I2C2_IRQn); //I2C_IRQn
+}
+
+
+void I2CDriver::threadFun(void* const args)
+{
+    int channelIdx = (int)args;
+    Channel channel;
+    s_channels[channelIdx] = &channel;
+
+    channel.driver = Thread::gettid();
+
+    if(channelIdx==0)NVIC_SetVector(I2C1_IRQn, (uint32_t)I2CDriver::channel_0_ISR);
+    if(channelIdx==1)NVIC_SetVector(I2C2_IRQn, (uint32_t)I2CDriver::channel_1_ISR);
+
+    I2C i2c(c_sda[channelIdx], c_scl[channelIdx]);
+
+    while(1) {
+        osSignalWait(DRV_USR_SIG,0);
+        switch(channels[channel].transfer.cmd) {
+            case START:
+                if(channel.freq!=channel.transfer.freq) i2c.frequency
+                i2c.start();
+                break;
+            case STOP:
+                i2c.stop();
+                break;
+        }
+        s_threads[2]
+    }
+}
+
+
+I2CDriver::I2CDriver(PinName sda, PinName scl)
+{
+    // check pins and determine i2c channel
+    int channel=0;
+    if(sda==sdas[0] && scl==scls[0]) channel=0; // I2C_1
+    else if (sda==sdas[1] && scl==scls[1]) channel=1; //I2C_2
+    else error("I2CDriver: Invalid I2C pinns selected");
+
+    if(s_channels[channel]==0)
+        new Thread(threadFun,(void *)channel,osPriorityRealtime);
+        
+    m_channel = *(s_channel[channel]);
+}
+
+void I2CDriver::sendNwait(){
+    osSignalSet( m_channel.driver, DRV_USR_SIG);
+    osSignalWait(DRV_USR_SIG,osWaitForever);
+}
+
+void I2CDriver::frequency(int hz);
+
+
+int I2CDriver::read(int address, char *data, int length, bool repeated = false);
+
+
+int I2CDriver::read(int ack);
+
+
+int I2CDriver::write(int address, const char *data, int length, bool repeated = false);
+
+
+int I2CDriver::write(int data);
+
+
+void I2CDriver::start(void){
+    lock();
+    m_channel.transfer.freq = _hz;
+    m_channel.transfer.cmd = START;
+    sendNwait();
+    unlock();   
+}
+
+
+void I2CDriver::stop(void){
+    lock();
+    m_channel.transfer.freq = _hz;
+    m_channel.transfer.cmd = STOP;
+    sendNwait();
+    unlock();   
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/I2CDriver.h	Sat Apr 13 13:37:29 2013 +0000
@@ -0,0 +1,152 @@
+#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);
+
+    /** Set the frequency of the I2C interface
+     *
+     *  @param hz The bus frequency in hertz
+     */
+    void frequency(int hz);
+
+    /** 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);
+
+    /** 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 osStatus unlock() {
+        m_channel.mutex.unlock(osWaitForever);
+    }
+
+
+protected:
+
+    enum Command {
+        START,
+        STOP,
+        WRITE_BYTE,
+        WRITE,
+        READ_BYTE,
+        READ,
+        READ_FROM_REGISTER
+    }
+
+    struct Transfer {
+        Command cmd;
+        int freq;
+        int adr;
+        int reg;
+        char* dta;
+        int len;
+        bool rep;
+        int res;
+    }
+
+    struct Channel {
+        osThreadId caller;
+        osThreadId driver;
+        Mutex  mutex;
+        Transfer transfer;
+        int freq;
+    }
+
+    static const PinName c_sda[]= {p9,p28};
+    static const PinName c_scl[]= {p10,p27};
+
+    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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-NXP.lib	Sat Apr 13 13:37:29 2013 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed-NXP/#c9f4bde8b624
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos.lib	Sat Apr 13 13:37:29 2013 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed-rtos/#53e6cccd8782
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-src.lib	Sat Apr 13 13:37:29 2013 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed-src/#6dfdb79ccc45