Пример #1
0
void appMain(void)
{
    uint16_t i;

    // ------------------------- serial number
    DPRINTF("Mote %#04x starting...\n", localAddress);

    // ------------------------- external flash
#if WRITE_TO_FLASH
    prepareExtFlash();
#endif

    // ------------------------- light sensors
    if (localAddress != 0x0796) {
        PRINT("init isl\n");
        islInit();
        islOn();
    } else {
        PRINT("init ads\n");
        adsInit();
        adsSelectInput(0);
    }

    // ------------------------- main loop
    mdelay(3000);
    DPRINTF("starting main loop...\n");
    for (i = 0; i < 6; ++i) {
        redLedToggle();
        mdelay(100);
    }
    ledOff();

    uint32_t nextDataReadTime = 0;
    uint32_t nextBlinkTime = 0;
    for (;;) {
        uint32_t now = getRealTime();
        if (timeAfter32(now, nextDataReadTime)) {
            if (getJiffies() < 300 * 1000ul ) {
                nextDataReadTime = now + DATA_INTERVAL_SMALL;
            } else {
                nextDataReadTime = now + DATA_INTERVAL;
            }
            DataPacket_t packet;
            readSensors(&packet);
#if PRINT_PACKET
            printPacket(&packet);
#endif
        }
        if (timeAfter32(now, nextBlinkTime)) {
            nextBlinkTime = now + BLINK_INTERVAL;
            ledOn();
            msleep(100);
            ledOff();
        }
        msleep(1000);
    }
}
Пример #2
0
void alarmsProcess(void)
{
    //
    // Note that this code works in the way that neither locking the list
    // nor disabling interrupts is required
    //
    uint32_t now = (uint32_t) getJiffies();

    // PRINTF("processAlarms: jiffies=%lu\n", now);

    Alarm_t **a = &SLIST_FIRST(&alarmListHead);
    while (*a) {
        Alarm_t *ap = *a;

        // the alarm must have valid callback
        ASSERT(ap->callback != NULL);

//        PRINTF("processAlarms: ap=%p, ap->jiffies=%lu\n", ap, ap->jiffies);

        if (timeAfter32(ap->jiffies, now)) {
            break;
        }

        // save next alarm for later reference
        Alarm_t **next = &SLIST_NEXT(ap, chain);
        // remove the alarm from the list
        *a = *next;
        // call the callback
        ap->callback(ap->data);
        // move to the next
        a = next;
    }
}
Пример #3
0
void alarmSchedule(Alarm_t *alarm, uint32_t milliseconds)
{
    // we want to avoid inserting local variables in the global alarm list
    // (but this warning, not an error, because the user function may never return)
    WARN_ON(isStackAddress(alarm));

    // PRINTF("alarmSchedule %p, ms=%lu\n", alarm, milliseconds);
    alarm->jiffies = (uint32_t)getJiffies() + milliseconds;

    // locking is required, because both kernel and user threads can be using this function
    Handle_t h;
    ATOMIC_START(h);

    // unschedule the alarm, if it was already scheduled
    SLIST_REMOVE_SAFE(&alarmListHead, alarm, Alarm_s, chain);

    // insert it in appropriate position
    Alarm_t **prev = &SLIST_FIRST(&alarmListHead);
    Alarm_t *a = *prev;
    while (a && timeAfter32(alarm->jiffies, a->jiffies)) {
        prev = &SLIST_NEXT(a, chain);
        a = *prev;
    }
    SLIST_INSERT(prev, alarm, chain);

#if USE_THREADS
    // always reschedule alarm processing in case some alarm was added
    // that might need to be processed before end of current kernel sleep time
    processFlags.bits.alarmsProcess = true;
    // and make sure the kernel thread is awake and ready to deal with it
    threadWakeup(KERNEL_THREAD_INDEX, THREAD_READY);
#endif

    ATOMIC_END(h);
}
Пример #4
0
static uint8_t markAsSeen(MosShortAddr address, bool addNew)
{
    uint32_t now = (uint32_t) getJiffies();
    // MOTE_INFO_VALID_TIME - ?
    uint8_t i;
    for (i = 0; i < MAX_MOTES; ++i) {
        if (motes[i].address == address) {
            break;
        }
    }
    if (i == MAX_MOTES && addNew) {
        for (i = 0; i < MAX_MOTES; ++i) {
            if (motes[i].address == 0
                    || timeAfter32(now, motes[i].validUntil)) {
                break;
            }
        }
        // save its address
        motes[i].address = address;
    }
    if (i == MAX_MOTES) {
        if (addNew) PRINTF("recv rreq: no more space!\n");
        return 0xff;
    }

    // mark it as seen
    motes[i].validUntil = now + MOTE_INFO_VALID_TIME;
    return i;
}
Пример #5
0
// alarm timer interrupt handler
ALARM_TIMER_INTERRUPT()
{
    // read & unset the highest bit
    volatile uint16_t x = TIMER_INTERRUPT_VECTOR;
    (void) x;

    if (isInSleepMode) {
        // wakeup and return
        EXIT_SLEEP_MODE();
        return;
    }

    uint16_t tar = ALARM_TIMER_READ();

    // Advance jiffies (MansOS time counter) while counter register <= counter
    // Spurios interrupts may happen when the alarm timer is restarted after stopping!
    while (!timeAfter16(ALARM_TIMER_REGISTER, tar)) {
        jiffies += JIFFY_TIMER_MS;
        ALARM_TIMER_REGISTER += PLATFORM_ALARM_TIMER_PERIOD;
    }

#if PLATFORM_HAS_CORRECTION_TIMER
    //
    // On MSP430 platforms binary ACLK oscillator usually is used.
    // It has constant rate 32768 Hz (the ACLK_SPEED define)
    // When ACLK ticks are converted to milliseconds, rounding error is introduced.
    // When TIMER_INTERRUPT_HZ = 1000, there are 32 ACLK ticks per millisecond;
    // The clock error is (32768 / 32) - 1000 = 1024 - 1000 = 24 milliseconds.
    // We improve the precision by applying a fix 24/3 = 8 times per second.
    //
    while (!timeAfter16(CORRECTION_TIMER_REGISTER, tar)) {
        CORRECTION_TIMER_REGISTER += PLATFORM_TIME_CORRECTION_PERIOD;
        jiffies -= 3;
    }
#endif

#ifdef USE_ALARMS
    if (hasAnyReadyAlarms(jiffies)) {
        alarmsProcess();
    }
#endif
#ifdef USE_PROTOTHREADS
    if (etimer_pending() && !etimer_polled()
            && !timeAfter32(jiffies, etimer_next_expiration_time())) {
         etimer_request_poll();
         EXIT_SLEEP_MODE();
    }
#endif

    // If TAR still > TACCR0 at this point, we are in trouble:
    // the interrupt will not be generated until the next wraparound (2 seconds).
    // So avoid it at all costs.
    while (!timeAfter16(ALARM_TIMER_REGISTER, ALARM_TIMER_READ() + 2)) {
        jiffies += JIFFY_TIMER_MS;
        ALARM_TIMER_REGISTER += PLATFORM_ALARM_TIMER_PERIOD;
    }
}
Пример #6
0
//-------------------------------------------
//      Entry point for the application
//-------------------------------------------
void appMain(void)
{
    PRINTF("\n\nAccelerometer data gathering app\n");

    extFlashWake();

    // start with clean and new...
    cleanFlash();

    accelOn();

    userButtonEnable(onUserButton);

    mdelay(START_DELAY);

    uint16_t lastSecond;
    uint16_t samplesPerSecond;

    for (;;) {
        while (!isActiveMode);

        redLedOn();

        lastSecond = getTimeSec();
        samplesPerSecond = 0;

        uint16_t i;
        for (i = 0; isActiveMode; i++) {
            if (i % 10 == 0) redLedToggle();

            uint32_t now = getTimeMs();
            uint32_t endTime = now + MAIN_LOOP_LENGTH;

            Packet_t p;
            p.timestamp = now;

            p.acc_x = accelReadX();
            p.acc_y = accelReadY();
            p.acc_z = accelReadZ();

            printPacket(&p);

            samplesPerSecond++;

            uint16_t currentSecond = getTimeSec();
            if (currentSecond != lastSecond) {
                PRINTF("samples per second = %u\n", samplesPerSecond);
                lastSecond = currentSecond;
                samplesPerSecond = 0;
            } 

            while (timeAfter32(endTime, getTimeMs()));
        }

        redLedOff();
    }
}
Пример #7
0
static inline bool isRoutingInfoValid(void)
{
    if (hopCountToRoot >= MAX_HOP_COUNT) return false;
    bool old = timeAfter32((uint32_t)getJiffies(), lastRootMessageTime + ROUTING_INFO_VALID_TIME);
    if (old) {
        hopCountToRoot = MAX_HOP_COUNT;
        return false;
    }
    return true;
}
Пример #8
0
uint32_t readSensorU32(uint16_t code, ReadFunctionU32 func, uint16_t expireTime)
{
    uint32_t now = getJiffies();
    SensorCache_t *cacheValue = &sensorCache[code];
    if (cacheValue->expireTime && !timeAfter32(now, cacheValue->expireTime)) {
        // take from cache
        return cacheValue->value.u32;
    }
    uint32_t result = func();
    if (expireTime) {
        // add to cache
        cacheValue->value.u32 = result;
        cacheValue->expireTime = now + expireTime;
    }
    return result;
}
Пример #9
0
static void roForwardTimerCb(void *x)
{
    static uint8_t moteToProcess;

    bool roOK = isRoutingInfoValid();

    if (motes[moteToProcess].address != 0
            && timeAfter32(motes[moteToProcess].validUntil, (uint32_t)getJiffies())
            && hopCountToRoot < MAX_HOP_COUNT
            && roOK) {
        forwardRoutingInfo(moteToProcess);
    }

    moteToProcess++;
    if (moteToProcess == MAX_MOTES) moteToProcess = 0;

    alarmSchedule(&roForwardTimer, calcNextForwardTime(moteToProcess));
}