ADC support on NUCLEO_H743ZI

The official pyboard running MicroPython.
This is the reference design and main target board for MicroPython.
You can buy one at the store.
Target audience: Users with a pyboard.
Post Reply
Travnicek
Posts: 1
Joined: Fri Nov 02, 2018 6:17 am

ADC support on NUCLEO_H743ZI

Post by Travnicek » Fri Nov 02, 2018 6:32 am

I have tried to read adc, but this error is returned: "ValueError: pin A0 does not have ADC capabilities"
I have found missing configuration for ADC in stm32h743_af.csv. Is there some issue related to ADC for NUCLEO_H743ZI or ADC configuration just missing in stm32h743_af.csv?

Dllanes
Posts: 4
Joined: Tue Apr 09, 2019 12:31 pm

Re: ADC support on NUCLEO_H743ZI

Post by Dllanes » Tue Apr 09, 2019 2:32 pm

Hi,
did you find how to fix this issue?
I am having the same problem
Thanks

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: ADC support on NUCLEO_H743ZI

Post by dhylands » Tue Apr 09, 2019 10:16 pm

Were you trying to use the board pin labelled A0?
Or the CPU pin A0?

Can you post the actual code that used?

And what missing configuration did you find?

I took a look at the pins.csv file for the NUCLEO_H743ZI and it seems to have errors.
https://github.com/micropython/micropyt ... I/pins.csv

It shows that board pin A0 connects to CPU pin A0, but according the user manual for the NUCLEO_H743ZI says that board pin A0 connects to cpu pin A3.
See: https://www.st.com/resource/en/user_man ... 499160.pdf on page 40.

Dllanes
Posts: 4
Joined: Tue Apr 09, 2019 12:31 pm

Re: ADC support on NUCLEO_H743ZI

Post by Dllanes » Wed Apr 10, 2019 10:43 am

Hi,

thank you for answering.
In fact, I have done the same test in several nucleo boards as the F746ZG with the same results.
I performed the test also with the F767ZI board and only the channels A0,A1,A2, A6 and A7 are working properly. The other ones give out the following error "ValueError: pin XY does not have ADC capabilities".

There are several pins in my design that seem not to be defined in micropython, is there a way to declare these pins to be used?which file should be modified?

I have been using the board pin nomenclature but I also tried with CPU names with same results.
Below can you see, how it is tested.

Code: Select all

from pyb import Pin, ADC
gpio_adc="A0"
adc=pyb.ADC(PIN(gpio_adc))

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: ADC support on NUCLEO_H743ZI

Post by dhylands » Wed Apr 10, 2019 2:28 pm

The way that pins are setup on the STM32 ports is as follows:
1 - In the ports/stm32/boards directory you'll see files which end in _af.csv. The one for the STM32F767 is stm32f767_af.csv This file contains all of the pins that the MCU (STM32F767 in this example) can have, along with all of the alternate functions, and which ADC inputs are tied to which pins.
2 - In the each board directory, you'll see a file called pins.csv which contains a mapping of board pins to MCU pins. This describes the pins which a particular board uses, and will be some subset of the MCU pins. The first field is the board pin name, and the second column is the CPU pin name. These 2 columns will wind up determining what shows up in pyb.Pin.board and pyb.Pin.cpu.

Lets look at board pin A0. In pins.csv it maps to CPU pin PA3, and if we then look in stm32f767_af.csv, for the row containing PA3 (line 6) if scroll way over to the rightmost column (which is the ADC column) we see: ADC123_IN3 which tells us that PA3 is available on ADC1, ADC2, and ADC3 and its on input channel 3.

Now lets look at pin A3 (one of the pins that doesn't work). The pins.csv file says it maps to PF3, and this agrees with the NUCLEO_F767ZI manual. Looking in the stm32f767_af.csv file, the ADC column for PF3 is blank, which is why micropython is reporting that ADC functionality is not supported on that pin. Now let's go check the datasheet: https://www.st.com/resource/en/datashee ... f767zi.pdf Page 67 shows us that PF3 connects to ADC3_IN9

So this tells me that A3 should be available on ADC3 input channel 9, which wasn't recorded in the stm32f767_af.csv file.

However, currently MicroPython only supports a single ADC unit, and on the STM32F767 that would be ADC1. So 2 things need to happen before PF3 can support ADC.
1 - stm32f767_af.csv needs to be corrected
2 - ports/stm32/adc.c needs to be modified to support multiple ADCs.

Dllanes
Posts: 4
Joined: Tue Apr 09, 2019 12:31 pm

Re: ADC support on NUCLEO_H743ZI

Post by Dllanes » Thu Apr 11, 2019 6:56 am

Hi Dave,

Thanks for your response :) .
dhylands wrote:
Wed Apr 10, 2019 2:28 pm
2 - In the each board directory, you'll see a file called pins.csv which contains a mapping of board pins to MCU pins. This describes the pins which a particular board uses, and will be some subset of the MCU pins. The first field is the board pin name, and the second column is the CPU pin name. These 2 columns will wind up determining what shows up in pyb.Pin.board and pyb.Pin.cpu.
Yeah, I added some pins to .csv and now is working, thanks.
dhylands wrote:
Wed Apr 10, 2019 2:28 pm
Now lets look at pin A3 (one of the pins that doesn't work). The pins.csv file says it maps to PF3, and this agrees with the NUCLEO_F767ZI manual. Looking in the stm32f767_af.csv file, the ADC column for PF3 is blank, which is why micropython is reporting that ADC functionality is not supported on that pin.
I am using 8 April 2019 master commit 74ed06828f4f8d4ec5c04f5b551e90f2fccbd0f3 and in file stm32f767_af.csv the ADC column isn't blank.
Image
dhylands wrote:
Wed Apr 10, 2019 2:28 pm
However, currently MicroPython only supports a single ADC unit, and on the STM32F767 that would be ADC1. So 2 things need to happen before PF3 can support ADC.
1 - stm32f767_af.csv needs to be corrected
2 - ports/stm32/adc.c needs to be modified to support multiple ADCs.
This is not a big issue because I have found this code (https://github.com/micropython/micropython/issues/1681) and it seems to work.

Code: Select all

  from micropython import const
    import stm

    _RCC_APB2ENR_ADC1EN_Pos = const(8)
    _ADC_CR2_ADON_Pos = const(0)
    _ADC_CR2_SWSTART_Pos = const(30)
    _ADC_SR_EOC_Pos = const(1)

    class ADC:
        def __init__(self, adc_block):
            self.adc_block = adc_block
            self.adc = {1: stm.ADC1, 2: stm.ADC2, 3: stm.ADC3}[adc_block]

        def init(self):
            # turn on CLK
            stm.mem32[stm.RCC + stm.RCC_APB2ENR] |= 1 << (_RCC_APB2ENR_ADC1EN_Pos + self.adc_block - 1)

            # reset ADC state
            stm.mem32[self.adc + stm.ADC_CR1] = 0
            stm.mem32[self.adc + stm.ADC_CR2] = 0

            # turn on ADC
            stm.mem32[self.adc + stm.ADC_CR2] |= 1 << _ADC_CR2_ADON_Pos

        def deinit(self):
            # turn off ADC
            stm.mem32[self.adc + stm.ADC_CR2] = 0

            # turn off CLK
            stm.mem32[stm.RCC + stm.RCC_APB2ENR] &= ~(1 << (_RCC_APB2ENR_ADC1EN_Pos + self.adc_block - 1))

        def read_channel(self, channel, sample_time=1):
            # select channel
            stm.mem32[self.adc + stm.ADC_SQR1] = 0
            stm.mem32[self.adc + stm.ADC_SQR2] = 0
            stm.mem32[self.adc + stm.ADC_SQR3] = channel

            # select sample time
            if channel <= 9:
                ch_pos = 3 * channel
                reg = stm.ADC_SMPR2
            else:
                ch_pos = 3 * (channel - 10)
                reg = stm.ADC_SMPR1
            reg += self.adc
            stm.mem32[reg] = (stm.mem32[reg] & ~(7 << ch_pos)) | sample_time << ch_pos

            # start conversion
            stm.mem32[self.adc + stm.ADC_CR2] |= 1 << _ADC_CR2_SWSTART_Pos

            # wait for end of conversion
            while not stm.mem32[self.adc + stm.ADC_SR] & (1 << _ADC_SR_EOC_Pos):
                pass

            # read and return value
            return stm.mem32[self.adc + stm.ADC_DR]

Post Reply