00001 /* 00002 * Copyright (c) 2008 Swedish Institute of Computer Science 00003 * All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions are met: 00007 * 00008 * * Redistributions of source code must retain the above copyright 00009 * notice, this list of conditions and the following disclaimer. 00010 * * Redistributions in binary form must reproduce the above copyright 00011 * notice, this list of conditions and the following disclaimer in 00012 * the documentation and/or other materials provided with the 00013 * distribution. 00014 * * Neither the name of the copyright holders nor the names of 00015 * contributors may be used to endorse or promote products derived 00016 * from this software without specific prior written permission. 00017 * 00018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00019 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00020 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00021 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 00022 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00023 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00024 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00025 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00026 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00027 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00028 * POSSIBILITY OF SUCH DAMAGE. 00029 */ 00030 /** 00031 * \file 00032 * 00033 * \brief 00034 * This controls the sleep operation for the LCD. 00035 * 00036 * \author 00037 * Mike Vidales mavida404@gmail.com 00038 * 00039 */ 00040 00041 #include <avr/interrupt.h> 00042 #include <avr/sleep.h> 00043 #include <avr/wdt.h> 00044 #include <util/delay.h> 00045 #include <stdbool.h> 00046 #include "main.h" 00047 #include "sleep.h" 00048 #include "uart.h" 00049 #include "key.h" 00050 #include "timer.h" 00051 #include "lcd.h" //temp 00052 00053 /** 00054 * \addtogroup lcd 00055 * \{ 00056 */ 00057 00058 /*---------------------------------------------------------------------------*/ 00059 00060 /** 00061 * \brief Prepares for and executes sleep. This function sets up the 00062 * processor to enter sleep mode, and to wake up when the joystick 00063 * button (PE2/PCINT2) is pressed or after the specified interval. 00064 * 00065 * \param howlong Seconds to sleep, 0=until button pushed 00066 */ 00067 void 00068 sleep_now(int howlong) 00069 { 00070 /* Disable watchdog (not currently used elsewhere) */ 00071 wdt_disable(); 00072 00073 /* Setup sleep mode */ 00074 if (howlong==0) { 00075 set_sleep_mode(SLEEP_MODE_PWR_DOWN); 00076 MCUCR |= (1<<JTD); //Disable JTAG so clock can stop 00077 } else { 00078 set_sleep_mode(SLEEP_MODE_PWR_SAVE); 00079 /* Using 8 bit TIMER2 */ 00080 TCNT2 = 0; 00081 TCCR2A = (1<<CS22)|(1<<CS21)|(1<<CS20); //Prescale by 1024 00082 TIMSK2 = (1<<TOIE2); //Enable overflow interrupt 00083 howlong*=30; //which is approximately 30 Hz 00084 00085 /* Using 16 bit TIMER1, which takes a bit more power 00086 timer_stop; //Disable interrupt 00087 timer_init; //make sure initialized for 1 second 00088 timer_start; //Start timer, enable interrupt 00089 */ 00090 } 00091 00092 /* Enable pin change 0 wakeup interrupt */ 00093 EIMSK |= (1 << PCIE0); 00094 /* Select joystick button input pin */ 00095 PCMSK0 |= (1 << PCINT2); 00096 00097 /* Sleep until timeout or button pushed */ 00098 while (ENTER_PORT & (1<<ENTER_PIN)) { 00099 sleep_mode(); 00100 if (!howlong--) break; 00101 } 00102 00103 /* Disable the interrupts for the enter button and TIMER2 */ 00104 EIMSK &= ~(1 << PCIE0); 00105 PCMSK0&= ~(1 <<PCINT2); 00106 TIMSK2&= ~(1 << TOIE2); 00107 } 00108 00109 /*---------------------------------------------------------------------------*/ 00110 00111 /** 00112 00113 * \brief This will send a wakeup command to ATmega1284p 00114 * It may already be awake, if not it will respond during the next wake cycle 00115 * Upon receiving the command it will return an acknowledgement frame 00116 * 00117 * \brief This will send a single character forever to the ATmega1284p to cause a wakeup. 00118 * The 1284p polls the USART for new data during each sleep cycle. Upon receiving a 00119 * character from the user LCD, it will wake up and send an acknowledgement frame. 00120 */ 00121 void 00122 sleep_wakeup(void) 00123 { 00124 lcd_puts_P(PSTR("WAKE 1284p")); 00125 00126 /* Flood 1284p with wake commands until it responds*/ 00127 for(;;){ 00128 uart_serial_send_frame(SEND_WAKE,0,0); 00129 _delay_us(1000); 00130 if (rx_char_ready()) 00131 break; 00132 } 00133 00134 /* Get a frame back */ 00135 uart_serial_rcv_frame(true); 00136 } 00137 00138 /*---------------------------------------------------------------------------*/ 00139 00140 /** 00141 * \brief This is the wake up button interrupt. When this interrupt fires, 00142 * nothing is done. The program will simply continue from the end of the sleep 00143 * command. 00144 */ 00145 ISR 00146 (PCINT0_vect) 00147 { 00148 00149 } 00150 /*---------------------------------------------------------------------------*/ 00151 00152 /** 00153 * \brief This is the timer2 overflow interrupt. When this interrupt fires, 00154 * the CPU will wake. 00155 */ 00156 ISR 00157 (TIMER2_OVF_vect) 00158 { 00159 00160 } 00161 00162 /** \} */