mFS file system library for EEPROM memory chips.

i2c_eeprom.cpp

Committer:
HBP
Date:
2011-02-21
Revision:
5:a0fe74dce80d
Parent:
0:cbf45dde2b49
Child:
7:5ac5121bb4e0

File content as of revision 5:a0fe74dce80d:

/** @file i2c_eeprom.cpp */
/*CPP**************************************************************************
* FILENAME :        i2c_eeprom.cpp                                            *
*                                                                             *
* DESCRIPTION :                                                               *
*       Simple library for external I2C EEEPROM.                              *
*                                                                             *
* AUTHOR :    Olli Vanhoja        START DATE :    2011-02-17                  *
******************************************************************************/

#include "mbed.h"
#include "i2c_eeprom.h"

I2C i2c(p28, p27);
DigitalOut BusyLed(LED1);
DigitalInOut scl_ext(p20); /** \attention Clock override pin connected to SCL */

i2c_eeprom::i2c_eeprom(int hwAddr, int speed)
{
    i_i2c_address = hwAddr;
    
    scl_ext.input();      // Make it input to start with...
    scl_ext.mode(PullUp); // ...with pull up
        
    i2c.frequency(speed);
}

void i2c_eeprom::write(char *data, uint16 iAddr, unsigned int n)
{
    char *pi2c_data[3]; // Pointers for CW items
    char i2c_data[3];   // Final CW
    
    BusyLed = 1;

    /* Convert address to hi and low byte array
     * This is really pointless even though they are
     * called pointers it would be lot easier to do this
     * conversion without any pointers */
    uint16 *piAddr = &iAddr;
    pi2c_data[0] = (char *)piAddr+1;
    pi2c_data[1] = (char *)piAddr;
    
    for (uint16 i=0; i < n; i++)
    {
        pi2c_data[2] = &data[i];
        
        // Apply actual values from pointer
        //for (int n=0; n < 3; n++)
        //    i2c_data[n] = *pi2c_data[n];
        i2c_data[0] = *pi2c_data[0];
        i2c_data[1] = *pi2c_data[1];
        i2c_data[2] = *pi2c_data[2];
        
        // Send write command
        if(i2c.write(i_i2c_address, i2c_data, 3))
            error("Write failed!\n\r");
        
        iAddr++; // increment address counter

        // Wait for ACK        
        while(i2c.write(i_i2c_address, NULL, 0)){}
    }
    
    BusyLed = 0;
}

void i2c_eeprom::read(uint16 iAddr, uint16 n, char *out)
{
    char *pi2c_data[2]; // Pointers for CW items
    char i2c_data[2];   // Final CW
    
    uint16 *piAddr = &iAddr;
    pi2c_data[0] = (char *)piAddr+1;
    pi2c_data[1] = (char *)piAddr;
    
    BusyLed = 1;
    
    // Apply actual values from pointer
    //for (int i=0; i < 2; i++)
    //    i2c_data[i] = *pi2c_data[i];
    i2c_data[0] = *pi2c_data[0];
    i2c_data[1] = *pi2c_data[1];
    
    // Send read command
    srread:
    if(i2c.write(i_i2c_address, i2c_data, 2))
    {
        i2c.start();
        scl_ext = 0;          // Setup override pin to pull clock low
        scl_ext.input();      // Make it input to start with...
        scl_ext.mode(PullUp); // ...with pull up
        wait(0.00005);        // Pause after stop
        scl_ext.output();     // Override clock pin low
        wait(0.00005);        // Pause
        scl_ext.input();      // Remove override...
        scl_ext.mode(PullUp); // ...with pull up
        wait(0.00005);        // Pause again

        i2c.start();
        i2c.stop();
        goto srread;
    }
    
    if(i2c.read(i_i2c_address, out, n))
        error("Read failed!\n\r");
    
    BusyLed = 0;
}