55 lines
1.9 KiB
C++
55 lines
1.9 KiB
C++
/**
|
|
* blink_lcgamboa.ino — IRAM-safe blink for lcgamboa esp32-picsimlab QEMU machine.
|
|
*
|
|
* The lcgamboa machine runs WiFi/BT init on core 1 which periodically disables
|
|
* the SPI flash cache. Any code or data in IROM/DROM (flash cache) will crash
|
|
* with "Cache disabled but cached memory region accessed" when that happens.
|
|
*
|
|
* Solution:
|
|
* - ALL functions tagged IRAM_ATTR (placed in SRAM, not flash)
|
|
* - ALL string constants tagged DRAM_ATTR (placed in SRAM, not flash)
|
|
* - Use esp_rom_printf() (ROM function, no cache needed) instead of Serial
|
|
* - Use direct GPIO register writes instead of Arduino/IDF cached helpers
|
|
* - Use ets_delay_us() (ROM function) instead of delay()
|
|
*/
|
|
|
|
// Direct GPIO register access (ESP32 TRM chapter 4)
|
|
#define GPIO_OUT_W1TS (*((volatile uint32_t*)0x3FF44008)) // set bits HIGH
|
|
#define GPIO_OUT_W1TC (*((volatile uint32_t*)0x3FF4400C)) // set bits LOW
|
|
#define GPIO_ENABLE_W1TS (*((volatile uint32_t*)0x3FF44020)) // enable output
|
|
|
|
#define LED_BIT (1u << 2) // GPIO2
|
|
|
|
extern "C" {
|
|
void ets_delay_us(uint32_t us);
|
|
int esp_rom_printf(const char* fmt, ...);
|
|
}
|
|
|
|
// String constants in DRAM (not DROM flash cache)
|
|
static const char DRAM_ATTR s_start[] = "LCGAMBOA_STARTED\n";
|
|
static const char DRAM_ATTR s_on[] = "LED_ON\n";
|
|
static const char DRAM_ATTR s_off[] = "LED_OFF\n";
|
|
static const char DRAM_ATTR s_done[] = "BLINK_DONE\n";
|
|
|
|
void IRAM_ATTR setup() {
|
|
GPIO_ENABLE_W1TS = LED_BIT; // GPIO2 → output
|
|
|
|
esp_rom_printf(s_start);
|
|
|
|
for (int i = 0; i < 5; i++) {
|
|
GPIO_OUT_W1TS = LED_BIT; // HIGH
|
|
esp_rom_printf(s_on);
|
|
ets_delay_us(300000); // 300 ms (ROM busy-wait, cache-safe)
|
|
|
|
GPIO_OUT_W1TC = LED_BIT; // LOW
|
|
esp_rom_printf(s_off);
|
|
ets_delay_us(300000);
|
|
}
|
|
|
|
esp_rom_printf(s_done);
|
|
}
|
|
|
|
void IRAM_ATTR loop() {
|
|
ets_delay_us(1000000); // idle 1 s, no flash access
|
|
}
|