Improvements to Olieman's MODI2C library. Supports calls from IRQ.
Dependents: FreeIMU FreeIMU_external_magnetometer FreeIMU
Fork of MODI2C by
Diff: MODI2C_IRQ.cpp
- Revision:
- 1:eed116eb680a
- Parent:
- 0:ff579e7e8efa
- Child:
- 5:fa0cca8e28b6
--- a/MODI2C_IRQ.cpp Sat Jun 30 14:55:14 2012 +0000 +++ b/MODI2C_IRQ.cpp Sat Nov 09 08:59:02 2013 +0000 @@ -4,15 +4,16 @@ //*********************IRQ FUNCTIONS************************ //********************************************************** - -void MODI2C::runUserIRQ(I2CData Data) { +void MODI2C::runUserIRQ(I2CData *Data) { - if (IRQOp==IRQ_I2C_BOTH) //Always call if both - callback.call(); - if ((IRQOp==IRQ_I2C_READ)&&(Data.address&0x01)) //Call if read and byte was read - callback.call(); - if ((IRQOp==IRQ_I2C_WRITE)&&(!(Data.address&0x01))) //Call if write and byte was written - callback.call(); + if (Data->IRQOp==IRQ_I2C_BOTH) //Always call if both + Data->callback.call(Data->pass_to_irq); + if ((Data->IRQOp==IRQ_I2C_READ)&&(Data->address&0x01)) //Call if read and byte was read + Data->callback.call(Data->pass_to_irq); + if ((Data->IRQOp==IRQ_I2C_WRITE)&&(!(Data->address&0x01))) //Call if write and byte was written + Data->callback.call(Data->pass_to_irq); + + if (Data->monitor_addr!=NULL) *(Data->monitor_addr)=0; } void MODI2C::IRQ1Handler( void ) { @@ -24,7 +25,7 @@ } void MODI2C::IRQHandler( I2CBuffer *Buffer, LPC_I2C_TypeDef *I2CMODULE) { - I2CData *Data = &Buffer->Data[0]; + I2CData *Data = (I2CData*)Buffer->curr; //Depending on the status register it determines next action, see datasheet //This is also pretty much copy pasting the datasheet @@ -144,66 +145,70 @@ } //Start user interrupt - Buffer->Data[0].caller->runUserIRQ(Buffer->Data[0]); - - removeBuffer(I2CMODULE); - - - - if (Buffer->queue!=0) + Buffer->curr->caller->runUserIRQ((I2CData*)Buffer->curr); + + Buffer->pool.free((I2CData*)Buffer->curr); + + if (Buffer->crit_flag) return; + + osEvent evt = Buffer->queue.get(0); + if (evt.status == osEventMessage){ + Buffer->curr = (I2CData*)evt.value.p; startBuffer(I2CMODULE); - else + } + else{ + Buffer->curr = NULL; _clearISR(I2CMODULE); + } } //Returns true if succeeded, false if buffer is full -bool MODI2C::addBuffer(I2CData Data, LPC_I2C_TypeDef *I2CMODULE) { +bool MODI2C::addBuffer(I2CData *Data, LPC_I2C_TypeDef *I2CMODULE) { + + int interrupt = __get_IPSR(); + I2CBuffer *Buffer; if (I2CMODULE == LPC_I2C1) { Buffer = &Buffer1; } else { Buffer = &Buffer2; } - if (Buffer->queue<I2C_BUFFER) { - - if(Data.status == NULL) { - Data.status = &defaultStatus; - wait_us(1); //I blame the compiler that this is needed - } - *Data.status = 0; - - Buffer->Data[Buffer->queue]=Data; - Buffer->queue++; - - //If queue was empty, set I2C settings, start conversion - if (Buffer->queue==1) { + + if(Data->status == NULL) { + Data->status = &defaultStatus; + wait_us(1); //I blame the compiler that this is needed + } + *(Data->status) = 0; + + if (Buffer->queue.put(Data, 0)!=osOK){ + if (interrupt!=0) + return false; //no waiting in ISR + else + while (Buffer->queue.put(Data, 0)!=osOK); + } + + if (interrupt!=0){ + if (Buffer->crit_flag_isr) return true; + }else Buffer->crit_flag_isr = true; + + if (Buffer->curr == NULL){ + if (interrupt==0) Buffer->crit_flag = true; + osEvent evt = Buffer->queue.get(0); + if (evt.status == osEventMessage){ + Buffer->curr = (volatile I2CData*)(evt.value.p); + if (interrupt==0) Buffer->crit_flag_isr = false; + if (interrupt==0) Buffer->crit_flag = false; startBuffer(I2CMODULE); + }else{ + if (interrupt==0) Buffer->crit_flag_isr = false; + if (interrupt==0) Buffer->crit_flag = false; } - - return true; - } else - return false; - -} - -//Returns true if buffer still has data, false if empty -bool MODI2C::removeBuffer(LPC_I2C_TypeDef *I2CMODULE) { - I2CBuffer *Buffer; - if (I2CMODULE == LPC_I2C1) { - Buffer = &Buffer1; - } else { - Buffer= &Buffer2; + }else{ + if (interrupt==0) Buffer->crit_flag_isr = false; } - - if (Buffer->queue>0) { - for (int i =0; i<Buffer->queue-1; i++) - Buffer->Data[i]=Buffer->Data[i+1]; - Buffer->queue--; - } - if (Buffer->queue>0) - return true; - else - return false; + + + return true; } //Starts new conversion @@ -216,7 +221,7 @@ } //Write settings - Buffer->Data[0].caller->writeSettings(); + Buffer->curr->caller->writeSettings(); Buffer->count=0; //Send Start