From e81c70149ecf73256f8bb7d77cefc07f2b91d2be Mon Sep 17 00:00:00 2001 From: tmk Date: Tue, 17 Jun 2014 22:41:14 +0900 Subject: Fix common files for mbed --- common/avr/bootloader.c | 148 +++++++++++++++++++++++++++++++++++++++++++++++ common/avr/eeconfig.c | 45 ++++++++++++++ common/avr/suspend.c | 98 +++++++++++++++++++++++++++++++ common/avr/suspend_avr.h | 27 +++++++++ 4 files changed, 318 insertions(+) create mode 100644 common/avr/bootloader.c create mode 100644 common/avr/eeconfig.c create mode 100644 common/avr/suspend.c create mode 100644 common/avr/suspend_avr.h (limited to 'common/avr') diff --git a/common/avr/bootloader.c b/common/avr/bootloader.c new file mode 100644 index 000000000..cda295b18 --- /dev/null +++ b/common/avr/bootloader.c @@ -0,0 +1,148 @@ +#include +#include +#include +#include +#include +#include +#include "bootloader.h" + +#ifdef PROTOCOL_LUFA +#include +#endif + + +/* Boot Section Size in *BYTEs* + * Teensy halfKay 512 + * Teensy++ halfKay 1024 + * Atmel DFU loader 4096 + * LUFA bootloader 4096 + * USBaspLoader 2048 + */ +#ifndef BOOTLOADER_SIZE +#warning To use bootloader_jump() you need to define BOOTLOADER_SIZE in config.h. +#define BOOTLOADER_SIZE 4096 +#endif + +#define FLASH_SIZE (FLASHEND + 1L) +#define BOOTLOADER_START (FLASH_SIZE - BOOTLOADER_SIZE) + + +/* + * Entering the Bootloader via Software + * http://www.fourwalledcubicle.com/files/LUFA/Doc/120730/html/_page__software_bootloader_start.html + */ +#define BOOTLOADER_RESET_KEY 0xB007B007 +uint32_t reset_key __attribute__ ((section (".noinit"))); + +/* initialize MCU status by watchdog reset */ +void bootloader_jump(void) { +#ifdef PROTOCOL_LUFA + USB_Disable(); + cli(); + _delay_ms(2000); +#endif + +#ifdef PROTOCOL_PJRC + cli(); + UDCON = 1; + USBCON = (1< +#include +#include +#include "eeconfig.h" + +void eeconfig_init(void) +{ + eeprom_write_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER); + eeprom_write_byte(EECONFIG_DEBUG, 0); + eeprom_write_byte(EECONFIG_DEFAULT_LAYER, 0); + eeprom_write_byte(EECONFIG_KEYMAP, 0); + eeprom_write_byte(EECONFIG_MOUSEKEY_ACCEL, 0); +#ifdef BACKLIGHT_ENABLE + eeprom_write_byte(EECONFIG_BACKLIGHT, 0); +#endif +} + +void eeconfig_enable(void) +{ + eeprom_write_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER); +} + +void eeconfig_disable(void) +{ + eeprom_write_word(EECONFIG_MAGIC, 0xFFFF); +} + +bool eeconfig_is_enabled(void) +{ + return (eeprom_read_word(EECONFIG_MAGIC) == EECONFIG_MAGIC_NUMBER); +} + +uint8_t eeconfig_read_debug(void) { return eeprom_read_byte(EECONFIG_DEBUG); } +void eeconfig_write_debug(uint8_t val) { eeprom_write_byte(EECONFIG_DEBUG, val); } + +uint8_t eeconfig_read_default_layer(void) { return eeprom_read_byte(EECONFIG_DEFAULT_LAYER); } +void eeconfig_write_default_layer(uint8_t val) { eeprom_write_byte(EECONFIG_DEFAULT_LAYER, val); } + +uint8_t eeconfig_read_keymap(void) { return eeprom_read_byte(EECONFIG_KEYMAP); } +void eeconfig_write_keymap(uint8_t val) { eeprom_write_byte(EECONFIG_KEYMAP, val); } + +#ifdef BACKLIGHT_ENABLE +uint8_t eeconfig_read_backlight(void) { return eeprom_read_byte(EECONFIG_BACKLIGHT); } +void eeconfig_write_backlight(uint8_t val) { eeprom_write_byte(EECONFIG_BACKLIGHT, val); } +#endif diff --git a/common/avr/suspend.c b/common/avr/suspend.c new file mode 100644 index 000000000..f44a036be --- /dev/null +++ b/common/avr/suspend.c @@ -0,0 +1,98 @@ +#include +#include +#include +#include +#include "matrix.h" +#include "action.h" +#include "backlight.h" +#include "suspend_avr.h" +#include "suspend.h" + + +#define wdt_intr_enable(value) \ +__asm__ __volatile__ ( \ + "in __tmp_reg__,__SREG__" "\n\t" \ + "cli" "\n\t" \ + "wdr" "\n\t" \ + "sts %0,%1" "\n\t" \ + "out __SREG__,__tmp_reg__" "\n\t" \ + "sts %0,%2" "\n\t" \ + : /* no outputs */ \ + : "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)) ) \ + : "r0" \ +) + + +void suspend_power_down(void) +{ +#ifdef BACKLIGHT_ENABLE + backlight_set(0); +#endif +#ifndef NO_SUSPEND_POWER_DOWN + // Enable watchdog to wake from MCU sleep + cli(); + wdt_reset(); + + // Watchdog Interrupt and System Reset Mode + //wdt_enable(WDTO_1S); + //WDTCSR |= _BV(WDIE); + + // Watchdog Interrupt Mode + wdt_intr_enable(WDTO_120MS); + + // TODO: more power saving + // See PicoPower application note + // - I/O port input with pullup + // - prescale clock + // - BOD disable + // - Power Reduction Register PRR + // sleep in power down mode + set_sleep_mode(SLEEP_MODE_PWR_DOWN); + sleep_enable(); + sei(); + sleep_cpu(); + sleep_disable(); + + // Disable watchdog after sleep + wdt_disable(); +#endif +} + +bool suspend_wakeup_condition(void) +{ + matrix_scan(); + for (uint8_t r = 0; r < MATRIX_ROWS; r++) { + if (matrix_get_row(r)) return true; + } + return false; +} + +// run immediately after wakeup +void suspend_wakeup_init(void) +{ + // clear keyboard state + clear_keyboard(); +#ifdef BACKLIGHT_ENABLE + backlight_init(); +#endif +} + +#ifndef NO_SUSPEND_POWER_DOWN +/* watchdog timeout */ +ISR(WDT_vect) +{ + /* wakeup from MCU sleep mode */ +/* + // blink LED + static uint8_t led_state = 0; + static uint8_t led_count = 0; + led_count++; + if ((led_count & 0x07) == 0) { + led_set((led_state ^= (1< +#include +#include +#include +#include + + +#define wdt_intr_enable(value) \ +__asm__ __volatile__ ( \ + "in __tmp_reg__,__SREG__" "\n\t" \ + "cli" "\n\t" \ + "wdr" "\n\t" \ + "sts %0,%1" "\n\t" \ + "out __SREG__,__tmp_reg__" "\n\t" \ + "sts %0,%2" "\n\t" \ + : /* no outputs */ \ + : "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)) ) \ + : "r0" \ +) + +#endif -- cgit v1.2.3-24-g4f1b