Esempio n. 1
0
void setup(void)
{
    wdt_reset();
    wdtDisable();
    setPinsOutput();
    randomMode = btn.read();                //invoke random wake mode if button pressed
    while (btn.isPressed()) btn.read();     //wait for the button to be released
    msRunTime = randomMode ? RANDOM_RUN_MS : MANUAL_RUN_MS;
    wdtLimit = random(RANDOM_SLEEP_MIN, RANDOM_SLEEP_MAX + 1);
}
Esempio n. 2
0
void goToSleep(void)
{
    do {
        GIMSK |= _BV(INT0);                       //enable INT0
        MCUCR &= ~(_BV(ISC01) | _BV(ISC00));      //INT0 on low level
        ACSR |= _BV(ACD);                         //disable the analog comparator
        ADCSRA &= ~_BV(ADEN);                     //disable ADC
        set_sleep_mode(SLEEP_MODE_PWR_DOWN);
        sleep_enable();
        if (randomMode) wdtEnable();              //start the WDT if we're in random mode
        //turn off the brown-out detector.
        //must have an ATtiny45 or ATtiny85 rev C or later for software to be able to disable the BOD.
        //current while sleeping will be <0.5uA if BOD is disabled, <25uA if not.
        cli();
        mcucr1 = MCUCR | _BV(BODS) | _BV(BODSE);  //turn off the brown-out detector
        mcucr2 = mcucr1 & ~_BV(BODSE);
        MCUCR = mcucr1;
        MCUCR = mcucr2;
        sei();                         //ensure interrupts enabled so we can wake up again
        sleep_cpu();                   //go to sleep
                                       //----zzzz----zzzz----zzzz----zzzz
        cli();                         //wake up here, disable interrupts
        GIMSK = 0x00;                  //disable INT0
        sleep_disable();
        wdtDisable();                  //don't need the watchdog while we're awake
        sei();                         //enable interrupts again (but INT0 is disabled above)
        if (buttonWake) {              //what woke us
            keepSleeping = false;      //the button woke us, so turn the lights on again
            msRunTime = MANUAL_RUN_MS;
            btn.read();
            while (!btn.wasReleased()) btn.read();        //wait for the button to be released
        }
        else if (randomMode && (++wdtCount < wdtLimit)) {
            keepSleeping = true;
            //setPinsOutput();            //briefly blink an LED so we can see the wdt wake-ups
            //digitalWrite(LED4, HIGH);
            //_delay_ms(10);
            //setPinsInput();
        }
        else {
            keepSleeping = false;
            msRunTime = RANDOM_RUN_MS;
            if (++mode > MAX_MODE) mode = 0;
        }
    } while (keepSleeping);
    
    setPinsOutput();
    buttonWake = false;
    msWakeUp = millis();
    if (randomMode) {              //set up for next time
        wdtCount = 0;
        wdtLimit = random(RANDOM_SLEEP_MIN, RANDOM_SLEEP_MAX + 1);
    }
}
Esempio n. 3
0
void main(void) {
    static uint32_t dataPointer = 0;
    static uint32_t readPointer = 0;
    static uint32_t dataAddress;
    static uint32_t dataLength;
    static uint16_t bufPointer = 0;
    uint8_t c = 0;
    uint8_t uart = 0;

    wdtDisable();

    // Move Interrupt Vectors into Bootloader Section
    c = INTERRUPTMOVE;
    INTERRUPTMOVE = c | (1 << IVCE);
    INTERRUPTMOVE = c | (1 << IVSEL);

    TCRA |= (1 << WGM21); // CTC Mode
#if F_CPU == 16000000
    TCRB |= (1 << CS22); // Prescaler: 64
    OCR = 250;
#else
#error F_CPU not compatible with timer module. DIY!
#endif
    TIMS |= (1 << OCIE); // Enable compare match interrupt

    for (uint8_t i = 0; i < serialAvailable(); i++) {
        serialInit(i, BAUD(BAUDRATE, F_CPU));
    }
    sei();
    set(buf, 0xFF, sizeof(buf));

    debugPrint("YASAB ");
    debugPrint(VERSION);
    debugPrint(" by xythobuz\n");

    while (systemTime < BOOTDELAY) {
        for (uint8_t i = 0; i < serialAvailable(); i++) {
            if (serialHasChar(i)) {
                c = serialGet(i); // Clear rx buffer
                uart = i;
                goto ok; // Yeah, shame on me...
            }
        }
    }
    gotoApplication();

ok:
    serialWrite(uart, OKAY);
    while (!serialTxBufferEmpty(uart)); // Wait till it's sent

    uint32_t t = systemTime;
    while (systemTime < (t + BOOTDELAY)) {
        if (serialHasChar(uart)) {
            if (serialGet(uart) == CONFIRM) {
                goto ack; // I deserve it...
            }
        }
    }
    gotoApplication();

ack:
    serialWrite(uart, ACK);
    while (!serialTxBufferEmpty(uart));

    dataAddress = readFourBytes(uart, serialGetBlocking(uart));
    serialWrite(uart, OKAY);
    while (!serialTxBufferEmpty(uart)); // Wait till it's sent
    debugPrint("Got address!\n");

    dataLength = readFourBytes(uart, serialGetBlocking(uart));
    if ((dataAddress + dataLength) >= BOOTSTART) {
        serialWrite(uart, ERROR);
    } else {
        serialWrite(uart, OKAY);
    }
    while (!serialTxBufferEmpty(uart));
    debugPrint("Got length!\n");

    while (readPointer < dataLength) {
        buf[bufPointer] = serialGetBlocking(uart);
        readPointer++;
        if (bufPointer < (SPM_PAGESIZE - 1)) {
            bufPointer++;
        } else {
            bufPointer = 0;
            program(uart, dataPointer + dataAddress, buf);
            dataPointer += SPM_PAGESIZE;
            set(buf, 0xFF, sizeof(buf));
            serialWrite(uart, OKAY);
        }
    }

    debugPrint("Got data!\n");

    if (bufPointer != 0) {
        program(uart, dataPointer + dataAddress, buf);
        serialWrite(uart, OKAY);
    }

    uint8_t sreg = SREG;
    cli();
    boot_spm_busy_wait();
    boot_rww_enable(); // Allows us to jump to application
    SREG = sreg;

    gotoApplication();
}