- doesn't pwoer save while Bluetooth turns ontags/v1.9
DDRB = 0x00; PORTB = 0xFF; // change pins input with pull-up | DDRB = 0x00; PORTB = 0xFF; // change pins input with pull-up | ||||
DDRD |= (1<<4); PORTD &= ~(1<<4); // MOS FET switch off | DDRD |= (1<<4); PORTD &= ~(1<<4); // MOS FET switch off | ||||
} | } | ||||
static inline bool KEY_POWER_STATE(void) { return PORTD & (1<<4); } | |||||
#else | #else | ||||
static inline void KEY_POWER_ON(void) {} | static inline void KEY_POWER_ON(void) {} | ||||
static inline void KEY_POWER_OFF(void) {} | static inline void KEY_POWER_OFF(void) {} | ||||
static inline bool KEY_POWER_STATE(void) { return true; } | |||||
#endif | #endif | ||||
static inline void KEY_INIT(void) | static inline void KEY_INIT(void) | ||||
{ | { | ||||
KEY_UNABLE(); | KEY_UNABLE(); | ||||
KEY_PREV_OFF(); | KEY_PREV_OFF(); | ||||
KEY_POWER_ON(); | |||||
KEY_POWER_OFF(); | |||||
} | } | ||||
static inline void KEY_SELECT(uint8_t ROW, uint8_t COL) | static inline void KEY_SELECT(uint8_t ROW, uint8_t COL) | ||||
{ | { |
// matrix power saving | // matrix power saving | ||||
#define MATRIX_POWER_SAVE 10000 | #define MATRIX_POWER_SAVE 10000 | ||||
static uint32_t matrix_last_modified = 0; | static uint32_t matrix_last_modified = 0; | ||||
static bool matrix_power = true; | |||||
// matrix state buffer(1:on, 0:off) | // matrix state buffer(1:on, 0:off) | ||||
static matrix_row_t *matrix; | static matrix_row_t *matrix; | ||||
matrix_prev = matrix; | matrix_prev = matrix; | ||||
matrix = tmp; | matrix = tmp; | ||||
matrix_power_up(); | |||||
// power on | |||||
if (!KEY_POWER_STATE()) KEY_POWER_ON(); | |||||
for (uint8_t row = 0; row < MATRIX_ROWS; row++) { | for (uint8_t row = 0; row < MATRIX_ROWS; row++) { | ||||
for (uint8_t col = 0; col < MATRIX_COLS; col++) { | for (uint8_t col = 0; col < MATRIX_COLS; col++) { | ||||
KEY_SELECT(row, col); | KEY_SELECT(row, col); | ||||
} | } | ||||
if (matrix[row] ^ matrix_prev[row]) matrix_last_modified = timer_read32(); | if (matrix[row] ^ matrix_prev[row]) matrix_last_modified = timer_read32(); | ||||
} | } | ||||
matrix_power_down(); | |||||
// power off | |||||
if (KEY_POWER_STATE() && | |||||
(USB_DeviceState == DEVICE_STATE_Suspended || | |||||
USB_DeviceState == DEVICE_STATE_Unattached ) && | |||||
timer_elapsed32(matrix_last_modified) > MATRIX_POWER_SAVE) { | |||||
KEY_POWER_OFF(); | |||||
suspend_power_down(); | |||||
} | |||||
return 1; | return 1; | ||||
} | } | ||||
} | } | ||||
void matrix_power_up(void) { | void matrix_power_up(void) { | ||||
if (matrix_power) return; | |||||
KEY_POWER_ON(); | KEY_POWER_ON(); | ||||
matrix_power = true; | |||||
} | } | ||||
void matrix_power_down(void) { | void matrix_power_down(void) { | ||||
if (!matrix_power) return; | |||||
// doesn't power save while USB connection is active | |||||
if (USB_DeviceState != DEVICE_STATE_Unattached) return; | |||||
if (timer_elapsed32(matrix_last_modified) <= MATRIX_POWER_SAVE) return; | |||||
KEY_POWER_OFF(); | KEY_POWER_OFF(); | ||||
suspend_power_down(); | |||||
matrix_power = false; | |||||
} | } |
USB_USBTask(); | USB_USBTask(); | ||||
#endif | #endif | ||||
} | } | ||||
print("USB configured.\n"); | |||||
print("\nUSB init\n"); | |||||
rn42_init(); | rn42_init(); | ||||
rn42_task_init(); | rn42_task_init(); | ||||
sleep_led_init(); | sleep_led_init(); | ||||
#endif | #endif | ||||
print("Keyboard start.\n"); | |||||
print("Keyboard start\n"); | |||||
while (1) { | while (1) { | ||||
while (USB_DeviceState == DEVICE_STATE_Suspended) { | |||||
while (rn42_rts() && // RN42 is off | |||||
USB_DeviceState == DEVICE_STATE_Suspended) { | |||||
print("[s]"); | print("[s]"); | ||||
matrix_power_down(); | |||||
suspend_power_down(); | |||||
suspend_power_down(); | |||||
suspend_power_down(); | |||||
suspend_power_down(); | |||||
suspend_power_down(); | |||||
suspend_power_down(); | |||||
suspend_power_down(); | suspend_power_down(); | ||||
if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) { | if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) { | ||||
USB_Device_SendRemoteWakeup(); | USB_Device_SendRemoteWakeup(); |
print("[C]"); | print("[C]"); | ||||
/* For battery powered device */ | /* For battery powered device */ | ||||
if (!USB_IsInitialized) { | if (!USB_IsInitialized) { | ||||
USB_Disable(); | |||||
USB_Init(); | USB_Init(); | ||||
USB_Device_EnableSOFEvents(); | USB_Device_EnableSOFEvents(); | ||||
} | } | ||||
{ | { | ||||
print("[D]"); | print("[D]"); | ||||
/* For battery powered device */ | /* For battery powered device */ | ||||
USB_IsInitialized = false; | |||||
/* TODO: This doesn't work. After several plug in/outs can not be enumerated. | /* TODO: This doesn't work. After several plug in/outs can not be enumerated. | ||||
if (USB_IsInitialized) { | if (USB_IsInitialized) { | ||||
USB_Disable(); // Disable all interrupts | USB_Disable(); // Disable all interrupts | ||||
void EVENT_USB_Device_Suspend() | void EVENT_USB_Device_Suspend() | ||||
{ | { | ||||
print("[S]"); | print("[S]"); | ||||
matrix_power_down(); | |||||
#ifdef SLEEP_LED_ENABLE | #ifdef SLEEP_LED_ENABLE | ||||
sleep_led_enable(); | sleep_led_enable(); | ||||
#endif | #endif |