/** \brief Replace the period of a running timer. */ void opentimers_setPeriod(opentimer_id_t id,time_type_t timetype,uint32_t newDuration) { if (timetype==TIME_MS) { opentimers_vars.timersBuf[id].period_ticks = newDuration*PORT_TICS_PER_MS; opentimers_vars.timersBuf[id].wraps_remaining = (newDuration*PORT_TICS_PER_MS/MAX_TICKS_IN_SINGLE_CLOCK);//65535=maxValue of uint16_t } else if (timetype==TIME_TICS) { opentimers_vars.timersBuf[id].period_ticks = newDuration; opentimers_vars.timersBuf[id].wraps_remaining = (newDuration/MAX_TICKS_IN_SINGLE_CLOCK);//65535=maxValue of uint16_t } else { // this should never happpen! // we can not print from within the drivers. Instead: // blink the error LED leds_error_blink(); // reset the board board_reset(); } if(opentimers_vars.timersBuf[id].wraps_remaining==0) { if (timetype==TIME_MS){ opentimers_vars.timersBuf[id].ticks_remaining = newDuration*PORT_TICS_PER_MS; } else if (timetype==TIME_TICS){ opentimers_vars.timersBuf[id].ticks_remaining = newDuration; } } else { opentimers_vars.timersBuf[id].ticks_remaining = MAX_TICKS_IN_SINGLE_CLOCK; } }
owerror_t openserial_printCritical( uint8_t calling_component, uint8_t error_code, errorparameter_t arg1, errorparameter_t arg2 ) { uint32_t reference; // blink error LED, this is serious leds_error_blink(); // schedule for the mote to reboot in 10s reference = opentimers_getValue(); opentimers_scheduleAbsolute( openserial_vars.reset_timerId, // timerId 10000, // duration reference, // reference TIME_MS, // timetype openserial_board_reset_cb // callback ); return openserial_printInfoErrorCritical( SERFRAME_MOTE2PC_CRITICAL, calling_component, error_code, arg1, arg2 ); // openserial_flush called by openserial_printInfoErrorCritical() }
kick_scheduler_t spi_isr() { #ifdef SPI_IN_INTERRUPT_MODE // save the byte just received in the RX buffer switch (spi_vars.returnType) { case SPI_FIRSTBYTE: if (spi_vars.numTxedBytes==0) { *spi_vars.pNextRxByte = U0RXBUF; } break; case SPI_BUFFER: *spi_vars.pNextRxByte = U0RXBUF; spi_vars.pNextRxByte++; break; case SPI_LASTBYTE: *spi_vars.pNextRxByte = U0RXBUF; break; } // one byte less to go spi_vars.pNextTxByte++; spi_vars.numTxedBytes++; spi_vars.txBytesLeft--; if (spi_vars.txBytesLeft>0) { // write next byte to TX buffer U0TXBUF = *spi_vars.pNextTxByte; } else { // put CS signal high to signal end of transmission to slave if (spi_vars.isLast==SPI_LAST) { P4OUT |= 0x04; } // SPI is not busy anymore spi_vars.busy = 0; // SPI is done! if (spi_vars.callback!=NULL) { // call the callback spi_vars.spi_cb(); // kick the OS return KICK_SCHEDULER; } } return DO_NOT_KICK_SCHEDULER; #else // this should never happpen! // we can not print from within the BSP. Instead: // blink the error LED leds_error_blink(); // reset the board board_reset(); return DO_NOT_KICK_SCHEDULER; // we will not get here, statement to please compiler #endif }
inline uint16_t radiotimer_getCapturedTime() { // this should never happpen! // we can not print from within the BSP. Instead: // blink the error LED leds_error_blink(); // reset the board board_reset(); return 0;// this line is never reached, but here to satisfy compiler }
owerror_t openserial_printCritical(uint8_t calling_component, uint8_t error_code, errorparameter_t arg1, errorparameter_t arg2) { // blink error LED, this is serious leds_error_blink(); // schedule for the mote to reboot in 10s opentimers_start(10000, TIMER_ONESHOT,TIME_MS, board_reset); return openserial_printInfoErrorCritical( SERFRAME_MOTE2PC_CRITICAL, calling_component, error_code, arg1, arg2 ); }
void scheduler_push_task(OpenMote* self, task_cbt cb, task_prio_t prio) { taskList_item_t* taskContainer; taskList_item_t** taskListWalker; INTERRUPT_DECLARATION(); DISABLE_INTERRUPTS(); // find an empty task container taskContainer = &(self->scheduler_vars).taskBuf[0]; while (taskContainer->cb!=NULL && taskContainer<=&(self->scheduler_vars).taskBuf[TASK_LIST_DEPTH-1]) { taskContainer++; } if (taskContainer>&(self->scheduler_vars).taskBuf[TASK_LIST_DEPTH-1]) { // task list has overflown. This should never happpen! // we can not print from within the kernel. Instead: // blink the error LED leds_error_blink(self); // reset the board board_reset(self); } // fill that task container with this task taskContainer->cb = cb; taskContainer->prio = prio; // find position in queue taskListWalker = &(self->scheduler_vars).task_list; while (*taskListWalker!=NULL && (*taskListWalker)->prio < taskContainer->prio) { taskListWalker = (taskList_item_t**)&((*taskListWalker)->next); } // insert at that position taskContainer->next = *taskListWalker; *taskListWalker = taskContainer; // maintain debug stats (self->scheduler_dbg).numTasksCur++; if ((self->scheduler_dbg).numTasksCur>(self->scheduler_dbg).numTasksMax) { (self->scheduler_dbg).numTasksMax = (self->scheduler_dbg).numTasksCur; } ENABLE_INTERRUPTS(); }
/** \brief Start a timer. The timer works as follows: - currentTimeout is the number of ticks before the next timer expires. - if a new timer is inserted, we check that it is not earlier than the soonest - if it is earliest, replace it - if not, insert it in the list \param duration Number milli-seconds after which the timer will fire. \param type Type of timer: - #TIMER_PERIODIC for a periodic timer. - #TIMER_ONESHOT for a on-shot timer. \param timetype Units of the <tt>duration</tt>: - #TIME_MS when <tt>duration</tt> is in ms. - #TIME_TICS when <tt>duration</tt> is in clock ticks. \param callback The function to call when the timer fires. \returns The id of the timer (which serves as a handler to stop it) if the timer could be started. \returns TOO_MANY_TIMERS_ERROR if the timer could NOT be started. */ opentimer_id_t opentimers_start(uint32_t duration, timer_type_t type, time_type_t timetype, opentimers_cbt callback) { uint8_t id; // find an unused timer for (id=0; id<MAX_NUM_TIMERS && opentimers_vars.timersBuf[id].isrunning==TRUE; id++); if (id<MAX_NUM_TIMERS) { // we found an unused timer // register the timer if (timetype==TIME_MS) { opentimers_vars.timersBuf[id].period_ticks = duration*PORT_TICS_PER_MS; opentimers_vars.timersBuf[id].wraps_remaining = (duration*PORT_TICS_PER_MS/MAX_TICKS_IN_SINGLE_CLOCK);//65535=maxValue of uint16_t } else if (timetype==TIME_TICS) { opentimers_vars.timersBuf[id].period_ticks = duration; opentimers_vars.timersBuf[id].wraps_remaining = (duration/MAX_TICKS_IN_SINGLE_CLOCK);//65535=maxValue of uint16_t } else { while (1); //error } //if the number of ticks falls below a 16bit value, use it, otherwise set to max 16bit value if(opentimers_vars.timersBuf[id].wraps_remaining==0){ if (timetype==TIME_MS){ opentimers_vars.timersBuf[id].ticks_remaining = duration*PORT_TICS_PER_MS; } else if (timetype==TIME_TICS) { opentimers_vars.timersBuf[id].ticks_remaining = duration; } else { // this should never happpen! // we can not print from within the drivers. Instead: // blink the error LED leds_error_blink(); // reset the board board_reset(); } }else{ opentimers_vars.timersBuf[id].ticks_remaining = MAX_TICKS_IN_SINGLE_CLOCK; } opentimers_vars.timersBuf[id].type = type; opentimers_vars.timersBuf[id].isrunning = TRUE; opentimers_vars.timersBuf[id].callback = callback; opentimers_vars.timersBuf[id].hasExpired = FALSE; // re-schedule the running timer, if needed if ( (opentimers_vars.running==FALSE) || (opentimers_vars.timersBuf[id].ticks_remaining < opentimers_vars.currentTimeout) ) { opentimers_vars.currentTimeout = opentimers_vars.timersBuf[id].ticks_remaining; if (opentimers_vars.running==FALSE) { bsp_timer_reset(); } bsp_timer_scheduleIn(opentimers_vars.timersBuf[id].ticks_remaining); } opentimers_vars.running = TRUE; } else { return TOO_MANY_TIMERS_ERROR; } return id; }
/* * @brief spi_isr SPI isr call back handler * * @param return kick_scheduler_t * */ kick_scheduler_t spi_isr(void) { #ifdef SPI_IN_INTERRUPT_MODE /* save the byte just received in the RX buffer */ switch (spi_vars.returnType) { case SPI_FIRSTBYTE: if (spi_vars.numTxedBytes==0) { spi_read_buffer_wait(&master, spi_vars.pNextRxByte, 1, 0); } break; case SPI_BUFFER: spi_read_buffer_wait(&master, spi_vars.pNextRxByte, 1, 0); spi_vars.pNextRxByte++; break; case SPI_LASTBYTE: spi_read_buffer_wait(&master, spi_vars.pNextRxByte, 1, 0); break; } /* one byte less to go */ spi_vars.pNextTxByte++; spi_vars.numTxedBytes++; spi_vars.txBytesLeft--; if (spi_vars.txBytesLeft>0) { /* write next byte to TX buffer */ spi_write_buffer_wait(&master, spi_vars.pNextTxByte, 1); } else { /* put CS signal high to signal end of transmission to slave */ if (spi_vars.isLast==SPI_LAST) { /* Stop the SPI transaction by setting SEL high */ spi_select_slave(&master, &slave, false); } /* SPI is not busy anymore */ spi_vars.busy = 0; /* SPI is done! */ if (spi_vars.callback!=NULL) { /* call the callback */ spi_vars.callback(); /* kick the OS */ return KICK_SCHEDULER; } } return DO_NOT_KICK_SCHEDULER; #else /* this should never happen! */ while(1); /* we can not print from within the BSP. Instead we blink the error LED */ leds_error_blink(); /* reset the board */ board_reset(); /* execution will not reach here, statement to make compiler happy */ return DO_NOT_KICK_SCHEDULER; #endif }