Interrupt based I2C functionality for the LPC1768. (If you want the other one, send a PM and I might make it). Also adds buffer functionality to the I2C bus.

Dependents:   Algoritmo_Fuzzy FlyBed1 FlyBedLight

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MODI2C.h Source File

MODI2C.h

00001 /* 
00002 
00003                             .       .
00004                            / `.   .' \
00005                    .---.  <    > <    >  .---.
00006                    |    \  \ - ~ ~ - /  /    |
00007                     ~-..-~             ~-..-~
00008                 \~~~\.'                    `./~~~/
00009                  \__/                        \__/
00010                   /                  .-    .  \
00011            _._ _.-    .-~ ~-.       /       }   \/~~~/
00012        _.-'q  }~     /       }     {        ;    \__/
00013       {'__,  /      (       /      {       /      `. ,~~|   .     .
00014        `''''='~~-.__(      /_      |      /- _      `..-'   \\   //
00015                    / \   =/  ~~--~~{    ./|    ~-.     `-..__\\_//_.-'
00016                   {   \  +\         \  =\ (        ~ - . _ _ _..---~
00017                   |  | {   }         \   \_\
00018                  '---.o___,'       .o___,'     "Stegosaurus"
00019 
00020 
00021 Face it, dinos much cooler than copyright notices.*/
00022 
00023 #include "mbed.h"
00024 
00025 
00026 #ifndef MODI2C_H
00027 #define MODI2C_H
00028 
00029 
00030 #define I2C_ENABLE          6
00031 #define I2C_START           5
00032 #define I2C_STOP            4
00033 #define I2C_FLAG            3
00034 #define I2C_ASSERT_ACK      2
00035 
00036 #define IRQ_I2C_BOTH        0
00037 #define IRQ_I2C_READ        1
00038 #define IRQ_I2C_WRITE       2
00039 
00040 
00041 
00042 #ifndef I2C_BUFFER
00043 #define I2C_BUFFER          10
00044 #endif
00045 
00046 
00047 /** Library that allows interrupt driven communication with I2C devices
00048   *
00049   * For now this is all in beta, so if you got weird results while the mbed I2C library works, it is probably my fault.
00050   * Similar to googles definition of beta, it is unlikely it will ever come out of beta.
00051   *
00052   * Example:
00053   * @code
00054   * #include "mbed.h"
00055   * #include "MODI2C.h"
00056   * #include "MPU6050.h"
00057   * 
00058   * Serial pc(USBTX, USBRX); // tx, rx
00059   * MODI2C mod(p9, p10);
00060   * 
00061   * int main() {
00062   *     char registerAdd = MPU6050_WHO_AM_I_REG;
00063   *     char registerResult;
00064   *     int status;
00065   * 
00066   *     while (1) {
00067   *         mod.write(MPU6050_ADDRESS*2, &registerAdd, 1, true);
00068   *         mod.read_nb(MPU6050_ADDRESS*2, &registerResult, 1, &status);
00069   * 
00070   *         while (!status) wait_us(1);
00071   *         pc.printf("Register holds 0x%02X\n\r", registerResult);
00072   *         wait(2);
00073   *     }
00074   * }
00075   * @endcode
00076   */
00077 class MODI2C {
00078 public:
00079     /**
00080     * Constructor.
00081     *
00082     * @param sda - mbed pin to use for the SDA I2C line.
00083     * @param scl - mbed pin to use for the SCL I2C line.
00084     */
00085     MODI2C(PinName sda, PinName scl);
00086 
00087     /**
00088     * Write data on the I2C bus.
00089     *
00090     * This function should generally be a drop-in replacement for the standard mbed write function.
00091     * However this function is completely non-blocking, so it barely takes time. This can cause different behavior.
00092     * Everything else is similar to read_nb.
00093     *
00094     * @param address - I2C address of the slave (7 bit address << 1).
00095     * @param data - pointer to byte array that holds the data
00096     * @param length - amount of bytes that need to be sent
00097     * @param repeated - determines if it should end with a stop condition (default false)
00098     * @param status - (optional) pointer to integer where the final status code of the I2C transmission is placed. (0x28 is success)
00099     * @param return - returns zero
00100     */
00101     int write(int address, char *data, int length, bool repeated = false, int *status = NULL);
00102     int write(int address, char *data, int length, int *status);
00103 
00104     /**
00105     * Read data non-blocking from the I2C bus.
00106     *
00107     * Reads data from the I2C bus, completely non-blocking. Aditionally it will always return zero, since it does
00108     * not wait to see how the transfer goes. A pointer to an integer can be added as argument which returns the status.
00109     *
00110     * @param address - I2C address of the slave (7 bit address << 1).
00111     * @param data - pointer to byte array where the data will be stored
00112     * @param length - amount of bytes that need to be received
00113     * @param repeated - determines if it should end with a stop condition
00114     * @param status - (optional) pointer to integer where the final status code of the I2C transmission is placed. (0x58 is success)
00115     * @param return - returns zero
00116     */
00117     int read_nb(int address, char *data, int length, bool repeated = false, int *status=NULL);
00118     int read_nb(int address, char *data, int length, int *status);
00119     
00120     /**
00121     * Read data from the I2C bus.
00122     *
00123     * This function should should be a drop-in replacement for the standard mbed function.
00124     *
00125     * @param address - I2C address of the slave (7 bit address << 1).
00126     * @param data - pointer to byte array where the data will be stored
00127     * @param length - amount of bytes that need to be received
00128     * @param repeated - determines if it should end with a stop condition
00129     * @param return - returns zero on success, LPC status code on failure
00130     */
00131     int read(int address, char *data, int length, bool repeated = false);
00132 
00133     /**
00134     * Sets the I2C bus frequency
00135     *
00136     * @param hz - the bus frequency in herz
00137     */
00138     void frequency(int hz);
00139 
00140     /**
00141     * Creates a start condition on the I2C bus
00142     *
00143     * If you use this function you probably break something (but mbed also had it public)
00144     */
00145     void start ( void );
00146 
00147     /**
00148     * Creates a stop condition on the I2C bus
00149     *
00150     * If you use this function you probably break something (but mbed also had it public)
00151     */
00152     void stop ( void );
00153     
00154     /**
00155     * Removes attached function
00156     */
00157     void detach( void );
00158     
00159     /**
00160     * Calls user function when I2C command is finished
00161     *
00162     * @param function - the function to call.
00163     * @param operation - when to call IRQ: IRQ_I2C_BOTH (default) - IRQ_I2C_READ - IRQ_I2C_WRITE
00164     */
00165     void attach(void (*function)(void), int operation = IRQ_I2C_BOTH);
00166     
00167     /**
00168     * Calls user function when I2C command is finished
00169     *
00170     * @param object - the object to call the function on.
00171     * @param member - the function to call
00172     * @param operation - when to call IRQ: IRQ_I2C_BOTH (default) - IRQ_I2C_READ - IRQ_I2C_WRITE
00173     */
00174     template<typename T>
00175         void attach(T *object, void (T::*member)(void), int operation = IRQ_I2C_BOTH);
00176         
00177     /**
00178     * Returns the current number of commands in the queue (including one currently being processed)
00179     *
00180     * Note that this is the number of commands, not the number of bytes
00181     *
00182     * @param return - number of commands in queue
00183     */
00184     int getQueue( void );
00185 
00186 
00187 private:
00188 
00189     struct I2CData {
00190         MODI2C *caller;
00191         char address;
00192         char *data;
00193         int  length;
00194         bool repeated;
00195         int *status;
00196     };
00197     
00198     struct I2CBuffer {
00199         int queue;
00200         int count;
00201         I2CData Data[I2C_BUFFER];
00202         };
00203         
00204     //Settings:
00205     int duty;
00206     
00207     FunctionPointer callback;
00208     int IRQOp;   
00209     void runUserIRQ( I2CData Data );
00210 
00211     //Remove later:
00212     LPC_I2C_TypeDef *I2CMODULE;
00213 
00214     
00215 
00216     //Whole bunch of static stuff, pretty much everything that is ever called from ISR
00217     static I2CBuffer Buffer1;
00218     static I2CBuffer Buffer2;
00219     
00220     static void IRQHandler(I2CBuffer *Buffer, LPC_I2C_TypeDef *I2CMODULE);
00221     static void IRQ1Handler(void);
00222     static void IRQ2Handler(void);
00223     
00224     static void bufferHandler(LPC_I2C_TypeDef *I2CMODULE);
00225     static bool addBuffer(I2CData Data, LPC_I2C_TypeDef *I2CMODULE);
00226     static bool removeBuffer(LPC_I2C_TypeDef *I2CMODULE);
00227     static void startBuffer(LPC_I2C_TypeDef *I2CMODULE);
00228 
00229     static int defaultStatus;
00230     
00231     static void _start(LPC_I2C_TypeDef *I2CMODULE);
00232     static void _stop(LPC_I2C_TypeDef *I2CMODULE);
00233     static void _clearISR( LPC_I2C_TypeDef *I2CMODULE );
00234     static void _setISR( LPC_I2C_TypeDef *I2CMODULE );
00235 
00236 
00237     void writeSettings( void );
00238     void writePinState( void );
00239     void setISR( void );
00240     void clearISR( void );
00241 
00242 
00243     DigitalOut led;
00244 
00245 };
00246 
00247 
00248 #endif