diff options
Diffstat (limited to 'tmk_core/common/avr')
-rw-r--r-- | tmk_core/common/avr/bootloader.c | 365 | ||||
-rw-r--r-- | tmk_core/common/avr/sleep_led.c | 43 | ||||
-rw-r--r-- | tmk_core/common/avr/suspend.c | 171 | ||||
-rw-r--r-- | tmk_core/common/avr/suspend_avr.h | 32 | ||||
-rw-r--r-- | tmk_core/common/avr/timer.c | 61 | ||||
-rw-r--r-- | tmk_core/common/avr/timer_avr.h | 26 | ||||
-rw-r--r-- | tmk_core/common/avr/xprintf.h | 17 |
7 files changed, 361 insertions, 354 deletions
diff --git a/tmk_core/common/avr/bootloader.c b/tmk_core/common/avr/bootloader.c index 29036f7c5..5f9ecc510 100644 --- a/tmk_core/common/avr/bootloader.c +++ b/tmk_core/common/avr/bootloader.c | |||
@@ -9,10 +9,9 @@ | |||
9 | #include <avr/boot.h> | 9 | #include <avr/boot.h> |
10 | 10 | ||
11 | #ifdef PROTOCOL_LUFA | 11 | #ifdef PROTOCOL_LUFA |
12 | #include <LUFA/Drivers/USB/USB.h> | 12 | # include <LUFA/Drivers/USB/USB.h> |
13 | #endif | 13 | #endif |
14 | 14 | ||
15 | |||
16 | /** \brief Bootloader Size in *bytes* | 15 | /** \brief Bootloader Size in *bytes* |
17 | * | 16 | * |
18 | * AVR Boot section size are defined by setting BOOTSZ fuse in fact. Consult with your MCU datasheet. | 17 | * AVR Boot section size are defined by setting BOOTSZ fuse in fact. Consult with your MCU datasheet. |
@@ -57,19 +56,19 @@ | |||
57 | #define FLASH_SIZE (FLASHEND + 1L) | 56 | #define FLASH_SIZE (FLASHEND + 1L) |
58 | 57 | ||
59 | #if !defined(BOOTLOADER_SIZE) | 58 | #if !defined(BOOTLOADER_SIZE) |
60 | uint16_t bootloader_start; | 59 | uint16_t bootloader_start; |
61 | #endif | 60 | #endif |
62 | 61 | ||
63 | #define BOOT_SIZE_256 0b110 | 62 | #define BOOT_SIZE_256 0b110 |
64 | #define BOOT_SIZE_512 0b100 | 63 | #define BOOT_SIZE_512 0b100 |
65 | #define BOOT_SIZE_1024 0b010 | 64 | #define BOOT_SIZE_1024 0b010 |
66 | #define BOOT_SIZE_2048 0b000 | 65 | #define BOOT_SIZE_2048 0b000 |
67 | 66 | ||
68 | //compatibility between ATMega8 and ATMega88 | 67 | // compatibility between ATMega8 and ATMega88 |
69 | #if !defined (MCUCSR) | 68 | #if !defined(MCUCSR) |
70 | #if defined (MCUSR) | 69 | # if defined(MCUSR) |
71 | #define MCUCSR MCUSR | 70 | # define MCUCSR MCUSR |
72 | #endif | 71 | # endif |
73 | #endif | 72 | #endif |
74 | 73 | ||
75 | /** \brief Entering the Bootloader via Software | 74 | /** \brief Entering the Bootloader via Software |
@@ -77,163 +76,223 @@ | |||
77 | * http://www.fourwalledcubicle.com/files/LUFA/Doc/120730/html/_page__software_bootloader_start.html | 76 | * http://www.fourwalledcubicle.com/files/LUFA/Doc/120730/html/_page__software_bootloader_start.html |
78 | */ | 77 | */ |
79 | #define BOOTLOADER_RESET_KEY 0xB007B007 | 78 | #define BOOTLOADER_RESET_KEY 0xB007B007 |
80 | uint32_t reset_key __attribute__ ((section (".noinit,\"aw\",@nobits;"))); | 79 | uint32_t reset_key __attribute__((section(".noinit,\"aw\",@nobits;"))); |
81 | 80 | ||
82 | /** \brief initialize MCU status by watchdog reset | 81 | /** \brief initialize MCU status by watchdog reset |
83 | * | 82 | * |
84 | * FIXME: needs doc | 83 | * FIXME: needs doc |
85 | */ | 84 | */ |
86 | void bootloader_jump(void) { | 85 | void bootloader_jump(void) { |
86 | #if !defined(BOOTLOADER_SIZE) | ||
87 | uint8_t high_fuse = boot_lock_fuse_bits_get(GET_HIGH_FUSE_BITS); | ||
87 | 88 | ||
88 | #if !defined(BOOTLOADER_SIZE) | 89 | if (high_fuse & BOOT_SIZE_256) { |
89 | uint8_t high_fuse = boot_lock_fuse_bits_get(GET_HIGH_FUSE_BITS); | 90 | bootloader_start = (FLASH_SIZE - 512) >> 1; |
90 | 91 | } else if (high_fuse & BOOT_SIZE_512) { | |
91 | if (high_fuse & BOOT_SIZE_256) { | 92 | bootloader_start = (FLASH_SIZE - 1024) >> 1; |
92 | bootloader_start = (FLASH_SIZE - 512) >> 1; | 93 | } else if (high_fuse & BOOT_SIZE_1024) { |
93 | } else if (high_fuse & BOOT_SIZE_512) { | 94 | bootloader_start = (FLASH_SIZE - 2048) >> 1; |
94 | bootloader_start = (FLASH_SIZE - 1024) >> 1; | 95 | } else { |
95 | } else if (high_fuse & BOOT_SIZE_1024) { | 96 | bootloader_start = (FLASH_SIZE - 4096) >> 1; |
96 | bootloader_start = (FLASH_SIZE - 2048) >> 1; | 97 | } |
97 | } else { | 98 | #endif |
98 | bootloader_start = (FLASH_SIZE - 4096) >> 1; | ||
99 | } | ||
100 | #endif | ||
101 | 99 | ||
102 | // Something like this might work, but it compiled larger than the block above | 100 | // Something like this might work, but it compiled larger than the block above |
103 | // bootloader_start = FLASH_SIZE - (256 << (~high_fuse & 0b110 >> 1)); | 101 | // bootloader_start = FLASH_SIZE - (256 << (~high_fuse & 0b110 >> 1)); |
104 | 102 | ||
103 | #if defined(BOOTLOADER_HALFKAY) | ||
104 | // http://www.pjrc.com/teensy/jump_to_bootloader.html | ||
105 | cli(); | ||
106 | // disable watchdog, if enabled (it's not) | ||
107 | // disable all peripherals | ||
108 | // a shutdown call might make sense here | ||
109 | UDCON = 1; | ||
110 | USBCON = (1 << FRZCLK); // disable USB | ||
111 | UCSR1B = 0; | ||
112 | _delay_ms(5); | ||
113 | # if defined(__AVR_AT90USB162__) // Teensy 1.0 | ||
114 | EIMSK = 0; | ||
115 | PCICR = 0; | ||
116 | SPCR = 0; | ||
117 | ACSR = 0; | ||
118 | EECR = 0; | ||
119 | TIMSK0 = 0; | ||
120 | TIMSK1 = 0; | ||
121 | UCSR1B = 0; | ||
122 | DDRB = 0; | ||
123 | DDRC = 0; | ||
124 | DDRD = 0; | ||
125 | PORTB = 0; | ||
126 | PORTC = 0; | ||
127 | PORTD = 0; | ||
128 | asm volatile("jmp 0x3E00"); | ||
129 | # elif defined(__AVR_ATmega32U4__) // Teensy 2.0 | ||
130 | EIMSK = 0; | ||
131 | PCICR = 0; | ||
132 | SPCR = 0; | ||
133 | ACSR = 0; | ||
134 | EECR = 0; | ||
135 | ADCSRA = 0; | ||
136 | TIMSK0 = 0; | ||
137 | TIMSK1 = 0; | ||
138 | TIMSK3 = 0; | ||
139 | TIMSK4 = 0; | ||
140 | UCSR1B = 0; | ||
141 | TWCR = 0; | ||
142 | DDRB = 0; | ||
143 | DDRC = 0; | ||
144 | DDRD = 0; | ||
145 | DDRE = 0; | ||
146 | DDRF = 0; | ||
147 | TWCR = 0; | ||
148 | PORTB = 0; | ||
149 | PORTC = 0; | ||
150 | PORTD = 0; | ||
151 | PORTE = 0; | ||
152 | PORTF = 0; | ||
153 | asm volatile("jmp 0x7E00"); | ||
154 | # elif defined(__AVR_AT90USB646__) // Teensy++ 1.0 | ||
155 | EIMSK = 0; | ||
156 | PCICR = 0; | ||
157 | SPCR = 0; | ||
158 | ACSR = 0; | ||
159 | EECR = 0; | ||
160 | ADCSRA = 0; | ||
161 | TIMSK0 = 0; | ||
162 | TIMSK1 = 0; | ||
163 | TIMSK2 = 0; | ||
164 | TIMSK3 = 0; | ||
165 | UCSR1B = 0; | ||
166 | TWCR = 0; | ||
167 | DDRA = 0; | ||
168 | DDRB = 0; | ||
169 | DDRC = 0; | ||
170 | DDRD = 0; | ||
171 | DDRE = 0; | ||
172 | DDRF = 0; | ||
173 | PORTA = 0; | ||
174 | PORTB = 0; | ||
175 | PORTC = 0; | ||
176 | PORTD = 0; | ||
177 | PORTE = 0; | ||
178 | PORTF = 0; | ||
179 | asm volatile("jmp 0xFC00"); | ||
180 | # elif defined(__AVR_AT90USB1286__) // Teensy++ 2.0 | ||
181 | EIMSK = 0; | ||
182 | PCICR = 0; | ||
183 | SPCR = 0; | ||
184 | ACSR = 0; | ||
185 | EECR = 0; | ||
186 | ADCSRA = 0; | ||
187 | TIMSK0 = 0; | ||
188 | TIMSK1 = 0; | ||
189 | TIMSK2 = 0; | ||
190 | TIMSK3 = 0; | ||
191 | UCSR1B = 0; | ||
192 | TWCR = 0; | ||
193 | DDRA = 0; | ||
194 | DDRB = 0; | ||
195 | DDRC = 0; | ||
196 | DDRD = 0; | ||
197 | DDRE = 0; | ||
198 | DDRF = 0; | ||
199 | PORTA = 0; | ||
200 | PORTB = 0; | ||
201 | PORTC = 0; | ||
202 | PORTD = 0; | ||
203 | PORTE = 0; | ||
204 | PORTF = 0; | ||
205 | asm volatile("jmp 0x1FC00"); | ||
206 | # endif | ||
207 | |||
208 | #elif defined(BOOTLOADER_CATERINA) | ||
209 | // this block may be optional | ||
210 | // TODO: figure it out | ||
211 | |||
212 | uint16_t *const bootKeyPtr = (uint16_t *)0x0800; | ||
213 | |||
214 | // Value used by Caterina bootloader use to determine whether to run the | ||
215 | // sketch or the bootloader programmer. | ||
216 | uint16_t bootKey = 0x7777; | ||
217 | |||
218 | *bootKeyPtr = bootKey; | ||
219 | |||
220 | // setup watchdog timeout | ||
221 | wdt_enable(WDTO_60MS); | ||
105 | 222 | ||
106 | #if defined(BOOTLOADER_HALFKAY) | 223 | while (1) { |
107 | // http://www.pjrc.com/teensy/jump_to_bootloader.html | 224 | } // wait for watchdog timer to trigger |
108 | cli(); | ||
109 | // disable watchdog, if enabled (it's not) | ||
110 | // disable all peripherals | ||
111 | // a shutdown call might make sense here | ||
112 | UDCON = 1; | ||
113 | USBCON = (1<<FRZCLK); // disable USB | ||
114 | UCSR1B = 0; | ||
115 | _delay_ms(5); | ||
116 | #if defined(__AVR_AT90USB162__) // Teensy 1.0 | ||
117 | EIMSK = 0; PCICR = 0; SPCR = 0; ACSR = 0; EECR = 0; | ||
118 | TIMSK0 = 0; TIMSK1 = 0; UCSR1B = 0; | ||
119 | DDRB = 0; DDRC = 0; DDRD = 0; | ||
120 | PORTB = 0; PORTC = 0; PORTD = 0; | ||
121 | asm volatile("jmp 0x3E00"); | ||
122 | #elif defined(__AVR_ATmega32U4__) // Teensy 2.0 | ||
123 | EIMSK = 0; PCICR = 0; SPCR = 0; ACSR = 0; EECR = 0; ADCSRA = 0; | ||
124 | TIMSK0 = 0; TIMSK1 = 0; TIMSK3 = 0; TIMSK4 = 0; UCSR1B = 0; TWCR = 0; | ||
125 | DDRB = 0; DDRC = 0; DDRD = 0; DDRE = 0; DDRF = 0; TWCR = 0; | ||
126 | PORTB = 0; PORTC = 0; PORTD = 0; PORTE = 0; PORTF = 0; | ||
127 | asm volatile("jmp 0x7E00"); | ||
128 | #elif defined(__AVR_AT90USB646__) // Teensy++ 1.0 | ||
129 | EIMSK = 0; PCICR = 0; SPCR = 0; ACSR = 0; EECR = 0; ADCSRA = 0; | ||
130 | TIMSK0 = 0; TIMSK1 = 0; TIMSK2 = 0; TIMSK3 = 0; UCSR1B = 0; TWCR = 0; | ||
131 | DDRA = 0; DDRB = 0; DDRC = 0; DDRD = 0; DDRE = 0; DDRF = 0; | ||
132 | PORTA = 0; PORTB = 0; PORTC = 0; PORTD = 0; PORTE = 0; PORTF = 0; | ||
133 | asm volatile("jmp 0xFC00"); | ||
134 | #elif defined(__AVR_AT90USB1286__) // Teensy++ 2.0 | ||
135 | EIMSK = 0; PCICR = 0; SPCR = 0; ACSR = 0; EECR = 0; ADCSRA = 0; | ||
136 | TIMSK0 = 0; TIMSK1 = 0; TIMSK2 = 0; TIMSK3 = 0; UCSR1B = 0; TWCR = 0; | ||
137 | DDRA = 0; DDRB = 0; DDRC = 0; DDRD = 0; DDRE = 0; DDRF = 0; | ||
138 | PORTA = 0; PORTB = 0; PORTC = 0; PORTD = 0; PORTE = 0; PORTF = 0; | ||
139 | asm volatile("jmp 0x1FC00"); | ||
140 | #endif | ||
141 | |||
142 | #elif defined(BOOTLOADER_CATERINA) | ||
143 | // this block may be optional | ||
144 | // TODO: figure it out | ||
145 | |||
146 | uint16_t *const bootKeyPtr = (uint16_t *)0x0800; | ||
147 | |||
148 | // Value used by Caterina bootloader use to determine whether to run the | ||
149 | // sketch or the bootloader programmer. | ||
150 | uint16_t bootKey = 0x7777; | ||
151 | |||
152 | *bootKeyPtr = bootKey; | ||
153 | |||
154 | // setup watchdog timeout | ||
155 | wdt_enable(WDTO_60MS); | ||
156 | |||
157 | while(1) {} // wait for watchdog timer to trigger | ||
158 | |||
159 | #elif defined(BOOTLOADER_USBASP) | ||
160 | // Taken with permission of Stephan Baerwolf from https://github.com/tinyusbboard/API/blob/master/apipage.c | ||
161 | wdt_enable(WDTO_15MS); | ||
162 | wdt_reset(); | ||
163 | asm volatile ( | ||
164 | "cli \n\t" | ||
165 | "ldi r29 , %[ramendhi] \n\t" | ||
166 | "ldi r28 , %[ramendlo] \n\t" | ||
167 | #if (FLASHEND>131071) | ||
168 | "ldi r18 , %[bootaddrhi] \n\t" | ||
169 | "st Y+, r18 \n\t" | ||
170 | #endif | ||
171 | "ldi r18 , %[bootaddrme] \n\t" | ||
172 | "st Y+, r18 \n\t" | ||
173 | "ldi r18 , %[bootaddrlo] \n\t" | ||
174 | "st Y+, r18 \n\t" | ||
175 | "out %[mcucsrio], __zero_reg__ \n\t" | ||
176 | "bootloader_startup_loop%=: \n\t" | ||
177 | "rjmp bootloader_startup_loop%= \n\t" | ||
178 | : | ||
179 | : [mcucsrio] "I" (_SFR_IO_ADDR(MCUCSR)), | ||
180 | #if (FLASHEND>131071) | ||
181 | [ramendhi] "M" (((RAMEND - 2) >> 8) & 0xff), | ||
182 | [ramendlo] "M" (((RAMEND - 2) >> 0) & 0xff), | ||
183 | [bootaddrhi] "M" ((((FLASH_SIZE - BOOTLOADER_SIZE) >> 1) >>16) & 0xff), | ||
184 | #else | ||
185 | [ramendhi] "M" (((RAMEND - 1) >> 8) & 0xff), | ||
186 | [ramendlo] "M" (((RAMEND - 1) >> 0) & 0xff), | ||
187 | #endif | ||
188 | [bootaddrme] "M" ((((FLASH_SIZE - BOOTLOADER_SIZE) >> 1) >> 8) & 0xff), | ||
189 | [bootaddrlo] "M" ((((FLASH_SIZE - BOOTLOADER_SIZE) >> 1) >> 0) & 0xff) | ||
190 | ); | ||
191 | |||
192 | #else // Assume remaining boards are DFU, even if the flag isn't set | ||
193 | |||
194 | #if !(defined(__AVR_ATmega32A__) || defined(__AVR_ATmega328P__)) // no USB - maybe BOOTLOADER_BOOTLOADHID instead though? | ||
195 | UDCON = 1; | ||
196 | USBCON = (1<<FRZCLK); // disable USB | ||
197 | UCSR1B = 0; | ||
198 | _delay_ms(5); // 5 seems to work fine | ||
199 | #endif | ||
200 | |||
201 | #ifdef BOOTLOADER_BOOTLOADHID | ||
202 | // force bootloadHID to stay in bootloader mode, so that it waits | ||
203 | // for a new firmware to be flashed | ||
204 | eeprom_write_byte((uint8_t *)1, 0x00); | ||
205 | #endif | ||
206 | |||
207 | // watchdog reset | ||
208 | reset_key = BOOTLOADER_RESET_KEY; | ||
209 | wdt_enable(WDTO_250MS); | ||
210 | for (;;); | ||
211 | #endif | ||
212 | 225 | ||
226 | #elif defined(BOOTLOADER_USBASP) | ||
227 | // Taken with permission of Stephan Baerwolf from https://github.com/tinyusbboard/API/blob/master/apipage.c | ||
228 | wdt_enable(WDTO_15MS); | ||
229 | wdt_reset(); | ||
230 | asm volatile("cli \n\t" | ||
231 | "ldi r29 , %[ramendhi] \n\t" | ||
232 | "ldi r28 , %[ramendlo] \n\t" | ||
233 | # if (FLASHEND > 131071) | ||
234 | "ldi r18 , %[bootaddrhi] \n\t" | ||
235 | "st Y+, r18 \n\t" | ||
236 | # endif | ||
237 | "ldi r18 , %[bootaddrme] \n\t" | ||
238 | "st Y+, r18 \n\t" | ||
239 | "ldi r18 , %[bootaddrlo] \n\t" | ||
240 | "st Y+, r18 \n\t" | ||
241 | "out %[mcucsrio], __zero_reg__ \n\t" | ||
242 | "bootloader_startup_loop%=: \n\t" | ||
243 | "rjmp bootloader_startup_loop%= \n\t" | ||
244 | : | ||
245 | : [ mcucsrio ] "I"(_SFR_IO_ADDR(MCUCSR)), | ||
246 | # if (FLASHEND > 131071) | ||
247 | [ ramendhi ] "M"(((RAMEND - 2) >> 8) & 0xff), [ ramendlo ] "M"(((RAMEND - 2) >> 0) & 0xff), [ bootaddrhi ] "M"((((FLASH_SIZE - BOOTLOADER_SIZE) >> 1) >> 16) & 0xff), | ||
248 | # else | ||
249 | [ ramendhi ] "M"(((RAMEND - 1) >> 8) & 0xff), [ ramendlo ] "M"(((RAMEND - 1) >> 0) & 0xff), | ||
250 | # endif | ||
251 | [ bootaddrme ] "M"((((FLASH_SIZE - BOOTLOADER_SIZE) >> 1) >> 8) & 0xff), [ bootaddrlo ] "M"((((FLASH_SIZE - BOOTLOADER_SIZE) >> 1) >> 0) & 0xff)); | ||
252 | |||
253 | #else // Assume remaining boards are DFU, even if the flag isn't set | ||
254 | |||
255 | # if !(defined(__AVR_ATmega32A__) || defined(__AVR_ATmega328P__)) // no USB - maybe BOOTLOADER_BOOTLOADHID instead though? | ||
256 | UDCON = 1; | ||
257 | USBCON = (1 << FRZCLK); // disable USB | ||
258 | UCSR1B = 0; | ||
259 | _delay_ms(5); // 5 seems to work fine | ||
260 | # endif | ||
261 | |||
262 | # ifdef BOOTLOADER_BOOTLOADHID | ||
263 | // force bootloadHID to stay in bootloader mode, so that it waits | ||
264 | // for a new firmware to be flashed | ||
265 | eeprom_write_byte((uint8_t *)1, 0x00); | ||
266 | # endif | ||
267 | |||
268 | // watchdog reset | ||
269 | reset_key = BOOTLOADER_RESET_KEY; | ||
270 | wdt_enable(WDTO_250MS); | ||
271 | for (;;) | ||
272 | ; | ||
273 | #endif | ||
213 | } | 274 | } |
214 | 275 | ||
215 | /* this runs before main() */ | 276 | /* this runs before main() */ |
216 | void bootloader_jump_after_watchdog_reset(void) __attribute__ ((used, naked, section (".init3"))); | 277 | void bootloader_jump_after_watchdog_reset(void) __attribute__((used, naked, section(".init3"))); |
217 | void bootloader_jump_after_watchdog_reset(void) | 278 | void bootloader_jump_after_watchdog_reset(void) { |
218 | { | 279 | #ifndef BOOTLOADER_HALFKAY |
219 | #ifndef BOOTLOADER_HALFKAY | 280 | if ((MCUCSR & (1 << WDRF)) && reset_key == BOOTLOADER_RESET_KEY) { |
220 | if ((MCUCSR & (1<<WDRF)) && reset_key == BOOTLOADER_RESET_KEY) { | 281 | reset_key = 0; |
221 | reset_key = 0; | 282 | |
222 | 283 | // My custom USBasploader requires this to come up. | |
223 | // My custom USBasploader requires this to come up. | 284 | MCUCSR = 0; |
224 | MCUCSR = 0; | 285 | |
225 | 286 | // Seems like Teensy halfkay loader requires clearing WDRF and disabling watchdog. | |
226 | // Seems like Teensy halfkay loader requires clearing WDRF and disabling watchdog. | 287 | MCUCSR &= ~(1 << WDRF); |
227 | MCUCSR &= ~(1<<WDRF); | 288 | wdt_disable(); |
228 | wdt_disable(); | 289 | |
229 | 290 | // This is compled into 'icall', address should be in word unit, not byte. | |
230 | 291 | # ifdef BOOTLOADER_SIZE | |
231 | // This is compled into 'icall', address should be in word unit, not byte. | 292 | ((void (*)(void))((FLASH_SIZE - BOOTLOADER_SIZE) >> 1))(); |
232 | #ifdef BOOTLOADER_SIZE | 293 | # else |
233 | ((void (*)(void))( (FLASH_SIZE - BOOTLOADER_SIZE) >> 1))(); | 294 | asm("ijmp" ::"z"(bootloader_start)); |
234 | #else | 295 | # endif |
235 | asm("ijmp" :: "z" (bootloader_start)); | 296 | } |
236 | #endif | 297 | #endif |
237 | } | ||
238 | #endif | ||
239 | } | 298 | } |
diff --git a/tmk_core/common/avr/sleep_led.c b/tmk_core/common/avr/sleep_led.c index 0cb774c81..61fa70dc3 100644 --- a/tmk_core/common/avr/sleep_led.c +++ b/tmk_core/common/avr/sleep_led.c | |||
@@ -16,14 +16,13 @@ | |||
16 | * 256*64 interrupts/second | 16 | * 256*64 interrupts/second |
17 | * F_CPU/(256*64) clocks/interrupt | 17 | * F_CPU/(256*64) clocks/interrupt |
18 | */ | 18 | */ |
19 | #define SLEEP_LED_TIMER_TOP F_CPU/(256*64) | 19 | #define SLEEP_LED_TIMER_TOP F_CPU / (256 * 64) |
20 | 20 | ||
21 | /** \brief Sleep LED initialization | 21 | /** \brief Sleep LED initialization |
22 | * | 22 | * |
23 | * FIXME: needs doc | 23 | * FIXME: needs doc |
24 | */ | 24 | */ |
25 | void sleep_led_init(void) | 25 | void sleep_led_init(void) { |
26 | { | ||
27 | /* Timer1 setup */ | 26 | /* Timer1 setup */ |
28 | /* CTC mode */ | 27 | /* CTC mode */ |
29 | TCCR1B |= _BV(WGM12); | 28 | TCCR1B |= _BV(WGM12); |
@@ -32,17 +31,16 @@ void sleep_led_init(void) | |||
32 | /* Set TOP value */ | 31 | /* Set TOP value */ |
33 | uint8_t sreg = SREG; | 32 | uint8_t sreg = SREG; |
34 | cli(); | 33 | cli(); |
35 | OCR1AH = (SLEEP_LED_TIMER_TOP>>8)&0xff; | 34 | OCR1AH = (SLEEP_LED_TIMER_TOP >> 8) & 0xff; |
36 | OCR1AL = SLEEP_LED_TIMER_TOP&0xff; | 35 | OCR1AL = SLEEP_LED_TIMER_TOP & 0xff; |
37 | SREG = sreg; | 36 | SREG = sreg; |
38 | } | 37 | } |
39 | 38 | ||
40 | /** \brief Sleep LED enable | 39 | /** \brief Sleep LED enable |
41 | * | 40 | * |
42 | * FIXME: needs doc | 41 | * FIXME: needs doc |
43 | */ | 42 | */ |
44 | void sleep_led_enable(void) | 43 | void sleep_led_enable(void) { |
45 | { | ||
46 | /* Enable Compare Match Interrupt */ | 44 | /* Enable Compare Match Interrupt */ |
47 | TIMSK1 |= _BV(OCIE1A); | 45 | TIMSK1 |= _BV(OCIE1A); |
48 | } | 46 | } |
@@ -51,8 +49,7 @@ void sleep_led_enable(void) | |||
51 | * | 49 | * |
52 | * FIXME: needs doc | 50 | * FIXME: needs doc |
53 | */ | 51 | */ |
54 | void sleep_led_disable(void) | 52 | void sleep_led_disable(void) { |
55 | { | ||
56 | /* Disable Compare Match Interrupt */ | 53 | /* Disable Compare Match Interrupt */ |
57 | TIMSK1 &= ~_BV(OCIE1A); | 54 | TIMSK1 &= ~_BV(OCIE1A); |
58 | } | 55 | } |
@@ -61,13 +58,11 @@ void sleep_led_disable(void) | |||
61 | * | 58 | * |
62 | * FIXME: needs doc | 59 | * FIXME: needs doc |
63 | */ | 60 | */ |
64 | void sleep_led_toggle(void) | 61 | void sleep_led_toggle(void) { |
65 | { | ||
66 | /* Disable Compare Match Interrupt */ | 62 | /* Disable Compare Match Interrupt */ |
67 | TIMSK1 ^= _BV(OCIE1A); | 63 | TIMSK1 ^= _BV(OCIE1A); |
68 | } | 64 | } |
69 | 65 | ||
70 | |||
71 | /** \brief Breathing Sleep LED brighness(PWM On period) table | 66 | /** \brief Breathing Sleep LED brighness(PWM On period) table |
72 | * | 67 | * |
73 | * (64[steps] * 4[duration]) / 64[PWM periods/s] = 4 second breath cycle | 68 | * (64[steps] * 4[duration]) / 64[PWM periods/s] = 4 second breath cycle |
@@ -75,15 +70,9 @@ void sleep_led_toggle(void) | |||
75 | * http://www.wolframalpha.com/input/?i=%28sin%28+x%2F64*pi%29**8+*+255%2C+x%3D0+to+63 | 70 | * http://www.wolframalpha.com/input/?i=%28sin%28+x%2F64*pi%29**8+*+255%2C+x%3D0+to+63 |
76 | * (0..63).each {|x| p ((sin(x/64.0*PI)**8)*255).to_i } | 71 | * (0..63).each {|x| p ((sin(x/64.0*PI)**8)*255).to_i } |
77 | */ | 72 | */ |
78 | static const uint8_t breathing_table[64] PROGMEM = { | 73 | static const uint8_t breathing_table[64] PROGMEM = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 6, 10, 15, 23, 32, 44, 58, 74, 93, 113, 135, 157, 179, 199, 218, 233, 245, 252, 255, 252, 245, 233, 218, 199, 179, 157, 135, 113, 93, 74, 58, 44, 32, 23, 15, 10, 6, 4, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; |
79 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 6, 10, | ||
80 | 15, 23, 32, 44, 58, 74, 93, 113, 135, 157, 179, 199, 218, 233, 245, 252, | ||
81 | 255, 252, 245, 233, 218, 199, 179, 157, 135, 113, 93, 74, 58, 44, 32, 23, | ||
82 | 15, 10, 6, 4, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 | ||
83 | }; | ||
84 | 74 | ||
85 | ISR(TIMER1_COMPA_vect) | 75 | ISR(TIMER1_COMPA_vect) { |
86 | { | ||
87 | /* Software PWM | 76 | /* Software PWM |
88 | * timer:1111 1111 1111 1111 | 77 | * timer:1111 1111 1111 1111 |
89 | * \_____/\/ \_______/____ count(0-255) | 78 | * \_____/\/ \_______/____ count(0-255) |
@@ -93,17 +82,17 @@ ISR(TIMER1_COMPA_vect) | |||
93 | static union { | 82 | static union { |
94 | uint16_t row; | 83 | uint16_t row; |
95 | struct { | 84 | struct { |
96 | uint8_t count:8; | 85 | uint8_t count : 8; |
97 | uint8_t duration:2; | 86 | uint8_t duration : 2; |
98 | uint8_t index:6; | 87 | uint8_t index : 6; |
99 | } pwm; | 88 | } pwm; |
100 | } timer = { .row = 0 }; | 89 | } timer = {.row = 0}; |
101 | 90 | ||
102 | timer.row++; | 91 | timer.row++; |
103 | 92 | ||
104 | // LED on | 93 | // LED on |
105 | if (timer.pwm.count == 0) { | 94 | if (timer.pwm.count == 0) { |
106 | led_set(1<<USB_LED_CAPS_LOCK); | 95 | led_set(1 << USB_LED_CAPS_LOCK); |
107 | } | 96 | } |
108 | // LED off | 97 | // LED off |
109 | if (timer.pwm.count == pgm_read_byte(&breathing_table[timer.pwm.index])) { | 98 | if (timer.pwm.count == pgm_read_byte(&breathing_table[timer.pwm.index])) { |
diff --git a/tmk_core/common/avr/suspend.c b/tmk_core/common/avr/suspend.c index 2259201b5..574000fcd 100644 --- a/tmk_core/common/avr/suspend.c +++ b/tmk_core/common/avr/suspend.c | |||
@@ -13,37 +13,36 @@ | |||
13 | #include "rgblight_reconfig.h" | 13 | #include "rgblight_reconfig.h" |
14 | 14 | ||
15 | #ifdef PROTOCOL_LUFA | 15 | #ifdef PROTOCOL_LUFA |
16 | #include "lufa.h" | 16 | # include "lufa.h" |
17 | #endif | 17 | #endif |
18 | 18 | ||
19 | #ifdef AUDIO_ENABLE | 19 | #ifdef AUDIO_ENABLE |
20 | #include "audio.h" | 20 | # include "audio.h" |
21 | #endif /* AUDIO_ENABLE */ | 21 | #endif /* AUDIO_ENABLE */ |
22 | 22 | ||
23 | #if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE) | 23 | #if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE) |
24 | #include "rgblight.h" | 24 | # include "rgblight.h" |
25 | extern rgblight_config_t rgblight_config; | 25 | extern rgblight_config_t rgblight_config; |
26 | static bool rgblight_enabled; | 26 | static bool rgblight_enabled; |
27 | static bool is_suspended; | 27 | static bool is_suspended; |
28 | #endif | 28 | #endif |
29 | 29 | ||
30 | 30 | #define wdt_intr_enable(value) \ | |
31 | #define wdt_intr_enable(value) \ | 31 | __asm__ __volatile__("in __tmp_reg__,__SREG__" \ |
32 | __asm__ __volatile__ ( \ | 32 | "\n\t" \ |
33 | "in __tmp_reg__,__SREG__" "\n\t" \ | 33 | "cli" \ |
34 | "cli" "\n\t" \ | 34 | "\n\t" \ |
35 | "wdr" "\n\t" \ | 35 | "wdr" \ |
36 | "sts %0,%1" "\n\t" \ | 36 | "\n\t" \ |
37 | "out __SREG__,__tmp_reg__" "\n\t" \ | 37 | "sts %0,%1" \ |
38 | "sts %0,%2" "\n\t" \ | 38 | "\n\t" \ |
39 | : /* no outputs */ \ | 39 | "out __SREG__,__tmp_reg__" \ |
40 | : "M" (_SFR_MEM_ADDR(_WD_CONTROL_REG)), \ | 40 | "\n\t" \ |
41 | "r" (_BV(_WD_CHANGE_BIT) | _BV(WDE)), \ | 41 | "sts %0,%2" \ |
42 | "r" ((uint8_t) ((value & 0x08 ? _WD_PS3_MASK : 0x00) | \ | 42 | "\n\t" \ |
43 | _BV(WDIE) | (value & 0x07)) ) \ | 43 | : /* no outputs */ \ |
44 | : "r0" \ | 44 | : "M"(_SFR_MEM_ADDR(_WD_CONTROL_REG)), "r"(_BV(_WD_CHANGE_BIT) | _BV(WDE)), "r"((uint8_t)((value & 0x08 ? _WD_PS3_MASK : 0x00) | _BV(WDIE) | (value & 0x07))) \ |
45 | ) | 45 | : "r0") |
46 | |||
47 | 46 | ||
48 | /** \brief Suspend idle | 47 | /** \brief Suspend idle |
49 | * | 48 | * |
@@ -58,23 +57,18 @@ void suspend_idle(uint8_t time) { | |||
58 | sleep_disable(); | 57 | sleep_disable(); |
59 | } | 58 | } |
60 | 59 | ||
61 | |||
62 | // TODO: This needs some cleanup | 60 | // TODO: This needs some cleanup |
63 | 61 | ||
64 | /** \brief Run keyboard level Power down | 62 | /** \brief Run keyboard level Power down |
65 | * | 63 | * |
66 | * FIXME: needs doc | 64 | * FIXME: needs doc |
67 | */ | 65 | */ |
68 | __attribute__ ((weak)) | 66 | __attribute__((weak)) void suspend_power_down_user(void) {} |
69 | void suspend_power_down_user (void) { } | ||
70 | /** \brief Run keyboard level Power down | 67 | /** \brief Run keyboard level Power down |
71 | * | 68 | * |
72 | * FIXME: needs doc | 69 | * FIXME: needs doc |
73 | */ | 70 | */ |
74 | __attribute__ ((weak)) | 71 | __attribute__((weak)) void suspend_power_down_kb(void) { suspend_power_down_user(); } |
75 | void suspend_power_down_kb(void) { | ||
76 | suspend_power_down_user(); | ||
77 | } | ||
78 | 72 | ||
79 | #ifndef NO_SUSPEND_POWER_DOWN | 73 | #ifndef NO_SUSPEND_POWER_DOWN |
80 | /** \brief Power down MCU with watchdog timer | 74 | /** \brief Power down MCU with watchdog timer |
@@ -98,43 +92,43 @@ static uint8_t wdt_timeout = 0; | |||
98 | * FIXME: needs doc | 92 | * FIXME: needs doc |
99 | */ | 93 | */ |
100 | static void power_down(uint8_t wdto) { | 94 | static void power_down(uint8_t wdto) { |
101 | #ifdef PROTOCOL_LUFA | 95 | # ifdef PROTOCOL_LUFA |
102 | if (USB_DeviceState == DEVICE_STATE_Configured) return; | 96 | if (USB_DeviceState == DEVICE_STATE_Configured) return; |
103 | #endif | 97 | # endif |
104 | wdt_timeout = wdto; | 98 | wdt_timeout = wdto; |
105 | 99 | ||
106 | // Watchdog Interrupt Mode | 100 | // Watchdog Interrupt Mode |
107 | wdt_intr_enable(wdto); | 101 | wdt_intr_enable(wdto); |
108 | 102 | ||
109 | #ifdef BACKLIGHT_ENABLE | 103 | # ifdef BACKLIGHT_ENABLE |
110 | backlight_set(0); | 104 | backlight_set(0); |
111 | #endif | 105 | # endif |
112 | 106 | ||
113 | // Turn off LED indicators | 107 | // Turn off LED indicators |
114 | uint8_t leds_off = 0; | 108 | uint8_t leds_off = 0; |
115 | #if defined(BACKLIGHT_CAPS_LOCK) && defined(BACKLIGHT_ENABLE) | 109 | # if defined(BACKLIGHT_CAPS_LOCK) && defined(BACKLIGHT_ENABLE) |
116 | if (is_backlight_enabled()) { | 110 | if (is_backlight_enabled()) { |
117 | // Don't try to turn off Caps Lock indicator as it is backlight and backlight is already off | 111 | // Don't try to turn off Caps Lock indicator as it is backlight and backlight is already off |
118 | leds_off |= (1<<USB_LED_CAPS_LOCK); | 112 | leds_off |= (1 << USB_LED_CAPS_LOCK); |
119 | } | 113 | } |
120 | #endif | 114 | # endif |
121 | led_set(leds_off); | 115 | led_set(leds_off); |
122 | 116 | ||
123 | #ifdef AUDIO_ENABLE | 117 | # ifdef AUDIO_ENABLE |
124 | // This sometimes disables the start-up noise, so it's been disabled | 118 | // This sometimes disables the start-up noise, so it's been disabled |
125 | // stop_all_notes(); | 119 | // stop_all_notes(); |
126 | #endif /* AUDIO_ENABLE */ | 120 | # endif /* AUDIO_ENABLE */ |
127 | #if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE) | 121 | # if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE) |
128 | #ifdef RGBLIGHT_ANIMATIONS | 122 | # ifdef RGBLIGHT_ANIMATIONS |
129 | rgblight_timer_disable(); | 123 | rgblight_timer_disable(); |
130 | #endif | 124 | # endif |
131 | if (!is_suspended) { | 125 | if (!is_suspended) { |
132 | is_suspended = true; | 126 | is_suspended = true; |
133 | rgblight_enabled = rgblight_config.enable; | 127 | rgblight_enabled = rgblight_config.enable; |
134 | rgblight_disable_noeeprom(); | 128 | rgblight_disable_noeeprom(); |
135 | } | 129 | } |
136 | #endif | 130 | # endif |
137 | suspend_power_down_kb(); | 131 | suspend_power_down_kb(); |
138 | 132 | ||
139 | // TODO: more power saving | 133 | // TODO: more power saving |
140 | // See PicoPower application note | 134 | // See PicoPower application note |
@@ -158,40 +152,36 @@ static void power_down(uint8_t wdto) { | |||
158 | * FIXME: needs doc | 152 | * FIXME: needs doc |
159 | */ | 153 | */ |
160 | void suspend_power_down(void) { | 154 | void suspend_power_down(void) { |
161 | suspend_power_down_kb(); | 155 | suspend_power_down_kb(); |
162 | 156 | ||
163 | #ifndef NO_SUSPEND_POWER_DOWN | 157 | #ifndef NO_SUSPEND_POWER_DOWN |
164 | power_down(WDTO_15MS); | 158 | power_down(WDTO_15MS); |
165 | #endif | 159 | #endif |
166 | } | 160 | } |
167 | 161 | ||
168 | __attribute__ ((weak)) void matrix_power_up(void) {} | 162 | __attribute__((weak)) void matrix_power_up(void) {} |
169 | __attribute__ ((weak)) void matrix_power_down(void) {} | 163 | __attribute__((weak)) void matrix_power_down(void) {} |
170 | bool suspend_wakeup_condition(void) { | 164 | bool suspend_wakeup_condition(void) { |
171 | matrix_power_up(); | 165 | matrix_power_up(); |
172 | matrix_scan(); | 166 | matrix_scan(); |
173 | matrix_power_down(); | 167 | matrix_power_down(); |
174 | for (uint8_t r = 0; r < MATRIX_ROWS; r++) { | 168 | for (uint8_t r = 0; r < MATRIX_ROWS; r++) { |
175 | if (matrix_get_row(r)) return true; | 169 | if (matrix_get_row(r)) return true; |
176 | } | 170 | } |
177 | return false; | 171 | return false; |
178 | } | 172 | } |
179 | 173 | ||
180 | /** \brief run user level code immediately after wakeup | 174 | /** \brief run user level code immediately after wakeup |
181 | * | 175 | * |
182 | * FIXME: needs doc | 176 | * FIXME: needs doc |
183 | */ | 177 | */ |
184 | __attribute__ ((weak)) | 178 | __attribute__((weak)) void suspend_wakeup_init_user(void) {} |
185 | void suspend_wakeup_init_user(void) { } | ||
186 | 179 | ||
187 | /** \brief run keyboard level code immediately after wakeup | 180 | /** \brief run keyboard level code immediately after wakeup |
188 | * | 181 | * |
189 | * FIXME: needs doc | 182 | * FIXME: needs doc |
190 | */ | 183 | */ |
191 | __attribute__ ((weak)) | 184 | __attribute__((weak)) void suspend_wakeup_init_kb(void) { suspend_wakeup_init_user(); } |
192 | void suspend_wakeup_init_kb(void) { | ||
193 | suspend_wakeup_init_user(); | ||
194 | } | ||
195 | /** \brief run immediately after wakeup | 185 | /** \brief run immediately after wakeup |
196 | * | 186 | * |
197 | * FIXME: needs doc | 187 | * FIXME: needs doc |
@@ -202,18 +192,18 @@ void suspend_wakeup_init(void) { | |||
202 | #ifdef BACKLIGHT_ENABLE | 192 | #ifdef BACKLIGHT_ENABLE |
203 | backlight_init(); | 193 | backlight_init(); |
204 | #endif | 194 | #endif |
205 | led_set(host_keyboard_leds()); | 195 | led_set(host_keyboard_leds()); |
206 | #if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE) | 196 | #if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE) |
207 | is_suspended = false; | 197 | is_suspended = false; |
208 | if (rgblight_enabled) { | 198 | if (rgblight_enabled) { |
209 | #ifdef BOOTLOADER_TEENSY | 199 | # ifdef BOOTLOADER_TEENSY |
210 | wait_ms(10); | 200 | wait_ms(10); |
211 | #endif | 201 | # endif |
212 | rgblight_enable_noeeprom(); | 202 | rgblight_enable_noeeprom(); |
213 | } | 203 | } |
214 | #ifdef RGBLIGHT_ANIMATIONS | 204 | # ifdef RGBLIGHT_ANIMATIONS |
215 | rgblight_timer_enable(); | 205 | rgblight_timer_enable(); |
216 | #endif | 206 | # endif |
217 | #endif | 207 | #endif |
218 | suspend_wakeup_init_kb(); | 208 | suspend_wakeup_init_kb(); |
219 | } | 209 | } |
@@ -226,8 +216,7 @@ ISR(WDT_vect) { | |||
226 | case WDTO_15MS: | 216 | case WDTO_15MS: |
227 | timer_count += 15 + 2; // WDTO_15MS + 2(from observation) | 217 | timer_count += 15 + 2; // WDTO_15MS + 2(from observation) |
228 | break; | 218 | break; |
229 | default: | 219 | default:; |
230 | ; | ||
231 | } | 220 | } |
232 | } | 221 | } |
233 | #endif | 222 | #endif |
diff --git a/tmk_core/common/avr/suspend_avr.h b/tmk_core/common/avr/suspend_avr.h index 357102da4..d73852ba1 100644 --- a/tmk_core/common/avr/suspend_avr.h +++ b/tmk_core/common/avr/suspend_avr.h | |||
@@ -7,21 +7,21 @@ | |||
7 | #include <avr/wdt.h> | 7 | #include <avr/wdt.h> |
8 | #include <avr/interrupt.h> | 8 | #include <avr/interrupt.h> |
9 | 9 | ||
10 | 10 | #define wdt_intr_enable(value) \ | |
11 | #define wdt_intr_enable(value) \ | 11 | __asm__ __volatile__("in __tmp_reg__,__SREG__" \ |
12 | __asm__ __volatile__ ( \ | 12 | "\n\t" \ |
13 | "in __tmp_reg__,__SREG__" "\n\t" \ | 13 | "cli" \ |
14 | "cli" "\n\t" \ | 14 | "\n\t" \ |
15 | "wdr" "\n\t" \ | 15 | "wdr" \ |
16 | "sts %0,%1" "\n\t" \ | 16 | "\n\t" \ |
17 | "out __SREG__,__tmp_reg__" "\n\t" \ | 17 | "sts %0,%1" \ |
18 | "sts %0,%2" "\n\t" \ | 18 | "\n\t" \ |
19 | : /* no outputs */ \ | 19 | "out __SREG__,__tmp_reg__" \ |
20 | : "M" (_SFR_MEM_ADDR(_WD_CONTROL_REG)), \ | 20 | "\n\t" \ |
21 | "r" (_BV(_WD_CHANGE_BIT) | _BV(WDE)), \ | 21 | "sts %0,%2" \ |
22 | "r" ((uint8_t) ((value & 0x08 ? _WD_PS3_MASK : 0x00) | \ | 22 | "\n\t" \ |
23 | _BV(WDIE) | (value & 0x07)) ) \ | 23 | : /* no outputs */ \ |
24 | : "r0" \ | 24 | : "M"(_SFR_MEM_ADDR(_WD_CONTROL_REG)), "r"(_BV(_WD_CHANGE_BIT) | _BV(WDE)), "r"((uint8_t)((value & 0x08 ? _WD_PS3_MASK : 0x00) | _BV(WDIE) | (value & 0x07))) \ |
25 | ) | 25 | : "r0") |
26 | 26 | ||
27 | #endif | 27 | #endif |
diff --git a/tmk_core/common/avr/timer.c b/tmk_core/common/avr/timer.c index b7d4f060e..63ec549df 100644 --- a/tmk_core/common/avr/timer.c +++ b/tmk_core/common/avr/timer.c | |||
@@ -22,7 +22,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
22 | #include "timer_avr.h" | 22 | #include "timer_avr.h" |
23 | #include "timer.h" | 23 | #include "timer.h" |
24 | 24 | ||
25 | |||
26 | // counter resolution 1ms | 25 | // counter resolution 1ms |
27 | // NOTE: union { uint32_t timer32; struct { uint16_t dummy; uint16_t timer16; }} | 26 | // NOTE: union { uint32_t timer32; struct { uint16_t dummy; uint16_t timer16; }} |
28 | volatile uint32_t timer_count; | 27 | volatile uint32_t timer_count; |
@@ -31,8 +30,7 @@ volatile uint32_t timer_count; | |||
31 | * | 30 | * |
32 | * FIXME: needs doc | 31 | * FIXME: needs doc |
33 | */ | 32 | */ |
34 | void timer_init(void) | 33 | void timer_init(void) { |
35 | { | ||
36 | #if TIMER_PRESCALER == 1 | 34 | #if TIMER_PRESCALER == 1 |
37 | uint8_t prescaler = 0x01; | 35 | uint8_t prescaler = 0x01; |
38 | #elif TIMER_PRESCALER == 8 | 36 | #elif TIMER_PRESCALER == 8 |
@@ -44,7 +42,7 @@ void timer_init(void) | |||
44 | #elif TIMER_PRESCALER == 1024 | 42 | #elif TIMER_PRESCALER == 1024 |
45 | uint8_t prescaler = 0x05; | 43 | uint8_t prescaler = 0x05; |
46 | #else | 44 | #else |
47 | # error "Timer prescaler value is NOT vaild." | 45 | # error "Timer prescaler value is NOT vaild." |
48 | #endif | 46 | #endif |
49 | 47 | ||
50 | #ifndef __AVR_ATmega32A__ | 48 | #ifndef __AVR_ATmega32A__ |
@@ -53,13 +51,13 @@ void timer_init(void) | |||
53 | 51 | ||
54 | TCCR0B = prescaler; | 52 | TCCR0B = prescaler; |
55 | 53 | ||
56 | OCR0A = TIMER_RAW_TOP; | 54 | OCR0A = TIMER_RAW_TOP; |
57 | TIMSK0 = (1<<OCIE0A); | 55 | TIMSK0 = (1 << OCIE0A); |
58 | #else | 56 | #else |
59 | // Timer0 CTC mode | 57 | // Timer0 CTC mode |
60 | TCCR0 = (1 << WGM01) | prescaler; | 58 | TCCR0 = (1 << WGM01) | prescaler; |
61 | 59 | ||
62 | OCR0 = TIMER_RAW_TOP; | 60 | OCR0 = TIMER_RAW_TOP; |
63 | TIMSK = (1 << OCIE0); | 61 | TIMSK = (1 << OCIE0); |
64 | #endif | 62 | #endif |
65 | } | 63 | } |
@@ -68,26 +66,18 @@ void timer_init(void) | |||
68 | * | 66 | * |
69 | * FIXME: needs doc | 67 | * FIXME: needs doc |
70 | */ | 68 | */ |
71 | inline | 69 | inline void timer_clear(void) { |
72 | void timer_clear(void) | 70 | ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { timer_count = 0; } |
73 | { | ||
74 | ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { | ||
75 | timer_count = 0; | ||
76 | } | ||
77 | } | 71 | } |
78 | 72 | ||
79 | /** \brief timer read | 73 | /** \brief timer read |
80 | * | 74 | * |
81 | * FIXME: needs doc | 75 | * FIXME: needs doc |
82 | */ | 76 | */ |
83 | inline | 77 | inline uint16_t timer_read(void) { |
84 | uint16_t timer_read(void) | ||
85 | { | ||
86 | uint32_t t; | 78 | uint32_t t; |
87 | 79 | ||
88 | ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { | 80 | ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { t = timer_count; } |
89 | t = timer_count; | ||
90 | } | ||
91 | 81 | ||
92 | return (t & 0xFFFF); | 82 | return (t & 0xFFFF); |
93 | } | 83 | } |
@@ -96,14 +86,10 @@ uint16_t timer_read(void) | |||
96 | * | 86 | * |
97 | * FIXME: needs doc | 87 | * FIXME: needs doc |
98 | */ | 88 | */ |
99 | inline | 89 | inline uint32_t timer_read32(void) { |
100 | uint32_t timer_read32(void) | ||
101 | { | ||
102 | uint32_t t; | 90 | uint32_t t; |
103 | 91 | ||
104 | ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { | 92 | ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { t = timer_count; } |
105 | t = timer_count; | ||
106 | } | ||
107 | 93 | ||
108 | return t; | 94 | return t; |
109 | } | 95 | } |
@@ -112,14 +98,10 @@ uint32_t timer_read32(void) | |||
112 | * | 98 | * |
113 | * FIXME: needs doc | 99 | * FIXME: needs doc |
114 | */ | 100 | */ |
115 | inline | 101 | inline uint16_t timer_elapsed(uint16_t last) { |
116 | uint16_t timer_elapsed(uint16_t last) | ||
117 | { | ||
118 | uint32_t t; | 102 | uint32_t t; |
119 | 103 | ||
120 | ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { | 104 | ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { t = timer_count; } |
121 | t = timer_count; | ||
122 | } | ||
123 | 105 | ||
124 | return TIMER_DIFF_16((t & 0xFFFF), last); | 106 | return TIMER_DIFF_16((t & 0xFFFF), last); |
125 | } | 107 | } |
@@ -128,25 +110,18 @@ uint16_t timer_elapsed(uint16_t last) | |||
128 | * | 110 | * |
129 | * FIXME: needs doc | 111 | * FIXME: needs doc |
130 | */ | 112 | */ |
131 | inline | 113 | inline uint32_t timer_elapsed32(uint32_t last) { |
132 | uint32_t timer_elapsed32(uint32_t last) | ||
133 | { | ||
134 | uint32_t t; | 114 | uint32_t t; |
135 | 115 | ||
136 | ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { | 116 | ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { t = timer_count; } |
137 | t = timer_count; | ||
138 | } | ||
139 | 117 | ||
140 | return TIMER_DIFF_32(t, last); | 118 | return TIMER_DIFF_32(t, last); |
141 | } | 119 | } |
142 | 120 | ||
143 | // excecuted once per 1ms.(excess for just timer count?) | 121 | // excecuted once per 1ms.(excess for just timer count?) |
144 | #ifndef __AVR_ATmega32A__ | 122 | #ifndef __AVR_ATmega32A__ |
145 | #define TIMER_INTERRUPT_VECTOR TIMER0_COMPA_vect | 123 | # define TIMER_INTERRUPT_VECTOR TIMER0_COMPA_vect |
146 | #else | 124 | #else |
147 | #define TIMER_INTERRUPT_VECTOR TIMER0_COMP_vect | 125 | # define TIMER_INTERRUPT_VECTOR TIMER0_COMP_vect |
148 | #endif | 126 | #endif |
149 | ISR(TIMER_INTERRUPT_VECTOR, ISR_NOBLOCK) | 127 | ISR(TIMER_INTERRUPT_VECTOR, ISR_NOBLOCK) { timer_count++; } |
150 | { | ||
151 | timer_count++; | ||
152 | } | ||
diff --git a/tmk_core/common/avr/timer_avr.h b/tmk_core/common/avr/timer_avr.h index 0e85eb101..9aea21c65 100644 --- a/tmk_core/common/avr/timer_avr.h +++ b/tmk_core/common/avr/timer_avr.h | |||
@@ -21,22 +21,22 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
21 | #include <stdint.h> | 21 | #include <stdint.h> |
22 | 22 | ||
23 | #ifndef TIMER_PRESCALER | 23 | #ifndef TIMER_PRESCALER |
24 | # if F_CPU > 16000000 | 24 | # if F_CPU > 16000000 |
25 | # define TIMER_PRESCALER 256 | 25 | # define TIMER_PRESCALER 256 |
26 | # elif F_CPU > 2000000 | 26 | # elif F_CPU > 2000000 |
27 | # define TIMER_PRESCALER 64 | 27 | # define TIMER_PRESCALER 64 |
28 | # elif F_CPU > 250000 | 28 | # elif F_CPU > 250000 |
29 | # define TIMER_PRESCALER 8 | 29 | # define TIMER_PRESCALER 8 |
30 | # else | 30 | # else |
31 | # define TIMER_PRESCALER 1 | 31 | # define TIMER_PRESCALER 1 |
32 | # endif | 32 | # endif |
33 | #endif | 33 | #endif |
34 | #define TIMER_RAW_FREQ (F_CPU/TIMER_PRESCALER) | 34 | #define TIMER_RAW_FREQ (F_CPU / TIMER_PRESCALER) |
35 | #define TIMER_RAW TCNT0 | 35 | #define TIMER_RAW TCNT0 |
36 | #define TIMER_RAW_TOP (TIMER_RAW_FREQ/1000) | 36 | #define TIMER_RAW_TOP (TIMER_RAW_FREQ / 1000) |
37 | 37 | ||
38 | #if (TIMER_RAW_TOP > 255) | 38 | #if (TIMER_RAW_TOP > 255) |
39 | # error "Timer0 can't count 1ms at this clock freq. Use larger prescaler." | 39 | # error "Timer0 can't count 1ms at this clock freq. Use larger prescaler." |
40 | #endif | 40 | #endif |
41 | 41 | ||
42 | #endif | 42 | #endif |
diff --git a/tmk_core/common/avr/xprintf.h b/tmk_core/common/avr/xprintf.h index 08d9f93a0..70e0f8e48 100644 --- a/tmk_core/common/avr/xprintf.h +++ b/tmk_core/common/avr/xprintf.h | |||
@@ -13,7 +13,7 @@ extern "C" { | |||
13 | #endif | 13 | #endif |
14 | 14 | ||
15 | extern void (*xfunc_out)(uint8_t); | 15 | extern void (*xfunc_out)(uint8_t); |
16 | #define xdev_out(func) xfunc_out = (void(*)(uint8_t))(func) | 16 | #define xdev_out(func) xfunc_out = (void (*)(uint8_t))(func) |
17 | 17 | ||
18 | /* This is a pointer to user defined output function. It must be initialized | 18 | /* This is a pointer to user defined output function. It must be initialized |
19 | before using this modle. | 19 | before using this modle. |
@@ -25,13 +25,11 @@ void xputc(char chr); | |||
25 | All outputs from this module are output via this function. | 25 | All outputs from this module are output via this function. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | |||
29 | /*-----------------------------------------------------------------------------*/ | 28 | /*-----------------------------------------------------------------------------*/ |
30 | void xputs(const char *string_p); | 29 | void xputs(const char *string_p); |
31 | 30 | ||
32 | /* The string placed in the ROM is forwarded to xputc() directly. | 31 | /* The string placed in the ROM is forwarded to xputc() directly. |
33 | */ | 32 | */ |
34 | |||
35 | 33 | ||
36 | /*-----------------------------------------------------------------------------*/ | 34 | /*-----------------------------------------------------------------------------*/ |
37 | void xitoa(long value, char radix, char width); | 35 | void xitoa(long value, char radix, char width); |
@@ -49,13 +47,12 @@ void xitoa(long value, char radix, char width); | |||
49 | 0x55 2 -8 "01010101" | 47 | 0x55 2 -8 "01010101" |
50 | */ | 48 | */ |
51 | 49 | ||
52 | |||
53 | /*-----------------------------------------------------------------------------*/ | 50 | /*-----------------------------------------------------------------------------*/ |
54 | #define xprintf(format, ...) __xprintf(PSTR(format), ##__VA_ARGS__) | 51 | #define xprintf(format, ...) __xprintf(PSTR(format), ##__VA_ARGS__) |
55 | #define xsprintf(str, format, ...) __xsprintf(str, PSTR(format), ##__VA_ARGS__) | 52 | #define xsprintf(str, format, ...) __xsprintf(str, PSTR(format), ##__VA_ARGS__) |
56 | #define xfprintf(func, format, ...) __xfprintf(func, PSTR(format), ##__VA_ARGS__) | 53 | #define xfprintf(func, format, ...) __xfprintf(func, PSTR(format), ##__VA_ARGS__) |
57 | 54 | ||
58 | void __xprintf(const char *format_p, ...); /* Send formatted string to the registered device */ | 55 | void __xprintf(const char *format_p, ...); /* Send formatted string to the registered device */ |
59 | // void __xsprintf(char*, const char *format_p, ...); /* Put formatted string to the memory */ | 56 | // void __xsprintf(char*, const char *format_p, ...); /* Put formatted string to the memory */ |
60 | // void __xfprintf(void(*func)(uint8_t), const char *format_p, ...); /* Send formatted string to the specified device */ | 57 | // void __xfprintf(void(*func)(uint8_t), const char *format_p, ...); /* Send formatted string to the specified device */ |
61 | 58 | ||
@@ -84,7 +81,6 @@ void __xprintf(const char *format_p, ...); /* Send formatted string to the regis | |||
84 | 81 | ||
85 | */ | 82 | */ |
86 | 83 | ||
87 | |||
88 | /*-----------------------------------------------------------------------------*/ | 84 | /*-----------------------------------------------------------------------------*/ |
89 | char xatoi(char **str, long *ret); | 85 | char xatoi(char **str, long *ret); |
90 | 86 | ||
@@ -108,4 +104,3 @@ char xatoi(char **str, long *ret); | |||
108 | #endif | 104 | #endif |
109 | 105 | ||
110 | #endif | 106 | #endif |
111 | |||