Skip to content

Commit

Permalink
ESP8266 No-WiFi library updates (#2347)
Browse files Browse the repository at this point in the history
* Add `os_get_random()` implementation for no_wifi library

* Filesystem fixes for `esp_no_wifi` library

Require `system_rtc_clock_cali_proc` to use filesystem as SPIFFS uses time functions
Call to `Storage::initialize()` required in `user_init()`

KNOWN ISSUE: Call to `spi_flash_get_id()` hangs in application code.

* Use flash cache control register definitions from RTOS SDK

* Expand SPI ext0-2 struct definitions (likely related to flash)

* Fix unused static variables in esp-lwip mem_manager.h

* Add Platform/Timers.h to SmingCore.h

* Update README
  • Loading branch information
mikee47 authored and slaff committed Sep 27, 2021
1 parent ac3c84c commit 4020f7a
Show file tree
Hide file tree
Showing 12 changed files with 228 additions and 8 deletions.
4 changes: 2 additions & 2 deletions Sming/Arch/Esp8266/Components/esp-lwip/mem_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand All @@ -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 );

Expand Down
16 changes: 14 additions & 2 deletions Sming/Arch/Esp8266/Components/esp8266/include/espinc/eagle_soc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
34 changes: 32 additions & 2 deletions Sming/Arch/Esp8266/Components/esp8266/include/espinc/spi_struct.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.*/
Expand Down
2 changes: 2 additions & 0 deletions Sming/Arch/Esp8266/Components/esp8266/startup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ extern "C" void user_init(void)

gdb_init();

Storage::initialize();

init(); // User code init
}

Expand Down
4 changes: 4 additions & 0 deletions Sming/Arch/Esp8266/Components/esp_no_wifi/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions Sming/Arch/Esp8266/Components/esp_no_wifi/no.wifi.ld
Original file line number Diff line number Diff line change
Expand Up @@ -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 );
63 changes: 63 additions & 0 deletions Sming/Arch/Esp8266/Components/esp_no_wifi/pm.c
Original file line number Diff line number Diff line change
@@ -1,3 +1,66 @@
#include <stdint.h>
#include <espinc/gpio_register.h>
#include <espinc/i2c_bbpll.h>

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;
}
18 changes: 18 additions & 0 deletions Sming/Arch/Esp8266/Components/esp_no_wifi/wpa.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#include <stddef.h>
#include <stdint.h>

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;
}
6 changes: 5 additions & 1 deletion Sming/Arch/Esp8266/Components/spi_flash/flashmem.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
81 changes: 81 additions & 0 deletions Sming/Components/rboot/Cache_Read_Enable.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
1 change: 1 addition & 0 deletions Sming/Core/SmingCore.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

#include "Platform/RTC.h"
#include "Platform/System.h"
#include "Platform/Timers.h"
#include "Platform/WDT.h"

#ifndef DISABLE_WIFI
Expand Down
6 changes: 5 additions & 1 deletion samples/Basic_Storage/app/application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Expand Down

0 comments on commit 4020f7a

Please sign in to comment.