diff --git a/README.md b/README.md index e4e730f..bd7e98a 100644 --- a/README.md +++ b/README.md @@ -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). diff --git a/components/espnow/espnow_recieve.c b/components/espnow/espnow_recieve.c index 7a24820..25e89b9 100644 --- a/components/espnow/espnow_recieve.c +++ b/components/espnow/espnow_recieve.c @@ -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); } diff --git a/components/r_encoder/r_encoder.c b/components/r_encoder/r_encoder.c index 2031e2e..cdbd545 100644 --- a/components/r_encoder/r_encoder.c +++ b/components/r_encoder/r_encoder.c @@ -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 diff --git a/main/keyboard_config.h b/main/keyboard_config.h index b53bda0..2e88d32 100644 --- a/main/keyboard_config.h +++ b/main/keyboard_config.h @@ -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 diff --git a/main/matrix.c b/main/matrix.c index 5a9ddba..b5378d5 100644 --- a/main/matrix.c +++ b/main/matrix.c @@ -23,12 +23,14 @@ //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}; @@ -36,6 +38,62 @@ const gpio_num_t MATRIX_COLS_PINS[]={GPIO_NUM_13,GPIO_NUM_14,GPIO_NUM_15,GPIO_NU // 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){ diff --git a/main/mk32_main.cpp b/main/mk32_main.cpp index 62e443e..0e65712 100755 --- a/main/mk32_main.cpp +++ b/main/mk32_main.cpp @@ -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){ @@ -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 @@ -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; @@ -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; @@ -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){ @@ -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!"); @@ -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(); } @@ -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;