/****************************************************************************
 *
 * NAME: vInitialiseApp
 *
 * DESCRIPTION:
 * Initialises Zigbee stack, hardware and application.
 *
 *
 * RETURNS:
 * void
 ****************************************************************************/
PRIVATE void vInitialiseApp(void)
{
    /*
     * Initialise JenOS modules. Initialise Power Manager even on non-sleeping nodes
     * as it allows the device to doze when in the idle task.
     * Parameter options: E_AHI_SLEEP_OSCON_RAMON or E_AHI_SLEEP_DEEP or ...
     */
    PWRM_vInit(E_AHI_SLEEP_OSCON_RAMON);

	#if JENNIC_CHIP == JN5169
		PDM_eInitialise(63, NULL);
	#else
		PDM_eInitialise(0, NULL);
	#endif


    /* Initialise Protocol Data Unit Manager */
    PDUM_vInit();

    ZPS_vExtendedStatusSetCallback(vfExtendedStatusCallBack);

    /* Initialise application */
    APP_vInitialiseNode();

    DBG_vPrintf(TRACE_START, "\nAPP Start: Tick Timer = %d", u32AHI_TickTimerRead());
    DBG_vPrintf(TRACE_START,"\nAPP Start: Initialised");
	
}
예제 #2
0
/****************************************************************************
 *
 * NAME: SetTickCompare
 *
 * DESCRIPTION:
 * Set the tick timer compare register
 *
 * RETURNS:
 * True if the compare register value is in the future
 *
 ****************************************************************************/
OS_HWCOUNTER_SET_CALLBACK(APP_cbSetTickTimerCompare, u32CompareValue)
{
    /* calculations are relative to the last compare register value to account for counter wrap around */
    int32 s32NextDelta = u32CompareValue - s_u32LastExpiredTime;
    uint32 u32CurDelta = u32AHI_TickTimerRead() - s_u32LastExpiredTime;

    /*
     * Race condition here. If the tick counter has incremented passed the compare point
     * in the time between reading it and loading the compare register the interrupt will be missed.
     * Increase the delta to take account of this time. To minimise this time, the number of
     * instructions between the register read and write to the interval register should be minimised.
     */
    u32CurDelta += 100;

    if (s32NextDelta > 0 && u32CurDelta < s32NextDelta)
    {
        vAHI_TickTimerInterval(u32CompareValue);
        s_u32CompareTime = u32CompareValue;
        return TRUE;
    }

    return FALSE;
}
예제 #3
0
PROCESS_THREAD(i2c_process, ev, data)
{
  static size_t i;
#if (DEBUG==1)
  static u32_t i2c_ticks;
#endif

  PROCESS_BEGIN();

  vAHI_SiRegisterCallback(i2c_irq);
  vAHI_SiConfigure(true,true,I2C_400KHZ_FAST_MODE);

  while ((transaction=list_pop(transactions)))
  {
#if (DEBUG==1)
    printf("i2c: to 0x%x start, %d written, %d read\n",
           transaction->addr, transaction->wrlen, transaction->rdlen);
    i2c_ticks = u32AHI_TickTimerRead();
#endif

    if (transaction->wrlen) {
      /* send slave address, start condition */
      vAHI_SiWriteData8(transaction->addr);
      vAHI_SiSetCmdReg(E_AHI_SI_START_BIT,     E_AHI_SI_NO_STOP_BIT,
                       E_AHI_SI_NO_SLAVE_READ, E_AHI_SI_SLAVE_WRITE,
                       E_AHI_SI_SEND_ACK,      E_AHI_SI_NO_IRQ_ACK);
      PROCESS_YIELD_UNTIL(ev==PROCESS_EVENT_POLL);
      if (i2c_status==FAIL) { /* we only test for ACK on the first byte! */
        if (transaction->cb) transaction->cb(false);
#if (DEBUG==1)
        printf("i2c: to 0x%x failed, %d written, %d read in %d ticks\n",
               transaction->addr, transaction->wrlen, transaction->rdlen,
               u32AHI_TickTimerRead() - i2c_ticks);
#endif
        continue;
      }
    }

    /* send wr data. If repeated_start and there is something to read, send no
     * stop condition, else send a stop condition on the last byte. */
    for (i=0; i<transaction->wrlen; i++) {
      vAHI_SiWriteData8(transaction->buf[i]);
      vAHI_SiSetCmdReg(E_AHI_SI_NO_START_BIT,
                       (transaction->wrlen!=0) ? E_AHI_SI_NO_STOP_BIT : transaction->rdlen,
                       E_AHI_SI_NO_SLAVE_READ, E_AHI_SI_SLAVE_WRITE,
                       E_AHI_SI_SEND_ACK,      E_AHI_SI_NO_IRQ_ACK);
      PROCESS_YIELD_UNTIL(ev==PROCESS_EVENT_POLL);
      if (i2c_status==FAIL) { /* we only test for ACK on the first byte! */
        if (transaction->cb) transaction->cb(false);
#if (DEBUG==1)
        printf("i2c: to 0x%x failed, %d written, %d read in %d ticks\n",
               transaction->addr, transaction->wrlen, transaction->rdlen,
               (uint32_t) u32AHI_TickTimerRead() - i2c_ticks);
#endif
        continue;
      }
    }

    if (transaction->rdlen) {
      /* send slave addr, start condition */
      vAHI_SiWriteData8(transaction->addr|1);
      vAHI_SiSetCmdReg(E_AHI_SI_START_BIT,     E_AHI_SI_NO_STOP_BIT,
                       E_AHI_SI_NO_SLAVE_READ, E_AHI_SI_SLAVE_WRITE,
                       E_AHI_SI_SEND_ACK,      E_AHI_SI_NO_IRQ_ACK);
      PROCESS_YIELD_UNTIL(ev==PROCESS_EVENT_POLL);
    }

    /* read data, send stop condition on last byte, send nak on last byte when
     * end_of_transmission is set.*/
    for (i=0; i<transaction->rdlen; i++) {
      vAHI_SiSetCmdReg(E_AHI_SI_NO_START_BIT, i==transaction->rdlen-1,
                       E_AHI_SI_SLAVE_READ,   E_AHI_SI_NO_SLAVE_WRITE,
                       (i==transaction->rdlen-1) ? E_AHI_SI_SEND_NACK : E_AHI_SI_SEND_ACK,
                       E_AHI_SI_NO_IRQ_ACK);
      PROCESS_YIELD_UNTIL(ev==PROCESS_EVENT_POLL);
      transaction->buf[transaction->wrlen+i] = u8AHI_SiReadData8();
    }

#if (DEBUG==1)
    printf("i2c: to 0x%x completed, %d written, %d read in %d ticks (rd:",
           transaction->addr, transaction->wrlen, transaction->rdlen,
           (u32_t) u32AHI_TickTimerRead() - i2c_ticks);
    for (i=0; i<transaction->rdlen+transaction->wrlen; i++)
      printf("0x%x,", transaction->buf[i]);
    printf(")\n");
#endif

    if (transaction->cb) transaction->cb(i2c_status==SUCCESS);
  }
  vAHI_SiConfigure(false,false,0);

  PROCESS_END();
}
예제 #4
0
static void
main_loop(void)
{
  int r;
  clock_time_t time_to_etimer;
  rtimer_clock_t ticks_to_rtimer;

  while(1) {
    do {
      /* Reset watchdog. */
      watchdog_periodic();
      r = process_run();
    } while(r > 0);
    /*
     * Idle processing.
     */
    watchdog_stop();

#if DCOSYNCH_CONF_ENABLED
    /* Calibrate the DCO every DCOSYNCH_PERIOD
     * if we have more than 500uSec until next rtimer
     * PS: Calibration disables interrupts and blocks for 200uSec.
     *  */
    if(clock_seconds() - last_dco_calibration_time > DCOSYNCH_PERIOD) {
      if(rtimer_arch_time_to_rtimer() > RTIMER_SECOND / 2000) {
        /* PRINTF("ContikiMain: Calibrating the DCO\n"); */
        eAHI_AttemptCalibration();
        /* Patch to allow CpuDoze after calibration */
        vREG_PhyWrite(REG_PHY_IS, REG_PHY_INT_VCO_CAL_MASK);
        last_dco_calibration_time = clock_seconds();
      }
    }
#endif /* DCOSYNCH_CONF_ENABLED */

    /* flush standard output before sleeping */
    uart_driver_flush(E_AHI_UART_0, TRUE, FALSE);

    /* calculate the time to the next etimer and rtimer */
    time_to_etimer = clock_arch_time_to_etimer();
    ticks_to_rtimer = rtimer_arch_time_to_rtimer();

#if JN516X_SLEEP_ENABLED
    /* we can sleep only up to the next rtimer/etimer */
    rtimer_clock_t max_sleep_time = ticks_to_rtimer;
    if(max_sleep_time >= JN516X_MIN_SLEEP_TIME) {
      /* also take into account etimers */
      uint64_t ticks_to_etimer = ((uint64_t)time_to_etimer * RTIMER_SECOND) / CLOCK_SECOND;
      max_sleep_time = MIN(ticks_to_etimer, ticks_to_rtimer);
    }

    if(max_sleep_time >= JN516X_MIN_SLEEP_TIME) {
      max_sleep_time -= JN516X_SLEEP_GUARD_TIME;
      /* bound the sleep time to 1 second */
      max_sleep_time = MIN(max_sleep_time, JN516X_MAX_SLEEP_TIME);

#if !RTIMER_USE_32KHZ
      /* convert to 32.768 kHz oscillator ticks */
      max_sleep_time = (uint64_t)max_sleep_time * JN516X_XOSC_SECOND / RTIMER_SECOND;
#endif
      vAHI_WakeTimerEnable(WAKEUP_TIMER, TRUE);
      /* sync with the tick timer */
      WAIT_FOR_EDGE(sleep_start);
      sleep_start_ticks = u32AHI_TickTimerRead();

      vAHI_WakeTimerStartLarge(WAKEUP_TIMER, max_sleep_time);
      ENERGEST_SWITCH(ENERGEST_TYPE_CPU, ENERGEST_TYPE_EXTRA_LPM);
      vAHI_Sleep(E_AHI_SLEEP_OSCON_RAMON);
    } else {
#else
    {
#endif /* JN516X_SLEEP_ENABLED */
      clock_arch_schedule_interrupt(time_to_etimer, ticks_to_rtimer);
      ENERGEST_SWITCH(ENERGEST_TYPE_CPU, ENERGEST_TYPE_LPM);
      vAHI_CpuDoze();
      watchdog_start();
      ENERGEST_SWITCH(ENERGEST_TYPE_LPM, ENERGEST_TYPE_CPU);
    }
  }
}
/*---------------------------------------------------------------------------*/
void
AppColdStart(void)
{
  /* After reset or sleep with memory off */
  main();
}
/*---------------------------------------------------------------------------*/
void
AppWarmStart(void)
{
  /* Wakeup after sleep with memory on.
   * Need to initialize devices but not the application state.
   * Note: the actual time this function is called is
   * ~8 ticks (32kHz timer) later than the scheduled sleep end time.
   */
  uint32_t sleep_ticks;
  uint64_t sleep_end;
  rtimer_clock_t sleep_ticks_rtimer;

  clock_arch_calibrate();
  leds_init();
  uart0_init(UART_BAUD_RATE); /* Must come before first PRINTF */
  NETSTACK_RADIO.init();
  watchdog_init();
  watchdog_stop();

  WAIT_FOR_EDGE(sleep_end);
  sleep_ticks = (uint32_t)(sleep_start - sleep_end) + 1;

#if RTIMER_USE_32KHZ
  sleep_ticks_rtimer = sleep_ticks;
#else
  {
    static uint32_t remainder;
    uint64_t t = (uint64_t)sleep_ticks * RTIMER_SECOND + remainder;
    sleep_ticks_rtimer = (uint32_t)(t / JN516X_XOSC_SECOND);
    remainder = t - sleep_ticks_rtimer * JN516X_XOSC_SECOND;
  }
#endif

  /* reinitialize rtimers */
  rtimer_arch_reinit(sleep_start_ticks, sleep_ticks_rtimer);

  ENERGEST_SWITCH(ENERGEST_TYPE_EXTRA_LPM, ENERGEST_TYPE_CPU);

  watchdog_start();

  /* reinitialize clock */
  clock_arch_init(1);
  /* schedule etimer interrupt */
  clock_arch_schedule_interrupt(clock_arch_time_to_etimer(), rtimer_arch_time_to_rtimer());

#if DCOSYNCH_CONF_ENABLED
  /* The radio is recalibrated on wakeup */
  last_dco_calibration_time = clock_seconds();
#endif

  main_loop();
}