Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions GNUmakefile
Original file line number Diff line number Diff line change
Expand Up @@ -977,6 +977,8 @@ endif
@$(MD5SUM) test.bin
$(TINYGO) build -size short -o test.bin -target=esp32c3-12f examples/blinky1
@$(MD5SUM) test.bin
$(TINYGO) build -size short -o test.bin -target=esp32c6 examples/machinetest
@$(MD5SUM) test.bin

$(TINYGO) build -size short -o test.bin -target=makerfabs-esp32c3spi35 examples/machinetest
@$(MD5SUM) test.bin
Expand Down
2 changes: 1 addition & 1 deletion builder/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -1047,7 +1047,7 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
if err != nil {
return result, err
}
case "esp32", "esp32-img", "esp32c3", "esp32s3", "esp8266":
case "esp32", "esp32-img", "esp32c3", "esp32c6", "esp32s3", "esp8266":
// Special format for the ESP family of chips (parsed by the ROM
// bootloader).
result.Binary = filepath.Join(tmpdir, "main"+outext)
Expand Down
1 change: 1 addition & 0 deletions builder/builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ func TestClangAttributes(t *testing.T) {
"cortex-m4",
"cortex-m7",
"esp32c3",
"esp32c6",
"esp32s3",
"fe310",
"gameboy-advance",
Expand Down
29 changes: 19 additions & 10 deletions builder/esp.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ package builder

import (
"bytes"
"crypto/sha256"
"debug/elf"
"encoding/binary"
"fmt"
Expand Down Expand Up @@ -100,12 +99,24 @@ func makeESPFirmwareImage(infile, outfile, format string) error {
chip_id := map[string]uint16{
"esp32": 0x0000,
"esp32c3": 0x0005,
"esp32c6": 0x000D,
"esp32s3": 0x0009,
}[chip]

// SPI flash speed/size byte (byte 3 of header):
// Upper nibble = flash size, lower nibble = flash frequency.
// The espflasher auto-detects and patches the flash size (upper nibble),
// but the frequency (lower nibble) must be correct per chip.
spiSpeedSize := map[string]uint8{
"esp32": 0x1f, // 80MHz=0x0F, 2MB=0x10
"esp32c3": 0x1f, // 80MHz=0x0F, 2MB=0x10
"esp32c6": 0x10, // 80MHz=0x00, 2MB=0x10 (C6 uses different freq encoding)
"esp32s3": 0x1f, // 80MHz=0x0F, 2MB=0x10
}[chip]

// Image header.
switch chip {
case "esp32", "esp32c3", "esp32s3":
case "esp32", "esp32c3", "esp32c6", "esp32s3":
// Header format:
// https://github.com/espressif/esp-idf/blob/v4.3/components/bootloader_support/include/esp_app_format.h#L71
// Note: not adding a SHA256 hash as the binary is modified by
Expand All @@ -126,12 +137,12 @@ func makeESPFirmwareImage(infile, outfile, format string) error {
}{
magic: 0xE9,
segment_count: byte(len(segments)),
spi_mode: 2, // ESP_IMAGE_SPI_MODE_DIO
spi_speed_size: 0x1f, // ESP_IMAGE_SPI_SPEED_80M, ESP_IMAGE_FLASH_SIZE_2MB
spi_mode: 2, // ESP_IMAGE_SPI_MODE_DIO
spi_speed_size: spiSpeedSize,
entry_addr: uint32(inf.Entry),
wp_pin: 0xEE, // disable WP pin
chip_id: chip_id,
hash_appended: true, // add a SHA256 hash
hash_appended: false, // disabled: espflasher patches header, invalidating the hash
})
case "esp8266":
// Header format:
Expand Down Expand Up @@ -173,11 +184,9 @@ func makeESPFirmwareImage(infile, outfile, format string) error {
outf.Write(make([]byte, 15-outf.Len()%16))
outf.WriteByte(checksum)

if chip != "esp8266" {
// SHA256 hash (to protect against image corruption, not for security).
hash := sha256.Sum256(outf.Bytes())
outf.Write(hash[:])
}
// Note: SHA256 hash intentionally omitted. espflasher patches the header
// (SPI mode/speed/size), which invalidates the hash. The ROM would report
// "SHA-256 comparison failed" and boot anyway, so it's just noise.

// QEMU (or more precisely, qemu-system-xtensa from Espressif) expects the
// image to be a certain size.
Expand Down
3 changes: 1 addition & 2 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -1046,10 +1046,9 @@ const (
)

func flashBinUsingEsp32(port, resetMode, tmppath string, options *compileopts.Options) error {
var opts *espflasher.FlasherOptions
opts := espflasher.DefaultOptions()
// On Windows, we have to explicitly specify the reset mode to use USB JTAG.
if runtime.GOOS == "windows" && resetMode == jtagReset {
opts = espflasher.DefaultOptions()
opts.ResetMode = espflasher.ResetUSBJTAG
}

Expand Down
2 changes: 1 addition & 1 deletion src/crypto/rand/rand_baremetal.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//go:build nrf || (stm32 && !(stm32f103 || stm32l0x1)) || (sam && atsamd51) || (sam && atsame5x) || esp32c3 || esp32s3 || tkey || (tinygo.riscv32 && virt)
//go:build nrf || (stm32 && !(stm32f103 || stm32l0x1)) || (sam && atsamd51) || (sam && atsame5x) || esp32c3 || esp32c6 || esp32s3 || tkey || (tinygo.riscv32 && virt)

// If you update the above build constraint, you'll probably also need to update
// src/runtime/rand_hwrng.go.
Expand Down
66 changes: 66 additions & 0 deletions src/device/esp/esp32c6.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// This is a very minimal bootloader for the ESP32-C6. It only initializes the
// flash and then continues with the generic RISC-V initialization code, which
// in turn will call runtime.main.
// It is written in assembly (and not in a higher level language) to make sure
// it is entirely loaded into IRAM and doesn't accidentally call functions
// stored in IROM.
//
// The ESP32-C6 has a unified IRAM/DRAM address space at 0x40800000, and
// separate DROM (0x42800000) / IROM (0x42000000) flash-mapped regions.

.section .init
.global call_start_cpu0
.type call_start_cpu0,@function
call_start_cpu0:
// At this point:
// - The ROM bootloader is finished and has jumped to here.
// - We're running from IRAM: both IRAM and DRAM segments have been loaded
// by the ROM bootloader.
// - We have a usable stack (but not the one we would like to use).
// - No flash mappings (MMU) are set up yet.

// Reset MMU, see bootloader_reset_mmu in the ESP-IDF.
call Cache_Suspend_ICache
mv s0, a0 // autoload value
call Cache_Invalidate_ICache_All
call Cache_MMU_Init

// Set up flash mapping (both IROM and DROM).
// On ESP32-C6, Cache_Dbus_MMU_Set is replaced by Cache_MSPI_MMU_Set
// which has an extra "sensitive" parameter.
// C equivalent:
// Cache_MSPI_MMU_Set(0, 0, 0x42000000, 0, 64, 256, 0)
// Maps 16MB starting at 0x42000000, covering both IROM and DROM.
li a0, 0 // sensitive: no flash encryption
li a1, 0 // ext_ram: MMU_ACCESS_FLASH
li a2, 0x42000000 // vaddr: start of flash-mapped region
li a3, 0 // paddr: physical address in the flash chip
li a4, 64 // psize: always 64 (kilobytes)
li a5, 256 // num: pages (16MB / 64K = 256, covers IROM+DROM)
li a6, 0 // fixed
call Cache_MSPI_MMU_Set

// Enable the flash cache.
mv a0, s0 // restore autoload value from Cache_Suspend_ICache call
call Cache_Resume_ICache

// Jump to generic RISC-V initialization, which initializes the stack
// pointer and globals register. It should not return.
j _start

.section .text.exception_vectors
.global _vector_table
.type _vector_table,@function

_vector_table:

.option push
.option norvc

.rept 32
j handleInterruptASM /* interrupt handler */
.endr

.option pop

.size _vector_table, .-_vector_table
54 changes: 54 additions & 0 deletions src/machine/board_esp32c6.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
//go:build esp32c6

// This file contains the default pin mappings for the ESP32-C6-DevKitC target.

package machine

// Digital Pins
const (
IO0 = GPIO0
IO1 = GPIO1
IO2 = GPIO2
IO3 = GPIO3
IO4 = GPIO4
IO5 = GPIO5
IO6 = GPIO6
IO7 = GPIO7
IO8 = GPIO8
IO9 = GPIO9
IO10 = GPIO10
IO11 = GPIO11
IO12 = GPIO12
IO13 = GPIO13
IO14 = GPIO14
IO15 = GPIO15
IO16 = GPIO16
IO17 = GPIO17
IO18 = GPIO18
IO19 = GPIO19
IO20 = GPIO20
IO21 = GPIO21
IO22 = GPIO22
IO23 = GPIO23
IO24 = GPIO24
IO25 = GPIO25
IO26 = GPIO26
IO27 = GPIO27
IO28 = GPIO28
IO29 = GPIO29
IO30 = GPIO30
)

// Built-in WS2812 (NeoPixel) addressable RGB LED on the ESP32-C6-DevKitC.
// Use tinygo.org/x/drivers/ws2812 to control it.
const (
LED = WS2812
WS2812 = GPIO8
NEOPIXEL = GPIO8
)

// UART pins
const (
UART_RX_PIN = GPIO17
UART_TX_PIN = GPIO16
)
Loading
Loading