/**************************************************************************** * * NAME: MibAdcStatusPatch_u8Analogue * * DESCRIPTION: * Called when analogue reading is complete * ****************************************************************************/ PUBLIC uint8 MibAdcStatusPatch_u8Analogue(void) { /* Note the reading */ psMibAdcStatus->sTemp.au16Read[psMibAdcStatus->u8Adc] = u16AHI_AdcRead(); /* JN5148 or JN5148J01 ? */ #if (defined(JENNIC_CHIP_JN5148) || defined(JENNIC_CHIP_JN5148J01)) { /* Do nothing */ } /* JN5142J01 */ #elif defined(JENNIC_CHIP_JN5142J01) { /* Left shift the conversion to scale from 8 to 12 bits */ psMibAdcStatus->sTemp.au16Read[psMibAdcStatus->u8Adc] <<= 4; } #else { /* Left shift the conversion to scale from 10 to 12 bits */ psMibAdcStatus->sTemp.au16Read[psMibAdcStatus->u8Adc] <<= 2; } #endif /* Update the table hash value */ psMibAdcStatus->sRead.u16Hash++; /* Debug */ //DBG_vPrintf(CONFIG_DBG_MIB_ADC_STATUS, "\nMibAdcStatusPatch_u8Analogue()", psMibAdcStatus->u8Adc); //DBG_vPrintf(CONFIG_DBG_MIB_ADC_STATUS, "\n\tu16AHI_AdcRead(%d)=%d", psMibAdcStatus->u8Adc, psMibAdcStatus->sTemp.au16Read[psMibAdcStatus->u8Adc]); /* Temperature reading ? */ if (psMibAdcStatus->u8Adc == E_AHI_ADC_SRC_TEMP) { int16 i16Temp; /* Convert reading to temperature */ i16Temp = MibAdcStatusPatch_i16DeciCentigrade(psMibAdcStatus->u8Adc); if (i16DebugTemp - i16Temp >= 50 || i16DebugTemp - i16Temp <= -50) { /* Debug */ DBG_vPrintf(CONFIG_DBG_MIB_ADC_STATUS, "\n\tMibAdcStatusPatch_i16DeciCentigrade(%d)=%d", psMibAdcStatus->u8Adc, i16Temp); /* UART ? */ #ifdef UART_H_INCLUDED { /* Debug */ UART_vNumber(u32Second, 10); UART_vString(" TEMP @ "); UART_vNumber(i16Temp, 10); UART_vString("C\r\n"); } #endif /* Note last debugged value */ i16DebugTemp = i16Temp; } /* Don't yet have a radio calibration temperature */ if (psMibAdcStatus->i16CalTemp == CONFIG_INT16_MIN) { /* Note current value (radio will have calibrated upon booting) */ psMibAdcStatus->i16CalTemp = i16Temp; } /* Have a calibration value ? */ else { int16 i16Diff; /* Calculate difference from last calibration value */ if (i16Temp > psMibAdcStatus->i16CalTemp) i16Diff = i16Temp - psMibAdcStatus->i16CalTemp; else i16Diff = psMibAdcStatus->i16CalTemp - i16Temp; /* Need to recalibrate the radio ? */ if (i16Diff >= MIB_ADC_TEMP_CALIBRATE) { teCalStatus eCalStatus; /* Attempt calibration */ eCalStatus = eAHI_AttemptCalibration(); /* Success ? */ if (eCalStatus == E_CAL_SUCCESS) { /* Note new calibration temperature */ psMibAdcStatus->i16CalTemp = i16Temp; } /* Debug */ DBG_vPrintf(CONFIG_DBG_MIB_ADC_STATUS, "\n\t%dC eAHI_AttemptCalibration()=%d", i16Temp, eCalStatus); /* UART ? */ #ifdef UART_H_INCLUDED { /* Debug */ UART_vNumber(u32Second, 10); UART_vString(" CALI @ "); UART_vNumber(i16Temp, 10); UART_vString("C\r\n"); } #endif } } /* JN5148 or JN5148J01 ? */ #if (defined(JENNIC_CHIP_JN5148) || defined(JENNIC_CHIP_JN5148J01)) { /* Valid oscillator pin ? */ if (psMibAdcStatus->u8OscPin < 21) { /* Do we need to pull the oscillator ? */ if (i16Temp >= MIB_ADC_TEMP_OSC_PULL_48 && u8MibAdcStatusPatchOscillator != 0x1) { /* Note state */ u8MibAdcStatusPatchOscillator = 0x1; /* Pull oscillator */ MibAdcStatus_vOscillatorPull(TRUE); /* Debug */ DBG_vPrintf(CONFIG_DBG_MIB_ADC_STATUS, "\n\t48 %dC to %dC PULL(%x)", psMibAdcStatus->i16ChipTemp, i16Temp, u8MibAdcStatusPatchOscillator); /* UART ? */ #ifdef UART_H_INCLUDED { /* Debug */ UART_vNumber(u32Second, 10); UART_vString(" OSCI @ "); UART_vNumber(i16Temp, 10); UART_vString("C = "); UART_vNumber(u8MibAdcStatusPatchOscillator, 2); UART_vString("\r\n"); } #endif } /* Do we need to push the oscillator ? */ else if (i16Temp <= MIB_ADC_TEMP_OSC_PUSH_48 && u8MibAdcStatusPatchOscillator != 0x0) { /* Note state */ u8MibAdcStatusPatchOscillator = 0x0; /* Push oscillator */ MibAdcStatus_vOscillatorPull(FALSE); /* Debug */ DBG_vPrintf(CONFIG_DBG_MIB_ADC_STATUS, "\n\t48 %dC to %dC PUSH(%x)", psMibAdcStatus->i16ChipTemp, i16Temp, u8MibAdcStatusPatchOscillator); /* UART ? */ #ifdef UART_H_INCLUDED { /* Debug */ UART_vNumber(u32Second, 10); UART_vString(" OSCI @ "); UART_vNumber(i16Temp, 10); UART_vString("C = "); UART_vNumber(u8MibAdcStatusPatchOscillator, 2); UART_vString("\r\n"); } #endif } } } /* Others ? */ #else { /* Below low push point ? */ if (i16Temp <= MIB_ADC_TEMP_OSC_PUSH_LO && u8MibAdcStatusPatchOscillator != 0x0) { /* Note state */ u8MibAdcStatusPatchOscillator = 0x0; /* Fully push oscillator - clear bits 20 and 21 of TEST3V register */ U32_CLR_BITS(pu32Test3V, (3<<20)); /* Debug */ DBG_vPrintf(CONFIG_DBG_MIB_ADC_STATUS, "\n\t42 %dC to %dC Pull(%x)", psMibAdcStatus->i16ChipTemp, i16Temp, u8MibAdcStatusPatchOscillator); /* UART ? */ #ifdef UART_H_INCLUDED { /* Debug */ UART_vNumber(u32Second, 10); UART_vString(" OSCI @ "); UART_vNumber(i16Temp, 10); UART_vString("C = "); UART_vNumber(u8MibAdcStatusPatchOscillator, 2); UART_vString("\r\n"); } #endif } /* Above high pull point ? */ else if (i16Temp >= MIB_ADC_TEMP_OSC_PULL_HI && u8MibAdcStatusPatchOscillator != 0x3) { /* Note state */ u8MibAdcStatusPatchOscillator = 0x3; /* Fully pull oscillator - set bits 20 and 21 of TEST3V register */ U32_SET_BITS(pu32Test3V, (3<<20)); /* Debug */ DBG_vPrintf(CONFIG_DBG_MIB_ADC_STATUS, "\n\t42 %dC to %dC Pull(%x)", psMibAdcStatus->i16ChipTemp, i16Temp, u8MibAdcStatusPatchOscillator); /* UART ? */ #ifdef UART_H_INCLUDED { /* Debug */ UART_vNumber(u32Second, 10); UART_vString(" OSCI @ "); UART_vNumber(i16Temp, 10); UART_vString("C = "); UART_vNumber(u8MibAdcStatusPatchOscillator, 2); UART_vString("\r\n"); } #endif } /* Below high push point or above low pull point ? */ else if (i16Temp <= MIB_ADC_TEMP_OSC_PUSH_HI && i16Temp >= MIB_ADC_TEMP_OSC_PULL_LO && u8MibAdcStatusPatchOscillator != 0x1) { /* Note state */ u8MibAdcStatusPatchOscillator = 0x1; /* Half pull oscillator - clear bit 20 and set bit 21 of TEST3V register */ U32_CLR_BITS(pu32Test3V, (1<<20)); U32_SET_BITS(pu32Test3V, (1<<21)); /* Debug */ DBG_vPrintf(CONFIG_DBG_MIB_ADC_STATUS, "\n\t42 %dC to %dC Pull(%x)", psMibAdcStatus->i16ChipTemp, i16Temp, u8MibAdcStatusPatchOscillator); /* UART ? */ #ifdef UART_H_INCLUDED { /* Debug */ UART_vNumber(u32Second, 10); UART_vString(" OSCI @ "); UART_vNumber(i16Temp, 10); UART_vString("C = "); UART_vNumber(u8MibAdcStatusPatchOscillator, 2); UART_vString("\r\n"); } #endif } } #endif /* Note current value */ psMibAdcStatus->i16ChipTemp = i16Temp; } /* Return the source we just read */ return psMibAdcStatus->u8Adc; }
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(); }