daniel-p-carvalho opened a new pull request, #20804:
URL: https://github.com/apache/nuttx/pull/20804

   ## Summary
   
   On the IPv2 ADC (STM32G4), `adc_common_cfg()` cleared 
`ADC_CCR.VREFEN`/`TSEN`/`VBATEN` every time an ADC was configured and nothing 
set them again. The internal channels (VREFINT, temperature sensor, VBAT/3) 
were therefore never enabled and read as disabled inputs: VREFINT returned 
about 64 instead of about 1496. The IPv1 driver has the 
`IO_ENABLE_TEMPER_VOLT_CH` ioctl for this, but IPv2 had no way to enable them.
   
   This change follows the L4, H5 and H7 drivers: `adc_internal()` scans the 
regular (and injected) channel lists and `adc_common_cfg()` sets the `ADC_CCR` 
bits that the listed internal channels need, then waits for the start-up time 
(12 us VREFINT, 120 us temperature sensor). No new ioctl or API. The bits are 
shared by the ADCs of a block and are not cleared in `adc_common_cfg()` any 
more: the block is reset on the first open and on the last close.
   
   Channel map (RM0440 Rev 9, Table 71 and section 21.4.11):
   
   | | VTS (TSEN) | VBAT/3 (VBATEN) | VREFINT (VREFEN) |
   |---|---|---|---|
   | ADC1 | 16 | 17 | 18 |
   | ADC2 | - | - | - |
   | ADC3 | - | 17 | 18 |
   | ADC4 | - | - | 18 |
   
   The other internal channels are OPAMP outputs and need no `ADC_CCR` bit. 
Other IPv2 chips (F3) keep the previous behavior. Not covered: ADC5 (the driver 
supports ADC1 to ADC4) and category 4 devices, where ADC3 channel 17 is the 
OPAMP6 output.
   
   ## Impact
   
   Only STM32G4 with the IPv2 ADC. No API change. Applications that enable the 
bits by writing `ADC_CCR` themselves keep working, and applications that do not 
use internal channels see no difference.
   
   ## Testing
   
   Host: Linux x86_64, `arm-none-eabi-gcc` 15.2.1. Target: custom STM32G474RE 
board (VDDA about 3.3 V), ADC1, software trigger, 12 bits, 640.5 cycles sample 
time, channel list `{5, 11, 14, 15, 12, 18, 16, 17}`, read with the `adc` 
example. `checkpatch` passes.
   
   Values read from channels 18, 16 and 17 (VREFINT, temperature sensor, 
VBAT/3):
   
   | | upstream master | with this change |
   |---|---|---|
   | 18 (VREFINT) | 64 | 1496 |
   | 16 (temperature sensor) | 97 | 931 |
   | 17 (VBAT/3) | 132 | 1357 |
   
   - VREFINT_CAL of this chip is 1654, so VDDA = 3.0 * 1654 / 1496 = 3.32 V.
   - VBAT/3 gives 1357 * 3.32 / 4095 * 3 = 3.30 V, matching VDDA (VBAT is tied 
to 3.3 V on this board).
   - The temperature sensor gives 0.754 V, about 28 C with the typical 
datasheet values (0.76 V at 30 C, 2.5 mV/C). The factory calibration was not 
used.
   
   Raw `adc -n 2` output with the change:
   
   ```
   Sample:
   1: channel: 14 value: 1093
   2: channel: 15 value: 3811
   3: channel: 12 value: 0
   4: channel: 18 value: 1495
   5: channel: 16 value: 936
   6: channel: 17 value: 1356
   ```
   
   Also built (no warnings from this file): `nucleo-g431rb:adc`, 
`nucleo-f303re:adc`, `nucleo-f446re:adc`, `b-g474e-dpow1:nsh` and 
`nucleo-g474re:nsh`. Not tested on hardware: F3, and ADC3/ADC4 of the G4.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to