Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: FreeIMU FreeIMU_external_magnetometer FreeIMU
Fork of MODI2C by
Revision 5:fa0cca8e28b6, committed 2018-03-28
- Comitter:
- tyftyftyf
- Date:
- Wed Mar 28 21:48:20 2018 +0000
- Parent:
- 4:52d01d39ab28
- Commit message:
- wip
Changed in this revision
| MODI2C_IRQ.cpp | Show annotated file Show diff for this revision Revisions of this file |
diff -r 52d01d39ab28 -r fa0cca8e28b6 MODI2C_IRQ.cpp
--- a/MODI2C_IRQ.cpp Sun Feb 09 14:05:04 2014 +0000
+++ b/MODI2C_IRQ.cpp Wed Mar 28 21:48:20 2018 +0000
@@ -144,27 +144,33 @@
Buffer = &Buffer2;
}
- //Start user interrupt
+ // Start user interrupt
Buffer->curr->caller->runUserIRQ((I2CData*)Buffer->curr);
-
+ // Free allocated data
Buffer->pool.free((I2CData*)Buffer->curr);
+ // Don't attempt to call startBuffer if another
+ // thread is about to call it
if (Buffer->crit_flag) return;
-
+
+ // See if there is any other data to be written
osEvent evt = Buffer->queue.get(0);
if (evt.status == osEventMessage){
Buffer->curr = (I2CData*)evt.value.p;
startBuffer(I2CMODULE);
}
else{
+ // Set curr to NULL to indicate no data being written now
Buffer->curr = NULL;
_clearISR(I2CMODULE);
}
}
-//Returns true if succeeded, false if buffer is full
+// Returns true if succeeded, false if buffer is full
bool MODI2C::addBuffer(I2CData *Data, LPC_I2C_TypeDef *I2CMODULE) {
-
+ // check if we are in an interrupt now
+ // __get_IPSR returns 0 when in Thread Mode,
+ // return value > 15 when in interrupt
int interrupt = __get_IPSR();
I2CBuffer *Buffer;
@@ -174,37 +180,49 @@
Buffer = &Buffer2;
}
+ // Hack to update status
if(Data->status == NULL) {
Data->status = &defaultStatus;
- wait_us(1); //I blame the compiler that this is needed
+ wait_us(1); // I blame the compiler that this is needed
}
*(Data->status) = 0;
+ // Attempt to enqueue data to be written
if (Buffer->queue.put(Data, 0)!=osOK){
- if (interrupt!=0)
- return false; //no waiting in ISR
+ if (interrupt != 0)
+ return false; // no waiting in ISR, and buffer is full.
+ // no choice but to exit, return false for failure
else
+ // wait for buffer to be available (should rarely happen!!)
+ // an interrupt will free Buffer when other write finishes
while (Buffer->queue.put(Data, 0)!=osOK);
}
- if (interrupt!=0){
+ // Check for critical section in if in interrupt
+ if (interrupt != 0){
if (Buffer->crit_flag_isr) return true;
- }else Buffer->crit_flag_isr = true;
+ } else Buffer->crit_flag_isr = true;
+ // If no active writing
if (Buffer->curr == NULL){
- if (interrupt==0) Buffer->crit_flag = true;
+ // If we are not in an interrupt, we want to prevent
+ // bufferHandler interrupt code from messing with Buffer.
+ if (interrupt == 0) Buffer->crit_flag = true;
+
+ // Get new data to be written
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;
+ if (interrupt == 0) Buffer->crit_flag_isr = false;
+ if (interrupt == 0) Buffer->crit_flag = false;
+ startBuffer(I2CMODULE); // start transfer
+ } else { // No data
+ // "Leave" critical section
+ if (interrupt == 0) Buffer->crit_flag_isr = false;
+ if (interrupt == 0) Buffer->crit_flag = false;
}
- }else{
- if (interrupt==0) Buffer->crit_flag_isr = false;
+ } else {
+ if (interrupt == 0) Buffer->crit_flag_isr = false;
}
