Skip to content
Open
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 @@ -971,6 +971,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
79 changes: 79 additions & 0 deletions src/machine/board_esp32c6.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
//go:build esp32c6

// This file contains the default pin mappings for the ESP32-C6 generic target.
Copy link
Member

Choose a reason for hiding this comment

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

There is not really such a thing as "generic" target. From the comments below, shouldn't this be board_esp32c6_devkitc?


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
)

// Analog pins
const (
A0 = GPIO0
A1 = GPIO1
A2 = GPIO2
A3 = GPIO3
A4 = GPIO4
A5 = GPIO5
A6 = GPIO6
)

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

// I2C pins
const (
SDA_PIN = GPIO6
SCL_PIN = GPIO7
)

// SPI pins
const (
SPI_MISO_PIN = GPIO2
SPI_MOSI_PIN = GPIO7
SPI_SS_PIN = GPIO10
SPI_SCK_PIN = GPIO6
)
2 changes: 1 addition & 1 deletion src/machine/i2c.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//go:build !baremetal || atmega || nrf || sam || stm32 || fe310 || k210 || rp2040 || rp2350 || mimxrt1062 || (esp32c3 && !m5stamp_c3) || esp32 || esp32s3
//go:build !baremetal || atmega || nrf || sam || stm32 || fe310 || k210 || rp2040 || rp2350 || mimxrt1062 || (esp32c3 && !m5stamp_c3) || esp32 || esp32c6 || esp32s3

package machine

Expand Down
19 changes: 19 additions & 0 deletions src/machine/machine_esp32c3s3_adc_sar.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//go:build (esp32c3 && !m5stamp_c3) || esp32s3

package machine

import (
"device/esp"
"runtime/volatile"
"unsafe"
)

// sarEnable enables the analog SAR I2C domain before any regI2C access,
// matching the prologue in adc_ll_calibration_prepare().
func (r regI2C) sarEnable() {
cfg := (*volatile.Register32)(unsafe.Pointer(anaConfigReg))
cfg2 := (*volatile.Register32)(unsafe.Pointer(anaConfig2Reg))
esp.RTC_CNTL.SetANA_CONF_SAR_I2C_PU(1)
cfg.Set(cfg.Get() &^ i2cSarEnMask)
cfg2.Set(cfg2.Get() | anaSarCfg2En)
}
19 changes: 19 additions & 0 deletions src/machine/machine_esp32c3s3_periph.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//go:build esp32c3 || esp32s3
Copy link
Member

Choose a reason for hiding this comment

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

Perhaps naming like machine_esp32x3_periph.go?

Choose a reason for hiding this comment

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

maybe not merge, but copy?


package machine

import "device/esp"

// enableI2C0PeriphClock enables the I2C0 peripheral clock via SYSTEM.
func enableI2C0PeriphClock() {
esp.SYSTEM.SetPERIP_RST_EN0_I2C_EXT0_RST(1)
esp.SYSTEM.SetPERIP_CLK_EN0_I2C_EXT0_CLK_EN(1)
esp.SYSTEM.SetPERIP_RST_EN0_I2C_EXT0_RST(0)
}

// enableLEDCPeriphClock enables the LEDC peripheral clock via SYSTEM.
func enableLEDCPeriphClock() {
esp.SYSTEM.SetPERIP_RST_EN0_LEDC_RST(1)
esp.SYSTEM.SetPERIP_CLK_EN0_LEDC_CLK_EN(1)
esp.SYSTEM.SetPERIP_RST_EN0_LEDC_RST(0)
}
Loading
Loading