Improvements to Olieman's MODI2C library. Supports calls from IRQ.
Dependents: FreeIMU FreeIMU_external_magnetometer FreeIMU
Fork of MODI2C by
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, ®isterAdd, 1, true); 00069 * mod.read_nb(MPU6050_ADDRESS*2, ®isterResult, 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
Generated on Tue Jul 12 2022 16:58:30 by
