accept configuration struct for ADC parameters (#1533)
Этот коммит содержится в:
родитель
3d6921b0e1
коммит
06f231468d
8 изменённых файлов: 371 добавлений и 64 удалений
|
@ -15,7 +15,7 @@ func main() {
|
|||
led.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
||||
|
||||
sensor := machine.ADC{machine.ADC2}
|
||||
sensor.Configure()
|
||||
sensor.Configure(machine.ADCConfig{})
|
||||
|
||||
for {
|
||||
val := sensor.Get()
|
||||
|
|
12
src/machine/adc.go
Обычный файл
12
src/machine/adc.go
Обычный файл
|
@ -0,0 +1,12 @@
|
|||
package machine
|
||||
|
||||
// Hardware abstraction layer for the analog-to-digital conversion (ADC)
|
||||
// peripheral.
|
||||
|
||||
// ADCConfig holds ADC configuration parameters. If left unspecified, the zero
|
||||
// value of each parameter will use the peripheral's default settings.
|
||||
type ADCConfig struct {
|
||||
Reference uint32 // analog reference voltage (AREF) in millivolts
|
||||
Resolution uint32 // number of bits for a single conversion (e.g., 8, 10, 12)
|
||||
Samples uint32 // number of samples for a single conversion (e.g., 4, 8, 16, 32)
|
||||
}
|
|
@ -307,13 +307,30 @@ func InitADC() {
|
|||
|
||||
// set calibration
|
||||
sam.ADC.CALIB.Set((bias << 8) | linearity)
|
||||
}
|
||||
|
||||
// Configure configures a ADC pin to be able to be used to read data.
|
||||
func (a ADC) Configure(config ADCConfig) {
|
||||
|
||||
// Wait for synchronization
|
||||
waitADCSync()
|
||||
|
||||
var resolution uint32
|
||||
switch config.Resolution {
|
||||
case 8:
|
||||
resolution = sam.ADC_CTRLB_RESSEL_8BIT
|
||||
case 10:
|
||||
resolution = sam.ADC_CTRLB_RESSEL_10BIT
|
||||
case 12:
|
||||
resolution = sam.ADC_CTRLB_RESSEL_12BIT
|
||||
case 16:
|
||||
resolution = sam.ADC_CTRLB_RESSEL_16BIT
|
||||
default:
|
||||
resolution = sam.ADC_CTRLB_RESSEL_12BIT
|
||||
}
|
||||
// Divide Clock by 32 with 12 bits resolution as default
|
||||
sam.ADC.CTRLB.Set((sam.ADC_CTRLB_PRESCALER_DIV32 << sam.ADC_CTRLB_PRESCALER_Pos) |
|
||||
(sam.ADC_CTRLB_RESSEL_12BIT << sam.ADC_CTRLB_RESSEL_Pos))
|
||||
uint16(resolution<<sam.ADC_CTRLB_RESSEL_Pos))
|
||||
|
||||
// Sampling Time Length
|
||||
sam.ADC.SAMPCTRL.Set(5)
|
||||
|
@ -325,18 +342,44 @@ func InitADC() {
|
|||
sam.ADC.INPUTCTRL.Set(sam.ADC_INPUTCTRL_MUXNEG_GND << sam.ADC_INPUTCTRL_MUXNEG_Pos)
|
||||
|
||||
// Averaging (see datasheet table in AVGCTRL register description)
|
||||
sam.ADC.AVGCTRL.Set((sam.ADC_AVGCTRL_SAMPLENUM_1 << sam.ADC_AVGCTRL_SAMPLENUM_Pos) |
|
||||
var samples uint32
|
||||
switch config.Resolution {
|
||||
case 1:
|
||||
samples = sam.ADC_AVGCTRL_SAMPLENUM_1
|
||||
case 2:
|
||||
samples = sam.ADC_AVGCTRL_SAMPLENUM_2
|
||||
case 4:
|
||||
samples = sam.ADC_AVGCTRL_SAMPLENUM_4
|
||||
case 8:
|
||||
samples = sam.ADC_AVGCTRL_SAMPLENUM_8
|
||||
case 16:
|
||||
samples = sam.ADC_AVGCTRL_SAMPLENUM_16
|
||||
case 32:
|
||||
samples = sam.ADC_AVGCTRL_SAMPLENUM_32
|
||||
case 64:
|
||||
samples = sam.ADC_AVGCTRL_SAMPLENUM_64
|
||||
case 128:
|
||||
samples = sam.ADC_AVGCTRL_SAMPLENUM_128
|
||||
case 256:
|
||||
samples = sam.ADC_AVGCTRL_SAMPLENUM_256
|
||||
case 512:
|
||||
samples = sam.ADC_AVGCTRL_SAMPLENUM_512
|
||||
case 1024:
|
||||
samples = sam.ADC_AVGCTRL_SAMPLENUM_1024
|
||||
default:
|
||||
samples = sam.ADC_AVGCTRL_SAMPLENUM_1
|
||||
}
|
||||
sam.ADC.AVGCTRL.Set(uint8(samples<<sam.ADC_AVGCTRL_SAMPLENUM_Pos) |
|
||||
(0x0 << sam.ADC_AVGCTRL_ADJRES_Pos))
|
||||
|
||||
// TODO: use config.Reference to set AREF level
|
||||
|
||||
// Analog Reference is AREF pin (3.3v)
|
||||
sam.ADC.INPUTCTRL.SetBits(sam.ADC_INPUTCTRL_GAIN_DIV2 << sam.ADC_INPUTCTRL_GAIN_Pos)
|
||||
|
||||
// 1/2 VDDANA = 0.5 * 3V3 = 1.65V
|
||||
sam.ADC.REFCTRL.SetBits(sam.ADC_REFCTRL_REFSEL_INTVCC1 << sam.ADC_REFCTRL_REFSEL_Pos)
|
||||
}
|
||||
|
||||
// Configure configures a ADCPin to be able to be used to read data.
|
||||
func (a ADC) Configure() {
|
||||
a.Pin.Configure(PinConfig{Mode: PinAnalog})
|
||||
return
|
||||
}
|
||||
|
|
|
@ -720,65 +720,83 @@ func InitADC() {
|
|||
|
||||
// calibrate ADC1
|
||||
sam.ADC1.CALIB.Set(uint16((biascomp | biasr2r | biasref) >> 16))
|
||||
|
||||
sam.ADC0.CTRLA.SetBits(sam.ADC_CTRLA_PRESCALER_DIV32 << sam.ADC_CTRLA_PRESCALER_Pos)
|
||||
// adcs[i]->CTRLB.bit.RESSEL = ADC_CTRLB_RESSEL_10BIT_Val;
|
||||
sam.ADC0.CTRLB.SetBits(sam.ADC_CTRLB_RESSEL_12BIT << sam.ADC_CTRLB_RESSEL_Pos)
|
||||
|
||||
// wait for sync
|
||||
for sam.ADC0.SYNCBUSY.HasBits(sam.ADC_SYNCBUSY_CTRLB) {
|
||||
}
|
||||
|
||||
// sampling Time Length
|
||||
sam.ADC0.SAMPCTRL.Set(5)
|
||||
|
||||
// wait for sync
|
||||
for sam.ADC0.SYNCBUSY.HasBits(sam.ADC_SYNCBUSY_SAMPCTRL) {
|
||||
}
|
||||
|
||||
// No Negative input (Internal Ground)
|
||||
sam.ADC0.INPUTCTRL.Set(sam.ADC_INPUTCTRL_MUXNEG_GND << sam.ADC_INPUTCTRL_MUXNEG_Pos)
|
||||
|
||||
// wait for sync
|
||||
for sam.ADC0.SYNCBUSY.HasBits(sam.ADC_SYNCBUSY_INPUTCTRL) {
|
||||
}
|
||||
|
||||
// Averaging (see datasheet table in AVGCTRL register description)
|
||||
// 1 sample only (no oversampling nor averaging), adjusting result by 0
|
||||
sam.ADC0.AVGCTRL.Set(sam.ADC_AVGCTRL_SAMPLENUM_1 | (0 << sam.ADC_AVGCTRL_ADJRES_Pos))
|
||||
|
||||
// wait for sync
|
||||
for sam.ADC0.SYNCBUSY.HasBits(sam.ADC_SYNCBUSY_AVGCTRL) {
|
||||
}
|
||||
|
||||
// same for ADC1, as for ADC0
|
||||
sam.ADC1.CTRLA.SetBits(sam.ADC_CTRLA_PRESCALER_DIV32 << sam.ADC_CTRLA_PRESCALER_Pos)
|
||||
sam.ADC1.CTRLB.SetBits(sam.ADC_CTRLB_RESSEL_12BIT << sam.ADC_CTRLB_RESSEL_Pos)
|
||||
for sam.ADC1.SYNCBUSY.HasBits(sam.ADC_SYNCBUSY_CTRLB) {
|
||||
}
|
||||
sam.ADC1.SAMPCTRL.Set(5)
|
||||
for sam.ADC1.SYNCBUSY.HasBits(sam.ADC_SYNCBUSY_SAMPCTRL) {
|
||||
}
|
||||
sam.ADC1.INPUTCTRL.Set(sam.ADC_INPUTCTRL_MUXNEG_GND << sam.ADC_INPUTCTRL_MUXNEG_Pos)
|
||||
for sam.ADC1.SYNCBUSY.HasBits(sam.ADC_SYNCBUSY_INPUTCTRL) {
|
||||
}
|
||||
sam.ADC1.AVGCTRL.Set(sam.ADC_AVGCTRL_SAMPLENUM_1 | (0 << sam.ADC_AVGCTRL_ADJRES_Pos))
|
||||
for sam.ADC1.SYNCBUSY.HasBits(sam.ADC_SYNCBUSY_AVGCTRL) {
|
||||
}
|
||||
|
||||
// wait for sync
|
||||
for sam.ADC0.SYNCBUSY.HasBits(sam.ADC_SYNCBUSY_REFCTRL) {
|
||||
}
|
||||
for sam.ADC1.SYNCBUSY.HasBits(sam.ADC_SYNCBUSY_REFCTRL) {
|
||||
}
|
||||
|
||||
// default is 3V3 reference voltage
|
||||
sam.ADC0.REFCTRL.SetBits(sam.ADC_REFCTRL_REFSEL_INTVCC1)
|
||||
sam.ADC1.REFCTRL.SetBits(sam.ADC_REFCTRL_REFSEL_INTVCC1)
|
||||
}
|
||||
|
||||
// Configure configures a ADCPin to be able to be used to read data.
|
||||
func (a ADC) Configure() {
|
||||
func (a ADC) Configure(config ADCConfig) {
|
||||
|
||||
for _, adc := range []*sam.ADC_Type{sam.ADC0, sam.ADC1} {
|
||||
|
||||
for adc.SYNCBUSY.HasBits(sam.ADC_SYNCBUSY_CTRLB) {
|
||||
} // wait for sync
|
||||
|
||||
adc.CTRLA.SetBits(sam.ADC_CTRLA_PRESCALER_DIV32 << sam.ADC_CTRLA_PRESCALER_Pos)
|
||||
var resolution uint32
|
||||
switch config.Resolution {
|
||||
case 8:
|
||||
resolution = sam.ADC_CTRLB_RESSEL_8BIT
|
||||
case 10:
|
||||
resolution = sam.ADC_CTRLB_RESSEL_10BIT
|
||||
case 12:
|
||||
resolution = sam.ADC_CTRLB_RESSEL_12BIT
|
||||
case 16:
|
||||
resolution = sam.ADC_CTRLB_RESSEL_16BIT
|
||||
default:
|
||||
resolution = sam.ADC_CTRLB_RESSEL_12BIT
|
||||
}
|
||||
adc.CTRLB.SetBits(uint16(resolution << sam.ADC_CTRLB_RESSEL_Pos))
|
||||
adc.SAMPCTRL.Set(5) // sampling Time Length
|
||||
|
||||
for adc.SYNCBUSY.HasBits(sam.ADC_SYNCBUSY_SAMPCTRL) {
|
||||
} // wait for sync
|
||||
|
||||
// No Negative input (Internal Ground)
|
||||
adc.INPUTCTRL.Set(sam.ADC_INPUTCTRL_MUXNEG_GND << sam.ADC_INPUTCTRL_MUXNEG_Pos)
|
||||
for adc.SYNCBUSY.HasBits(sam.ADC_SYNCBUSY_INPUTCTRL) {
|
||||
} // wait for sync
|
||||
|
||||
// Averaging (see datasheet table in AVGCTRL register description)
|
||||
var samples uint32
|
||||
switch config.Resolution {
|
||||
case 1:
|
||||
samples = sam.ADC_AVGCTRL_SAMPLENUM_1
|
||||
case 2:
|
||||
samples = sam.ADC_AVGCTRL_SAMPLENUM_2
|
||||
case 4:
|
||||
samples = sam.ADC_AVGCTRL_SAMPLENUM_4
|
||||
case 8:
|
||||
samples = sam.ADC_AVGCTRL_SAMPLENUM_8
|
||||
case 16:
|
||||
samples = sam.ADC_AVGCTRL_SAMPLENUM_16
|
||||
case 32:
|
||||
samples = sam.ADC_AVGCTRL_SAMPLENUM_32
|
||||
case 64:
|
||||
samples = sam.ADC_AVGCTRL_SAMPLENUM_64
|
||||
case 128:
|
||||
samples = sam.ADC_AVGCTRL_SAMPLENUM_128
|
||||
case 256:
|
||||
samples = sam.ADC_AVGCTRL_SAMPLENUM_256
|
||||
case 512:
|
||||
samples = sam.ADC_AVGCTRL_SAMPLENUM_512
|
||||
case 1024:
|
||||
samples = sam.ADC_AVGCTRL_SAMPLENUM_1024
|
||||
default: // 1 sample only (no oversampling nor averaging), adjusting result by 0
|
||||
samples = sam.ADC_AVGCTRL_SAMPLENUM_1
|
||||
}
|
||||
adc.AVGCTRL.Set(uint8(samples<<sam.ADC_AVGCTRL_SAMPLENUM_Pos) |
|
||||
(0 << sam.ADC_AVGCTRL_ADJRES_Pos))
|
||||
|
||||
for adc.SYNCBUSY.HasBits(sam.ADC_SYNCBUSY_AVGCTRL) {
|
||||
} // wait for sync
|
||||
for adc.SYNCBUSY.HasBits(sam.ADC_SYNCBUSY_REFCTRL) {
|
||||
} // wait for sync
|
||||
|
||||
// TODO: use config.Reference to set AREF level
|
||||
|
||||
// default is 3V3 reference voltage
|
||||
adc.REFCTRL.SetBits(sam.ADC_REFCTRL_REFSEL_INTVCC1)
|
||||
}
|
||||
|
||||
a.Pin.Configure(PinConfig{Mode: PinAnalog})
|
||||
}
|
||||
|
||||
|
|
|
@ -118,7 +118,7 @@ func InitADC() {
|
|||
}
|
||||
|
||||
// Configure configures a ADCPin to be able to be used to read data.
|
||||
func (a ADC) Configure() {
|
||||
func (a ADC) Configure(ADCConfig) {
|
||||
return // no pin specific setup on AVR machine.
|
||||
}
|
||||
|
||||
|
|
|
@ -73,7 +73,7 @@ func InitADC() {
|
|||
}
|
||||
|
||||
// Configure configures an ADC pin to be able to be used to read data.
|
||||
func (adc ADC) Configure() {
|
||||
func (adc ADC) Configure(ADCConfig) {
|
||||
}
|
||||
|
||||
// Get reads the current analog value from this ADC peripheral.
|
||||
|
|
|
@ -4,6 +4,7 @@ package machine
|
|||
|
||||
import (
|
||||
"device/nrf"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// Hardware pins
|
||||
|
@ -61,6 +62,122 @@ func (i2c I2C) setPins(scl, sda Pin) {
|
|||
i2c.Bus.PSELSDA.Set(uint32(sda))
|
||||
}
|
||||
|
||||
// SPI
|
||||
func (spi SPI) setPins(sck, sdo, sdi Pin) {
|
||||
if sck == 0 {
|
||||
sck = SPI0_SCK_PIN
|
||||
}
|
||||
if sdo == 0 {
|
||||
sdo = SPI0_SDO_PIN
|
||||
}
|
||||
if sdi == 0 {
|
||||
sdi = SPI0_SDI_PIN
|
||||
}
|
||||
spi.Bus.PSEL.SCK.Set(uint32(sck))
|
||||
spi.Bus.PSEL.MOSI.Set(uint32(sdo))
|
||||
spi.Bus.PSEL.MISO.Set(uint32(sdi))
|
||||
}
|
||||
|
||||
// InitADC initializes the registers needed for ADC.
|
||||
func InitADC() {
|
||||
return // no specific setup on nrf52 machine.
|
||||
}
|
||||
|
||||
// Configure configures an ADC pin to be able to read analog data.
|
||||
func (a ADC) Configure(ADCConfig) {
|
||||
return // no pin specific setup on nrf52 machine.
|
||||
}
|
||||
|
||||
// Get returns the current value of a ADC pin in the range 0..0xffff.
|
||||
func (a ADC) Get() uint16 {
|
||||
var pwmPin uint32
|
||||
var value int16
|
||||
|
||||
switch a.Pin {
|
||||
case 2:
|
||||
pwmPin = nrf.SAADC_CH_PSELP_PSELP_AnalogInput0
|
||||
|
||||
case 3:
|
||||
pwmPin = nrf.SAADC_CH_PSELP_PSELP_AnalogInput1
|
||||
|
||||
case 4:
|
||||
pwmPin = nrf.SAADC_CH_PSELP_PSELP_AnalogInput2
|
||||
|
||||
case 5:
|
||||
pwmPin = nrf.SAADC_CH_PSELP_PSELP_AnalogInput3
|
||||
|
||||
case 28:
|
||||
pwmPin = nrf.SAADC_CH_PSELP_PSELP_AnalogInput4
|
||||
|
||||
case 29:
|
||||
pwmPin = nrf.SAADC_CH_PSELP_PSELP_AnalogInput5
|
||||
|
||||
case 30:
|
||||
pwmPin = nrf.SAADC_CH_PSELP_PSELP_AnalogInput6
|
||||
|
||||
case 31:
|
||||
pwmPin = nrf.SAADC_CH_PSELP_PSELP_AnalogInput7
|
||||
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
|
||||
nrf.SAADC.RESOLUTION.Set(nrf.SAADC_RESOLUTION_VAL_12bit)
|
||||
|
||||
// Enable ADC.
|
||||
nrf.SAADC.ENABLE.Set(nrf.SAADC_ENABLE_ENABLE_Enabled << nrf.SAADC_ENABLE_ENABLE_Pos)
|
||||
for i := 0; i < 8; i++ {
|
||||
nrf.SAADC.CH[i].PSELN.Set(nrf.SAADC_CH_PSELP_PSELP_NC)
|
||||
nrf.SAADC.CH[i].PSELP.Set(nrf.SAADC_CH_PSELP_PSELP_NC)
|
||||
}
|
||||
|
||||
// Configure ADC.
|
||||
nrf.SAADC.CH[0].CONFIG.Set(((nrf.SAADC_CH_CONFIG_RESP_Bypass << nrf.SAADC_CH_CONFIG_RESP_Pos) & nrf.SAADC_CH_CONFIG_RESP_Msk) |
|
||||
((nrf.SAADC_CH_CONFIG_RESP_Bypass << nrf.SAADC_CH_CONFIG_RESN_Pos) & nrf.SAADC_CH_CONFIG_RESN_Msk) |
|
||||
((nrf.SAADC_CH_CONFIG_GAIN_Gain1_5 << nrf.SAADC_CH_CONFIG_GAIN_Pos) & nrf.SAADC_CH_CONFIG_GAIN_Msk) |
|
||||
((nrf.SAADC_CH_CONFIG_REFSEL_Internal << nrf.SAADC_CH_CONFIG_REFSEL_Pos) & nrf.SAADC_CH_CONFIG_REFSEL_Msk) |
|
||||
((nrf.SAADC_CH_CONFIG_TACQ_3us << nrf.SAADC_CH_CONFIG_TACQ_Pos) & nrf.SAADC_CH_CONFIG_TACQ_Msk) |
|
||||
((nrf.SAADC_CH_CONFIG_MODE_SE << nrf.SAADC_CH_CONFIG_MODE_Pos) & nrf.SAADC_CH_CONFIG_MODE_Msk))
|
||||
|
||||
// Set pin to read.
|
||||
nrf.SAADC.CH[0].PSELN.Set(pwmPin)
|
||||
nrf.SAADC.CH[0].PSELP.Set(pwmPin)
|
||||
|
||||
// Destination for sample result.
|
||||
nrf.SAADC.RESULT.PTR.Set(uint32(uintptr(unsafe.Pointer(&value))))
|
||||
nrf.SAADC.RESULT.MAXCNT.Set(1) // One sample
|
||||
|
||||
// Start tasks.
|
||||
nrf.SAADC.TASKS_START.Set(1)
|
||||
for nrf.SAADC.EVENTS_STARTED.Get() == 0 {
|
||||
}
|
||||
nrf.SAADC.EVENTS_STARTED.Set(0x00)
|
||||
|
||||
// Start the sample task.
|
||||
nrf.SAADC.TASKS_SAMPLE.Set(1)
|
||||
|
||||
// Wait until the sample task is done.
|
||||
for nrf.SAADC.EVENTS_END.Get() == 0 {
|
||||
}
|
||||
nrf.SAADC.EVENTS_END.Set(0x00)
|
||||
|
||||
// Stop the ADC
|
||||
nrf.SAADC.TASKS_STOP.Set(1)
|
||||
for nrf.SAADC.EVENTS_STOPPED.Get() == 0 {
|
||||
}
|
||||
nrf.SAADC.EVENTS_STOPPED.Set(0)
|
||||
|
||||
// Disable the ADC.
|
||||
nrf.SAADC.ENABLE.Set(nrf.SAADC_ENABLE_ENABLE_Disabled << nrf.SAADC_ENABLE_ENABLE_Pos)
|
||||
|
||||
if value < 0 {
|
||||
value = 0
|
||||
}
|
||||
|
||||
// Return 16-bit result from 12-bit value.
|
||||
return uint16(value << 4)
|
||||
}
|
||||
|
||||
// PWM
|
||||
var (
|
||||
pwmChannelPins = [3]uint32{0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}
|
||||
|
|
|
@ -4,6 +4,7 @@ package machine
|
|||
|
||||
import (
|
||||
"device/nrf"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// Hardware pins
|
||||
|
@ -77,6 +78,122 @@ func (i2c I2C) setPins(scl, sda Pin) {
|
|||
i2c.Bus.PSEL.SDA.Set(uint32(sda))
|
||||
}
|
||||
|
||||
// SPI
|
||||
func (spi SPI) setPins(sck, sdo, sdi Pin) {
|
||||
if sck == 0 {
|
||||
sck = SPI0_SCK_PIN
|
||||
}
|
||||
if sdo == 0 {
|
||||
sdo = SPI0_SDO_PIN
|
||||
}
|
||||
if sdi == 0 {
|
||||
sdi = SPI0_SDI_PIN
|
||||
}
|
||||
spi.Bus.PSEL.SCK.Set(uint32(sck))
|
||||
spi.Bus.PSEL.MOSI.Set(uint32(sdo))
|
||||
spi.Bus.PSEL.MISO.Set(uint32(sdi))
|
||||
}
|
||||
|
||||
// InitADC initializes the registers needed for ADC.
|
||||
func InitADC() {
|
||||
return // no specific setup on nrf52840 machine.
|
||||
}
|
||||
|
||||
// Configure configures an ADC pin to be able to read analog data.
|
||||
func (a ADC) Configure(ADCConfig) {
|
||||
return // no pin specific setup on nrf52840 machine.
|
||||
}
|
||||
|
||||
// Get returns the current value of a ADC pin in the range 0..0xffff.
|
||||
func (a ADC) Get() uint16 {
|
||||
var pwmPin uint32
|
||||
var value int16
|
||||
|
||||
switch a.Pin {
|
||||
case 2:
|
||||
pwmPin = nrf.SAADC_CH_PSELP_PSELP_AnalogInput0
|
||||
|
||||
case 3:
|
||||
pwmPin = nrf.SAADC_CH_PSELP_PSELP_AnalogInput1
|
||||
|
||||
case 4:
|
||||
pwmPin = nrf.SAADC_CH_PSELP_PSELP_AnalogInput2
|
||||
|
||||
case 5:
|
||||
pwmPin = nrf.SAADC_CH_PSELP_PSELP_AnalogInput3
|
||||
|
||||
case 28:
|
||||
pwmPin = nrf.SAADC_CH_PSELP_PSELP_AnalogInput4
|
||||
|
||||
case 29:
|
||||
pwmPin = nrf.SAADC_CH_PSELP_PSELP_AnalogInput5
|
||||
|
||||
case 30:
|
||||
pwmPin = nrf.SAADC_CH_PSELP_PSELP_AnalogInput6
|
||||
|
||||
case 31:
|
||||
pwmPin = nrf.SAADC_CH_PSELP_PSELP_AnalogInput7
|
||||
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
|
||||
nrf.SAADC.RESOLUTION.Set(nrf.SAADC_RESOLUTION_VAL_12bit)
|
||||
|
||||
// Enable ADC.
|
||||
nrf.SAADC.ENABLE.Set(nrf.SAADC_ENABLE_ENABLE_Enabled << nrf.SAADC_ENABLE_ENABLE_Pos)
|
||||
for i := 0; i < 8; i++ {
|
||||
nrf.SAADC.CH[i].PSELN.Set(nrf.SAADC_CH_PSELP_PSELP_NC)
|
||||
nrf.SAADC.CH[i].PSELP.Set(nrf.SAADC_CH_PSELP_PSELP_NC)
|
||||
}
|
||||
|
||||
// Configure ADC.
|
||||
nrf.SAADC.CH[0].CONFIG.Set(((nrf.SAADC_CH_CONFIG_RESP_Bypass << nrf.SAADC_CH_CONFIG_RESP_Pos) & nrf.SAADC_CH_CONFIG_RESP_Msk) |
|
||||
((nrf.SAADC_CH_CONFIG_RESP_Bypass << nrf.SAADC_CH_CONFIG_RESN_Pos) & nrf.SAADC_CH_CONFIG_RESN_Msk) |
|
||||
((nrf.SAADC_CH_CONFIG_GAIN_Gain1_5 << nrf.SAADC_CH_CONFIG_GAIN_Pos) & nrf.SAADC_CH_CONFIG_GAIN_Msk) |
|
||||
((nrf.SAADC_CH_CONFIG_REFSEL_Internal << nrf.SAADC_CH_CONFIG_REFSEL_Pos) & nrf.SAADC_CH_CONFIG_REFSEL_Msk) |
|
||||
((nrf.SAADC_CH_CONFIG_TACQ_3us << nrf.SAADC_CH_CONFIG_TACQ_Pos) & nrf.SAADC_CH_CONFIG_TACQ_Msk) |
|
||||
((nrf.SAADC_CH_CONFIG_MODE_SE << nrf.SAADC_CH_CONFIG_MODE_Pos) & nrf.SAADC_CH_CONFIG_MODE_Msk))
|
||||
|
||||
// Set pin to read.
|
||||
nrf.SAADC.CH[0].PSELN.Set(pwmPin)
|
||||
nrf.SAADC.CH[0].PSELP.Set(pwmPin)
|
||||
|
||||
// Destination for sample result.
|
||||
nrf.SAADC.RESULT.PTR.Set(uint32(uintptr(unsafe.Pointer(&value))))
|
||||
nrf.SAADC.RESULT.MAXCNT.Set(1) // One sample
|
||||
|
||||
// Start tasks.
|
||||
nrf.SAADC.TASKS_START.Set(1)
|
||||
for nrf.SAADC.EVENTS_STARTED.Get() == 0 {
|
||||
}
|
||||
nrf.SAADC.EVENTS_STARTED.Set(0x00)
|
||||
|
||||
// Start the sample task.
|
||||
nrf.SAADC.TASKS_SAMPLE.Set(1)
|
||||
|
||||
// Wait until the sample task is done.
|
||||
for nrf.SAADC.EVENTS_END.Get() == 0 {
|
||||
}
|
||||
nrf.SAADC.EVENTS_END.Set(0x00)
|
||||
|
||||
// Stop the ADC
|
||||
nrf.SAADC.TASKS_STOP.Set(1)
|
||||
for nrf.SAADC.EVENTS_STOPPED.Get() == 0 {
|
||||
}
|
||||
nrf.SAADC.EVENTS_STOPPED.Set(0)
|
||||
|
||||
// Disable the ADC.
|
||||
nrf.SAADC.ENABLE.Set(nrf.SAADC_ENABLE_ENABLE_Disabled << nrf.SAADC_ENABLE_ENABLE_Pos)
|
||||
|
||||
if value < 0 {
|
||||
value = 0
|
||||
}
|
||||
|
||||
// Return 16-bit result from 12-bit value.
|
||||
return uint16(value << 4)
|
||||
}
|
||||
|
||||
// PWM
|
||||
var (
|
||||
pwmChannelPins = [4]uint32{0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче