diff --git a/Makefile b/Makefile index 64d7708f..9a0b64e6 100644 --- a/Makefile +++ b/Makefile @@ -303,6 +303,8 @@ smoketest: @$(MD5SUM) test.hex $(TINYGO) build -size short -o test.hex -target=circuitplay-express examples/dac @$(MD5SUM) test.hex + $(TINYGO) build -size short -o test.hex -target=pyportal examples/dac + @$(MD5SUM) test.hex ifneq ($(AVR), 0) $(TINYGO) build -size short -o test.hex -target=atmega1284p examples/serial @$(MD5SUM) test.hex diff --git a/src/examples/dac/circuitplay_express.go b/src/examples/dac/circuitplay_express.go new file mode 100644 index 00000000..386135ab --- /dev/null +++ b/src/examples/dac/circuitplay_express.go @@ -0,0 +1,13 @@ +// +build circuitplay_express + +package main + +import ( + "machine" +) + +func init() { + enable := machine.PA30 + enable.Configure(machine.PinConfig{Mode: machine.PinOutput}) + enable.Set(true) +} diff --git a/src/examples/dac/dac.go b/src/examples/dac/dac.go index f1c80c74..d3454ec8 100644 --- a/src/examples/dac/dac.go +++ b/src/examples/dac/dac.go @@ -10,16 +10,12 @@ import ( ) func main() { - enable := machine.PA30 - enable.Configure(machine.PinConfig{Mode: machine.PinOutput}) - enable.Set(true) - speaker := machine.A0 speaker.Configure(machine.PinConfig{Mode: machine.PinOutput}) machine.DAC0.Configure(machine.DACConfig{}) - data := []uint16{32768, 8192, 2048, 512, 0} + data := []uint16{0xFFFF, 0x8000, 0x4000, 0x2000, 0x1000, 0x0000} for { for _, val := range data { diff --git a/src/examples/dac/pyportal.go b/src/examples/dac/pyportal.go new file mode 100644 index 00000000..0e014d50 --- /dev/null +++ b/src/examples/dac/pyportal.go @@ -0,0 +1,13 @@ +// +build pyportal + +package main + +import ( + "machine" +) + +func init() { + enable := machine.SPK_SD + enable.Configure(machine.PinConfig{Mode: machine.PinOutput}) + enable.Set(true) +} diff --git a/src/machine/board_wioterminal.go b/src/machine/board_wioterminal.go index 14f0a494..19cb39ec 100644 --- a/src/machine/board_wioterminal.go +++ b/src/machine/board_wioterminal.go @@ -132,9 +132,6 @@ const ( PIN_DAC0 = PA02 PIN_DAC1 = PA05 - DAC0 = PIN_DAC0 - DAC1 = PIN_DAC1 - // FPO Analog RPIs //FPC_A7 = FPC_D7 //FPC_A8 = FPC_D8 diff --git a/src/machine/machine_atsamd51.go b/src/machine/machine_atsamd51.go index 7008590b..3488c355 100644 --- a/src/machine/machine_atsamd51.go +++ b/src/machine/machine_atsamd51.go @@ -2297,3 +2297,61 @@ func ResetProcessor() { arm.SystemReset() } + +// DAC on the SAMD51. +type DAC struct { +} + +var ( + DAC0 = DAC{} +) + +// DACConfig placeholder for future expansion. +type DACConfig struct { +} + +// Configure the DAC. +// output pin must already be configured. +func (dac DAC) Configure(config DACConfig) { + // Turn on clock for DAC + sam.MCLK.APBDMASK.SetBits(sam.MCLK_APBDMASK_DAC_) + + // Use Generic Clock Generator 4 as source for DAC. + sam.GCLK.PCHCTRL[42].Set((sam.GCLK_PCHCTRL_GEN_GCLK4 << sam.GCLK_PCHCTRL_GEN_Pos) | sam.GCLK_PCHCTRL_CHEN) + for sam.GCLK.SYNCBUSY.HasBits(sam.GCLK_SYNCBUSY_GENCTRL_GCLK4 << sam.GCLK_SYNCBUSY_GENCTRL_Pos) { + } + + // reset DAC + sam.DAC.CTRLA.Set(sam.DAC_CTRLA_SWRST) + + // wait for reset complete + for sam.DAC.CTRLA.HasBits(sam.DAC_CTRLA_SWRST) { + } + for sam.DAC.SYNCBUSY.HasBits(sam.DAC_SYNCBUSY_SWRST) { + } + + // enable + sam.DAC.CTRLB.Set(sam.DAC_CTRLB_REFSEL_VREFPU << sam.DAC_CTRLB_REFSEL_Pos) + sam.DAC.DACCTRL[0].SetBits((sam.DAC_DACCTRL_CCTRL_CC12M << sam.DAC_DACCTRL_CCTRL_Pos) | sam.DAC_DACCTRL_ENABLE) + sam.DAC.CTRLA.Set(sam.DAC_CTRLA_ENABLE) + + for sam.DAC.SYNCBUSY.HasBits(sam.DAC_SYNCBUSY_ENABLE) { + } + for !sam.DAC.STATUS.HasBits(sam.DAC_STATUS_READY0) { + } +} + +// Set writes a single 16-bit value to the DAC. +// Since the ATSAMD51 only has a 12-bit DAC, the passed-in value will be scaled down. +func (dac DAC) Set(value uint16) error { + sam.DAC.DATA[0].Set(value >> 4) + syncDAC() + return nil +} + +func syncDAC() { + for !sam.DAC.STATUS.HasBits(sam.DAC_STATUS_EOC0) { + } + for sam.DAC.SYNCBUSY.HasBits(sam.DAC_SYNCBUSY_DATA0) { + } +}