Improvements to Olieman's MODI2C library. Supports calls from IRQ.
Dependents: FreeIMU FreeIMU_external_magnetometer FreeIMU
Fork of MODI2C by
MODI2C.h@0:ff579e7e8efa, 2012-06-30 (annotated)
- 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?
User | Revision | Line number | New 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, ®isterAdd, 1, true); |
Sissors | 0:ff579e7e8efa | 68 | * mod.read_nb(MPU6050_ADDRESS*2, ®isterResult, 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 |