ButterflyMP3
|
00001 00037 #include <avr/io.h> 00038 #include <avr/pgmspace.h> 00039 #include <avr/interrupt.h> 00040 00041 #include "power.h" 00042 #include "main.h" 00043 #include "types.h" 00044 #include "uart.h" 00045 #include "vs1001.h" 00046 #include "lcdgraphics.h" 00047 #include "eeprom.h" 00048 #include "ADC.h" 00049 #include "button.h" 00050 00051 00058 void Power_save(void) 00059 { 00060 // PRINT("pDWN"); 00061 SMCR = (2<<SM0) | (1<<SE); // Enable Power-down mode 00062 asm volatile ("sleep"::); 00063 // NOTE: need to hit a button when inserting card to wakeup. !! 00064 // will add RTC later for power down time out etc which should 00065 // wake up and detect card once a second. 00066 SMCR = 0; // Just woke, disable sleep 00067 } 00068 00069 00076 void Power_idle(void) 00077 { 00078 //PRINT("pIDLE"); 00079 SMCR = (1<<SE); // Enable idle mode 00080 asm volatile ("sleep"::); 00081 00082 SMCR = 0; // Just woke, disable sleep 00083 } 00084 00085 00091 void Power_off(void) 00092 { 00093 char k; 00094 PRINT("pOFF");EOL(); 00095 #ifdef VS1001 00096 uint16 buf[2]; 00097 #endif 00098 00099 //SHUTDOWN LCD 00100 LCD_Sleep(); 00101 00102 //SHUTDOWN UART 00103 UART_Shutdown(); 00104 00105 //SHUTDOWN vs1001k 00106 #ifdef VS1001 00107 vs1001_read(SCI_MODE, 1, buf); 00108 buf[1] |= SM_PDOWN; 00109 vs1001_write(SCI_MODE,1,buf); 00110 #else 00111 //TODO: put routines for vs1011e here! 00112 #endif 00113 CBI(RESET_PORT, RESET_PIN); // RESET- low 00114 // RESET_PIN is pulled low by external resistor ( R9 rev C) during bootloader mode 00115 // R9 is neccesary to hold reset low while Butterfly is in bootloader mode. 00116 00117 //MMC should go into shutdown by default as per 00118 //"SanDisk MultiMediaCard and Reduced-Size MultiMediaCard Product Manual" 00119 //Doc No. 80-36-00320 v1.0 page 1-4 sec 1.10 00120 00121 while(1){ 00122 // Put into low power mode (no write to eeprom) 00123 Power_save(); 00124 00125 if(!(PINB & (1<<PINB6))) // mt if(!(PINB & (1<<PORTB6))) 00126 { // joystick "up" detected 00127 00128 //wake up UART 00129 UART_Init(); 00130 00131 //wake up VS1001 00132 SBI(RESET_PORT, RESET_PIN); // RESET- Hi 00133 00134 //wake up LCD 00135 LCD_Wake(); 00136 00137 // wait for up key to be released to avoid double detect. 00138 while (!(PINB & (1<<PINB6))); 00139 00140 k = getkey(); //clear the key buffer of any false detections 00141 gPowerSaveTimer = 0; // reset the timeout. 00142 00143 return; 00144 } 00145 else if(!(PINB & (1<<PINB7))) 00146 { //Joystick "down" detected 00147 00148 //save current settings 00149 save_player_options(); 00150 00151 //TODO: Write MMC Serial Number to EEPROM 00152 00153 //write current song to EEPROM 00154 save_player_state(); 00155 00156 //Jump to Bootloader 00157 WDTCR = (1<<WDCE) | (1<<WDE); //Enable Watchdog Timer to give reset 00158 while(1); 00159 // wait for watchdog-reset, since the BOOTRST-fuse is 00160 // programmed, the Boot-section will be entered upon reset. 00161 00162 // Press UP to turn on again. (and exit the bootloader) 00163 00164 } 00165 } 00166 00167 // NOTE: for the standby mode to work as intended, the butterfly must have 00168 // the original bootloader installed and have the 00169 // "Boot Reset vector Enabled - BOOTRST" fuse programmed. 00170 00171 } 00172 00179 void Power_Init(void) 00180 { 00181 00182 // clear portf for ADC use 00183 DDRF = 0x00; 00184 PORTF = 0x00; 00185 00186 //setup adc internal 1.1 volt reference and voltage sensor 00187 ADMUX = VOLTAGE_SENSOR|(1<<REFS0)|(1<<REFS1); 00188 //Free running mode 00189 ADCSRB = (0<<ADTS2) |(0<<ADTS1) |(0<<ADTS0); 00190 // set ADC prescaler to , 8MHz / 128 = 62.5kHz , auto trigger 00191 ADCSRA = (1<<ADEN)| (1<<ADSC) | (0<<ADATE) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0); 00192 00193 } 00194 00195 00196 00197 00205 uint16 Power_check(void) 00206 { 00207 uint8 i; 00208 uint16 batteryVoltage=0; 00209 uint32 ADC_temp; 00210 00211 // Check Battery Voltage. 00212 ADCSRA |= (1<<ADEN)|(1<<ADSC); //Start ADC 00213 while(!(ADCSRA & 0x10)); // wait for conversion done, ADIF flag active 00214 00215 for(i=0;i<8;i++) // do the ADC conversion 8 times for better accuracy 00216 { 00217 ADCSRA |= (1<<ADSC); // do single conversion 00218 while(!(ADCSRA & 0x10)); // wait for conversion done, ADIF flag active 00219 00220 ADC_temp = ADCL; // read out ADCL register 00221 ADC_temp += (ADCH << 8); // read out ADCH register 00222 00223 batteryVoltage += ADC_temp; // accumulate result (8 samples) for later averaging 00224 } 00225 00226 batteryVoltage = batteryVoltage >> 3; // average the 8 samples 00227 00228 ADCSRA &= ~((1<<ADEN)); 00229 //ADCSRA |= (1<<ADIF); //reset interruppt flag 00230 00231 PRINT("VOLTAGE "); 00232 UART_Printfu16(batteryVoltage); 00233 EOL(); 00234 00235 return batteryVoltage; 00236 } 00237 00254 uint16 Power_pcnt(uint16 voltage) 00255 { 00256 uint16 percentage; 00257 00258 if (voltage > PWR_MAX_V){ // battery is really really good 00259 percentage = 100; 00260 00261 }else if (voltage> PWR_GOOD_V){ // battery is freshly charged 00262 percentage = (voltage - PWR_GOOD_V) * (100-66); 00263 percentage /= (PWR_MAX_V -PWR_GOOD_V); 00264 percentage += 66; 00265 00266 }else if (voltage>PWR_LOW_V){ // normal operation mode 00267 percentage = (voltage - PWR_LOW_V) * (66-12); 00268 percentage /= (PWR_GOOD_V - PWR_LOW_V); 00269 percentage += 12; 00270 00271 }else{ // only 12% left 00272 percentage = (voltage - PWR_ABS_MIN_V) * (12-0); 00273 percentage /= (PWR_LOW_V - PWR_ABS_MIN_V); 00274 00275 } 00276 00277 // old calculation 00278 //percentage = (voltage-PWR_ABS_MIN_V)*100/(PWR_MAX_V-PWR_ABS_MIN_V); 00279 00280 return percentage; 00281 } 00282