예제 #1
0
/**************************************************************************//**
*
* mss_hal_init
*
* @brief      initialize mss HAL unit, shall do the following tasks:
*             - setup CPU frequency (if necessary)
*             - if @ref MSS_TASK_USE_TIMER set to TRUE, this function shall
*               setup timer interrupt which shall increment the timer counter
*               mss_timer_tick_cnt and call @ref mss_timer_tick() function
*               periodically
*             - if @ref MSS_PREEMPTIVE_SCHEDULING is set to TRUE, setup the
*               software interrupt or hardware interrupt which is used to call
*               mss_scheduler during preemption
*
* @param      -
*
* @return     -
*
* @remark     the global interrupt shall not be enabled here
*
******************************************************************************/
void mss_hal_init(void)
{
    // check calibration data
    MSS_DEBUG_CHECK(CALBC1_8MHZ != 0xFF);
    MSS_DEBUG_CHECK(CALDCO_8MHZ != 0xFF);

    // set basic clock module+
    BCSCTL1 = XT2OFF | CALBC1_8MHZ;
    DCOCTL = CALDCO_8MHZ;
    BCSCTL2 |= DIVS_3;  // 1 MHz SMCLK
    BCSCTL3 = LFXT1S_2; // source VLOCLK as ACLK

    // wait until clock stabilizes
    do
    {
        IFG1 &= ~OFIFG;
        __delay_cycles(100);
    } while(IFG1 & OFIFG);

#if (MSS_TASK_USE_TIMER == TRUE)
    // use watchdog timer to generate mss timer interrupt tick
    WDTCTL = WDT_MDLY_0_5;
    IE1 |= WDTIE;
#endif

#if (MSS_PREEMPTIVE_SCHEDULING == TRUE)
    // enable interrupt
    CACTL1 = CAIE;
#endif /* (MSS_PREEMPTIVE_SCHEDULING == TRUE) */
}
예제 #2
0
/**************************************************************************//**
*
* mss_timer_get_state
*
* @brief      get the state of a mss timer. will automatically reset the timer
*             state to MSS_TIMER_STATE_IDLE if the current state is
*             MSS_TIMER_STATE_EXPIRED_ONE_SHOT or 
*             MSS_TIMER_STATE_RUNNING_PERIODIC if current state is 
*             MSS_TIMER_STATE_EXPIRED_PERIODIC
*
* @param[in]  hdl     timer handle
*
* @return     true if success, false if failed
*
******************************************************************************/
mss_timer_state_t mss_timer_get_state(mss_timer_t hdl)
{
  mss_int_flag_t int_flag;
  mss_timer_state_t state;
    
  // check timer handler
  MSS_DEBUG_CHECK(hdl != MSS_TIMER_INVALID_HDL);

  MSS_ENTER_CRITICAL_SECTION(int_flag);
  
  // return timer state
  state = hdl->state;

  if(state & TIMER_ALL_EXPIRED_MASK)
  {
    if(hdl->reload_tick == 0)
    {
      // set timer state as idle
      hdl->state = MSS_TIMER_STATE_IDLE;
    }
    else
    {
      // set timer state as idle
      hdl->state = MSS_TIMER_STATE_RUNNING_PERIODIC;
    }
  }

  MSS_LEAVE_CRITICAL_SECTION(int_flag);

  return (state);
}
예제 #3
0
/**************************************************************************//**
*
* mss_timer_init
*
* @brief      initialize mss timer module
*
* @param      -
*
* @return     -
*
******************************************************************************/
void mss_timer_init(void)
{
  uint8_t i;
  
  // initialize timer blocks
  for(i=0 ; i<MSS_MAX_NUM_OF_TIMER ; i++)
  {
	timer_tbl[i].task_id = MSS_INVALID_TASK_ID;
	timer_tbl[i].state = MSS_TIMER_STATE_IDLE;
	timer_tbl[i].expired_tick = 0;
	timer_tbl[i].reload_tick = 0;
  }
  
  // initialize linked list timer
  active_timer_llist = llist_create();
  MSS_DEBUG_CHECK(active_timer_llist != LLIST_INVALID_HDL);
}
예제 #4
0
/**************************************************************************//**
*
* mss_timer_stop
*
* @brief      stop a running mss timer (timer state is reset back to 
*             MSS_TIMER_STATE_IDLE)
*
* @param[in]  hdl     timer handle
*
* @return     true if success, false if failed
*
******************************************************************************/
void mss_timer_stop(mss_timer_t hdl)
{
  mss_int_flag_t int_flag;

  // check timer handler
  MSS_DEBUG_CHECK(hdl != MSS_TIMER_INVALID_HDL);

  MSS_ENTER_CRITICAL_SECTION(int_flag);

  if(hdl->state & TIMER_ALL_RUNNING_MASK)
  {
    // search for the timer and remove it
    llist_remove(active_timer_llist, hdl);

    // set timer state as idle
    hdl->state = MSS_TIMER_STATE_IDLE;
  }

  MSS_LEAVE_CRITICAL_SECTION(int_flag);
}
예제 #5
0
/**************************************************************************//**
*
* timer_start
*
* @brief      start a mss timer
*
* @param[in]  hdl     timer handle
* @param[in]  tick    number of timer ticks to run
*                     (maximum value is ((sizeof(mss_timer_tick_t)/2)-1) )
* @param[in]  reload  number of ticks of reloading/periodic timer. 0 means
*                     that it is a one shot timer (maximum value is 
*                     ((sizeof(mss_timer_tick_t)/2)-1) )
*
* @return     true if success, false if failed
*
******************************************************************************/
static bool timer_start(mss_timer_t hdl, mss_timer_tick_t tick,
		                mss_timer_tick_t reload)
{
  bool ret = false;
  mss_int_flag_t int_flag;

  // check timer handler
  MSS_DEBUG_CHECK(hdl != MSS_TIMER_INVALID_HDL);

  if((!(tick & MSB_TMR_MASK)) && (tick > 0))
  {
    // disable timer interrupt to enable re-setting the timer
    MSS_ENTER_CRITICAL_SECTION(int_flag);

    // set timer to active state and set timer counter
    hdl->expired_tick = mss_timer_tick_cnt + tick;
    hdl->reload_tick = reload;

    if(!(hdl->state & TIMER_ALL_RUNNING_MASK))
    {
      // put the timer into the active timer linked list
      llist_add_first(active_timer_llist, hdl);
    }

    // set new state
    hdl->state = (reload > 0) ? MSS_TIMER_STATE_RUNNING_PERIODIC :
  		                      MSS_TIMER_STATE_RUNNING_ONE_SHOT;

    // sort the active timer list
    llist_sort(active_timer_llist, timer_cmp);

    // return true
    ret = true;

    MSS_LEAVE_CRITICAL_SECTION(int_flag);
  }

  return ret;
}