PortentaH7 PINOUT

Hello,
I have been trying for a week to have ADC1_Inp1 to work on pin PA0_C. It should work according to this :
Capture
I used the following code :

#include <Arduino.h>
#define HWREG(x)    (*((volatile uint32_t *)(x)))

// put your setup code here, to run once:
void GPIOH_Init();
void GPIOH_Port15_Toggle();
//void SystemClock_Config();
void SystemCLCKInit();
//void SysPinConfig(); //For future tests of ADC with EXTI1 IT (put the pin setup PA0 PA0_C here as well)
void ADC_start();
void ADC_Init();
//void VREFBUF_Init();
//void ADC_Reset();
uint32_t dataFromADC = 0;
int dataFromRegister = 0;
int nbSamples = 0;
void setup() {
  Serial.begin(115200);
  SystemCLCKInit();
  // put your setup code here, to run once:
  //SystemClock_Config();
  GPIOH_Init();
  digitalWrite(LEDR, LOW);
  delay(1000);
  VREFBUF_Init();
  digitalWrite(LEDR, HIGH);
  digitalWrite(LEDB, LOW);
  delay(1000);
  ADC_Init();
  //analogReference(EXTERNAL);
  digitalWrite(LEDB, HIGH);
  digitalWrite(LEDG, LOW);
  delay(1000);
  ADC_Start();
  digitalWrite(LEDG, HIGH);
  digitalWrite(LEDB, LOW);
}

void loop() {
  // put your main code here, to run repeatedly:
  while(ADC_ISR_EOC & ADC_ISR_EOC_Msk!=1){//check end of conversion
//    dataFromRegister=READ_REG(ADC1->ISR);
//    Serial.print("Flag :");
//    Serial.println(dataFromRegister,BIN);
    //delay(100);
  }dataFromADC = READ_REG(ADC1->DR);
  Serial.print("ADC_DR:");
  Serial.println(dataFromADC);
  GPIOH_Port15_Toggle();
}
void VREFBUF_Init(void) {
  SET_BIT(RCC->APB4ENR,RCC_APB4ENR_VREFEN_Msk);
  //RCC_APB4ENR_VREFEN;
  //RCC->APB4ENR|=(1<<RCC_APB4ENR_VREFEN_Msk);
  delay(1000);
  dataFromRegister=READ_REG(RCC->APB4ENR);
  Serial.print("CLCK : ");
  Serial.println(dataFromRegister,BIN);
  delay(1000);
  SET_BIT(VREFBUF->CSR,VREFBUF_CSR_ENVR_Msk);
  CLEAR_BIT(VREFBUF->CSR,VREFBUF_CSR_HIZ_Msk);
  while(VREFBUF_CSR_VRR & VREFBUF_CSR_VRR_Msk !=1){
    dataFromRegister=READ_REG(VREFBUF->CSR);
    Serial.println(dataFromRegister,BIN);
    }
}
void ADC_Init(void) {
  /***************CLOCK and PIN config******************/
//  MODIFY_REG(RCC->D3CCIPR,RCC_D3CCIPR_ADCSEL_Msk,0x1L);
//  delay(1000);
//  dataFromRegister=READ_REG(RCC->D3CCIPR);
//  Serial.print("D3CCIPR :");
//  Serial.println(dataFromRegister,BIN);
  
  SET_BIT(RCC->APB4ENR,RCC_APB4ENR_SYSCFGEN_Msk);
  delay(1000);
  dataFromRegister=READ_REG(RCC->APB4ENR);
  Serial.print("RCC_APB4ENR:");
  Serial.println(dataFromRegister,BIN);
  SET_BIT(RCC->APB4ENR,RCC_APB4ENR_RTCAPBEN_Msk);
  delay(1000);
  dataFromRegister=READ_REG(RCC->APB4ENR);
  Serial.print("RCC_APB4ENR1:");
  Serial.println(dataFromRegister,BIN);
  SET_BIT(RCC->AHB1ENR,RCC_AHB1ENR_ADC12EN_Msk);
  delay(1000);
  dataFromRegister=READ_REG(RCC->AHB1ENR);
  Serial.print("RCC_AHB1ENR:");
  Serial.println(dataFromRegister,BIN);
  //GPIOA PORT 1------------------------------------
  SET_BIT(RCC->AHB4ENR,RCC_AHB4ENR_GPIOAEN_Msk);
  delay(1000);
  dataFromRegister=READ_REG(RCC->AHB4ENR);
  Serial.print("RCC_AHB4ENR:");
  Serial.println(dataFromRegister,BIN);
  SET_BIT(GPIOA->MODER, GPIO_MODER_MODE1_0);
  SET_BIT(GPIOA->MODER, GPIO_MODER_MODE1_1);
  CLEAR_BIT(GPIOA->PUPDR, GPIO_PUPDR_PUPD1_0);
  CLEAR_BIT(GPIOA->PUPDR, GPIO_PUPDR_PUPD1_1);
  SET_BIT(SYSCFG->PMCR, SYSCFG_PMCR_PA0SO_Msk);
  delay(1000);
  dataFromRegister=READ_REG(SYSCFG->PMCR);
  Serial.print("SYSCFG->PMCR:");
  Serial.println(dataFromRegister,BIN);
  SET_BIT(RCC->AHB1ENR,RCC_AHB1ENR_ADC12EN_Msk);
  delay(1000);
  dataFromRegister=READ_REG(RCC->AHB1ENR);
  Serial.print("RCC->AHB1ENR2:");
  Serial.println(dataFromRegister,BIN);
  
  /***************ADC not Enabled yet********************/
  //ADC VOLTAGE REGULATOR-----------------------------
  CLEAR_BIT(ADC1->CR,ADC_CR_DEEPPWD_Msk);
  //dataFromRegister=READ_REG(ADC1->CR);
  //Serial.print("ADCR: ");
  //Serial.println(dataFromRegister,BIN);
  //delay(1000);
  SET_BIT(ADC1->CR,ADC_CR_ADVREGEN_Msk);
  delay(1000);
  dataFromRegister=READ_REG(ADC1->CR);
  Serial.print("ADCAL: ");
  Serial.println(dataFromRegister,BIN);
  delay(1000);
//  
  //ADC CALIBRATION-----------------------------------
  CLEAR_BIT(ADC1->CR,ADC_CR_ADCALDIF_Msk);
  SET_BIT(ADC1->CR,ADC_CR_ADCALLIN_Msk);
  SET_BIT(ADC1->CR,ADC_CR_ADCAL_Msk);
  while(ADC_CR_ADCAL & ADC_CR_ADCAL_Msk!=0){
    dataFromRegister=READ_REG(ADC1->CR);
    Serial.print("ADC1_CR: ");
    Serial.println(dataFromRegister,BIN);
    }
  
  //ADC prescaler selection clock and sample time delay
  //MODIFY_REG(ADC12_COMMON->CCR,ADC_CCR_CKMODE | ADC_CCR_PRESC | ADC_CCR_DELAY ,0x3UL | 0x3UL | 0x8UL);
  SET_BIT(ADC12_COMMON->CCR, ADC_CCR_CKMODE_0 | ADC_CCR_CKMODE_1 | ADC_CCR_PRESC_0 | ADC_CCR_PRESC_1 | ADC_CCR_DELAY_3);
//  MODIFY_REG(ADC12_COMMON->CCR,ADC_CCR_PRESC_Msk,0x3UL);
//  MODIFY_REG(ADC12_COMMON->CCR,ADC_CCR_DELAY_Msk,0x8UL);
  dataFromRegister=READ_REG(ADC12_COMMON->CCR);
  Serial.print("ADC_CCR: ");
  Serial.println(dataFromRegister,BIN);
  delay(1000);
  
  //Set input mode------------------------------------
  CLEAR_BIT(ADC1->DIFSEL,ADC_DIFSEL_DIFSEL_1);
  
  /*******************ADC Enable**********************/
  SET_BIT(ADC1->ISR,ADC_ISR_ADRDY_Msk);
  SET_BIT(ADC1->CR,ADC_CR_ADEN_Msk);
  while(ADC_ISR_ADRDY & ADC_ISR_ADRDY_Msk !=1){}
  SET_BIT(ADC1->ISR,ADC_ISR_ADRDY_Msk);
  
  /********************ADC Enabled********************/
  //ADC CFGR------------------------------------------
  SET_BIT(ADC1->CFGR, ADC_CFGR_RES_2 | ADC_CFGR_RES_1 | ADC_CFGR_OVRMOD_Msk | ADC_CFGR_CONT_Msk);
  CLEAR_BIT(ADC1->CFGR, ADC_CFGR_DMNGT_0 | ADC_CFGR_DMNGT_1 | ADC_CFGR_RES_0 | ADC_CFGR_EXTEN_0 | ADC_CFGR_EXTEN_1); 
  
  //DATA ALIGNEMENT-----------------------------------
  // ADC PCSEL----------------------------------------
  SET_BIT(ADC1->PCSEL,ADC_PCSEL_PCSEL_1); 
  //ADC SQR1------------------------------------------
  SET_BIT(ADC1->SQR1,ADC_SQR1_SQ1_0);
  //ADC SMPR1-----------------------------------------
  SET_BIT(ADC1->SMPR1,ADC_SMPR1_SMP1_0 | ADC_SMPR1_SMP1_1);
}
void ADC_Start(void) {
  SET_BIT(ADC1->CR,ADC_CR_ADSTART_Msk);
}
void GPIOH_Init(void) {
  SET_BIT(RCC->AHB4ENR,RCC_AHB4ENR_GPIOHEN_Msk);
  delay(1000);
  SET_BIT(GPIOH->MODER, GPIO_MODER_MODE15_0);
  CLEAR_BIT(GPIOH->MODER, GPIO_MODER_MODE15_1);
  CLEAR_BIT(GPIOH->OTYPER, GPIO_OTYPER_OT15);
}
void GPIOH_Port15_Toggle(void) {
  
  SET_BIT(GPIOH->BSRR, GPIO_BSRR_BS15);
  CLEAR_BIT(GPIOH->BSRR, GPIO_BSRR_BS15);
  SET_BIT(GPIOH->BSRR, GPIO_BSRR_BR15);
  CLEAR_BIT(GPIOH->BSRR, GPIO_BSRR_BR15);
}
void SystemCLCKInit(void) {

    /* Enable the floating-point unit. Any configuration of the
    floating-point unit must be done here prior to it being enabled */
    HWREG(0xE000ED88) = ((HWREG(0xE000ED88) & ~0x00F00000) | 0x00F00000);

    /*------- Reset the RCC clock configuration to the default reset state -------*/
    /* Set HSION bit */
    RCC->CR |= 0x00000001;
    dataFromRegister=READ_REG(RCC->CR);
    Serial.print("CR: ");
    Serial.println(dataFromRegister,BIN);
    delay(1000);
    /* Reset CFGR register */
    RCC->CFGR = 0x00000000;
    dataFromRegister=READ_REG(RCC->CFGR);
    Serial.print("RCC->CFGR: ");
    Serial.println(dataFromRegister,BIN);
    delay(1000);
    /* Reset HSEON, CSSON , CSION,RC48ON, CSIKERON PLL1ON, PLL2ON and PLL3ON bits */
    RCC->CR &= (uint32_t)0xEAF6ED7F;
    dataFromRegister=READ_REG(RCC->CR);
    Serial.print("RCC->CR: ");
    Serial.println(dataFromRegister,BIN);
    delay(1000);
    /* Reset D1CFGR register */
    RCC->D1CFGR = 0x00000000;
    dataFromRegister=READ_REG(RCC->D1CFGR);
    Serial.print("RCC->D1CFGR: ");
    Serial.println(dataFromRegister,BIN);
    delay(1000);
    /* Reset D2CFGR register */
    RCC->D2CFGR = 0x00000000;
    dataFromRegister=READ_REG(RCC->D2CFGR);
    Serial.print("RCC->D2CFGR: ");
    Serial.println(dataFromRegister,BIN);
    delay(1000);
    /* Reset D3CFGR register */
    RCC->D3CFGR = 0x00000000;
    dataFromRegister=READ_REG(RCC->D3CFGR);
    Serial.print("RCC->D3CFGR: ");
    Serial.println(dataFromRegister,BIN);
    delay(1000);
    /* Reset PLLCKSELR register */
    RCC->PLLCKSELR = 0x00000000;
    dataFromRegister=READ_REG(RCC->PLLCKSELR);
    Serial.print("RCC->PLLCKSELR: ");
    Serial.println(dataFromRegister,BIN);
    delay(1000);
    /* Reset PLLCFGR register */
    RCC->PLLCFGR = 0x00000000;
    dataFromRegister=READ_REG(RCC->PLLCFGR);
    Serial.print("RCC->PLLCFGR: ");
    Serial.println(dataFromRegister,BIN);
    delay(1000);
    /* Reset PLL1DIVR register */
    RCC->PLL1DIVR = 0x00000000;
    dataFromRegister=READ_REG(RCC->PLL1DIVR);
    Serial.print("RCC->PLL1DIVR: ");
    Serial.println(dataFromRegister,BIN);
    delay(1000);
    /* Reset PLL1FRACR register */
    RCC->PLL1FRACR = 0x00000000;
    dataFromRegister=READ_REG(RCC->PLL1FRACR);
    Serial.print("RCC->PLL1FRACR: ");
    Serial.println(dataFromRegister,BIN);
    delay(1000);
    /* Reset PLL2DIVR register */
    RCC->PLL2DIVR = 0x00000000;
    dataFromRegister=READ_REG(RCC->PLL2DIVR);
    Serial.print("RCC->PLL2DIVR: ");
    Serial.println(dataFromRegister,BIN);
    delay(1000);
    /* Reset PLL2FRACR register */
    RCC->PLL2FRACR = 0x00000000;
    dataFromRegister=READ_REG(RCC->PLL2FRACR);
    Serial.print("RCC->PLL2FRACR: ");
    Serial.println(dataFromRegister,BIN);
    delay(1000);
    /* Reset PLL3DIVR register */
    RCC->PLL3DIVR = 0x00000000;
    dataFromRegister=READ_REG(RCC->PLL3DIVR);
    Serial.print("RCC->PLL3DIVR: ");
    Serial.println(dataFromRegister,BIN);
    delay(1000);
    /* Reset PLL3FRACR register */
    RCC->PLL3FRACR = 0x00000000;
    dataFromRegister=READ_REG(RCC->PLL3FRACR);
    Serial.print("RCC->PLL3FRACR: ");
    Serial.println(dataFromRegister,BIN);
    delay(1000);
    /* Reset HSEBYP bit */
    RCC->CR &= (uint32_t)0xFFFBFFFF;
    dataFromRegister=READ_REG(RCC->CR);
    Serial.print("RCC->CR: ");
    Serial.println(dataFromRegister,BIN);
    delay(1000);
    /* Disable all interrupts */
    RCC->CIER = 0x00000000;
    dataFromRegister=READ_REG(RCC->CIER);
    Serial.print("RCC->CIER : ");
    Serial.println(dataFromRegister,BIN);
    delay(1000);
    /* Change the switch matrix read issuing capability to 1 for the AXI SRAM target (Target 7) */
    HWREG(0x51008108) = 0x000000001;
}

(It is entirely programed with CMSIS definitions and following the RM0399 reference manual from STM). Weirdly enough this code works pretty well with ADC2_INP0, when used on ADC1_INP1 the ADC_DR (Data Register) will keep having a (2^RES-1) value, my investigations lead me to this part of the Arduino-core-Mbed library :
variants
So does it mean the Pin map from Arduino is false or did I miss something important??
PS : I don't really need the answer since it works fine with ADC2 but that still bothers me... Also don't mind the Serial it's for debugging purposes

I'm in the same boat, I'm trying to figure out how the pinNames lineup to the arduino docs, I've dug through all the code, the schematic, etc. I just want to know what pin names line up so I can start writing some code. Here's where I'm stuck.

#include <Arduino.h>
#include <mbed.h>

#include <Arduino_PortentaBreakout.h>

mbed::CAN can1(CAN0_RX, CAN0_TX);

CAN0_RX is type breakoutPIn, and mbed required pinName, like PH_8. The arduino pinout shows the pin names for the ones on the board, but not the ones in the high density connectors. So it just says 49 and 51 pins on one of the connectors. OK, but what does that map to? grrrr

My five cents:
When it comes to pin names used, e.g. your CAN0_RX, these are always the pin number of the MCU chip itself, e.g. PH_8 (the name of the port, not really the physical pin number).

In any BSP, HAL, IDE you would never use a breakout board pin numbering, e.g. on a header in breakout board, e.g. mentioned on silk screen as SCL1.
This does not matter (for the FW): only which physical port pin is it directly on MCU chip.

For the routing - Where is this PH_8 going to? On which header pin will it appear ...? It so different from breakout board to another (and not really logical, e.g. J2, pin X is not the same as PB1 on MCU).

You have to study the schematics of your breakout board: which PH_X pin goes to where? But use in SW/FW only the MCU port names (PH_X) - no idea for FW how it is called and where it is on schematics. It would your FW also very dependent on the breakout board schematics.

You had to know the schematics of your board (PH_8 comes out as JX, pin Y). And use still PH_8 to configure and drive the signal.

Yes, painful (esp. when documentation is lacking). But the manual should give you already a very clue:
Portenta H7 PinOut

There there that the Port numbers are given.
For the breakout board, e.g. what is "CAN1 TX" - you had to check the routing of the signal.

BTW:
A good starting point is also to use the datasheet:
They give you the "Pin Muxing" there. It tells you which pin can have which function (via this ALT). There are just few pins possible from MCU for this function. It might make the tracing for schematics easier if you know it can be only PX_Y used as CAN1 TX.

Suggestion:
If you are not really sure where this MCU pin comes out, e.g. on a breakout board, you can do this:

  • configure this pin as GPIO PX_Y (not for the intended function, e.g. not as CAN1 TX), as an GPIO output

  • have a command (best via UART terminal) to toggle this GPIO pin (set it to 0 or 1)

  • try to find where this bit comes out: if you see it on a header - you would know: "seems to be PX_Y")

Now you know: "PX_Y is on header JX, pin Y. And now I can change it to CAN1 TX ALT function". And this CAN1 TX should still come out as the GPIO before (still the same pin on MCU).

2 Likes

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