Improvements to Olieman's MODI2C library. Supports calls from IRQ.

Dependencies:   FPointer

Dependents:   FreeIMU FreeIMU_external_magnetometer FreeIMU

Fork of MODI2C by Erik -

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