mFS file system library for EEPROM memory chips.

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers i2c_eeprom.cpp Source File

i2c_eeprom.cpp

Go to the documentation of this file.
00001 /** @file i2c_eeprom.cpp */
00002 /*CPP**************************************************************************
00003  * FILENAME :        i2c_eeprom.cpp                                           *
00004  *                                                                            *
00005  * DESCRIPTION :                                                              *
00006  *       Simple library for external I2C EEEPROM.                             *
00007  *                                                                            *
00008  * AUTHOR :    Olli Vanhoja        START DATE :    2011-02-17                 *
00009  *****************************************************************************/
00010 
00011 #include "mbed.h"
00012 #include "i2c_eeprom.h"
00013 
00014 I2C i2c(p28, p27); /**< I2C */
00015 DigitalOut BusyLed(LED1);  /**< Busy led */
00016 DigitalInOut scl_ext (p20); /**< \attention Clock override pin connected to SCL */
00017 
00018 i2c_eeprom::i2c_eeprom(int hwAddr, int speed)
00019 {
00020     i_i2c_address = hwAddr;
00021     
00022     scl_ext .input();      // Make it input to start with...
00023     scl_ext .mode(PullUp); // ...with pull up
00024         
00025     i2c.frequency(speed);
00026 }
00027 
00028 void i2c_eeprom::write(char *data, uint16_t iAddr, unsigned int n)
00029 {
00030     char *pi2c_data[3]; // Pointers for CW items
00031     char i2c_data[3];   // Final CW
00032     
00033     BusyLed = 1;
00034 
00035     /* Convert address to hi and low byte array
00036      * This is really pointless even though they are
00037      * called pointers it would be lot easier to do this
00038      * conversion without any pointers */
00039     uint16_t *piAddr = &iAddr;
00040     pi2c_data[0] = (char *)piAddr+1;
00041     pi2c_data[1] = (char *)piAddr;
00042     
00043     for (uint16_t i=0; i < n; i++)
00044     {
00045         pi2c_data[2] = &data[i];
00046         
00047         // Apply actual values from pointer
00048         //for (int n=0; n < 3; n++)
00049         //    i2c_data[n] = *pi2c_data[n];
00050         i2c_data[0] = *pi2c_data[0];
00051         i2c_data[1] = *pi2c_data[1];
00052         i2c_data[2] = *pi2c_data[2];
00053         
00054         // Send write command
00055         strwrite:
00056         if(i2c.write(i_i2c_address, i2c_data, 3))
00057         {
00058             autoreset();
00059             goto strwrite;
00060         }
00061         
00062         iAddr++; // increment address counter
00063 
00064         // Wait for ACK        
00065         while(i2c.write(i_i2c_address, NULL, 0)){}
00066     }
00067     
00068     BusyLed = 0;
00069 }
00070 
00071 void i2c_eeprom::read(uint16_t iAddr, uint16_t n, char *out)
00072 {
00073     char *pi2c_data[2]; // Pointers for CW items
00074     char i2c_data[2];   // Final CW
00075     
00076     uint16_t *piAddr = &iAddr;
00077     pi2c_data[0] = (char *)piAddr+1;
00078     pi2c_data[1] = (char *)piAddr;
00079     
00080     BusyLed = 1;
00081     
00082     // Apply actual values from pointer
00083     //for (int i=0; i < 2; i++)
00084     //    i2c_data[i] = *pi2c_data[i];
00085     i2c_data[0] = *pi2c_data[0];
00086     i2c_data[1] = *pi2c_data[1];
00087     
00088     // Send read command
00089     strread:
00090     if(i2c.write(i_i2c_address, i2c_data, 2))
00091     {
00092         autoreset();
00093         goto strread;
00094     }
00095     
00096     if(i2c.read(i_i2c_address, out, n))
00097     {
00098         autoreset();
00099         goto strread;
00100     }
00101     
00102     BusyLed = 0;
00103 }
00104 
00105 void i2c_eeprom::autoreset()
00106 {
00107     i2c.start();
00108     scl_ext  = 0;          // Setup override pin to pull clock low
00109     scl_ext .input();      // Make it input to start with...
00110     scl_ext .mode(PullUp); // ...with pull up
00111     wait(0.00005);        // Pause after stop
00112     scl_ext .output();     // Override clock pin low
00113     wait(0.00005);        // Pause
00114     scl_ext .input();      // Remove override...
00115     scl_ext .mode(PullUp); // ...with pull up
00116     wait(0.00005);        // Pause again
00117     i2c.start();
00118     i2c.stop();
00119 }