diff --git a/Sming/Arch/Esp8266/Components/esp-lwip/mem_manager.h b/Sming/Arch/Esp8266/Components/esp-lwip/mem_manager.h index 667e7ac848..c9c4ba684a 100644 --- a/Sming/Arch/Esp8266/Components/esp-lwip/mem_manager.h +++ b/Sming/Arch/Esp8266/Components/esp-lwip/mem_manager.h @@ -55,7 +55,7 @@ //#define configADJUSTED_HEAP_SIZE ( configTOTAL_HEAP_SIZE - portBYTE_ALIGNMENT ) //static unsigned char ucHeap[ configTOTAL_HEAP_SIZE ]; -static unsigned char *ucHeap; +// static unsigned char *ucHeap; typedef struct A_BLOCK_LINK { @@ -67,7 +67,7 @@ static const unsigned short heapSTRUCT_SIZE = ( sizeof( xBlockLink ) + portBYTE_ //static const size_t xTotalHeapSize = ( ( size_t ) configADJUSTED_HEAP_SIZE ) & ( ( size_t ) ~portBYTE_ALIGNMENT_MASK ); -static xBlockLink xStart, *pxEnd = NULL; +// static xBlockLink xStart, *pxEnd = NULL; //static size_t xFreeBytesRemaining = ( ( size_t ) configADJUSTED_HEAP_SIZE ) & ( ( size_t ) ~portBYTE_ALIGNMENT_MASK ); diff --git a/Sming/Arch/Esp8266/Components/esp8266/include/espinc/eagle_soc.h b/Sming/Arch/Esp8266/Components/esp8266/include/espinc/eagle_soc.h index f65e7e8731..844f2f21dd 100644 --- a/Sming/Arch/Esp8266/Components/esp8266/include/espinc/eagle_soc.h +++ b/Sming/Arch/Esp8266/Components/esp8266/include/espinc/eagle_soc.h @@ -187,8 +187,20 @@ //}} //CACHE{{ -#define CACHE_FLASH_CTRL_REG (0x3ff00000 + 0x0c) -#define CACHE_READ_EN_BIT BIT8 +#define CACHE_FLASH_CTRL_REG (PERIPHS_DPORT_BASEADDR + 0x0c) +#define CACHE_FLUSH_START_BIT BIT0 // Clear then set to initiate cache flushing operation +#define CACHE_EMPTY_FLAG_BIT BIT1 // Set when cache has been cleared +#define CACHE_READ_EN_BIT BIT8 // Enable caching mechanism +#define CACHE_MAP_SEGMENT_S 16 // Which starting segment on 2M boundary (0-3) +#define CACHE_MAP_SEGMENT_MASK 0x3 +#define CACHE_MAP_2M BIT24 // Set to map 2M block, otherwise 1M +#define CACHE_MAP_1M_HIGH BIT25 // If CACHE_MAP_2M is clear determines which 1M block is mapped +#define CACHE_1M_SIZE 0x00100000 +#define CACHE_2M_SIZE 0x00200000 + +#define CACHE_IRAM_CTRL_REG (PERIPHS_DPORT_BASEADDR + 0x24) +#define CACHE_IRAM_EN_3 BIT3 // Set to enable IRAM bank #3 at 0x40108000 (16K) +#define CACHE_IRAM_EN_4 BIT4 // Set to enable IRAM bank #4 at 0x4010C000 (16K) //}} #define DRAM_BASE (0x3FFE8000) diff --git a/Sming/Arch/Esp8266/Components/esp8266/include/espinc/spi_struct.h b/Sming/Arch/Esp8266/Components/esp8266/include/espinc/spi_struct.h index a3b2d2d64c..0fc0bc417d 100644 --- a/Sming/Arch/Esp8266/Components/esp8266/include/espinc/spi_struct.h +++ b/Sming/Arch/Esp8266/Components/esp8266/include/espinc/spi_struct.h @@ -231,8 +231,38 @@ typedef struct { uint32_t val; } slave3; uint32_t data_buf[16]; /*data buffer*/ - uint32_t reserved_80[30]; - uint32_t ext2; + uint32_t reserved_80[28]; + union { + // See spi_register.h, related to flash accesses ? + struct { + uint32_t t_pp_time: 12; + uint32_t reserved13: 4; + uint32_t t_pp_shift: 4; + uint32_t reserved20: 11; + uint32_t t_pp_ena: 1; + }; + uint32_t val; + } ext0; + union { + // See spi_register.h, related to flash accesses ? + struct { + uint32_t t_erase_time: 12; + uint32_t reserved13: 4; + uint32_t t_erase_shift: 4; + uint32_t reserved20: 11; + uint32_t t_erase_ena: 1; + }; + uint32_t val; + } ext1; + union { + // See spi_register.h, related to flash accesses ? + // See also RTOS SDK `Cache_Read_Disable_2` function + struct { + uint32_t st: 3; + uint32_t reserved3: 29; + }; + uint32_t val; + } ext2; union { struct { uint32_t int_hold_ena: 2; /*This register is for two SPI masters to share the same cs clock and data signals. The bits of one SPI are set if the other SPI is busy the SPI will be hold. 1(3): hold at ,idle, phase 2: hold at ,prepare, phase.*/ diff --git a/Sming/Arch/Esp8266/Components/esp8266/startup.cpp b/Sming/Arch/Esp8266/Components/esp8266/startup.cpp index ff62f084d2..f171bb20a9 100644 --- a/Sming/Arch/Esp8266/Components/esp8266/startup.cpp +++ b/Sming/Arch/Esp8266/Components/esp8266/startup.cpp @@ -39,6 +39,8 @@ extern "C" void user_init(void) gdb_init(); + Storage::initialize(); + init(); // User code init } diff --git a/Sming/Arch/Esp8266/Components/esp_no_wifi/README.rst b/Sming/Arch/Esp8266/Components/esp_no_wifi/README.rst index a81ca6fc75..a63473d36c 100644 --- a/Sming/Arch/Esp8266/Components/esp_no_wifi/README.rst +++ b/Sming/Arch/Esp8266/Components/esp_no_wifi/README.rst @@ -74,6 +74,10 @@ If you want to disassemble other SDK libraries, do this:: Known issues ------------ +- Call to `spi_flash_get_id()` hangs in application code +- ROMs must be located below 1M + SDK implementation of `Cache_Read_Enable_New()` has internal flag which doesn't get initialised (default is 0xff, must be 1 or the function does nothing). + Further work is required to implement the following (list incomplete): - Sleep/power saving modes diff --git a/Sming/Arch/Esp8266/Components/esp_no_wifi/no.wifi.ld b/Sming/Arch/Esp8266/Components/esp_no_wifi/no.wifi.ld index f9721fb20a..c68a5b9e7f 100644 --- a/Sming/Arch/Esp8266/Components/esp_no_wifi/no.wifi.ld +++ b/Sming/Arch/Esp8266/Components/esp_no_wifi/no.wifi.ld @@ -5,3 +5,4 @@ PROVIDE ( system_get_free_heap_size = xPortGetFreeHeapSize ); PROVIDE ( system_restart = system_restart_local ); PROVIDE ( os_random = phy_get_rand ); PROVIDE ( system_get_cpu_freq = ets_get_cpu_frequency ); +PROVIDE ( system_rtc_clock_cali_proc = pm_rtc_clock_cali_proc ); diff --git a/Sming/Arch/Esp8266/Components/esp_no_wifi/pm.c b/Sming/Arch/Esp8266/Components/esp_no_wifi/pm.c index 1a344427d4..82384ac5f7 100644 --- a/Sming/Arch/Esp8266/Components/esp_no_wifi/pm.c +++ b/Sming/Arch/Esp8266/Components/esp_no_wifi/pm.c @@ -1,3 +1,66 @@ +#include +#include +#include + +void ets_delay_us(uint32_t); + +// Crystal frequency: 0=40, 1=26, 2=24 +extern uint8_t chip6_phy_init_ctrl; + void uart_tx_flush(void) { } + +/* + * Returns a calibration factor giving the ratio of system clock ticks to RTC time. + * NB. The calibration code is from `pm_rtc_clock_cali` in the `phy_sleep` module. + * To keep things simple we're just rolling it up into one function here. + */ +uint32_t pm_rtc_clock_cali_proc(void) +{ + static uint32_t calibration_value; + + rom_i2c_writeReg(106, 2, 8, 0); + + uint32_t value; + do { + value = GPIO_REG_READ(GPIO_RTC_CALIB_VALUE_ADDRESS); + } while((value & RTC_CALIB_RDY) == 0); + + const uint32_t rtcCalibValue = 0x0101; + GPIO_REG_WRITE(GPIO_RTC_CALIB_SYNC_ADDRESS, rtcCalibValue); + GPIO_REG_WRITE(GPIO_RTC_CALIB_SYNC_ADDRESS, rtcCalibValue | RTC_CALIB_START); + ets_delay_us(10); + + do { + value = GPIO_REG_READ(GPIO_RTC_CALIB_VALUE_ADDRESS); + } while((value & RTC_CALIB_RDY) == 0); + value &= RTC_CALIB_VALUE; + + uint32_t xtal_freq; + switch(chip6_phy_init_ctrl) { + case 0: + case 1: + xtal_freq = 26; + break; + case 2: + xtal_freq = 24; + break; + default: + xtal_freq = 40; + break; + } + + value = value * 16 / xtal_freq; + if(value < 512) { + return value; + } + + if(calibration_value == 0) { + calibration_value = value; + return value; + } + + calibration_value = ((calibration_value * 3) + (value * 5)) / 8; + return calibration_value; +} diff --git a/Sming/Arch/Esp8266/Components/esp_no_wifi/wpa.c b/Sming/Arch/Esp8266/Components/esp_no_wifi/wpa.c new file mode 100644 index 0000000000..6ce38aefc1 --- /dev/null +++ b/Sming/Arch/Esp8266/Components/esp_no_wifi/wpa.c @@ -0,0 +1,18 @@ +#include +#include + +uint32_t os_random(); + +int os_get_random(unsigned char* buf, size_t len) +{ + uint32_t rnd = 0; + for(size_t i = 0; i < len; ++i) { + if(rnd == 0) { + rnd = os_random(); + } + *buf++ = rnd & 0xff; + rnd >>= 8; + } + + return len; +} \ No newline at end of file diff --git a/Sming/Arch/Esp8266/Components/spi_flash/flashmem.c b/Sming/Arch/Esp8266/Components/spi_flash/flashmem.c index cf66c77799..8d06db8a8d 100644 --- a/Sming/Arch/Esp8266/Components/spi_flash/flashmem.c +++ b/Sming/Arch/Esp8266/Components/spi_flash/flashmem.c @@ -44,7 +44,11 @@ uint32_t flashmem_get_address(const void* memptr) uint32_t addr = (uint32_t)memptr - INTERNAL_FLASH_START_ADDRESS; // Determine which 1MB memory bank is mapped uint32_t ctrl = READ_PERI_REG(CACHE_FLASH_CTRL_REG); - uint8_t bank = (((ctrl >> 16) & 0x07) << 1) | ((ctrl >>25) & 0x01); + uint8_t segment = (ctrl >> CACHE_MAP_SEGMENT_S) & CACHE_MAP_SEGMENT_MASK; + uint8_t bank = segment << 1; + if(ctrl & CACHE_MAP_1M_HIGH) { + bank |= 0x01; + } addr += 0x100000U * bank; return addr; } diff --git a/Sming/Components/rboot/Cache_Read_Enable.rst b/Sming/Components/rboot/Cache_Read_Enable.rst index 89c0cdea33..00c0b631e8 100644 --- a/Sming/Components/rboot/Cache_Read_Enable.rst +++ b/Sming/Components/rboot/Cache_Read_Enable.rst @@ -62,3 +62,84 @@ Where SOC_CACHE_SIZE is defined as:: #endif +06/04/2021 @author mikee47 UPDATE +--------------------------------- + +RTOS SDK code has changed, now see usage in ``esp_fast_boot.c``. +Call looks like this:: + + Cache_Read_Enable(sub_region, region, SOC_CACHE_SIZE); + +See ``esp_fast_boot_restart()``. Code (rearranged) looks like this:: + + extern void pm_goto_rf_on(void); + extern void clockgate_watchdog(int on); + + int esp_fast_boot_restart(void) + { + const esp_partition_t* to_boot = esp_ota_get_boot_partition(); + if (!to_boot) { + ESP_LOGI(TAG, "no OTA boot partition"); + to_boot = esp_ota_get_running_partition(); + if (!to_boot) { + ESP_LOGE(TAG, "ERROR: Fail to get running partition"); + return -EINVAL; + } + } + + uint32_t image_start = to_boot->address; + uint32_t image_size = to_boot->size - 4; + + esp_image_header_t image; + int ret = spi_flash_read(image_start, &image, sizeof(esp_image_header_t)); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "ERROR: Fail to read image head from spi flash error=%d", ret); + return -EIO; + } + + uint32_t image_entry = image.entry_addr; + uint8_t region; + if (image_start < 0x200000) { + region = 0; + } else if (image_start < 0x400000) { + region = 1; + } else if (image_start < 0x600000) { + region = 2; + } else if (image_start < 0x800000) { + region = 3; + } else { + ESP_LOGE(TAG, "ERROR: App bin error, start_addr 0x%08x image_len %d\n", image_start, image_size); + return -EINVAL; + } + + uint8_t sub_region; + uint32_t image_mask = image_start & 0x1fffff; + if (image_mask < 0x100000) { + sub_region = 0; + } else { + sub_region = 1; + } + + pm_goto_rf_on(); + clockgate_watchdog(0); + REG_WRITE(0x3ff00018, 0xffff00ff); + SET_PERI_REG_MASK(0x60000D48, BIT1); + CLEAR_PERI_REG_MASK(0x60000D48, BIT1); + + REG_WRITE(INT_ENA_WDEV, 0); + _xt_isr_mask(UINT32_MAX); + + const uint32_t sp = DRAM_BASE + DRAM_SIZE - 16; + + Cache_Read_Disable(); + Cache_Read_Enable(sub_region, region, SOC_CACHE_SIZE); + + __asm__ __volatile__( + "mov a1, %0\n" + : : "a"(sp) : "memory" + ); + + void (*user_start)(size_t start_addr); + user_start = (void *)entry_addr; + user_start(image_start); + } diff --git a/Sming/Core/SmingCore.h b/Sming/Core/SmingCore.h index 928e339938..d5bf98265a 100644 --- a/Sming/Core/SmingCore.h +++ b/Sming/Core/SmingCore.h @@ -30,6 +30,7 @@ #include "Platform/RTC.h" #include "Platform/System.h" +#include "Platform/Timers.h" #include "Platform/WDT.h" #ifndef DISABLE_WIFI diff --git a/samples/Basic_Storage/app/application.cpp b/samples/Basic_Storage/app/application.cpp index 55d2bb63a2..405f8b0acc 100644 --- a/samples/Basic_Storage/app/application.cpp +++ b/samples/Basic_Storage/app/application.cpp @@ -16,8 +16,12 @@ void listDevices() Serial.print(toString(dev.getType())); Serial.print(_F(", size = 0x")); Serial.print(dev.getSize(), HEX); +#ifndef DISABLE_WIFI + // KNOWN ISSUE: Call to `spi_flash_get_id()` hangs in application code Serial.print(_F(", ID = 0x")); - Serial.println(dev.getId(), HEX); + Serial.print(dev.getId(), HEX); +#endif + Serial.println(); } Serial.println(); }