Esempio n. 1
0
File: sdmmc.c Progetto: stxent/halm
/*----------------------------------------------------------------------------*/
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();
}
Esempio n. 5
0
File: eeprom.c Progetto: cmp1084/f3g
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();
}
Esempio n. 7
0
File: pm.c Progetto: cmp1084/f3g
 /** \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();
}
Esempio n. 10
0
extern void threadSignal(int lockNum, int conditionNum) {
    interruptDisable();
    // Signal the condition variable
    conditions[lockNum][conditionNum]++;
    interruptEnable();
}
Esempio n. 11
0
extern void threadLock(int lockNum) {
    interruptDisable();
    threadLockInternal(lockNum);
    interruptEnable();
}