Skip to content
This repository has been archived by the owner on May 5, 2024. It is now read-only.

Commit

Permalink
Added wake up from deep sleep on key press
Browse files Browse the repository at this point in the history
  • Loading branch information
Galzai committed Sep 12, 2018
1 parent 78213f9 commit 2af4451
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 22 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,9 @@ In order to define your keyboard:

### Power consumption and deep sleep:
- For better battery usage you can define the number of inactive minutes you would like your device to wait before sleeping in keyboard_config.h.
- The controller is defined to wake up when the capacity on GPIO pin 2 is modified ("touch sensor"), if you do not want to enable deep sleep simply undefine SLEEP_MINS.
- Notice that on windows reconnection after waking from deep sleep might take a couple of minutes, no problem on linux.
- Notice that waking from deep sleep on keypress is only possible on keys which connect rtc gpio pins (so make sure to have at least 1 rtc row pin, and 1 rtc col pins
wake up keys of your choice), if you do not want to enable deep sleep simply undefine SLEEP_MINS.
- Notice that on windows reconnection after waking from deep sleep might take a couple of minutes, no problem on linux and android.
(on windows you can rescan for bluetooth devices and it should recconect without waiting).
- Tested current (hopefully will improve in future):
40 mA for BLE (without split functionality).
Expand Down
1 change: 0 additions & 1 deletion components/espnow/espnow_recieve.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,6 @@ static void espnow_recv_cb(const uint8_t *mac_addr, const uint8_t *data, int dat
if(data_len==1){
memcpy(CURRENT_ENCODER, data, sizeof(CURRENT_ENCODER) );
r_encoder_command(CURRENT_ENCODER[0], slave_encoder_map[current_layout]);
xQueueSend(media_q,(void*)&CURRENT_ENCODER, (TickType_t) 0);

}

Expand Down
2 changes: 0 additions & 2 deletions components/r_encoder/r_encoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@
#include "driver/pcnt.h"
#include "HID_kbdmousejoystick.h"

#define CHECK_BIT(var,pos) ((var) & (1<<(pos)))

int PastEncoderCount=0;

//How to process encoder activity
Expand Down
2 changes: 2 additions & 0 deletions main/keyboard_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@
*----- Everything below here should not be modified for standard usage----
*
* */
#define CHECK_BIT(var,pos) ((var) & (1<<(pos)))
#define SET_BIT(var,pos) (var |= 1UL << pos);

#define KEYMAP_COLS MATRIX_COLS*KEYPADS // used for a symmetrical split keyboard
#define REPORT_LEN 2+MATRIX_ROWS*KEYMAP_COLS+3 //size of hid reports with NKRO and room for 3 key macro
Expand Down
60 changes: 59 additions & 1 deletion main/matrix.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,77 @@
//GPIO libraries
#include "esp_system.h"
#include "driver/gpio.h"
#include "driver/rtc_io.h"
#include "keyboard_config.h"

#include "esp_sleep.h"

/* Define pins, notice that:
* GPIO6-11 are usually used for SPI flash
* GPIO34-39 can only be set as input mode and do not have software pullup or pulldown functions.
* GPIOS 0,2,4,12-15,25-27,32-39 Can be used as RTC GPIOS as well (please read about power management in ReadMe)
*/
const gpio_num_t MATRIX_ROWS_PINS[]={GPIO_NUM_0,GPIO_NUM_4,GPIO_NUM_5,GPIO_NUM_12};
const gpio_num_t MATRIX_COLS_PINS[]={GPIO_NUM_13,GPIO_NUM_14,GPIO_NUM_15,GPIO_NUM_16,GPIO_NUM_17,GPIO_NUM_18};

// matrix state
uint8_t MATRIX_STATE[MATRIX_ROWS][MATRIX_COLS]={0};

// deinitializing rtc matrix pins on deep sleep wake up
void rtc_matrix_deinit(void){

// Deinitializing columns
for(uint8_t col=0; col < MATRIX_COLS; col++){

if(rtc_gpio_is_valid_gpio(MATRIX_COLS_PINS[col])==1){
rtc_gpio_set_level(MATRIX_COLS_PINS[col], 0);
rtc_gpio_set_direction(MATRIX_COLS_PINS[col], RTC_GPIO_MODE_DISABLED);
gpio_reset_pin(MATRIX_COLS_PINS[col]);
}
}

// Deinitializing rows
for(uint8_t row=0; row < MATRIX_ROWS; row++){

if(rtc_gpio_is_valid_gpio(MATRIX_ROWS_PINS[row])==1){
rtc_gpio_set_level(MATRIX_ROWS_PINS[row], 0);
rtc_gpio_set_direction(MATRIX_ROWS_PINS[row], RTC_GPIO_MODE_DISABLED);
gpio_reset_pin(MATRIX_ROWS_PINS[row]);
}
}
}

// Initializing rtc matrix pins for deep sleep wake up
void rtc_matrix_setup(void){
uint64_t rtc_mask = 0;

// Initializing columns
for(uint8_t col=0; col < MATRIX_COLS; col++){

if(rtc_gpio_is_valid_gpio(MATRIX_COLS_PINS[col])==1){
rtc_gpio_init((MATRIX_COLS_PINS[col]));
rtc_gpio_set_direction(MATRIX_COLS_PINS[col], RTC_GPIO_MODE_INPUT_OUTPUT);
rtc_gpio_set_level(MATRIX_COLS_PINS[col], 1);
printf("\n%d is level %d",MATRIX_COLS_PINS[col],gpio_get_level(MATRIX_COLS_PINS[col]));
}
}

// Initializing rows
for(uint8_t row=0; row < MATRIX_ROWS; row++){

if(rtc_gpio_is_valid_gpio(MATRIX_ROWS_PINS[row])==1){
rtc_gpio_init((MATRIX_ROWS_PINS[row]));
rtc_gpio_set_direction(MATRIX_ROWS_PINS[row], RTC_GPIO_MODE_INPUT_OUTPUT);
rtc_gpio_set_drive_capability(MATRIX_ROWS_PINS[row],GPIO_DRIVE_CAP_0);
rtc_gpio_set_level(MATRIX_ROWS_PINS[row], 0);
rtc_gpio_wakeup_enable(MATRIX_ROWS_PINS[row],GPIO_INTR_HIGH_LEVEL);
SET_BIT(rtc_mask,MATRIX_ROWS_PINS[row]);

printf("\n%d is level %d",MATRIX_ROWS_PINS[row],gpio_get_level(MATRIX_ROWS_PINS[row]));
}
esp_sleep_enable_ext1_wakeup(rtc_mask,ESP_EXT1_WAKEUP_ANY_HIGH);
}
}

// Initializing matrix pins
void matrix_setup(void){

Expand Down
33 changes: 17 additions & 16 deletions main/mk32_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,13 @@ static config_data_t config;
QueueHandle_t espnow_recieve_q;

bool DEEP_SLEEP = true; // flag to check if we need to go to deep sleep
bool BLE_SLEEP= true;
bool OLED_SLEEP = false;
bool OLED_SLEEP = false; // flag to stop oled when going to deep sleep (otherwise I2C occasionally crashes)

#ifdef OLED_ENABLE
TaskHandle_t xOledTask;
#endif

//Task for continually updating the OLED
extern "C" void oled_task(void *pvParameters){

while(1){
Expand All @@ -78,6 +78,7 @@ extern "C" void oled_task(void *pvParameters){
}
}

//How to handle key reports
extern "C" void key_reports(void *pvParameters)
{
// Arrays for holding the report at various stages
Expand Down Expand Up @@ -129,6 +130,7 @@ extern "C" void key_reports(void *pvParameters)

}

//Handling rotary encoder
extern "C" void encoder_report(void *pvParameters){
uint8_t encoder_state=0;
uint8_t past_encoder_state=0;
Expand All @@ -144,6 +146,7 @@ extern "C" void encoder_report(void *pvParameters){
}
}

//Handling rotary encoder for slave pad
extern "C" void slave_encoder_report(void *pvParameters){
uint8_t encoder_state=0;
uint8_t past_encoder_state=0;
Expand Down Expand Up @@ -194,19 +197,16 @@ extern "C" void espnow_update_matrix(void *pvParameters){
}
}
}

//what to do after waking from deep sleep
extern "C" void esp_wake_deep_sleep(void) {
esp_default_wake_deep_sleep();
touch_pad_deinit();
}
//what to do after waking from deep sleep, doesn't seem to work after updating esp-idf
//extern "C" void RTC_IRAM_ATTR esp_wake_deep_sleep(void) {
// rtc_matrix_deinit();;
// SLEEP_WAKE=true;
//}

/*If no key press has been recieved in SLEEP_MINS amount of minutes, put device into deep sleep
* wake up on touch on GPIO pin 2
* */
extern "C" void deep_sleep(void *pvParameters){


uint64_t initial_time = esp_timer_get_time(); // notice that timer returns time passed in microseconds!
uint64_t current_time_passed = 0;
while(1){
Expand All @@ -218,7 +218,7 @@ extern "C" void deep_sleep(void *pvParameters){
initial_time = esp_timer_get_time();
DEEP_SLEEP= true;
}
//

if(current_time_passed>=1000000*60*SLEEP_MINS){
if(DEEP_SLEEP == true){
ESP_LOGE(SYSTEM_REPORT_TAG,"going to sleep!");
Expand All @@ -230,12 +230,10 @@ extern "C" void deep_sleep(void *pvParameters){
esp_bt_controller_disable();
esp_wifi_stop();

// wake up esp32 using touch sensor
touch_pad_init();
touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER);
touch_pad_config(TOUCH_PAD_NUM2,TOUCH_THRESHOLD);
// wake up esp32 using rtc gpio
rtc_matrix_setup(); // doesnt work
esp_sleep_enable_touchpad_wakeup();
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH,ESP_PD_OPTION_AUTO);
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH,ESP_PD_OPTION_ON);
esp_deep_sleep_start();

}
Expand All @@ -253,7 +251,10 @@ extern "C" void deep_sleep(void *pvParameters){

extern "C" void app_main()
{
//Reset the rtc GPIOS
rtc_matrix_deinit();

//Underclocking for better current draw (not really effective)
// esp_pm_config_esp32_t pm_config;
// pm_config.max_freq_mhz = 10;
// pm_config.min_freq_mhz = 10;
Expand Down

0 comments on commit 2af4451

Please sign in to comment.