Saturday, June 19, 2010

PIC wake from SLEEP on serial port RX hack

I am writing firmware for my ABPM controller. One important feature I require is to be able to configure and control it via a serial interface (ie RS232 at 0/5V voltage levels). As this will be an always-on battery powered device it will spend most of it's time in SLEEP state to conserve power. The PIC16F627A, my current target of choice, can wake from sleep on almost any peripheral activity. Unfortunately this does not include the USART in asynchronous mode (presumably because the baud rate clock consumes too much power).

Fortunately there is a hack to get around this problem: tie the RX line together with the INT pin of the PIC. Any activity on the bus will trigger an INT interrupt which can be used to tell the device to wake up and go into alert mode to accept commands via the serial bus.

The down side of this approach is that it uses the INT pin (although its use can be shared if necessary) and the first character to arrive while sleeping will be corrupted. This is not a problem: just hit RETURN a few times if  using a terminal emulator, or prefix any command sequence with a few CR characters if issuing the commands from software.

The code (I'm using the free HiTech's PIC C 'Lite' edition) looks something like this:

// variables shared with interrupts must be declared as volatile
volatile unsigned char sleepMode;

main () {

    // setup stuff...

    // main loop
    while (1) {

        // do work...

        if (sleepMode) {
            SLEEP();
        } else {
            // need to clear watchdog timer frequently
            CLRWDT();
        }
    }

}
// interrupt handler
interrupt isr () {

    // check for INT interrupt
    if (INTF) {
        // clear interrupt flag, else it will be retriggered
        INTF = 0;
        // inform main loop that we are now awake
        sleepMode = 0;
    }

    // check other interrupts...
}

No comments: