From 56da26b416084c5dc72f0923e77ba046e9143f95 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Sun, 30 Nov 2025 11:11:18 +0100 Subject: [PATCH 1/4] nrf: fix typo in ADC configuration This shouldn't change behavior (both values are 0), but it's a bit more correct. --- src/machine/machine_nrf52xxx.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/machine/machine_nrf52xxx.go b/src/machine/machine_nrf52xxx.go index 90a1a7fbf5..075cef62fd 100644 --- a/src/machine/machine_nrf52xxx.go +++ b/src/machine/machine_nrf52xxx.go @@ -26,7 +26,7 @@ func InitADC() { // Samples can be 1(default), 2, 4, 8, 16, 32, 64, 128, 256 samples func (a *ADC) Configure(config ADCConfig) { var configVal uint32 = nrf.SAADC_CH_CONFIG_RESP_Bypass< Date: Sun, 30 Nov 2025 11:12:58 +0100 Subject: [PATCH 2/4] nrf: don't set PSELN, it's ignored in single ended mode anyway We use single ended mode, so according to the datasheet PSELN is ignored. --- src/machine/machine_nrf52xxx.go | 1 - 1 file changed, 1 deletion(-) diff --git a/src/machine/machine_nrf52xxx.go b/src/machine/machine_nrf52xxx.go index 075cef62fd..ef3c7cb776 100644 --- a/src/machine/machine_nrf52xxx.go +++ b/src/machine/machine_nrf52xxx.go @@ -141,7 +141,6 @@ func (a *ADC) Get() uint16 { } // Set pin to read. - nrf.SAADC.CH[0].PSELN.Set(pwmPin) nrf.SAADC.CH[0].PSELP.Set(pwmPin) // Destination for sample result. From 26c7023bf87306b556e2f1dd32ee4cf2d2ff4f86 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Sun, 30 Nov 2025 11:14:11 +0100 Subject: [PATCH 3/4] nrf: rename pwmPin to adcPin Just a small refactor, to fix the naming. --- src/machine/machine_nrf52xxx.go | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/machine/machine_nrf52xxx.go b/src/machine/machine_nrf52xxx.go index ef3c7cb776..15e7a577c5 100644 --- a/src/machine/machine_nrf52xxx.go +++ b/src/machine/machine_nrf52xxx.go @@ -116,32 +116,32 @@ func (a *ADC) Configure(config ADCConfig) { // Get returns the current value of an ADC pin in the range 0..0xffff. func (a *ADC) Get() uint16 { - var pwmPin uint32 + var adcPin uint32 var rawValue volatile.Register16 switch a.Pin { case 2: - pwmPin = nrf.SAADC_CH_PSELP_PSELP_AnalogInput0 + adcPin = nrf.SAADC_CH_PSELP_PSELP_AnalogInput0 case 3: - pwmPin = nrf.SAADC_CH_PSELP_PSELP_AnalogInput1 + adcPin = nrf.SAADC_CH_PSELP_PSELP_AnalogInput1 case 4: - pwmPin = nrf.SAADC_CH_PSELP_PSELP_AnalogInput2 + adcPin = nrf.SAADC_CH_PSELP_PSELP_AnalogInput2 case 5: - pwmPin = nrf.SAADC_CH_PSELP_PSELP_AnalogInput3 + adcPin = nrf.SAADC_CH_PSELP_PSELP_AnalogInput3 case 28: - pwmPin = nrf.SAADC_CH_PSELP_PSELP_AnalogInput4 + adcPin = nrf.SAADC_CH_PSELP_PSELP_AnalogInput4 case 29: - pwmPin = nrf.SAADC_CH_PSELP_PSELP_AnalogInput5 + adcPin = nrf.SAADC_CH_PSELP_PSELP_AnalogInput5 case 30: - pwmPin = nrf.SAADC_CH_PSELP_PSELP_AnalogInput6 + adcPin = nrf.SAADC_CH_PSELP_PSELP_AnalogInput6 case 31: - pwmPin = nrf.SAADC_CH_PSELP_PSELP_AnalogInput7 + adcPin = nrf.SAADC_CH_PSELP_PSELP_AnalogInput7 default: return 0 } // Set pin to read. - nrf.SAADC.CH[0].PSELP.Set(pwmPin) + nrf.SAADC.CH[0].PSELP.Set(adcPin) // Destination for sample result. // Note: rawValue doesn't need to be kept alive for the GC, since the From ee828b5b4f298e7abca92317f329549ac53e0953 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Sun, 30 Nov 2025 11:14:57 +0100 Subject: [PATCH 4/4] nrf: add ADC_VDDH which is an ADC pin for VDDH VDDH is typically connected to USB (~5V) or directly to a battery. Measuring the voltage on VDDH is a way to measure the current battery voltage, which in turn can be useful to determine how much power is left in the battery. I've special cased the nrf52840 in a somewhat unusual way, maybe there is a better way, feel free to comment! --- src/machine/machine_nrf52840.go | 4 ++++ src/machine/machine_nrf52xxx.go | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/src/machine/machine_nrf52840.go b/src/machine/machine_nrf52840.go index c30933ba4e..c858355fdf 100644 --- a/src/machine/machine_nrf52840.go +++ b/src/machine/machine_nrf52840.go @@ -110,3 +110,7 @@ func eraseBlockSize() int64 { } const spiMaxBufferSize = 0xffff // from the datasheet: TXD.MAXCNT and RXD.MAXCNT + +// ADC instance for the VDDH input pin. This pin is typically connected to USB +// input voltage (~5V) or directly to a battery. +var ADC_VDDH = ADC{adcVDDHPin} diff --git a/src/machine/machine_nrf52xxx.go b/src/machine/machine_nrf52xxx.go index 15e7a577c5..6fa267e7bf 100644 --- a/src/machine/machine_nrf52xxx.go +++ b/src/machine/machine_nrf52xxx.go @@ -12,6 +12,8 @@ func CPUFrequency() uint32 { return 64000000 } +var adcVDDHPin = Pin(254) // special pin number for VDDH on the nrf52840 + // InitADC initializes the registers needed for ADC. func InitADC() { // Enable ADC. @@ -136,6 +138,12 @@ func (a *ADC) Get() uint16 { adcPin = nrf.SAADC_CH_PSELP_PSELP_AnalogInput6 case 31: adcPin = nrf.SAADC_CH_PSELP_PSELP_AnalogInput7 + case adcVDDHPin: + if Device == "nrf52840" { + adcPin = 0x0D // VDDHDIV5 on the nrf52840 + } else { + return 0 + } default: return 0 }