Skip to content
Merged
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
6 changes: 6 additions & 0 deletions make/smoketest.mk
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,8 @@ ifneq ($(XTENSA), 0)
@$(MD5SUM) $(SMOKE_OUT).bin
$(TINYGO) build -size short -o $(SMOKE_OUT).bin -target=xiao-esp32c6 examples/blinkm
@$(MD5SUM) $(SMOKE_OUT).bin
$(TINYGO) build -size short -o $(SMOKE_OUT).bin -target=xiao-esp32c6 examples/i2s-tone
@$(MD5SUM) $(SMOKE_OUT).bin
# esp32h2-devkitm-1
$(TINYGO) build -size short -o $(SMOKE_OUT).bin -target=esp32h2-devkitm-1 examples/machinetest
@$(MD5SUM) $(SMOKE_OUT).bin
Expand All @@ -532,6 +534,8 @@ ifneq ($(XTENSA), 0)
@$(MD5SUM) $(SMOKE_OUT).bin
$(TINYGO) build -size short -o $(SMOKE_OUT).bin -target=xiao-esp32s3 examples/adc
@$(MD5SUM) $(SMOKE_OUT).bin
$(TINYGO) build -size short -o $(SMOKE_OUT).bin -target=xiao-esp32s3 examples/i2s-tone
@$(MD5SUM) $(SMOKE_OUT).bin
# esp32s3-supermini
$(TINYGO) build -size short -o $(SMOKE_OUT).bin -target=esp32s3-supermini examples/blinky1
@$(MD5SUM) $(SMOKE_OUT).bin
Expand Down Expand Up @@ -567,6 +571,8 @@ smoketest-riscv: | build/smoke
@$(MD5SUM) $(SMOKE_OUT).bin
$(TINYGO) build -size short -o $(SMOKE_OUT).bin -target=xiao-esp32c3 examples/machinetest
@$(MD5SUM) $(SMOKE_OUT).bin
$(TINYGO) build -size short -o $(SMOKE_OUT).bin -target=xiao-esp32c3 examples/i2s-tone
@$(MD5SUM) $(SMOKE_OUT).bin
$(TINYGO) build -size short -o $(SMOKE_OUT).bin -target=esp32-c3-devkit-rust-1 examples/blinky1
@$(MD5SUM) $(SMOKE_OUT).bin
$(TINYGO) build -size short -o $(SMOKE_OUT).bin -target=esp32c3-12f examples/blinky1
Expand Down
11 changes: 11 additions & 0 deletions src/examples/i2s-tone/esp32xx.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
//go:build esp32c3 || esp32c6 || esp32s3

package main

import "machine"

const (
pinSCK = machine.GPIO3
pinWS = machine.GPIO4
pinSDO = machine.GPIO5
)
2 changes: 1 addition & 1 deletion src/machine/i2s.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//go:build (sam && atsamd21) || nrf52 || nrf52833 || nrf52840
//go:build (sam && atsamd21) || nrf52 || nrf52833 || nrf52840 || esp32c3 || esp32c6 || esp32s3

// This is the definition for I2S bus functions.
// Actual implementations if available for any given hardware
Expand Down
78 changes: 78 additions & 0 deletions src/machine/machine_esp32c3_i2s.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
//go:build esp32c3

package machine

import (
"device/esp"
"runtime/interrupt"
)

// GPIO matrix signals (IDF soc/esp32c3/include/soc/gpio_sig_map.h).
const (
i2sSignalTxBCK = 13
i2sSignalTxWS = 14
i2sSignalTxSD = 15
i2sSignalRxSD = 15
i2sSignalRxBCK = 16
i2sSignalRxWS = 17
)

const cpuInterruptFromI2S = 11

// The C3 has one interrupt register for both directions of a channel.
const (
gdmaOutEOF = esp.DMA_INT_RAW_CH0_OUT_EOF
gdmaInSucEOF = esp.DMA_INT_RAW_CH0_IN_SUC_EOF
)

var i2sGDMARegs = i2sGDMA{
outConf0: &esp.DMA.OUT_CONF0_CH0,
outLink: &esp.DMA.OUT_LINK_CH0,
outPeriSel: &esp.DMA.OUT_PERI_SEL_CH0,
outIntEna: &esp.DMA.INT_ENA_CH0,
outIntClr: &esp.DMA.INT_CLR_CH0,
outIntSt: &esp.DMA.INT_ST_CH0,
outEOFAddr: &esp.DMA.OUT_EOF_DES_ADDR_CH0,
inConf0: &esp.DMA.IN_CONF0_CH0,
inLink: &esp.DMA.IN_LINK_CH0,
inPeriSel: &esp.DMA.IN_PERI_SEL_CH0,
inIntEna: &esp.DMA.INT_ENA_CH0,
inIntClr: &esp.DMA.INT_CLR_CH0,
inIntSt: &esp.DMA.INT_ST_CH0,
inEOFAddr: &esp.DMA.IN_SUC_EOF_DES_ADDR_CH0,
}

// i2sEnableClocks enables and resets I2S and enables GDMA. The one I2S block
// uses the I2S1 bits (IDF hal/esp32c3/include/hal/clk_gate_ll.h line 36).
func i2sEnableClocks() {
esp.SYSTEM.SetPERIP_CLK_EN0_I2S1_CLK_EN(1)
esp.SYSTEM.SetPERIP_RST_EN0_I2S1_RST(1)
esp.SYSTEM.SetPERIP_RST_EN0_I2S1_RST(0)
if esp.SYSTEM.GetPERIP_CLK_EN1_DMA_CLK_EN() == 0 {
esp.SYSTEM.SetPERIP_CLK_EN1_DMA_CLK_EN(1)
esp.SYSTEM.SetPERIP_RST_EN1_DMA_RST(1)
esp.SYSTEM.SetPERIP_RST_EN1_DMA_RST(0)
}
esp.DMA.MISC_CONF.SetBits(esp.DMA_MISC_CONF_CLK_EN)
esp.I2S0.SetTX_CLKM_CONF_CLK_EN(1)
}

func i2sSetTxClock(div, x, y, z, yn1 uint32) {
i2sSetClockDiv(&esp.I2S0.TX_CLKM_CONF, &esp.I2S0.TX_CLKM_DIV_CONF, 0, div, x, y, z, yn1)
esp.I2S0.SetTX_CLKM_CONF_TX_CLK_SEL(i2sPLL160MClockSel)
esp.I2S0.SetTX_CLKM_CONF_TX_CLK_ACTIVE(1)
esp.I2S0.SetRX_CLKM_CONF_MCLK_SEL(0)
}

func i2sSetRxClock(div, x, y, z, yn1 uint32) {
i2sSetClockDiv(&esp.I2S0.RX_CLKM_CONF, &esp.I2S0.RX_CLKM_DIV_CONF, 0, div, x, y, z, yn1)
esp.I2S0.SetRX_CLKM_CONF_RX_CLK_SEL(i2sPLL160MClockSel)
esp.I2S0.SetRX_CLKM_CONF_RX_CLK_ACTIVE(1)
}

func i2sEnableInterrupt() {
esp.INTERRUPT_CORE0.SetDMA_CH0_INT_MAP(cpuInterruptFromI2S)
interrupt.New(cpuInterruptFromI2S, func(interrupt.Interrupt) {
I2S0.handleInterrupt()
}).Enable()
}
83 changes: 83 additions & 0 deletions src/machine/machine_esp32c6_i2s.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
//go:build esp32c6

package machine

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

// GPIO matrix signals (IDF soc/esp32c6/include/soc/gpio_sig_map.h).
const (
i2sSignalTxBCK = 13
i2sSignalTxWS = 14
i2sSignalTxSD = 15
i2sSignalRxSD = 15
i2sSignalRxBCK = 16
i2sSignalRxWS = 17
)

const cpuInterruptFromI2S = 11

// Interrupt bits from IDF soc/esp32c6/include/soc/gdma_struct.h.
const (
gdmaOutEOF = 1 << 1
gdmaInSucEOF = 1 << 1
)

// The generated DMA_Type puts OUT_CONF0_CH0 at 0x190, but it is at 0xD0
// (IDF soc/esp32c6/include/soc/gdma_reg.h line 1650).
var i2sGDMARegs = i2sGDMA{
outConf0: (*volatile.Register32)(unsafe.Add(unsafe.Pointer(esp.DMA), 0xD0)),
outLink: &esp.DMA.OUT_LINK_CH0,
outPeriSel: &esp.DMA.OUT_PERI_SEL_CH0,
outIntEna: &esp.DMA.OUT_INT_ENA_CH0,
outIntClr: &esp.DMA.OUT_INT_CLR_CH0,
outIntSt: &esp.DMA.OUT_INT_ST_CH0,
outEOFAddr: &esp.DMA.OUT_EOF_DES_ADDR_CH0,
inConf0: &esp.DMA.IN_CONF0_CH0,
inLink: &esp.DMA.IN_LINK_CH0,
inPeriSel: &esp.DMA.IN_PERI_SEL_CH0,
inIntEna: &esp.DMA.IN_INT_ENA_CH0,
inIntClr: &esp.DMA.IN_INT_CLR_CH0,
inIntSt: &esp.DMA.IN_INT_ST_CH0,
inEOFAddr: &esp.DMA.IN_SUC_EOF_DES_ADDR_CH0,
}

func i2sEnableClocks() {
esp.PCR.SetI2S_CONF_I2S_CLK_EN(1)
esp.PCR.SetI2S_CONF_I2S_RST_EN(1)
esp.PCR.SetI2S_CONF_I2S_RST_EN(0)
if esp.PCR.GetGDMA_CONF_GDMA_CLK_EN() == 0 {
esp.PCR.SetGDMA_CONF_GDMA_CLK_EN(1)
esp.PCR.SetGDMA_CONF_GDMA_RST_EN(1)
esp.PCR.SetGDMA_CONF_GDMA_RST_EN(0)
}
esp.DMA.MISC_CONF.SetBits(esp.DMA_MISC_CONF_CLK_EN)
}

// The C6 I2S clocks are in PCR (IDF hal/esp32c6/include/hal/i2s_ll.h).
func i2sSetTxClock(div, x, y, z, yn1 uint32) {
i2sSetClockDiv(&esp.PCR.I2S_TX_CLKM_CONF, &esp.PCR.I2S_TX_CLKM_DIV_CONF,
esp.PCR_I2S_TX_CLKM_CONF_I2S_TX_CLKM_DIV_NUM_Pos, div, x, y, z, yn1)
esp.PCR.SetI2S_TX_CLKM_CONF_I2S_TX_CLKM_SEL(i2sPLL160MClockSel)
esp.PCR.SetI2S_TX_CLKM_CONF_I2S_TX_CLKM_EN(1)
esp.PCR.SetI2S_RX_CLKM_CONF_I2S_MCLK_SEL(0)
}

func i2sSetRxClock(div, x, y, z, yn1 uint32) {
i2sSetClockDiv(&esp.PCR.I2S_RX_CLKM_CONF, &esp.PCR.I2S_RX_CLKM_DIV_CONF,
esp.PCR_I2S_RX_CLKM_CONF_I2S_RX_CLKM_DIV_NUM_Pos, div, x, y, z, yn1)
esp.PCR.SetI2S_RX_CLKM_CONF_I2S_RX_CLKM_SEL(i2sPLL160MClockSel)
esp.PCR.SetI2S_RX_CLKM_CONF_I2S_RX_CLKM_EN(1)
}

func i2sEnableInterrupt() {
esp.INTERRUPT_CORE0.DMA_OUT_CH0_INTR_MAP.Set(cpuInterruptFromI2S)
esp.INTERRUPT_CORE0.DMA_IN_CH0_INTR_MAP.Set(cpuInterruptFromI2S)
interrupt.New(cpuInterruptFromI2S, func(interrupt.Interrupt) {
I2S0.handleInterrupt()
}).Enable()
}
79 changes: 79 additions & 0 deletions src/machine/machine_esp32s3_i2s.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
//go:build esp32s3

package machine

import (
"device/esp"
"runtime/interrupt"
)

// GPIO matrix signals for I2S0 (IDF soc/esp32s3/include/soc/gpio_sig_map.h).
const (
i2sSignalTxBCK = 22
i2sSignalTxWS = 24
i2sSignalTxSD = 25
i2sSignalRxSD = 25
i2sSignalRxBCK = 26
i2sSignalRxWS = 27
)

// Line 18 is a free level 1 interrupt. espradio uses 12, 13 and 17
// (ESP32-S3 TRM, table "CPU Interrupts").
const cpuInterruptFromI2S = 18

// Interrupt bits from IDF soc/esp32s3/include/soc/gdma_struct.h.
const (
gdmaOutEOF = 1 << 1
gdmaInSucEOF = 1 << 1
)

var i2sGDMARegs = i2sGDMA{
outConf0: &esp.DMA.OUT_CONF0_CH0,
outLink: &esp.DMA.OUT_LINK_CH0,
outPeriSel: &esp.DMA.OUT_PERI_SEL_CH0,
outIntEna: &esp.DMA.OUT_INT_ENA_CH0,
outIntClr: &esp.DMA.OUT_INT_CLR_CH0,
outIntSt: &esp.DMA.OUT_INT_ST_CH0,
outEOFAddr: &esp.DMA.OUT_EOF_DES_ADDR_CH0,
inConf0: &esp.DMA.IN_CONF0_CH0,
inLink: &esp.DMA.IN_LINK_CH0,
inPeriSel: &esp.DMA.IN_PERI_SEL_CH0,
inIntEna: &esp.DMA.IN_INT_ENA_CH0,
inIntClr: &esp.DMA.IN_INT_CLR_CH0,
inIntSt: &esp.DMA.IN_INT_ST_CH0,
inEOFAddr: &esp.DMA.IN_SUC_EOF_DES_ADDR_CH0,
}

func i2sEnableClocks() {
esp.SYSTEM.SetPERIP_CLK_EN0_I2S0_CLK_EN(1)
esp.SYSTEM.SetPERIP_RST_EN0_I2S0_RST(1)
esp.SYSTEM.SetPERIP_RST_EN0_I2S0_RST(0)
if esp.SYSTEM.GetPERIP_CLK_EN1_DMA_CLK_EN() == 0 {
esp.SYSTEM.SetPERIP_CLK_EN1_DMA_CLK_EN(1)
esp.SYSTEM.SetPERIP_RST_EN1_DMA_RST(1)
esp.SYSTEM.SetPERIP_RST_EN1_DMA_RST(0)
}
esp.DMA.MISC_CONF.SetBits(esp.DMA_MISC_CONF_CLK_EN)
esp.I2S0.SetTX_CLKM_CONF_CLK_EN(1)
}

func i2sSetTxClock(div, x, y, z, yn1 uint32) {
i2sSetClockDiv(&esp.I2S0.TX_CLKM_CONF, &esp.I2S0.TX_CLKM_DIV_CONF, 0, div, x, y, z, yn1)
esp.I2S0.SetTX_CLKM_CONF_TX_CLK_SEL(i2sPLL160MClockSel)
esp.I2S0.SetTX_CLKM_CONF_TX_CLK_ACTIVE(1)
esp.I2S0.SetRX_CLKM_CONF_MCLK_SEL(0)
}

func i2sSetRxClock(div, x, y, z, yn1 uint32) {
i2sSetClockDiv(&esp.I2S0.RX_CLKM_CONF, &esp.I2S0.RX_CLKM_DIV_CONF, 0, div, x, y, z, yn1)
esp.I2S0.SetRX_CLKM_CONF_RX_CLK_SEL(i2sPLL160MClockSel)
esp.I2S0.SetRX_CLKM_CONF_RX_CLK_ACTIVE(1)
}

func i2sEnableInterrupt() {
esp.INTERRUPT_CORE0.SetDMA_OUT_CH0_INT_MAP(cpuInterruptFromI2S)
esp.INTERRUPT_CORE0.SetDMA_IN_CH0_INT_MAP(cpuInterruptFromI2S)
interrupt.New(cpuInterruptFromI2S, func(interrupt.Interrupt) {
I2S0.handleInterrupt()
}).Enable()
}
Loading
Loading