/*----------------------------------------------------------------------------*/ static void interruptHandler(void *object) { static const uint32_t hostErrors = INT_FRUN | INT_HLE; static const uint32_t integrityErrors = INT_RE | INT_RCRC | INT_DCRC | INT_SBE | INT_EBE; static const uint32_t timeoutErrors = INT_RTO | INT_DRTO | INT_HTO; struct Sdmmc * const interface = object; LPC_SDMMC_Type * const reg = interface->base.reg; const uint32_t status = reg->MINTSTS; interruptDisable(interface->finalizer); irqDisable(interface->base.irq); reg->INTMASK = 0; reg->RINTSTS = INT_MASK; if (status & hostErrors) { interface->status = E_ERROR; } else if (status & integrityErrors) { interface->status = E_INTERFACE; } else if (status & timeoutErrors) { interface->status = E_TIMEOUT; } else if (!(reg->STATUS & STATUS_DATA_BUSY)) { interface->status = E_OK; } else { interruptEnable(interface->finalizer); if (!(reg->STATUS & STATUS_DATA_BUSY)) { interface->status = E_OK; interruptDisable(interface->finalizer); } else interface->status = E_BUSY; } if (interface->status != E_BUSY && interface->callback) interface->callback(interface->callbackArgument); }
extern int threadCreate(thFuncPtr funcPtr, void *argPtr) { interruptDisable(); // Create a thread structure for the user function thread_t *t = (thread_t *) malloc(sizeof(thread_t)); getcontext(&t->context); // Make a stack for it t->context.uc_stack.ss_sp = malloc(STACK_SIZE); t->context.uc_stack.ss_size = STACK_SIZE; t->context.uc_stack.ss_flags = 0; t->context.uc_link = &start->t->context; // Add other details t->func = funcPtr; t->arg = argPtr; t->done = 0; t->id = ++thread_count; makecontext(&t->context, (void (*)(void)) runThread, 1, t); // Create the node structure node_t *newnode = (node_t *) malloc(sizeof(node_t)); newnode->t = t; // Add it to the list append_node(newnode); // Run it (or something else) threadYieldInternal(); interruptEnable(); return newnode->t->id; }
void runThread(thread_t *t) { // Wrapper function for running the user function interruptEnable(); t->result = t->func(t->arg); t->done = 1; interruptDisable(); }
extern void threadExit(void *result) { interruptDisable(); // Store the result and mark thread as complete current->t->result = result; current->t->done = 1; // Remove it from the list remove_node(current); // Move on to other threads threadYieldInternal(); interruptEnable(); }
void eepromWrite(char addr, char byte) { //Sleep until the EEPROM is ready to be read (this might be 3.4 ms, maximum) while(EECR & (1 << EEPE)) { pmSleep(); } EEARL = addr; //Set the EEPROM address EEDR = byte; //Set the data to write into EEPROM addr interruptDisable(); EECR = (0 << EEPM1) | (0 << EEPM0) | //Atomic write operation (0 << EERIE) | //Writing a single byte, so there is no need to interrupt (1 << EEMPE) //Within four clocks EECR |= (1 << EEPE); interruptEnable(); }
extern void threadJoin(int thread_id, void **result) { interruptDisable(); // Find the thread node_t *tmp = start; while (tmp->t->id != thread_id) { tmp = tmp->next; } // Switch threads until it's done while (!tmp->t->done) { threadYieldInternal(); } // Store the result if (result) *result = tmp->t->result; interruptEnable(); }
/** \todo Correct ADC prescale and timer0 prescale to not affect these peripherals by * a faster system clk. * \todo Use a MHz frequency value as parameter instead. * Let the function find the closest prescale to give that CPU freq * and return the actual frequency set. * * \param prescale * legal values [0..8] * Prescale Clock division factor * 0 1 * 1 2 * 2 4 * 3 8 * 4 16 * 5 32 * 6 64 * 7 128 * 8 256 */ void pmClkPrescale(unsigned char prescale) { int interruptWasEnabled = 0; //Dont do anything if we are fed with faulty prescaler if(prescale > 8) return; //{ // prescale = 8; //TODO: Consider setting prescale to 8 and continue //} //Turn interrupt off //Look at the I bit (nr. 7) in SREG to determine if global interrupt was enabled if(SREG & (1 << 7)) { interruptWasEnabled = 1; } interruptDisable(); //This write sequency must be completed in four cycles CLKPR = (1 << CLKPCE); CLKPR = (0 << CLKPCE) | (prescale); //(0 << CLKPS3); if(interruptWasEnabled) { interruptEnable(); } }
extern void threadWait(int lockNum, int conditionNum) { interruptDisable(); // Prevent erroroneous calls if (!locks[lockNum]) { printf("threadWait called with unlocked mutex\n"); exit(1); } threadUnlock(lockNum); // Take the current thread out of the rotation node_t *old = current; remove_node(current); // Wait for a condition variable signal while (!conditions[lockNum][conditionNum]) { threadYield(); } // Put the thread back into the rotation append_node(old); threadLockInternal(lockNum); interruptEnable(); }
extern void threadYield() { interruptDisable(); threadYieldInternal(); interruptEnable(); }
extern void threadSignal(int lockNum, int conditionNum) { interruptDisable(); // Signal the condition variable conditions[lockNum][conditionNum]++; interruptEnable(); }
extern void threadLock(int lockNum) { interruptDisable(); threadLockInternal(lockNum); interruptEnable(); }