The Smart Card Detective (SCD)
|
00001 00036 #include <avr/interrupt.h> 00037 #include <avr/sleep.h> 00038 00039 #include "utils.h" 00040 #include "scd_io.h" 00041 00042 void Write16bitRegister(volatile uint16_t *reg, uint16_t value) 00043 { 00044 uint8_t sreg; 00045 00046 sreg = SREG; 00047 cli(); 00048 *reg = value; 00049 SREG = sreg; 00050 } 00051 00052 uint16_t Read16bitRegister(volatile uint16_t *reg) 00053 { 00054 uint16_t i; 00055 uint8_t sreg; 00056 00057 sreg = SREG; 00058 cli(); 00059 i = *reg; 00060 SREG = sreg; 00061 00062 return i; 00063 } 00064 00069 void SleepUntilTerminalClock() 00070 { 00071 uint8_t sreg, lcdstate; 00072 00073 Write16bitRegister(&OCR3A, 100); 00074 Write16bitRegister(&TCNT3, 1); 00075 TCCR3A = 0; 00076 TIMSK3 = 0x02; //Interrupt on Timer3 compare A match 00077 TCCR3B = 0x0F; // CTC, timer external source 00078 sreg = SREG; 00079 00080 // stop LCD and LEDs before going to sleep 00081 lcdstate = GetLCDState(); 00082 if(lcdAvailable && lcdstate != 0) LCDOff(); 00083 Led1Off(); 00084 Led2Off(); 00085 Led3Off(); 00086 Led4Off(); 00087 00088 // go to sleep 00089 set_sleep_mode(SLEEP_MODE_IDLE); // it is also possible to use sleep_mode() below 00090 cli(); 00091 sleep_enable(); 00092 sei(); 00093 sleep_cpu(); 00094 00095 // back from sleep 00096 sleep_disable(); 00097 SREG = sreg; 00098 TIMSK3 = 0; // disable interrupts on Timer3 00099 TCCR3B = 0; // stop timer 00100 Led4On(); 00101 } 00102 00107 void SleepUntilCardInserted() 00108 { 00109 uint8_t sreg, lcdstate; 00110 00111 // stop LCD and LEDs before going to sleep 00112 lcdstate = GetLCDState(); 00113 if(lcdAvailable && lcdstate != 0) LCDOff(); 00114 Led1Off(); 00115 Led2Off(); 00116 Led3Off(); 00117 Led4Off(); 00118 00119 // go to sleep 00120 sreg = SREG; 00121 set_sleep_mode(SLEEP_MODE_PWR_DOWN); 00122 cli(); 00123 sleep_enable(); 00124 sei(); 00125 sleep_cpu(); 00126 00127 // back from sleep 00128 sleep_disable(); 00129 SREG = sreg; 00130 Led4On(); 00131 } 00132