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

Dependencies:   FPointer

Dependents:   FreeIMU FreeIMU_external_magnetometer FreeIMU

Fork of MODI2C by Erik -

Committer:
tyftyftyf
Date:
Sat Nov 09 08:59:02 2013 +0000
Revision:
1:eed116eb680a
Parent:
0:ff579e7e8efa
Child:
3:eb8120aa14fd
Based on Olieman's MODI2C library. Enables per-request interrupt config. The library can now be used in an interrupt.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
tyftyftyf 1:eed116eb680a 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"
tyftyftyf 1:eed116eb680a 24 #include "FPointer.h"
tyftyftyf 1:eed116eb680a 25 #include "rtos.h"
Sissors 0:ff579e7e8efa 26
Sissors 0:ff579e7e8efa 27 #ifndef MODI2C_H
Sissors 0:ff579e7e8efa 28 #define MODI2C_H
Sissors 0:ff579e7e8efa 29
Sissors 0:ff579e7e8efa 30
Sissors 0:ff579e7e8efa 31 #define I2C_ENABLE 6
Sissors 0:ff579e7e8efa 32 #define I2C_START 5
Sissors 0:ff579e7e8efa 33 #define I2C_STOP 4
Sissors 0:ff579e7e8efa 34 #define I2C_FLAG 3
Sissors 0:ff579e7e8efa 35 #define I2C_ASSERT_ACK 2
Sissors 0:ff579e7e8efa 36
tyftyftyf 1:eed116eb680a 37 #define IRQ_I2C_BOTH 1
tyftyftyf 1:eed116eb680a 38 #define IRQ_I2C_READ 2
tyftyftyf 1:eed116eb680a 39 #define IRQ_I2C_WRITE 3
Sissors 0:ff579e7e8efa 40
Sissors 0:ff579e7e8efa 41
Sissors 0:ff579e7e8efa 42
Sissors 0:ff579e7e8efa 43 #ifndef I2C_BUFFER
tyftyftyf 1:eed116eb680a 44 #define I2C_BUFFER 20
Sissors 0:ff579e7e8efa 45 #endif
Sissors 0:ff579e7e8efa 46
Sissors 0:ff579e7e8efa 47
Sissors 0:ff579e7e8efa 48 /** Library that allows interrupt driven communication with I2C devices
Sissors 0:ff579e7e8efa 49 *
Sissors 0:ff579e7e8efa 50 * 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 51 * Similar to googles definition of beta, it is unlikely it will ever come out of beta.
Sissors 0:ff579e7e8efa 52 *
Sissors 0:ff579e7e8efa 53 * Example:
Sissors 0:ff579e7e8efa 54 * @code
Sissors 0:ff579e7e8efa 55 * #include "mbed.h"
Sissors 0:ff579e7e8efa 56 * #include "MODI2C.h"
Sissors 0:ff579e7e8efa 57 * #include "MPU6050.h"
tyftyftyf 1:eed116eb680a 58 *
Sissors 0:ff579e7e8efa 59 * Serial pc(USBTX, USBRX); // tx, rx
Sissors 0:ff579e7e8efa 60 * MODI2C mod(p9, p10);
tyftyftyf 1:eed116eb680a 61 *
Sissors 0:ff579e7e8efa 62 * int main() {
Sissors 0:ff579e7e8efa 63 * char registerAdd = MPU6050_WHO_AM_I_REG;
Sissors 0:ff579e7e8efa 64 * char registerResult;
Sissors 0:ff579e7e8efa 65 * int status;
tyftyftyf 1:eed116eb680a 66 *
Sissors 0:ff579e7e8efa 67 * while (1) {
Sissors 0:ff579e7e8efa 68 * mod.write(MPU6050_ADDRESS*2, &registerAdd, 1, true);
Sissors 0:ff579e7e8efa 69 * mod.read_nb(MPU6050_ADDRESS*2, &registerResult, 1, &status);
tyftyftyf 1:eed116eb680a 70 *
Sissors 0:ff579e7e8efa 71 * while (!status) wait_us(1);
Sissors 0:ff579e7e8efa 72 * pc.printf("Register holds 0x%02X\n\r", registerResult);
Sissors 0:ff579e7e8efa 73 * wait(2);
Sissors 0:ff579e7e8efa 74 * }
Sissors 0:ff579e7e8efa 75 * }
Sissors 0:ff579e7e8efa 76 * @endcode
Sissors 0:ff579e7e8efa 77 */
tyftyftyf 1:eed116eb680a 78 class MODI2C
tyftyftyf 1:eed116eb680a 79 {
Sissors 0:ff579e7e8efa 80 public:
Sissors 0:ff579e7e8efa 81 /**
Sissors 0:ff579e7e8efa 82 * Constructor.
Sissors 0:ff579e7e8efa 83 *
Sissors 0:ff579e7e8efa 84 * @param sda - mbed pin to use for the SDA I2C line.
Sissors 0:ff579e7e8efa 85 * @param scl - mbed pin to use for the SCL I2C line.
Sissors 0:ff579e7e8efa 86 */
Sissors 0:ff579e7e8efa 87 MODI2C(PinName sda, PinName scl);
Sissors 0:ff579e7e8efa 88
Sissors 0:ff579e7e8efa 89 /**
Sissors 0:ff579e7e8efa 90 * Write data on the I2C bus.
Sissors 0:ff579e7e8efa 91 *
Sissors 0:ff579e7e8efa 92 * This function should generally be a drop-in replacement for the standard mbed write function.
Sissors 0:ff579e7e8efa 93 * However this function is completely non-blocking, so it barely takes time. This can cause different behavior.
Sissors 0:ff579e7e8efa 94 * Everything else is similar to read_nb.
Sissors 0:ff579e7e8efa 95 *
Sissors 0:ff579e7e8efa 96 * @param address - I2C address of the slave (7 bit address << 1).
Sissors 0:ff579e7e8efa 97 * @param data - pointer to byte array that holds the data
Sissors 0:ff579e7e8efa 98 * @param length - amount of bytes that need to be sent
Sissors 0:ff579e7e8efa 99 * @param repeated - determines if it should end with a stop condition (default false)
Sissors 0:ff579e7e8efa 100 * @param status - (optional) pointer to integer where the final status code of the I2C transmission is placed. (0x28 is success)
Sissors 0:ff579e7e8efa 101 * @param return - returns zero
Sissors 0:ff579e7e8efa 102 */
tyftyftyf 1:eed116eb680a 103 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);
Sissors 0:ff579e7e8efa 104 int write(int address, char *data, int length, int *status);
tyftyftyf 1:eed116eb680a 105 int write(int address, char *data, int length, bool repeated);
Sissors 0:ff579e7e8efa 106
Sissors 0:ff579e7e8efa 107 /**
Sissors 0:ff579e7e8efa 108 * Read data non-blocking from the I2C bus.
Sissors 0:ff579e7e8efa 109 *
Sissors 0:ff579e7e8efa 110 * Reads data from the I2C bus, completely non-blocking. Aditionally it will always return zero, since it does
Sissors 0:ff579e7e8efa 111 * 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 112 *
Sissors 0:ff579e7e8efa 113 * @param address - I2C address of the slave (7 bit address << 1).
Sissors 0:ff579e7e8efa 114 * @param data - pointer to byte array where the data will be stored
Sissors 0:ff579e7e8efa 115 * @param length - amount of bytes that need to be received
Sissors 0:ff579e7e8efa 116 * @param repeated - determines if it should end with a stop condition
Sissors 0:ff579e7e8efa 117 * @param status - (optional) pointer to integer where the final status code of the I2C transmission is placed. (0x58 is success)
Sissors 0:ff579e7e8efa 118 * @param return - returns zero
Sissors 0:ff579e7e8efa 119 */
tyftyftyf 1:eed116eb680a 120 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);
tyftyftyf 1:eed116eb680a 121
Sissors 0:ff579e7e8efa 122 /**
Sissors 0:ff579e7e8efa 123 * Read data from the I2C bus.
Sissors 0:ff579e7e8efa 124 *
Sissors 0:ff579e7e8efa 125 * This function should should be a drop-in replacement for the standard mbed function.
Sissors 0:ff579e7e8efa 126 *
Sissors 0:ff579e7e8efa 127 * @param address - I2C address of the slave (7 bit address << 1).
Sissors 0:ff579e7e8efa 128 * @param data - pointer to byte array where the data will be stored
Sissors 0:ff579e7e8efa 129 * @param length - amount of bytes that need to be received
Sissors 0:ff579e7e8efa 130 * @param repeated - determines if it should end with a stop condition
Sissors 0:ff579e7e8efa 131 * @param return - returns zero on success, LPC status code on failure
Sissors 0:ff579e7e8efa 132 */
Sissors 0:ff579e7e8efa 133 int read(int address, char *data, int length, bool repeated = false);
Sissors 0:ff579e7e8efa 134
Sissors 0:ff579e7e8efa 135 /**
Sissors 0:ff579e7e8efa 136 * Sets the I2C bus frequency
Sissors 0:ff579e7e8efa 137 *
Sissors 0:ff579e7e8efa 138 * @param hz - the bus frequency in herz
Sissors 0:ff579e7e8efa 139 */
Sissors 0:ff579e7e8efa 140 void frequency(int hz);
Sissors 0:ff579e7e8efa 141
Sissors 0:ff579e7e8efa 142 /**
Sissors 0:ff579e7e8efa 143 * Creates a start condition on the I2C bus
Sissors 0:ff579e7e8efa 144 *
Sissors 0:ff579e7e8efa 145 * If you use this function you probably break something (but mbed also had it public)
Sissors 0:ff579e7e8efa 146 */
Sissors 0:ff579e7e8efa 147 void start ( void );
Sissors 0:ff579e7e8efa 148
Sissors 0:ff579e7e8efa 149 /**
Sissors 0:ff579e7e8efa 150 * Creates a stop condition on the I2C bus
Sissors 0:ff579e7e8efa 151 *
Sissors 0:ff579e7e8efa 152 * If you use this function you probably break something (but mbed also had it public)
Sissors 0:ff579e7e8efa 153 */
Sissors 0:ff579e7e8efa 154 void stop ( void );
Sissors 0:ff579e7e8efa 155
Sissors 0:ff579e7e8efa 156 struct I2CData {
Sissors 0:ff579e7e8efa 157 MODI2C *caller;
Sissors 0:ff579e7e8efa 158 char address;
Sissors 0:ff579e7e8efa 159 char *data;
Sissors 0:ff579e7e8efa 160 int length;
Sissors 0:ff579e7e8efa 161 bool repeated;
Sissors 0:ff579e7e8efa 162 int *status;
tyftyftyf 1:eed116eb680a 163 FPointer callback;
tyftyftyf 1:eed116eb680a 164 uint32_t pass_to_irq;
tyftyftyf 1:eed116eb680a 165 int IRQOp;
tyftyftyf 1:eed116eb680a 166 volatile char *monitor_addr;
Sissors 0:ff579e7e8efa 167 };
tyftyftyf 1:eed116eb680a 168
tyftyftyf 1:eed116eb680a 169 private:
Sissors 0:ff579e7e8efa 170 struct I2CBuffer {
tyftyftyf 1:eed116eb680a 171 //volatile int queue;
Sissors 0:ff579e7e8efa 172 int count;
tyftyftyf 1:eed116eb680a 173 volatile I2CData *curr;
tyftyftyf 1:eed116eb680a 174 MemoryPool<I2CData, I2C_BUFFER> pool;
tyftyftyf 1:eed116eb680a 175 //I2CData Data[I2C_BUFFER];
tyftyftyf 1:eed116eb680a 176 Queue<I2CData, I2C_BUFFER> queue;
tyftyftyf 1:eed116eb680a 177 volatile bool crit_flag_isr;
tyftyftyf 1:eed116eb680a 178 volatile bool crit_flag;
Sissors 0:ff579e7e8efa 179
tyftyftyf 1:eed116eb680a 180 I2CBuffer():count(0),curr(NULL),crit_flag_isr(false),crit_flag(false){}
tyftyftyf 1:eed116eb680a 181 };
tyftyftyf 1:eed116eb680a 182
Sissors 0:ff579e7e8efa 183 //Settings:
Sissors 0:ff579e7e8efa 184 int duty;
tyftyftyf 1:eed116eb680a 185
tyftyftyf 1:eed116eb680a 186 void runUserIRQ( I2CData *Data );
Sissors 0:ff579e7e8efa 187
Sissors 0:ff579e7e8efa 188 //Remove later:
Sissors 0:ff579e7e8efa 189 LPC_I2C_TypeDef *I2CMODULE;
Sissors 0:ff579e7e8efa 190
Sissors 0:ff579e7e8efa 191 //Whole bunch of static stuff, pretty much everything that is ever called from ISR
Sissors 0:ff579e7e8efa 192 static I2CBuffer Buffer1;
Sissors 0:ff579e7e8efa 193 static I2CBuffer Buffer2;
tyftyftyf 1:eed116eb680a 194
Sissors 0:ff579e7e8efa 195 static void IRQHandler(I2CBuffer *Buffer, LPC_I2C_TypeDef *I2CMODULE);
Sissors 0:ff579e7e8efa 196 static void IRQ1Handler(void);
Sissors 0:ff579e7e8efa 197 static void IRQ2Handler(void);
tyftyftyf 1:eed116eb680a 198
Sissors 0:ff579e7e8efa 199 static void bufferHandler(LPC_I2C_TypeDef *I2CMODULE);
tyftyftyf 1:eed116eb680a 200 static bool addBuffer(I2CData *Data, LPC_I2C_TypeDef *I2CMODULE);
Sissors 0:ff579e7e8efa 201 static void startBuffer(LPC_I2C_TypeDef *I2CMODULE);
Sissors 0:ff579e7e8efa 202
Sissors 0:ff579e7e8efa 203 static int defaultStatus;
tyftyftyf 1:eed116eb680a 204
Sissors 0:ff579e7e8efa 205 static void _start(LPC_I2C_TypeDef *I2CMODULE);
Sissors 0:ff579e7e8efa 206 static void _stop(LPC_I2C_TypeDef *I2CMODULE);
Sissors 0:ff579e7e8efa 207 static void _clearISR( LPC_I2C_TypeDef *I2CMODULE );
Sissors 0:ff579e7e8efa 208 static void _setISR( LPC_I2C_TypeDef *I2CMODULE );
Sissors 0:ff579e7e8efa 209
Sissors 0:ff579e7e8efa 210
Sissors 0:ff579e7e8efa 211 void writeSettings( void );
Sissors 0:ff579e7e8efa 212 void writePinState( void );
Sissors 0:ff579e7e8efa 213 void setISR( void );
Sissors 0:ff579e7e8efa 214 void clearISR( void );
Sissors 0:ff579e7e8efa 215
Sissors 0:ff579e7e8efa 216
Sissors 0:ff579e7e8efa 217 DigitalOut led;
Sissors 0:ff579e7e8efa 218
Sissors 0:ff579e7e8efa 219 };
Sissors 0:ff579e7e8efa 220
Sissors 0:ff579e7e8efa 221
Sissors 0:ff579e7e8efa 222 #endif