Skip to content

esp32: add interrupt support (vector table, timer alarm, GPIO SetInterrupt)#5510

Open
deadprogram wants to merge 6 commits into
esp32-improve-builderfrom
esp32-irq-impl
Open

esp32: add interrupt support (vector table, timer alarm, GPIO SetInterrupt)#5510
deadprogram wants to merge 6 commits into
esp32-improve-builderfrom
esp32-irq-impl

Conversation

@deadprogram

@deadprogram deadprogram commented Jul 8, 2026

Copy link
Copy Markdown
Member

This PR add interrupt support (vector table, timer alarm, GPIO SetInterrupt) to the esp32.

It also then hooks the IRQ up for receiving UART data.

Tested locally on my venerable esp32-mini32 board.

UPDATE: added the support needed for XIP and also the linker changes for minimal espradio support.
FURTHER UPDATE: this PR turned into all the commits to get initial WiFI on ESP32 working as well.

This PR needs #5511 to correctly flash the larger programs.

@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown

Size difference with the dev branch:

Binary size difference
 flash                          ram
 before   after   diff          before   after   diff

@deadprogram

Copy link
Copy Markdown
Member Author

A few more things to do on this, moving back to draft.

@deadprogram
deadprogram marked this pull request as draft July 9, 2026 13:41
@deadprogram
deadprogram changed the base branch from dev to esp32-improve-builder July 11, 2026 08:09
Comment thread targets/esp32.ld
_arena_start = ABSOLUTE(.);
} >DRAM1
_arena_end = ORIGIN(DRAM1) + LENGTH(DRAM1);
ASSERT((_arena_end - _arena_start) >= 32K, "arena region < 32K")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm curious where and how are you using the .arena section.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@deadprogram
deadprogram force-pushed the esp32-improve-builder branch from 9ab93af to 8aede78 Compare July 13, 2026 22:37
@deadprogram
deadprogram marked this pull request as ready for review July 13, 2026 22:40
@deadprogram
deadprogram force-pushed the esp32-improve-builder branch 2 times, most recently from a97c882 to 1adaa91 Compare July 18, 2026 13:24
…rrupt)

Signed-off-by: deadprogram <ron@hybridgroup.com>
Signed-off-by: deadprogram <ron@hybridgroup.com>
Add full flash XIP support for ESP32, enabling code and read-only data to
execute/load directly from flash via the MMU cache rather than consuming
precious SRAM. This increases available RAM from ~328KB to effectively
unlimited for code/rodata, while keeping ~121KB for the Go heap.

Changes:
- src/device/esp/esp32.S: Add MMU initialization in call_start_cpu0
  - Call ROM bootloader mmu_init() and cache_flash_mmu_set() to map DROM/IROM
  - Enable flash cache via ROM Cache_Read_Enable()
  - Fix tinygo_scanCurrentStack to spill all register windows for GC

- targets/esp32-interrupts.S: Add exception diagnostics

- targets/esp32.ld: Major linker script restructure for XIP
  - Add DROM (4MB @ 0x3F400000) and IROM (4MB @ 0x400D0000) regions
  - Move .rodata to DROM, main .text to IROM (both flash-mapped)
  - Keep boot code, vectors, and WiFi blob IRAM sections in SRAM0
  - Create WiFi arena in SRAM1 pool 7/6 (64KB @ 0x3FFF0000)
  - Move .bss and heap to SRAM2 (200KB @ 0x3FFAE000), avoiding ROM/MAC regions
  - Add _drom_flash_addr variable (patched by builder with flash offset)

- targets/esp32.json: Add linker wrap flags for malloc/free and WiFi functions

Signed-off-by: deadprogram <ron@hybridgroup.com>
Signed-off-by: deadprogram <ron@hybridgroup.com>
Work around an lld (LLVM 22) bug where l32r PC-relative offsets are
miscalculated when auto-generated .literal.* sections are prepended to
.text.* sections by the linker script. The assembler emits .literal
entries for movi instructions whose constants exceed the 12-bit signed
range; lld then resolves the l32r relocations with incorrect offsets,
causing every l32r in the boot code to load from the wrong literal
pool entry.

The symptom was a TG0WDT_SYS_RESET boot loop: the watchdog disable
code loaded wrong register addresses via l32r and silently wrote to
the wrong peripheral registers, leaving the watchdog running.

Fix by constructing PS_WOE_MASK (0x40000) with movi+slli instead of a
single large-constant movi, eliminating all auto-generated .literal
section entries. This is compatible with both LLVM 20 and LLVM 22.

Also revert DRAM origin to 0x3FFAE000 (200K) and remove rom_phyFuns
symbols that belong in a separate WiFi commit.

Signed-off-by: deadprogram <ron@hybridgroup.com>
Signed-off-by: deadprogram <ron@hybridgroup.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants