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:
Wed Mar 28 21:48:20 2018 +0000
Revision:
5:fa0cca8e28b6
Parent:
4:52d01d39ab28
wip

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 3:eb8120aa14fd 44 #define I2C_BUFFER 10
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
tyftyftyf 4:52d01d39ab28 99 * @param function - pointer to a callback function of the form "uint32_t func(uint32_t)"
tyftyftyf 4:52d01d39ab28 100 * @param pass_to_irq - what to pass to the callback function as parameter
Sissors 0:ff579e7e8efa 101 * @param repeated - determines if it should end with a stop condition (default false)
Sissors 0:ff579e7e8efa 102 * @param status - (optional) pointer to integer where the final status code of the I2C transmission is placed. (0x28 is success)
Sissors 0:ff579e7e8efa 103 * @param return - returns zero
Sissors 0:ff579e7e8efa 104 */
tyftyftyf 1:eed116eb680a 105 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 106 int write(int address, char *data, int length, int *status);
tyftyftyf 1:eed116eb680a 107 int write(int address, char *data, int length, bool repeated);
Sissors 0:ff579e7e8efa 108
Sissors 0:ff579e7e8efa 109 /**
Sissors 0:ff579e7e8efa 110 * Read data non-blocking from the I2C bus.
Sissors 0:ff579e7e8efa 111 *
Sissors 0:ff579e7e8efa 112 * Reads data from the I2C bus, completely non-blocking. Aditionally it will always return zero, since it does
Sissors 0:ff579e7e8efa 113 * 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 114 *
Sissors 0:ff579e7e8efa 115 * @param address - I2C address of the slave (7 bit address << 1).
Sissors 0:ff579e7e8efa 116 * @param data - pointer to byte array where the data will be stored
Sissors 0:ff579e7e8efa 117 * @param length - amount of bytes that need to be received
tyftyftyf 4:52d01d39ab28 118 * @param function - pointer to a callback function of the form "uint32_t func(uint32_t)"
tyftyftyf 4:52d01d39ab28 119 * @param pass_to_irq - what to pass to the callback function as parameter
Sissors 0:ff579e7e8efa 120 * @param repeated - determines if it should end with a stop condition
Sissors 0:ff579e7e8efa 121 * @param status - (optional) pointer to integer where the final status code of the I2C transmission is placed. (0x58 is success)
Sissors 0:ff579e7e8efa 122 * @param return - returns zero
Sissors 0:ff579e7e8efa 123 */
tyftyftyf 1:eed116eb680a 124 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 125
Sissors 0:ff579e7e8efa 126 /**
Sissors 0:ff579e7e8efa 127 * Read data from the I2C bus.
Sissors 0:ff579e7e8efa 128 *
Sissors 0:ff579e7e8efa 129 * This function should should be a drop-in replacement for the standard mbed function.
Sissors 0:ff579e7e8efa 130 *
Sissors 0:ff579e7e8efa 131 * @param address - I2C address of the slave (7 bit address << 1).
Sissors 0:ff579e7e8efa 132 * @param data - pointer to byte array where the data will be stored
Sissors 0:ff579e7e8efa 133 * @param length - amount of bytes that need to be received
Sissors 0:ff579e7e8efa 134 * @param repeated - determines if it should end with a stop condition
Sissors 0:ff579e7e8efa 135 * @param return - returns zero on success, LPC status code on failure
Sissors 0:ff579e7e8efa 136 */
Sissors 0:ff579e7e8efa 137 int read(int address, char *data, int length, bool repeated = false);
Sissors 0:ff579e7e8efa 138
Sissors 0:ff579e7e8efa 139 /**
Sissors 0:ff579e7e8efa 140 * Sets the I2C bus frequency
Sissors 0:ff579e7e8efa 141 *
Sissors 0:ff579e7e8efa 142 * @param hz - the bus frequency in herz
Sissors 0:ff579e7e8efa 143 */
Sissors 0:ff579e7e8efa 144 void frequency(int hz);
Sissors 0:ff579e7e8efa 145
Sissors 0:ff579e7e8efa 146 /**
Sissors 0:ff579e7e8efa 147 * Creates a start condition on the I2C bus
Sissors 0:ff579e7e8efa 148 *
Sissors 0:ff579e7e8efa 149 * If you use this function you probably break something (but mbed also had it public)
Sissors 0:ff579e7e8efa 150 */
Sissors 0:ff579e7e8efa 151 void start ( void );
Sissors 0:ff579e7e8efa 152
Sissors 0:ff579e7e8efa 153 /**
Sissors 0:ff579e7e8efa 154 * Creates a stop condition on the I2C bus
Sissors 0:ff579e7e8efa 155 *
Sissors 0:ff579e7e8efa 156 * If you use this function you probably break something (but mbed also had it public)
Sissors 0:ff579e7e8efa 157 */
Sissors 0:ff579e7e8efa 158 void stop ( void );
Sissors 0:ff579e7e8efa 159
Sissors 0:ff579e7e8efa 160 struct I2CData {
Sissors 0:ff579e7e8efa 161 MODI2C *caller;
Sissors 0:ff579e7e8efa 162 char address;
Sissors 0:ff579e7e8efa 163 char *data;
Sissors 0:ff579e7e8efa 164 int length;
Sissors 0:ff579e7e8efa 165 bool repeated;
Sissors 0:ff579e7e8efa 166 int *status;
tyftyftyf 1:eed116eb680a 167 FPointer callback;
tyftyftyf 1:eed116eb680a 168 uint32_t pass_to_irq;
tyftyftyf 1:eed116eb680a 169 int IRQOp;
tyftyftyf 1:eed116eb680a 170 volatile char *monitor_addr;
Sissors 0:ff579e7e8efa 171 };
tyftyftyf 1:eed116eb680a 172
tyftyftyf 1:eed116eb680a 173 private:
Sissors 0:ff579e7e8efa 174 struct I2CBuffer {
tyftyftyf 1:eed116eb680a 175 //volatile int queue;
Sissors 0:ff579e7e8efa 176 int count;
tyftyftyf 1:eed116eb680a 177 volatile I2CData *curr;
tyftyftyf 1:eed116eb680a 178 MemoryPool<I2CData, I2C_BUFFER> pool;
tyftyftyf 1:eed116eb680a 179 //I2CData Data[I2C_BUFFER];
tyftyftyf 1:eed116eb680a 180 Queue<I2CData, I2C_BUFFER> queue;
tyftyftyf 1:eed116eb680a 181 volatile bool crit_flag_isr;
tyftyftyf 1:eed116eb680a 182 volatile bool crit_flag;
Sissors 0:ff579e7e8efa 183
tyftyftyf 1:eed116eb680a 184 I2CBuffer():count(0),curr(NULL),crit_flag_isr(false),crit_flag(false){}
tyftyftyf 1:eed116eb680a 185 };
tyftyftyf 1:eed116eb680a 186
Sissors 0:ff579e7e8efa 187 //Settings:
Sissors 0:ff579e7e8efa 188 int duty;
tyftyftyf 1:eed116eb680a 189
tyftyftyf 1:eed116eb680a 190 void runUserIRQ( I2CData *Data );
Sissors 0:ff579e7e8efa 191
Sissors 0:ff579e7e8efa 192 //Remove later:
Sissors 0:ff579e7e8efa 193 LPC_I2C_TypeDef *I2CMODULE;
Sissors 0:ff579e7e8efa 194
Sissors 0:ff579e7e8efa 195 //Whole bunch of static stuff, pretty much everything that is ever called from ISR
Sissors 0:ff579e7e8efa 196 static I2CBuffer Buffer1;
Sissors 0:ff579e7e8efa 197 static I2CBuffer Buffer2;
tyftyftyf 1:eed116eb680a 198
Sissors 0:ff579e7e8efa 199 static void IRQHandler(I2CBuffer *Buffer, LPC_I2C_TypeDef *I2CMODULE);
Sissors 0:ff579e7e8efa 200 static void IRQ1Handler(void);
Sissors 0:ff579e7e8efa 201 static void IRQ2Handler(void);
tyftyftyf 1:eed116eb680a 202
Sissors 0:ff579e7e8efa 203 static void bufferHandler(LPC_I2C_TypeDef *I2CMODULE);
tyftyftyf 1:eed116eb680a 204 static bool addBuffer(I2CData *Data, LPC_I2C_TypeDef *I2CMODULE);
Sissors 0:ff579e7e8efa 205 static void startBuffer(LPC_I2C_TypeDef *I2CMODULE);
Sissors 0:ff579e7e8efa 206
Sissors 0:ff579e7e8efa 207 static int defaultStatus;
tyftyftyf 1:eed116eb680a 208
Sissors 0:ff579e7e8efa 209 static void _start(LPC_I2C_TypeDef *I2CMODULE);
Sissors 0:ff579e7e8efa 210 static void _stop(LPC_I2C_TypeDef *I2CMODULE);
Sissors 0:ff579e7e8efa 211 static void _clearISR( LPC_I2C_TypeDef *I2CMODULE );
Sissors 0:ff579e7e8efa 212 static void _setISR( LPC_I2C_TypeDef *I2CMODULE );
Sissors 0:ff579e7e8efa 213
Sissors 0:ff579e7e8efa 214
Sissors 0:ff579e7e8efa 215 void writeSettings( void );
Sissors 0:ff579e7e8efa 216 void writePinState( void );
Sissors 0:ff579e7e8efa 217 void setISR( void );
Sissors 0:ff579e7e8efa 218 void clearISR( void );
Sissors 0:ff579e7e8efa 219
Sissors 0:ff579e7e8efa 220
Sissors 0:ff579e7e8efa 221 DigitalOut led;
Sissors 0:ff579e7e8efa 222
Sissors 0:ff579e7e8efa 223 };
Sissors 0:ff579e7e8efa 224
Sissors 0:ff579e7e8efa 225
Sissors 0:ff579e7e8efa 226 #endif