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 #include "MODI2C.h"
Sissors 0:ff579e7e8efa 2
Sissors 0:ff579e7e8efa 3 MODI2C::I2CBuffer MODI2C::Buffer1 = {0,0}; //Sets the initial buffer empty and count on zero
Sissors 0:ff579e7e8efa 4 MODI2C::I2CBuffer MODI2C::Buffer2 = {0,0}; //Sets the initial buffer empty
Sissors 0:ff579e7e8efa 5 //int MODI2C::status=0;
Sissors 0:ff579e7e8efa 6 int MODI2C::defaultStatus=0;
Sissors 0:ff579e7e8efa 7
Sissors 0:ff579e7e8efa 8
Sissors 0:ff579e7e8efa 9
Sissors 0:ff579e7e8efa 10
Sissors 0:ff579e7e8efa 11 MODI2C::MODI2C(PinName sda, PinName scl) : led(LED3) {
Sissors 0:ff579e7e8efa 12 //Check which connection we are using, if not correct, go to error status
Sissors 0:ff579e7e8efa 13 if ((sda==p9) && (scl==p10))
Sissors 0:ff579e7e8efa 14 I2CMODULE = LPC_I2C1;
Sissors 0:ff579e7e8efa 15 else if ((sda==p28) && (scl==p27))
Sissors 0:ff579e7e8efa 16 I2CMODULE = LPC_I2C2;
Sissors 0:ff579e7e8efa 17 else
Sissors 0:ff579e7e8efa 18 error("MODI2C pins not valid");
Sissors 0:ff579e7e8efa 19
Sissors 0:ff579e7e8efa 20 //Default settings:
Sissors 0:ff579e7e8efa 21 frequency(100000);
Sissors 0:ff579e7e8efa 22
Sissors 0:ff579e7e8efa 23 writePinState();
Sissors 0:ff579e7e8efa 24 }
Sissors 0:ff579e7e8efa 25
Sissors 0:ff579e7e8efa 26 int MODI2C::write(int address, char *data, int length, bool repeated, int *status) {
Sissors 0:ff579e7e8efa 27
Sissors 0:ff579e7e8efa 28 I2CData Data;
Sissors 0:ff579e7e8efa 29 //Store relevant information
Sissors 0:ff579e7e8efa 30 address &= 0xFE;
Sissors 0:ff579e7e8efa 31 Data.caller = this;
Sissors 0:ff579e7e8efa 32 Data.address = address;
Sissors 0:ff579e7e8efa 33 Data.repeated = repeated;
Sissors 0:ff579e7e8efa 34 Data.data = data;
Sissors 0:ff579e7e8efa 35 Data.length = length;
Sissors 0:ff579e7e8efa 36 Data.status = status;
Sissors 0:ff579e7e8efa 37
Sissors 0:ff579e7e8efa 38 while(!addBuffer(Data, I2CMODULE));
Sissors 0:ff579e7e8efa 39
Sissors 0:ff579e7e8efa 40 return 0;
Sissors 0:ff579e7e8efa 41 }
Sissors 0:ff579e7e8efa 42
Sissors 0:ff579e7e8efa 43 int MODI2C::write(int address, char *data, int length, int *status) {
Sissors 0:ff579e7e8efa 44 return write(address, data, length, false, status);
Sissors 0:ff579e7e8efa 45 }
Sissors 0:ff579e7e8efa 46
Sissors 0:ff579e7e8efa 47 int MODI2C::read_nb(int address, char *data, int length, bool repeated, int *status) {
Sissors 0:ff579e7e8efa 48 //Store relevant information
Sissors 0:ff579e7e8efa 49 address |= 0x01;
Sissors 0:ff579e7e8efa 50
Sissors 0:ff579e7e8efa 51 //isIdle check here
Sissors 0:ff579e7e8efa 52 I2CData Data;
Sissors 0:ff579e7e8efa 53
Sissors 0:ff579e7e8efa 54
Sissors 0:ff579e7e8efa 55 Data.caller = this;
Sissors 0:ff579e7e8efa 56 Data.address = address;
Sissors 0:ff579e7e8efa 57 Data.repeated = repeated;
Sissors 0:ff579e7e8efa 58 Data.data = data;
Sissors 0:ff579e7e8efa 59 Data.length = length;
Sissors 0:ff579e7e8efa 60 Data.status = status;
Sissors 0:ff579e7e8efa 61
Sissors 0:ff579e7e8efa 62 while(!addBuffer(Data, I2CMODULE));
Sissors 0:ff579e7e8efa 63
Sissors 0:ff579e7e8efa 64 return 0;
Sissors 0:ff579e7e8efa 65 }
Sissors 0:ff579e7e8efa 66
Sissors 0:ff579e7e8efa 67 int MODI2C::read_nb(int address, char *data, int length, int *status) {
Sissors 0:ff579e7e8efa 68 return read_nb(address, data, length, false, status);
Sissors 0:ff579e7e8efa 69 }
Sissors 0:ff579e7e8efa 70
Sissors 0:ff579e7e8efa 71 int MODI2C::read(int address, char *data, int length, bool repeated) {
Sissors 0:ff579e7e8efa 72 int stat;
Sissors 0:ff579e7e8efa 73 //Store relevant information
Sissors 0:ff579e7e8efa 74 address |= 0x01;
Sissors 0:ff579e7e8efa 75
Sissors 0:ff579e7e8efa 76 //isIdle check here
Sissors 0:ff579e7e8efa 77 I2CData Data;
Sissors 0:ff579e7e8efa 78
Sissors 0:ff579e7e8efa 79
Sissors 0:ff579e7e8efa 80 Data.caller = this;
Sissors 0:ff579e7e8efa 81 Data.address = address;
Sissors 0:ff579e7e8efa 82 Data.repeated = repeated;
Sissors 0:ff579e7e8efa 83 Data.data = data;
Sissors 0:ff579e7e8efa 84 Data.length = length;
Sissors 0:ff579e7e8efa 85 Data.status = &stat;
Sissors 0:ff579e7e8efa 86
Sissors 0:ff579e7e8efa 87 while(!addBuffer(Data, I2CMODULE));
Sissors 0:ff579e7e8efa 88
Sissors 0:ff579e7e8efa 89 I2CBuffer *Buffer;
Sissors 0:ff579e7e8efa 90 if (I2CMODULE == LPC_I2C1) {
Sissors 0:ff579e7e8efa 91 Buffer = &Buffer1;
Sissors 0:ff579e7e8efa 92 } else {
Sissors 0:ff579e7e8efa 93 Buffer = &Buffer2;
Sissors 0:ff579e7e8efa 94 }
Sissors 0:ff579e7e8efa 95
Sissors 0:ff579e7e8efa 96 while(Buffer->queue!=0)
Sissors 0:ff579e7e8efa 97 wait_us(1);
Sissors 0:ff579e7e8efa 98
Sissors 0:ff579e7e8efa 99 if (stat==0x58) //Return zero if ended correctly, otherwise return return code.
Sissors 0:ff579e7e8efa 100 return 0;
Sissors 0:ff579e7e8efa 101 else
Sissors 0:ff579e7e8efa 102 return stat;
Sissors 0:ff579e7e8efa 103 }
Sissors 0:ff579e7e8efa 104
Sissors 0:ff579e7e8efa 105
Sissors 0:ff579e7e8efa 106 void MODI2C::start( void ) {
Sissors 0:ff579e7e8efa 107 _start(I2CMODULE);
Sissors 0:ff579e7e8efa 108 }
Sissors 0:ff579e7e8efa 109
Sissors 0:ff579e7e8efa 110 void MODI2C::stop( void ) {
Sissors 0:ff579e7e8efa 111 _stop(I2CMODULE);
Sissors 0:ff579e7e8efa 112 }
Sissors 0:ff579e7e8efa 113
Sissors 0:ff579e7e8efa 114 void MODI2C::frequency(int hz) {
Sissors 0:ff579e7e8efa 115 //The I2C clock by default runs on quarter of system clock, which is 96MHz
Sissors 0:ff579e7e8efa 116 //So to calculate high/low count times, we do 96MHz/4/2/frequency
Sissors 0:ff579e7e8efa 117 duty = 96000000/8/hz;
Sissors 0:ff579e7e8efa 118 if (duty>65535)
Sissors 0:ff579e7e8efa 119 duty=65535;
Sissors 0:ff579e7e8efa 120 if (duty<4)
Sissors 0:ff579e7e8efa 121 duty=4;
Sissors 0:ff579e7e8efa 122 }
Sissors 0:ff579e7e8efa 123
Sissors 0:ff579e7e8efa 124 int MODI2C::getQueue( void ) {
Sissors 0:ff579e7e8efa 125 I2CBuffer *Buffer;
Sissors 0:ff579e7e8efa 126 if (I2CMODULE == LPC_I2C1) {
Sissors 0:ff579e7e8efa 127 Buffer = &Buffer1;
Sissors 0:ff579e7e8efa 128 } else {
Sissors 0:ff579e7e8efa 129 Buffer = &Buffer2;
Sissors 0:ff579e7e8efa 130 }
Sissors 0:ff579e7e8efa 131 return Buffer->queue;
Sissors 0:ff579e7e8efa 132 }
Sissors 0:ff579e7e8efa 133
Sissors 0:ff579e7e8efa 134
Sissors 0:ff579e7e8efa 135
Sissors 0:ff579e7e8efa 136 //*******************************************
Sissors 0:ff579e7e8efa 137 //***********Internal functions**************
Sissors 0:ff579e7e8efa 138 //*******************************************
Sissors 0:ff579e7e8efa 139
Sissors 0:ff579e7e8efa 140
Sissors 0:ff579e7e8efa 141 void MODI2C::writeSettings( void ) {
Sissors 0:ff579e7e8efa 142 I2CMODULE->I2CONSET = 1<<I2C_ENABLE; //Enable I2C
Sissors 0:ff579e7e8efa 143 I2CMODULE->I2CONCLR = I2C_STOP;
Sissors 0:ff579e7e8efa 144 I2CMODULE->MMCTRL = 0; //Disable monitor mode
Sissors 0:ff579e7e8efa 145 I2CMODULE->I2SCLH = duty;
Sissors 0:ff579e7e8efa 146 I2CMODULE->I2SCLL = duty;
Sissors 0:ff579e7e8efa 147
Sissors 0:ff579e7e8efa 148 }
Sissors 0:ff579e7e8efa 149
Sissors 0:ff579e7e8efa 150 void MODI2C::writePinState( void ) {
Sissors 0:ff579e7e8efa 151 if (I2CMODULE == LPC_I2C1) {
Sissors 0:ff579e7e8efa 152 LPC_PINCON->PINSEL0 |= 0x0000000F; //Sets pins as I2C
Sissors 0:ff579e7e8efa 153 LPC_PINCON->PINMODE0 |= 0x0000000A; //Neither pull up nor pull down
Sissors 0:ff579e7e8efa 154 LPC_PINCON->PINMODE_OD0 |= 0x00000003; //Open drain mode enabled
Sissors 0:ff579e7e8efa 155 } else if (I2CMODULE == LPC_I2C2) {
Sissors 0:ff579e7e8efa 156 LPC_PINCON->PINSEL0 |= (1<<21)|(1<<23); //Same story, different register settings
Sissors 0:ff579e7e8efa 157 LPC_PINCON->PINMODE0 |= (1<<21)|(1<<23);
Sissors 0:ff579e7e8efa 158 LPC_PINCON->PINMODE_OD0 |= (1<<10)|(1<<11);
Sissors 0:ff579e7e8efa 159 }
Sissors 0:ff579e7e8efa 160 }
Sissors 0:ff579e7e8efa 161
Sissors 0:ff579e7e8efa 162
Sissors 0:ff579e7e8efa 163
Sissors 0:ff579e7e8efa 164 void MODI2C::attach( void (*function)(void), int operation) {
Sissors 0:ff579e7e8efa 165 IRQOp = operation;
Sissors 0:ff579e7e8efa 166 callback.attach(function);
Sissors 0:ff579e7e8efa 167 }
Sissors 0:ff579e7e8efa 168
Sissors 0:ff579e7e8efa 169 template<typename T>
Sissors 0:ff579e7e8efa 170 void MODI2C::attach(T *object, void (T::*member)(void), int operation) {
Sissors 0:ff579e7e8efa 171 IRQOp = operation;
Sissors 0:ff579e7e8efa 172 callback.attach(object, member);
Sissors 0:ff579e7e8efa 173 }
Sissors 0:ff579e7e8efa 174
Sissors 0:ff579e7e8efa 175 void MODI2C::detach( void ) {
Sissors 0:ff579e7e8efa 176 callback.attach(NULL);
Sissors 0:ff579e7e8efa 177 }
Sissors 0:ff579e7e8efa 178
Sissors 0:ff579e7e8efa 179 void MODI2C::_start(LPC_I2C_TypeDef *I2CMODULE) {
Sissors 0:ff579e7e8efa 180 if (!(I2CMODULE->I2CONSET & 1<<I2C_START)) //If already sent, skip
Sissors 0:ff579e7e8efa 181 I2CMODULE->I2CONSET = 1<<I2C_START; //Send start condition
Sissors 0:ff579e7e8efa 182 }
Sissors 0:ff579e7e8efa 183
Sissors 0:ff579e7e8efa 184 void MODI2C::_stop(LPC_I2C_TypeDef *I2CMODULE) {
Sissors 0:ff579e7e8efa 185 I2CMODULE->I2CONSET = 1<<I2C_STOP; //Send stop condition
Sissors 0:ff579e7e8efa 186 I2CMODULE->I2CONCLR = 1<<I2C_FLAG;
Sissors 0:ff579e7e8efa 187 }
Sissors 0:ff579e7e8efa 188
Sissors 0:ff579e7e8efa 189 //Set interrupt vector
Sissors 0:ff579e7e8efa 190 void MODI2C::setISR(void) {
Sissors 0:ff579e7e8efa 191 _setISR(I2CMODULE);
Sissors 0:ff579e7e8efa 192 }
Sissors 0:ff579e7e8efa 193
Sissors 0:ff579e7e8efa 194 void MODI2C::_setISR(LPC_I2C_TypeDef *I2CMODULE) {
Sissors 0:ff579e7e8efa 195 if (I2CMODULE == LPC_I2C1) {
Sissors 0:ff579e7e8efa 196 NVIC_SetVector(I2C1_IRQn, (uint32_t)&IRQ1Handler);
Sissors 0:ff579e7e8efa 197 NVIC_EnableIRQ(I2C1_IRQn);
Sissors 0:ff579e7e8efa 198 } else if (I2CMODULE == LPC_I2C2) {
Sissors 0:ff579e7e8efa 199 NVIC_SetVector(I2C2_IRQn, (uint32_t)&IRQ2Handler);
Sissors 0:ff579e7e8efa 200 NVIC_EnableIRQ(I2C2_IRQn);
Sissors 0:ff579e7e8efa 201 }
Sissors 0:ff579e7e8efa 202 }
Sissors 0:ff579e7e8efa 203
Sissors 0:ff579e7e8efa 204 void MODI2C::clearISR( void ) {
Sissors 0:ff579e7e8efa 205 _clearISR(I2CMODULE);
Sissors 0:ff579e7e8efa 206 }
Sissors 0:ff579e7e8efa 207
Sissors 0:ff579e7e8efa 208 void MODI2C::_clearISR( LPC_I2C_TypeDef *I2CMODULE ) {
Sissors 0:ff579e7e8efa 209 if (I2CMODULE == LPC_I2C1) {
Sissors 0:ff579e7e8efa 210 NVIC_DisableIRQ(I2C1_IRQn);
Sissors 0:ff579e7e8efa 211 } else if (I2CMODULE == LPC_I2C2) {
Sissors 0:ff579e7e8efa 212 NVIC_DisableIRQ(I2C2_IRQn);
Sissors 0:ff579e7e8efa 213 }
Sissors 0:ff579e7e8efa 214 }