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

Dependencies:   FPointer

Dependents:   FreeIMU FreeIMU_external_magnetometer FreeIMU

Fork of MODI2C by Erik -

Committer:
Sissors
Date:
Sat Jun 30 14:55:14 2012 +0000
Revision:
0:ff579e7e8efa
Child:
1:eed116eb680a
v1.0

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Sissors 0:ff579e7e8efa 1 /*
Sissors 0:ff579e7e8efa 2
Sissors 0:ff579e7e8efa 3 . .
Sissors 0:ff579e7e8efa 4 / `. .' \
Sissors 0:ff579e7e8efa 5 .---. < > < > .---.
Sissors 0:ff579e7e8efa 6 | \ \ - ~ ~ - / / |
Sissors 0:ff579e7e8efa 7 ~-..-~ ~-..-~
Sissors 0:ff579e7e8efa 8 \~~~\.' `./~~~/
Sissors 0:ff579e7e8efa 9 \__/ \__/
Sissors 0:ff579e7e8efa 10 / .- . \
Sissors 0:ff579e7e8efa 11 _._ _.- .-~ ~-. / } \/~~~/
Sissors 0:ff579e7e8efa 12 _.-'q }~ / } { ; \__/
Sissors 0:ff579e7e8efa 13 {'__, / ( / { / `. ,~~| . .
Sissors 0:ff579e7e8efa 14 `''''='~~-.__( /_ | /- _ `..-' \\ //
Sissors 0:ff579e7e8efa 15 / \ =/ ~~--~~{ ./| ~-. `-..__\\_//_.-'
Sissors 0:ff579e7e8efa 16 { \ +\ \ =\ ( ~ - . _ _ _..---~
Sissors 0:ff579e7e8efa 17 | | { } \ \_\
Sissors 0:ff579e7e8efa 18 '---.o___,' .o___,' "Stegosaurus"
Sissors 0:ff579e7e8efa 19
Sissors 0:ff579e7e8efa 20
Sissors 0:ff579e7e8efa 21 Face it, dinos much cooler than copyright notices.*/
Sissors 0:ff579e7e8efa 22
Sissors 0:ff579e7e8efa 23 #include "mbed.h"
Sissors 0:ff579e7e8efa 24
Sissors 0:ff579e7e8efa 25
Sissors 0:ff579e7e8efa 26 #ifndef MODI2C_H
Sissors 0:ff579e7e8efa 27 #define MODI2C_H
Sissors 0:ff579e7e8efa 28
Sissors 0:ff579e7e8efa 29
Sissors 0:ff579e7e8efa 30 #define I2C_ENABLE 6
Sissors 0:ff579e7e8efa 31 #define I2C_START 5
Sissors 0:ff579e7e8efa 32 #define I2C_STOP 4
Sissors 0:ff579e7e8efa 33 #define I2C_FLAG 3
Sissors 0:ff579e7e8efa 34 #define I2C_ASSERT_ACK 2
Sissors 0:ff579e7e8efa 35
Sissors 0:ff579e7e8efa 36 #define IRQ_I2C_BOTH 0
Sissors 0:ff579e7e8efa 37 #define IRQ_I2C_READ 1
Sissors 0:ff579e7e8efa 38 #define IRQ_I2C_WRITE 2
Sissors 0:ff579e7e8efa 39
Sissors 0:ff579e7e8efa 40
Sissors 0:ff579e7e8efa 41
Sissors 0:ff579e7e8efa 42 #ifndef I2C_BUFFER
Sissors 0:ff579e7e8efa 43 #define I2C_BUFFER 10
Sissors 0:ff579e7e8efa 44 #endif
Sissors 0:ff579e7e8efa 45
Sissors 0:ff579e7e8efa 46
Sissors 0:ff579e7e8efa 47 /** Library that allows interrupt driven communication with I2C devices
Sissors 0:ff579e7e8efa 48 *
Sissors 0:ff579e7e8efa 49 * For now this is all in beta, so if you got weird results while the mbed I2C library works, it is probably my fault.
Sissors 0:ff579e7e8efa 50 * Similar to googles definition of beta, it is unlikely it will ever come out of beta.
Sissors 0:ff579e7e8efa 51 *
Sissors 0:ff579e7e8efa 52 * Example:
Sissors 0:ff579e7e8efa 53 * @code
Sissors 0:ff579e7e8efa 54 * #include "mbed.h"
Sissors 0:ff579e7e8efa 55 * #include "MODI2C.h"
Sissors 0:ff579e7e8efa 56 * #include "MPU6050.h"
Sissors 0:ff579e7e8efa 57 *
Sissors 0:ff579e7e8efa 58 * Serial pc(USBTX, USBRX); // tx, rx
Sissors 0:ff579e7e8efa 59 * MODI2C mod(p9, p10);
Sissors 0:ff579e7e8efa 60 *
Sissors 0:ff579e7e8efa 61 * int main() {
Sissors 0:ff579e7e8efa 62 * char registerAdd = MPU6050_WHO_AM_I_REG;
Sissors 0:ff579e7e8efa 63 * char registerResult;
Sissors 0:ff579e7e8efa 64 * int status;
Sissors 0:ff579e7e8efa 65 *
Sissors 0:ff579e7e8efa 66 * while (1) {
Sissors 0:ff579e7e8efa 67 * mod.write(MPU6050_ADDRESS*2, &registerAdd, 1, true);
Sissors 0:ff579e7e8efa 68 * mod.read_nb(MPU6050_ADDRESS*2, &registerResult, 1, &status);
Sissors 0:ff579e7e8efa 69 *
Sissors 0:ff579e7e8efa 70 * while (!status) wait_us(1);
Sissors 0:ff579e7e8efa 71 * pc.printf("Register holds 0x%02X\n\r", registerResult);
Sissors 0:ff579e7e8efa 72 * wait(2);
Sissors 0:ff579e7e8efa 73 * }
Sissors 0:ff579e7e8efa 74 * }
Sissors 0:ff579e7e8efa 75 * @endcode
Sissors 0:ff579e7e8efa 76 */
Sissors 0:ff579e7e8efa 77 class MODI2C {
Sissors 0:ff579e7e8efa 78 public:
Sissors 0:ff579e7e8efa 79 /**
Sissors 0:ff579e7e8efa 80 * Constructor.
Sissors 0:ff579e7e8efa 81 *
Sissors 0:ff579e7e8efa 82 * @param sda - mbed pin to use for the SDA I2C line.
Sissors 0:ff579e7e8efa 83 * @param scl - mbed pin to use for the SCL I2C line.
Sissors 0:ff579e7e8efa 84 */
Sissors 0:ff579e7e8efa 85 MODI2C(PinName sda, PinName scl);
Sissors 0:ff579e7e8efa 86
Sissors 0:ff579e7e8efa 87 /**
Sissors 0:ff579e7e8efa 88 * Write data on the I2C bus.
Sissors 0:ff579e7e8efa 89 *
Sissors 0:ff579e7e8efa 90 * This function should generally be a drop-in replacement for the standard mbed write function.
Sissors 0:ff579e7e8efa 91 * However this function is completely non-blocking, so it barely takes time. This can cause different behavior.
Sissors 0:ff579e7e8efa 92 * Everything else is similar to read_nb.
Sissors 0:ff579e7e8efa 93 *
Sissors 0:ff579e7e8efa 94 * @param address - I2C address of the slave (7 bit address << 1).
Sissors 0:ff579e7e8efa 95 * @param data - pointer to byte array that holds the data
Sissors 0:ff579e7e8efa 96 * @param length - amount of bytes that need to be sent
Sissors 0:ff579e7e8efa 97 * @param repeated - determines if it should end with a stop condition (default false)
Sissors 0:ff579e7e8efa 98 * @param status - (optional) pointer to integer where the final status code of the I2C transmission is placed. (0x28 is success)
Sissors 0:ff579e7e8efa 99 * @param return - returns zero
Sissors 0:ff579e7e8efa 100 */
Sissors 0:ff579e7e8efa 101 int write(int address, char *data, int length, bool repeated = false, int *status = NULL);
Sissors 0:ff579e7e8efa 102 int write(int address, char *data, int length, int *status);
Sissors 0:ff579e7e8efa 103
Sissors 0:ff579e7e8efa 104 /**
Sissors 0:ff579e7e8efa 105 * Read data non-blocking from the I2C bus.
Sissors 0:ff579e7e8efa 106 *
Sissors 0:ff579e7e8efa 107 * Reads data from the I2C bus, completely non-blocking. Aditionally it will always return zero, since it does
Sissors 0:ff579e7e8efa 108 * not wait to see how the transfer goes. A pointer to an integer can be added as argument which returns the status.
Sissors 0:ff579e7e8efa 109 *
Sissors 0:ff579e7e8efa 110 * @param address - I2C address of the slave (7 bit address << 1).
Sissors 0:ff579e7e8efa 111 * @param data - pointer to byte array where the data will be stored
Sissors 0:ff579e7e8efa 112 * @param length - amount of bytes that need to be received
Sissors 0:ff579e7e8efa 113 * @param repeated - determines if it should end with a stop condition
Sissors 0:ff579e7e8efa 114 * @param status - (optional) pointer to integer where the final status code of the I2C transmission is placed. (0x58 is success)
Sissors 0:ff579e7e8efa 115 * @param return - returns zero
Sissors 0:ff579e7e8efa 116 */
Sissors 0:ff579e7e8efa 117 int read_nb(int address, char *data, int length, bool repeated = false, int *status=NULL);
Sissors 0:ff579e7e8efa 118 int read_nb(int address, char *data, int length, int *status);
Sissors 0:ff579e7e8efa 119
Sissors 0:ff579e7e8efa 120 /**
Sissors 0:ff579e7e8efa 121 * Read data from the I2C bus.
Sissors 0:ff579e7e8efa 122 *
Sissors 0:ff579e7e8efa 123 * This function should should be a drop-in replacement for the standard mbed function.
Sissors 0:ff579e7e8efa 124 *
Sissors 0:ff579e7e8efa 125 * @param address - I2C address of the slave (7 bit address << 1).
Sissors 0:ff579e7e8efa 126 * @param data - pointer to byte array where the data will be stored
Sissors 0:ff579e7e8efa 127 * @param length - amount of bytes that need to be received
Sissors 0:ff579e7e8efa 128 * @param repeated - determines if it should end with a stop condition
Sissors 0:ff579e7e8efa 129 * @param return - returns zero on success, LPC status code on failure
Sissors 0:ff579e7e8efa 130 */
Sissors 0:ff579e7e8efa 131 int read(int address, char *data, int length, bool repeated = false);
Sissors 0:ff579e7e8efa 132
Sissors 0:ff579e7e8efa 133 /**
Sissors 0:ff579e7e8efa 134 * Sets the I2C bus frequency
Sissors 0:ff579e7e8efa 135 *
Sissors 0:ff579e7e8efa 136 * @param hz - the bus frequency in herz
Sissors 0:ff579e7e8efa 137 */
Sissors 0:ff579e7e8efa 138 void frequency(int hz);
Sissors 0:ff579e7e8efa 139
Sissors 0:ff579e7e8efa 140 /**
Sissors 0:ff579e7e8efa 141 * Creates a start condition on the I2C bus
Sissors 0:ff579e7e8efa 142 *
Sissors 0:ff579e7e8efa 143 * If you use this function you probably break something (but mbed also had it public)
Sissors 0:ff579e7e8efa 144 */
Sissors 0:ff579e7e8efa 145 void start ( void );
Sissors 0:ff579e7e8efa 146
Sissors 0:ff579e7e8efa 147 /**
Sissors 0:ff579e7e8efa 148 * Creates a stop condition on the I2C bus
Sissors 0:ff579e7e8efa 149 *
Sissors 0:ff579e7e8efa 150 * If you use this function you probably break something (but mbed also had it public)
Sissors 0:ff579e7e8efa 151 */
Sissors 0:ff579e7e8efa 152 void stop ( void );
Sissors 0:ff579e7e8efa 153
Sissors 0:ff579e7e8efa 154 /**
Sissors 0:ff579e7e8efa 155 * Removes attached function
Sissors 0:ff579e7e8efa 156 */
Sissors 0:ff579e7e8efa 157 void detach( void );
Sissors 0:ff579e7e8efa 158
Sissors 0:ff579e7e8efa 159 /**
Sissors 0:ff579e7e8efa 160 * Calls user function when I2C command is finished
Sissors 0:ff579e7e8efa 161 *
Sissors 0:ff579e7e8efa 162 * @param function - the function to call.
Sissors 0:ff579e7e8efa 163 * @param operation - when to call IRQ: IRQ_I2C_BOTH (default) - IRQ_I2C_READ - IRQ_I2C_WRITE
Sissors 0:ff579e7e8efa 164 */
Sissors 0:ff579e7e8efa 165 void attach(void (*function)(void), int operation = IRQ_I2C_BOTH);
Sissors 0:ff579e7e8efa 166
Sissors 0:ff579e7e8efa 167 /**
Sissors 0:ff579e7e8efa 168 * Calls user function when I2C command is finished
Sissors 0:ff579e7e8efa 169 *
Sissors 0:ff579e7e8efa 170 * @param object - the object to call the function on.
Sissors 0:ff579e7e8efa 171 * @param member - the function to call
Sissors 0:ff579e7e8efa 172 * @param operation - when to call IRQ: IRQ_I2C_BOTH (default) - IRQ_I2C_READ - IRQ_I2C_WRITE
Sissors 0:ff579e7e8efa 173 */
Sissors 0:ff579e7e8efa 174 template<typename T>
Sissors 0:ff579e7e8efa 175 void attach(T *object, void (T::*member)(void), int operation = IRQ_I2C_BOTH);
Sissors 0:ff579e7e8efa 176
Sissors 0:ff579e7e8efa 177 /**
Sissors 0:ff579e7e8efa 178 * Returns the current number of commands in the queue (including one currently being processed)
Sissors 0:ff579e7e8efa 179 *
Sissors 0:ff579e7e8efa 180 * Note that this is the number of commands, not the number of bytes
Sissors 0:ff579e7e8efa 181 *
Sissors 0:ff579e7e8efa 182 * @param return - number of commands in queue
Sissors 0:ff579e7e8efa 183 */
Sissors 0:ff579e7e8efa 184 int getQueue( void );
Sissors 0:ff579e7e8efa 185
Sissors 0:ff579e7e8efa 186
Sissors 0:ff579e7e8efa 187 private:
Sissors 0:ff579e7e8efa 188
Sissors 0:ff579e7e8efa 189 struct I2CData {
Sissors 0:ff579e7e8efa 190 MODI2C *caller;
Sissors 0:ff579e7e8efa 191 char address;
Sissors 0:ff579e7e8efa 192 char *data;
Sissors 0:ff579e7e8efa 193 int length;
Sissors 0:ff579e7e8efa 194 bool repeated;
Sissors 0:ff579e7e8efa 195 int *status;
Sissors 0:ff579e7e8efa 196 };
Sissors 0:ff579e7e8efa 197
Sissors 0:ff579e7e8efa 198 struct I2CBuffer {
Sissors 0:ff579e7e8efa 199 int queue;
Sissors 0:ff579e7e8efa 200 int count;
Sissors 0:ff579e7e8efa 201 I2CData Data[I2C_BUFFER];
Sissors 0:ff579e7e8efa 202 };
Sissors 0:ff579e7e8efa 203
Sissors 0:ff579e7e8efa 204 //Settings:
Sissors 0:ff579e7e8efa 205 int duty;
Sissors 0:ff579e7e8efa 206
Sissors 0:ff579e7e8efa 207 FunctionPointer callback;
Sissors 0:ff579e7e8efa 208 int IRQOp;
Sissors 0:ff579e7e8efa 209 void runUserIRQ( I2CData Data );
Sissors 0:ff579e7e8efa 210
Sissors 0:ff579e7e8efa 211 //Remove later:
Sissors 0:ff579e7e8efa 212 LPC_I2C_TypeDef *I2CMODULE;
Sissors 0:ff579e7e8efa 213
Sissors 0:ff579e7e8efa 214
Sissors 0:ff579e7e8efa 215
Sissors 0:ff579e7e8efa 216 //Whole bunch of static stuff, pretty much everything that is ever called from ISR
Sissors 0:ff579e7e8efa 217 static I2CBuffer Buffer1;
Sissors 0:ff579e7e8efa 218 static I2CBuffer Buffer2;
Sissors 0:ff579e7e8efa 219
Sissors 0:ff579e7e8efa 220 static void IRQHandler(I2CBuffer *Buffer, LPC_I2C_TypeDef *I2CMODULE);
Sissors 0:ff579e7e8efa 221 static void IRQ1Handler(void);
Sissors 0:ff579e7e8efa 222 static void IRQ2Handler(void);
Sissors 0:ff579e7e8efa 223
Sissors 0:ff579e7e8efa 224 static void bufferHandler(LPC_I2C_TypeDef *I2CMODULE);
Sissors 0:ff579e7e8efa 225 static bool addBuffer(I2CData Data, LPC_I2C_TypeDef *I2CMODULE);
Sissors 0:ff579e7e8efa 226 static bool removeBuffer(LPC_I2C_TypeDef *I2CMODULE);
Sissors 0:ff579e7e8efa 227 static void startBuffer(LPC_I2C_TypeDef *I2CMODULE);
Sissors 0:ff579e7e8efa 228
Sissors 0:ff579e7e8efa 229 static int defaultStatus;
Sissors 0:ff579e7e8efa 230
Sissors 0:ff579e7e8efa 231 static void _start(LPC_I2C_TypeDef *I2CMODULE);
Sissors 0:ff579e7e8efa 232 static void _stop(LPC_I2C_TypeDef *I2CMODULE);
Sissors 0:ff579e7e8efa 233 static void _clearISR( LPC_I2C_TypeDef *I2CMODULE );
Sissors 0:ff579e7e8efa 234 static void _setISR( LPC_I2C_TypeDef *I2CMODULE );
Sissors 0:ff579e7e8efa 235
Sissors 0:ff579e7e8efa 236
Sissors 0:ff579e7e8efa 237 void writeSettings( void );
Sissors 0:ff579e7e8efa 238 void writePinState( void );
Sissors 0:ff579e7e8efa 239 void setISR( void );
Sissors 0:ff579e7e8efa 240 void clearISR( void );
Sissors 0:ff579e7e8efa 241
Sissors 0:ff579e7e8efa 242
Sissors 0:ff579e7e8efa 243 DigitalOut led;
Sissors 0:ff579e7e8efa 244
Sissors 0:ff579e7e8efa 245 };
Sissors 0:ff579e7e8efa 246
Sissors 0:ff579e7e8efa 247
Sissors 0:ff579e7e8efa 248 #endif