Skip to content

Commit 7417c14

Browse files
authored
nrf: make ADC resolution changeable (#4701)
Signed-off-by: Paul Schroeder <[email protected]>
1 parent 4f39be9 commit 7417c14

File tree

1 file changed

+43
-30
lines changed

1 file changed

+43
-30
lines changed

src/machine/machine_nrf52xxx.go

+43-30
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,17 @@ func CPUFrequency() uint32 {
1414

1515
// InitADC initializes the registers needed for ADC.
1616
func InitADC() {
17-
return // no specific setup on nrf52 machine.
18-
}
19-
20-
// Configure configures an ADC pin to be able to read analog data.
21-
func (a ADC) Configure(config ADCConfig) {
2217
// Enable ADC.
23-
// The ADC does not consume a noticeable amount of current simply by being
24-
// enabled.
18+
// The ADC does not consume a noticeable amount of current by being enabled.
2519
nrf.SAADC.ENABLE.Set(nrf.SAADC_ENABLE_ENABLE_Enabled << nrf.SAADC_ENABLE_ENABLE_Pos)
20+
}
2621

27-
// Use fixed resolution of 12 bits.
28-
// TODO: is it useful for users to change this?
29-
nrf.SAADC.RESOLUTION.Set(nrf.SAADC_RESOLUTION_VAL_12bit)
30-
22+
// Configure configures an ADC pin to be able to read analog data.
23+
// Reference voltage can be 150, 300, 600, 1200, 1800, 2400, 3000(default), 3600 mV
24+
// Resolution can be 8, 10, 12(default), 14 bits
25+
// SampleTime will be ceiled to 3(default), 5, 10, 15, 20 or 40(max) µS respectively
26+
// Samples can be 1(default), 2, 4, 8, 16, 32, 64, 128, 256 samples
27+
func (a *ADC) Configure(config ADCConfig) {
3128
var configVal uint32 = nrf.SAADC_CH_CONFIG_RESP_Bypass<<nrf.SAADC_CH_CONFIG_RESP_Pos |
3229
nrf.SAADC_CH_CONFIG_RESP_Bypass<<nrf.SAADC_CH_CONFIG_RESN_Pos |
3330
nrf.SAADC_CH_CONFIG_REFSEL_Internal<<nrf.SAADC_CH_CONFIG_REFSEL_Pos |
@@ -51,11 +48,26 @@ func (a ADC) Configure(config ADCConfig) {
5148
case 3600: // 3.6V
5249
configVal |= nrf.SAADC_CH_CONFIG_GAIN_Gain1_6 << nrf.SAADC_CH_CONFIG_GAIN_Pos
5350
default:
54-
// TODO: return an error
51+
// TODO: return an error, will that interfere with any interfaced if one will be?
52+
}
53+
54+
var resolution uint32
55+
switch config.Resolution {
56+
case 8:
57+
resolution = nrf.SAADC_RESOLUTION_VAL_8bit
58+
case 10:
59+
resolution = nrf.SAADC_RESOLUTION_VAL_10bit
60+
case 12:
61+
resolution = nrf.SAADC_RESOLUTION_VAL_12bit
62+
case 14:
63+
resolution = nrf.SAADC_RESOLUTION_VAL_14bit
64+
default:
65+
resolution = nrf.SAADC_RESOLUTION_VAL_12bit
5566
}
67+
nrf.SAADC.RESOLUTION.Set(resolution)
5668

57-
// Source resistance, according to table 89 on page 364 of the nrf52832 datasheet.
58-
// https://infocenter.nordicsemi.com/pdf/nRF52832_PS_v1.4.pdf
69+
// Source resistance, according to table 41 on page 676 of the nrf52832 datasheet.
70+
// https://docs-be.nordicsemi.com/bundle/ps_nrf52840/attach/nRF52840_PS_v1.11.pdf?_LANG=enus
5971
if config.SampleTime <= 3 { // <= 10kΩ
6072
configVal |= nrf.SAADC_CH_CONFIG_TACQ_3us << nrf.SAADC_CH_CONFIG_TACQ_Pos
6173
} else if config.SampleTime <= 5 { // <= 40kΩ
@@ -102,36 +114,28 @@ func (a ADC) Configure(config ADCConfig) {
102114
nrf.SAADC.CH[0].CONFIG.Set(configVal)
103115
}
104116

105-
// Get returns the current value of a ADC pin in the range 0..0xffff.
106-
func (a ADC) Get() uint16 {
117+
// Get returns the current value of an ADC pin in the range 0..0xffff.
118+
func (a *ADC) Get() uint16 {
107119
var pwmPin uint32
108120
var rawValue volatile.Register16
109121

110122
switch a.Pin {
111123
case 2:
112124
pwmPin = nrf.SAADC_CH_PSELP_PSELP_AnalogInput0
113-
114125
case 3:
115126
pwmPin = nrf.SAADC_CH_PSELP_PSELP_AnalogInput1
116-
117127
case 4:
118128
pwmPin = nrf.SAADC_CH_PSELP_PSELP_AnalogInput2
119-
120129
case 5:
121130
pwmPin = nrf.SAADC_CH_PSELP_PSELP_AnalogInput3
122-
123131
case 28:
124132
pwmPin = nrf.SAADC_CH_PSELP_PSELP_AnalogInput4
125-
126133
case 29:
127134
pwmPin = nrf.SAADC_CH_PSELP_PSELP_AnalogInput5
128-
129135
case 30:
130136
pwmPin = nrf.SAADC_CH_PSELP_PSELP_AnalogInput6
131-
132137
case 31:
133138
pwmPin = nrf.SAADC_CH_PSELP_PSELP_AnalogInput7
134-
135139
default:
136140
return 0
137141
}
@@ -164,13 +168,22 @@ func (a ADC) Get() uint16 {
164168
}
165169
nrf.SAADC.EVENTS_STOPPED.Set(0)
166170

167-
value := int16(rawValue.Get())
168-
if value < 0 {
169-
value = 0
171+
// convert to 16 bit resolution/value
172+
var resolutionAdjustment uint8
173+
switch nrf.SAADC.RESOLUTION.Get() {
174+
case nrf.SAADC_RESOLUTION_VAL_8bit:
175+
resolutionAdjustment = 8
176+
case nrf.SAADC_RESOLUTION_VAL_10bit:
177+
resolutionAdjustment = 6
178+
case nrf.SAADC_RESOLUTION_VAL_12bit:
179+
resolutionAdjustment = 4
180+
case nrf.SAADC_RESOLUTION_VAL_14bit:
181+
resolutionAdjustment = 2
182+
default:
183+
resolutionAdjustment = 4 // 12bit
170184
}
171185

172-
// Return 16-bit result from 12-bit value.
173-
return uint16(value << 4)
186+
return rawValue.Get() << resolutionAdjustment
174187
}
175188

176189
// SPI on the NRF.
@@ -196,7 +209,7 @@ type SPIConfig struct {
196209
Mode uint8
197210
}
198211

199-
// Configure is intended to setup the SPI interface.
212+
// Configure is intended to set up the SPI interface.
200213
func (spi SPI) Configure(config SPIConfig) error {
201214
// Disable bus to configure it
202215
spi.Bus.ENABLE.Set(nrf.SPIM_ENABLE_ENABLE_Disabled)

0 commit comments

Comments
 (0)