Use The Internal Vref on Poretnta H7 Lite

I want to use the internal reference voltage on my Portenta H7. The external one provided on the breakout board is very poor (just a high value pullup to +3.1V!) and I would prefer to avoid building a better one since this hardware problem has already been solved. It should be possible to connect the internal reference to the Vref pin on the board just by writing the appropriate value to the register. Eventually I want to drive a potentiometer with this voltage so as to sense the position of the wiper. Of course I would not then connect the Vref pin to any other voltage source, but rather I would use it AS a voltage source.

The problem is I cannot write to the VREFBUF_CSR register. This code has worked with other registers, but not this one. I have tried it on both the M7 and the M4 cores with no luck.

Any idea what I am doing wrong? Many thanks in advance for your time!

BTW is there some existing software someplace to do this? I couldn't find any.

////////////////////////////////////////////////////////////////////////////
// VOLTAGE REFERENCE TEST
////////////////////////////////////////////////////////////////////////////
// 
// This writes to the register at VREFBUF_CSR then reads back from the same
// register. If the read succeeds it flashes the LED slowly, if it fails
// it flashes the LED rapidly. I have tried it on both the M7 core and the
// M4 core with no success. If I can get this to work I eventually want to make Vref 
// available to the ADC and also outside the board.
//

#define VREFBUF_CSR 0x58003C00
unsigned long volatile *p_vrefbuf_csr = (unsigned long volatile *)VREFBUF_CSR;
unsigned long n;

void setup() {
  pinMode(LEDG, OUTPUT); // Set green LED as output
}

void loop() {
  // First, write to and then read back from the register
  *p_vrefbuf_csr = 0x31L; // Write to the VREFBUF_CSR register
  n = *p_vrefbuf_csr;     // Read back from the same register

  // Second, blink the LED to indicate success or failure
  digitalWrite(LEDG, LOW); // Green LED on
  delay(200);
  digitalWrite(LEDG, HIGH); // Green LED off
  // Fast blink if fail, slow blink if succeed
  if(n == 0)
    delay(200); // The readback failed, blink fast
  else
    delay(1000); // The readback may have succeeded (at least it is nonzero), blink slowly
}
1 Like

Hello,
sorry for the late answer I started very recently on portenta and I have come to face the same issues as you with my ADC. Here is the code I use to setup VREFBUF, hope it helps :

void VREFBUF_Init(void){
  
  *RCC_APB4ENR|=(1 << 15);// Enable VREF Peripheral Clock
  *VREFBUF_CSR|=(1<<0);//VREF enable
  *VREFBUF_CSR&=~(1<<1);//VREF+pin connected
  while((*VREFBUF_CSR & (1<<3))==0){// Wait for VREF to reach the voltage setup
      dataFromRegister=*VREFBUF_CSR;//debug
      Serial.println(dataFromRegister,BIN);//debug
    }
}

I declared my registers that way :

//VREFBUF REG-------------------------------------
volatile uint32_t* const VREFBUF_CSR = (uint32_t *) 0x58003C00;
volatile uint32_t* const VREFBUF_CCR = (uint32_t *) 0x58003C04;
//REG RCC-----------------------------------------------
volatile uint32_t* const RCC_APB4ENR = (uint32_t *) 0x580244F4;//to enable sysconf

Note that this is a part of a larger code don't forget the System_Clock_Reset() when you use RCC registers.
Best of luck!
As for your question last time I checked the HAL librairies did not have a function to setup VREFBUF.

I'm new to Arduino and the Portenta H7 (not lite) .

As the 3k1 VREF reference voltage is not stable, I want to use an external AREF. Setting it with analogReference(EXTERNAL) does not work for H7 / H7 lite. Do you have an idea how to set AREF to external mode or any other internal stable voltage for the H7?

Thank you so much for replying!

I have already solved the problem using hardware, I just connected a Vref source (2.048 volts) to the Vref terminal. The H7 is configured by default to accept an external reference voltage. But next time it would be nice to avoid the extra parts.

Marolta - there is a high value pullup resistor between the Vref line and the 3.3V line so as to give some limited functionality (sort of...) to the ADC with the board as delivered. Your Vref source will pull this down to a stable and noise free value without difficulty, it is not necessary to remove the pullup resistor. I get a 10 bit resolution when using the software as supplied, with only a couple of lsb of noise.

May I ask where you found the Vref pin on the H7? When I look at the datasheet (https://www.mouser.com/pdfDocs/Pinout-PortentaH7_latest.pdf) I do not see any connections between any of the PCB pins and the Vref pins from the stm32h747. Also the Aref pin is described as a read only pin (is that where I am wrong? ). That's the main reason as to why I did go for a software solution.

Edit : Nevermind you have the breakout board

Sorry, I meant the Aref terminal on the board itself. Like most pins this can be used either for input or output, and it is programmed as an input by default. If you are paranoid about damaging the board, you can connect a 330 ohm resistor in series. Then, once your software is running, measure the voltage drop across this resistor. If it is less than a few millivolts it is safe to short out the resistor, thereby getting full accuracy from the ADC.

There is some confusion because if you measure the voltage on this pin it is about 3.3 volts, because of the high value pullup resistor on the board. But it is still OK to connect it to a voltage reference source, the reference source will simply sink a small amount of current. All the voltage references that I know of are easily capable of this.

On the Portenta, the VREF pin is here:


And here on the schematic (page 2, C1):

Thanks a lot for the help that saves me from a lot of trouble, I will experiment with that (and VREFBUF which needs a special configuration on the VREF pin which you can find here if you are interested https://www.st.com/resource/en/application_note/an5690-vrefbuf-peripheral-applications-and-trimming-technique-stmicroelectronics.pdf).

EDIT : for future reference I could try my code (above) and it works with the circuit shown in the ref manual (use CMSIS def for an easier code).

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.