machine/rp2040: add basic support for ADC

Signed-off-by: deadprogram <ron@hybridgroup.com>
Этот коммит содержится в:
deadprogram 2021-06-05 13:15:43 +02:00 коммит произвёл Ron Evans
родитель 42ec3e2469
коммит 9912dd6db1
3 изменённых файлов: 80 добавлений и 4 удалений

Просмотреть файл

@ -38,6 +38,12 @@ const (
// Onboard LED
LED Pin = GP25
// Analog pins
ADC0 = GP26
ADC1 = GP27
ADC2 = GP28
ADC3 = GP29
// Onboard crystal oscillator frequency, in MHz.
xoscFreq = 12 // MHz
)

61
src/machine/machine_rp2040_adc.go Обычный файл
Просмотреть файл

@ -0,0 +1,61 @@
// +build rp2040
package machine
import (
"device/rp"
)
func InitADC() {
// reset ADC
rp.RESETS.RESET.SetBits(rp.RESETS_RESET_ADC)
rp.RESETS.RESET.ClearBits(rp.RESETS_RESET_ADC)
for !rp.RESETS.RESET_DONE.HasBits(rp.RESETS_RESET_ADC) {
}
// enable ADC
rp.ADC.CS.Set(rp.ADC_CS_EN)
waitForReady()
}
// Configure configures a ADC pin to be able to be used to read data.
func (a ADC) Configure(config ADCConfig) {
switch a.Pin {
case GP26, GP27, GP28, GP29:
a.Pin.Configure(PinConfig{Mode: PinAnalog})
default:
// invalid ADC
return
}
}
func (a ADC) Get() uint16 {
rp.ADC.CS.SetBits(uint32(a.getADCChannel()) << rp.ADC_CS_AINSEL_Pos)
rp.ADC.CS.SetBits(rp.ADC_CS_START_ONCE)
waitForReady()
// rp2040 uses 12-bit sampling, so scale to 16-bit
return uint16(rp.ADC.RESULT.Get() << 4)
}
func waitForReady() {
for !rp.ADC.CS.HasBits(rp.ADC_CS_READY) {
}
}
func (a ADC) getADCChannel() uint8 {
switch a.Pin {
case GP26:
return 0
case GP27:
return 1
case GP28:
return 2
case GP29:
return 3
default:
return 0
}
}

Просмотреть файл

@ -66,6 +66,7 @@ const (
PinInput
PinInputPulldown
PinInputPullup
PinAnalog
)
// set drives the pin high
@ -109,6 +110,11 @@ func (p Pin) pulldown() {
p.padCtrl().ClearBits(rp.PADS_BANK0_GPIO0_PUE)
}
func (p Pin) pulloff() {
p.padCtrl().ClearBits(rp.PADS_BANK0_GPIO0_PDE)
p.padCtrl().ClearBits(rp.PADS_BANK0_GPIO0_PUE)
}
// setFunc will set pin function to fn.
func (p Pin) setFunc(fn pinFunc) {
// Set input enable, Clear output disable
@ -125,7 +131,6 @@ func (p Pin) init() {
mask := uint32(1) << p
rp.SIO.GPIO_OE_CLR.Set(mask)
p.clr()
p.setFunc(fnSIO)
}
// Configure configures the gpio pin as per mode.
@ -134,15 +139,19 @@ func (p Pin) Configure(config PinConfig) {
mask := uint32(1) << p
switch config.Mode {
case PinOutput:
p.setFunc(fnSIO)
rp.SIO.GPIO_OE_SET.Set(mask)
case PinInput:
rp.SIO.GPIO_OE_CLR.Set(mask)
p.setFunc(fnSIO)
case PinInputPulldown:
rp.SIO.GPIO_OE_CLR.Set(mask)
p.setFunc(fnSIO)
p.pulldown()
case PinInputPullup:
rp.SIO.GPIO_OE_CLR.Set(mask)
p.setFunc(fnSIO)
p.pullup()
case PinAnalog:
p.setFunc(fnNULL)
p.pulloff()
}
}