move some heap to psram and some updates

This commit is contained in:
sharandac
2020-08-12 11:03:36 +02:00
parent 33fe453f5e
commit aeb15d34a8
22 changed files with 358 additions and 31 deletions

View File

@@ -12,11 +12,36 @@ pio run -t upload
or simple press "build and upload" in platformIO.
# known issues
* the webserver crashes the ESP32 really often
* the battery indicator is not accurate, rather a problem with the power management unit ( axp202 )
* from time to time the esp32 crashes accidentally
* and some other small things
# how to use
On startup you see the main screen (time tile). It show the time and the current weather (if correct configure). Now you can swipe with you fingers up, down, left and right between the four main screens. The four screens are organized in time, apps, note and setup tile.
For the weather app you need an openweather.com api-id. http://openweathermap.org/appid is a good starting point.
# for the programmers
Internal RAM is very limited, use PSRAM as much as possible. When you work with ArduinoJson, include this
```#include "hardware/json_psram_allocator.h"```
and create your json with
```SpiRamJsonDocument doc( 1000 );```
to move your json into PSRAM, here is enough RAM for all the crazy stuff you will do. And use
```ps_malloc(), ps_calloc() and ps_realloc()```
as often as possible.
And one very important thing: Do not talk directly to the hardware!
# how to make a screenshot
The firmware has an integrated webserver. Over this a screenshot can be triggered. The image has the format RGB565 and can be read with gimp. From bash it look like this
```bash

View File

@@ -19,6 +19,7 @@ monitor_filters =
esp32_exception_decoder
build_flags =
-DCORE_DEBUG_LEVEL=3
-mfix-esp32-psram-cache-issue
src_filter =
+<*>
lib_deps =

View File

@@ -37,7 +37,7 @@
#include "gui/keyboard.h"
#include "hardware/motor.h"
#include "hardware/powermgm.h"
#include "hardware/json_config_psram_allocator.h"
#include "hardware/json_psram_allocator.h"
EventGroupHandle_t weather_widget_event_handle = NULL;
TaskHandle_t _weather_widget_sync_Task;

View File

@@ -27,7 +27,7 @@
#include "weather_forecast.h"
#include "hardware/powermgm.h"
#include "hardware/json_config_psram_allocator.h"
#include "hardware/json_psram_allocator.h"
/* Utility function to convert numbers to directions */
static void weather_wind_to_string( weather_forcast_t* container, int speed, int directionDegree);

View File

@@ -32,6 +32,6 @@
/*
* firmeware version string
*/
#define __FIRMWARE__ "2020081103"
#define __FIRMWARE__ "2020081202"
#endif // _CONFIG_H

View File

@@ -75,12 +75,12 @@ uint32_t mainbar_add_tile( uint16_t x, uint16_t y ) {
tile_entrys++;
if ( tile_pos_table == NULL ) {
tile_pos_table = ( lv_point_t * )malloc( sizeof( lv_point_t ) * tile_entrys );
tile_pos_table = ( lv_point_t * )ps_malloc( sizeof( lv_point_t ) * tile_entrys );
if ( tile_pos_table == NULL ) {
log_e("tile_pos_table malloc faild");
while(true);
}
tile = ( lv_tile_t * )malloc( sizeof( lv_tile_t ) * tile_entrys );
tile = ( lv_tile_t * )ps_malloc( sizeof( lv_tile_t ) * tile_entrys );
if ( tile == NULL ) {
log_e("tile malloc faild");
while(true);
@@ -90,14 +90,14 @@ uint32_t mainbar_add_tile( uint16_t x, uint16_t y ) {
lv_point_t *new_tile_pos_table;
lv_tile_t *new_tile;
new_tile_pos_table = ( lv_point_t * )realloc( tile_pos_table, sizeof( lv_point_t ) * tile_entrys );
new_tile_pos_table = ( lv_point_t * )ps_realloc( tile_pos_table, sizeof( lv_point_t ) * tile_entrys );
if ( new_tile_pos_table == NULL ) {
log_e("tile_pos_table realloc faild");
while(true);
}
tile_pos_table = new_tile_pos_table;
new_tile = ( lv_tile_t * )realloc( tile, sizeof( lv_tile_t ) * tile_entrys );
new_tile = ( lv_tile_t * )ps_realloc( tile, sizeof( lv_tile_t ) * tile_entrys );
if ( new_tile == NULL ) {
log_e("tile realloc faild");
while(true);

View File

@@ -226,7 +226,9 @@ void update_Task( void * pvParameters ) {
WiFiClient client;
lv_label_set_text( update_status_label, "start update ..." );
lv_obj_align( update_status_label, update_btn, LV_ALIGN_OUT_BOTTOM_MID, 0, 15 );
lv_obj_align( update_status_label, update_btn, LV_ALIGN_OUT_BOTTOM_MID, 0, 15 );
httpUpdate.rebootOnUpdate( false );
t_httpUpdate_return ret = httpUpdate.update( client, "http://www.neo-guerillaz.de/ttgo-t-watch2020_v1.ino.bin" );
@@ -242,7 +244,7 @@ void update_Task( void * pvParameters ) {
break;
case HTTP_UPDATE_OK:
lv_label_set_text( update_status_label, "update ok" );
lv_label_set_text( update_status_label, "update ok, turn off and on!" );
lv_obj_align( update_status_label, update_btn, LV_ALIGN_OUT_BOTTOM_MID, 0, 15 );
break;
}

View File

@@ -24,7 +24,7 @@
#include "update_check_version.h"
#include "hardware/json_config_psram_allocator.h"
#include "hardware/json_psram_allocator.h"
uint64_t update_check_new_version( void ) {
char url[512]="";

View File

@@ -29,7 +29,7 @@
#include "gui/statusbar.h"
#include "gui/keyboard.h"
#include "hardware/json_config_psram_allocator.h"
#include "hardware/json_psram_allocator.h"
update_config_t update_config;

228
src/hardware/blectl.cpp Normal file
View File

@@ -0,0 +1,228 @@
/****************************************************************************
* Aug 11 17:13:51 2020
* Copyright 2020 Dirk Brosswick
* Email: dirk.brosswick@googlemail.com
****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*
* inspire by https://github.com/bburky/t-watch-2020-project
*
*/
#include "config.h"
#include "Arduino.h"
#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>
#include "blectl.h"
EventGroupHandle_t blectl_status = NULL;
portMUX_TYPE blectlMux = portMUX_INITIALIZER_UNLOCKED;
BLEServer *pServer = NULL;
BLECharacteristic *pTxCharacteristic;
uint8_t txValue = 0;
#define MAX_MESSAGE_SIZE 512
String message;
/*
*
*/
class BleCtlServerCallbacks: public BLEServerCallbacks {
void onConnect(BLEServer* pServer) {
blectl_set_event( BLECTL_CONNECT );
Serial.printf("BLE connected\r\n");
};
void onDisconnect(BLEServer* pServer) {
blectl_clear_event( BLECTL_CONNECT );
Serial.printf("BLE disconnected\r\n");
delay(500);
pServer->getAdvertising()->start();
Serial.printf("BLE advertising...\r\n");
}
};
/*
*
*/
class BtlCtlSecurity : public BLESecurityCallbacks {
uint32_t onPassKeyRequest(){
Serial.printf("BLE: PassKeyRequest\r\n");
// TODO: when is this used?
return 123456;
}
void onPassKeyNotify(uint32_t pass_key){
blectl_set_event( BLECTL_PAIRING );
Serial.printf("Bluetooth Pairing Request\r\nPIN: %06d\r\n", pass_key);
}
bool onConfirmPIN(uint32_t pass_key){
Serial.printf("BLE: The passkey YES/NO number :%06d\r\n", pass_key);
// vTaskDelay(5000);
// return true;
// TODO: when is this used?
return false;
}
bool onSecurityRequest(){
Serial.printf("BLE: SecurityRequest\r\n");
// TODO: when is this used?
return true;
}
void onAuthenticationComplete( esp_ble_auth_cmpl_t cmpl ){
Serial.printf("Bluetooth pairing %s\r\n", cmpl.success ? "successful" : "unsuccessful");
if( cmpl.success ){
uint16_t length;
esp_ble_gap_get_whitelist_size( &length );
log_i("size: %d", length );
} else {
// Restart advertising
pServer->startAdvertising();
}
if ( blectl_get_event( BLECTL_PAIRING )) {
blectl_clear_event( BLECTL_PAIRING );
}
}
};
class BleCtlCallbacks : public BLECharacteristicCallbacks
{
void onWrite(BLECharacteristic *pCharacteristic)
{
std::string rxValue = pCharacteristic->getValue();
if (rxValue.length() > 0)
{
for (int i = 0; i < rxValue.length(); i++) {
if (rxValue[i] == 0x10) {
if ( message.length() ) {
log_i("BLE: Discarding %d bytes\n", message.length());
}
message.clear();
} else if (rxValue[i] == '\n') {
if (message.length()+1 > MAX_MESSAGE_SIZE) {
message.clear();
log_e("BLE Error: Message too long");
return;
}
message[message.length()] = 0;
// processMessage();
message.clear();
} else {
message += rxValue[i];
if (message.length() > MAX_MESSAGE_SIZE) {
message.clear();
log_e("BLE Error: Message too long");
return;
}
}
}
}
}
};
/*
*
*/
void blectl_setup( void ) {
blectl_status = xEventGroupCreate();
blectl_set_event( BLECTL_CONNECT | BLECTL_OFF_REQUEST | BLECTL_ON_REQUEST | BLECTL_PAIRING | BLECTL_STANDBY_REQUEST | BLECTL_ACTIVE | BLECTL_SCAN );
// Create the BLE Device
// Name needs to match filter in Gadgetbridge's banglejs getSupportedType() function.
// This is too long I think:
// BLEDevice::init("Espruino Gadgetbridge Compatible Device");
BLEDevice::init("Espruino");
// The minimum power level (-12dbm) ESP_PWR_LVL_N12 was too low
BLEDevice::setPower( ESP_PWR_LVL_N9 );
// Enable encryption
BLEServer* pServer = BLEDevice::createServer();
BLEDevice::setEncryptionLevel( ESP_BLE_SEC_ENCRYPT_NO_MITM );
BLEDevice::setSecurityCallbacks( new BtlCtlSecurity() );
// Enable authentication
BLESecurity *pSecurity = new BLESecurity();
pSecurity->setAuthenticationMode(ESP_LE_AUTH_REQ_SC_BOND);
pSecurity->setCapability(ESP_IO_CAP_OUT);
pSecurity->setInitEncryptionKey(ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK);
pSecurity->setRespEncryptionKey(ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK);
// Create the BLE Server
pServer = BLEDevice::createServer();
pServer->setCallbacks( new BleCtlServerCallbacks() );
// Create the BLE Service
BLEService *pService = pServer->createService(SERVICE_UUID);
// Create a BLE Characteristic
pTxCharacteristic = pService->createCharacteristic( CHARACTERISTIC_UUID_TX, BLECharacteristic::PROPERTY_NOTIFY );
pTxCharacteristic->setAccessPermissions(ESP_GATT_PERM_READ_ENCRYPTED | ESP_GATT_PERM_WRITE_ENCRYPTED);
pTxCharacteristic->addDescriptor( new BLE2902() );
BLECharacteristic *pRxCharacteristic = pService->createCharacteristic( CHARACTERISTIC_UUID_RX, BLECharacteristic::PROPERTY_WRITE );
pRxCharacteristic->setAccessPermissions(ESP_GATT_PERM_READ_ENCRYPTED | ESP_GATT_PERM_WRITE_ENCRYPTED);
pRxCharacteristic->setCallbacks( new BleCtlCallbacks() );
// Start the service
pService->start();
// Start advertising
pServer->getAdvertising()->addServiceUUID( pService->getUUID() );
// Slow advertising interval for battery life
// The maximum 0x4000 interval of ~16 sec was too slow, I could not reliably connect
pServer->getAdvertising()->setMinInterval( 1000 );
pServer->getAdvertising()->setMaxInterval( 2000 );
pServer->getAdvertising()->start();
Serial.printf("BLE advertising...\r\n");
}
/*
*
*/
void blectl_set_event( EventBits_t bits ) {
portENTER_CRITICAL_ISR(&blectlMux);
xEventGroupSetBits( blectl_status, bits );
portEXIT_CRITICAL_ISR(&blectlMux);
}
/*
*
*/
void blectl_clear_event( EventBits_t bits ) {
portENTER_CRITICAL_ISR(&blectlMux);
xEventGroupClearBits( blectl_status, bits );
portEXIT_CRITICAL_ISR(&blectlMux);
}
/*
*
*/
EventBits_t blectl_get_event( EventBits_t bits ) {
portENTER_CRITICAL_ISR(&blectlMux);
EventBits_t temp = xEventGroupGetBits( blectl_status ) & bits;
portEXIT_CRITICAL_ISR(&blectlMux);
return( temp );
}

62
src/hardware/blectl.h Normal file
View File

@@ -0,0 +1,62 @@
/****************************************************************************
* Aug 11 17:13:51 2020
* Copyright 2020 Dirk Brosswick
* Email: dirk.brosswick@googlemail.com
****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef _BLECTL_H
#define _BLECTL_H
#include "TTGO.h"
// See the following for generating UUIDs:
// https://www.uuidgenerator.net/
#define SERVICE_UUID BLEUUID("6E400001-B5A3-F393-E0A9-E50E24DCCA9E") // UART service UUID
#define CHARACTERISTIC_UUID_RX BLEUUID("6E400002-B5A3-F393-E0A9-E50E24DCCA9E")
#define CHARACTERISTIC_UUID_TX BLEUUID("6E400003-B5A3-F393-E0A9-E50E24DCCA9E")
#define BLECTL_CONNECT _BV(0)
#define BLECTL_STANDBY_REQUEST _BV(1)
#define BLECTL_ON_REQUEST _BV(2)
#define BLECTL_OFF_REQUEST _BV(3)
#define BLECTL_ACTIVE _BV(4)
#define BLECTL_SCAN _BV(5)
#define BLECTL_PAIRING _BV(6)
void blectl_setup( void );
/*
* @brief trigger a blectl managemt event
*
* @param bits event to trigger
*/
void blectl_set_event( EventBits_t bits );
/*
* @brief clear a blectl managemt event
*
* @param bits event to clear
*/
void blectl_clear_event( EventBits_t bits );
/*
* @brief get a blectl managemt event state
*
* @param bits event state, example: POWERMGM_STANDBY to evaluate if the system in standby
*/
EventBits_t blectl_get_event( EventBits_t bits );
#endif // _BLECTL_H

View File

@@ -25,7 +25,7 @@
#include "bma.h"
#include "powermgm.h"
#include "json_config_psram_allocator.h"
#include "json_psram_allocator.h"
#include "gui/statusbar.h"

View File

@@ -26,7 +26,7 @@
#include "powermgm.h"
#include "motor.h"
#include "json_config_psram_allocator.h"
#include "json_psram_allocator.h"
display_config_t display_config;

View File

@@ -7,11 +7,11 @@ struct SpiRamAllocator {
void* allocate( size_t size ) {
void *psram = ps_calloc( size, 1 );
if ( psram ) {
log_i("allocate %dbytes(%p) json psram", size, psram );
log_i("allocate %d bytes (%p) json psram", size, psram );
return( psram );
}
else {
log_e("allocate %dbytes(%p) json psram failed", size, psram );
log_e("allocate %d bytes (%p) json psram failed", size, psram );
while(1);
}
}

View File

@@ -21,7 +21,7 @@
*/
#include "config.h"
#include <TTGO.h>
#include "json_config_psram_allocator.h"
#include "json_psram_allocator.h"
#include "motor.h"
#include "powermgm.h"

View File

@@ -1,7 +1,7 @@
#include "config.h"
#include <TTGO.h>
#include <soc/rtc.h>
#include "json_config_psram_allocator.h"
#include "json_psram_allocator.h"
#include "display.h"
#include "pmu.h"

View File

@@ -24,8 +24,6 @@
#include <soc/rtc.h>
#include <WiFi.h>
#include <esp_wifi.h>
#include <esp_bt.h>
#include <esp_bt_main.h>
#include <time.h>
#include "driver/adc.h"

View File

@@ -24,7 +24,7 @@
#include "config.h"
#include "timesync.h"
#include "powermgm.h"
#include "json_config_psram_allocator.h"
#include "json_psram_allocator.h"
EventGroupHandle_t time_event_handle = NULL;
TaskHandle_t _timesync_Task;

View File

@@ -27,7 +27,7 @@
#include "powermgm.h"
#include "wifictl.h"
#include "json_config_psram_allocator.h"
#include "json_psram_allocator.h"
#include "gui/statusbar.h"
#include "webserver/webserver.h"
@@ -461,21 +461,24 @@ void wifictl_Task( void * pvParameters ) {
while ( true ) {
vTaskDelay( 500 );
if ( powermgm_get_event( POWERMGM_WIFI_ON_REQUEST ) ) {
statusbar_wifi_set_state( true, "activate" );
lv_obj_invalidate( lv_scr_act() );
WiFi.mode( WIFI_STA );
powermgm_clear_event( POWERMGM_WIFI_OFF_REQUEST | POWERMGM_WIFI_ACTIVE | POWERMGM_WIFI_CONNECTED | POWERMGM_WIFI_SCAN | POWERMGM_WIFI_ON_REQUEST );
log_i("request wifictl on done");
if ( powermgm_get_event( POWERMGM_WIFI_OFF_REQUEST ) && powermgm_get_event( POWERMGM_WIFI_ON_REQUEST ) ) {
log_e("confused by wifictl on/off at the same time. off request accept");
}
else if ( powermgm_get_event( POWERMGM_WIFI_OFF_REQUEST ) ) {
if ( powermgm_get_event( POWERMGM_WIFI_OFF_REQUEST ) ) {
statusbar_wifi_set_state( false, "" );
lv_obj_invalidate( lv_scr_act() );
WiFi.mode( WIFI_OFF );
esp_wifi_stop();
powermgm_clear_event( POWERMGM_WIFI_OFF_REQUEST | POWERMGM_WIFI_ACTIVE | POWERMGM_WIFI_CONNECTED | POWERMGM_WIFI_SCAN | POWERMGM_WIFI_ON_REQUEST );
log_i("request wifictl off done");
}
else if ( powermgm_get_event( POWERMGM_WIFI_ON_REQUEST ) ) {
statusbar_wifi_set_state( true, "activate" );
lv_obj_invalidate( lv_scr_act() );
WiFi.mode( WIFI_STA );
log_i("request wifictl on done");
}
powermgm_clear_event( POWERMGM_WIFI_OFF_REQUEST | POWERMGM_WIFI_ACTIVE | POWERMGM_WIFI_CONNECTED | POWERMGM_WIFI_SCAN | POWERMGM_WIFI_ON_REQUEST );
vTaskSuspend( _wifictl_Task );
}
}

View File

@@ -32,6 +32,7 @@
#include "hardware/powermgm.h"
#include "hardware/motor.h"
#include "hardware/wifictl.h"
#include "hardware/blectl.h"
#include "app/weather/weather.h"
#include "app/example_app/example_app.h"
@@ -40,6 +41,7 @@ TTGOClass *ttgo = TTGOClass::getWatch();
void setup()
{
Serial.begin(115200);
Serial.printf("starting t-watch V1, version: " __FIRMWARE__ "\r\n");
ttgo->begin();
@@ -49,6 +51,9 @@ void setup()
motor_setup();
// force to store all heap data in psram to get more internal ram
heap_caps_malloc_extmem_enable( 1 );
display_setup( ttgo );
screenshot_setup();
@@ -85,6 +90,9 @@ void setup()
wifictl_on();
display_set_brightness( display_get_brightness() );
// enable to store data in normal heap
heap_caps_malloc_extmem_enable( 16*1024 );
Serial.printf("Total heap: %d\r\n", ESP.getHeapSize());
Serial.printf("Free heap: %d\r\n", ESP.getFreeHeap());
Serial.printf("Total PSRAM: %d\r\n", ESP.getPsramSize());
@@ -93,7 +101,7 @@ void setup()
void loop()
{
delay(10);
delay(1);
gui_loop( ttgo );
powermgm_loop( ttgo );
}

Binary file not shown.

View File

@@ -1 +1 @@
{"version":"2020081103","host":"http://www.neo-guerillaz.de","file":"ttgo-t-watch2020_v1.ino.bin"}
{"version":"2020081202","host":"http://www.neo-guerillaz.de","file":"ttgo-t-watch2020_v1.ino.bin"}