Hello,
I'm working with the BL706 and trying to figure out the optimal ADC settings.
I have the settings setup for 3.2V as the VRef and the PGA set to "None".

I'm finding that measuring 3.2V is reading around 42000 rather than the expected 65535.
This is leaving around 35% of the reading range unusable.
Is there a reccomended set of settings to use to be able to use the full resolution when using the 3.2V VRef? Using the 2.0V VRef works fine.

I have tested on 4 different chips and results are repeatable across devices.

I'm using GPIO_PIN_19/ADC_CHAN9, with the ADC in scan mode scanning a set of three pins.

This is the settings that I'm using for setting up the ADC:


  adc_cfg.clkDiv         = ADC_CLK_DIV_4;
  adc_cfg.vref           = ADC_VREF_3P2V;
  adc_cfg.resWidth       = ADC_DATA_WIDTH_16_WITH_128_AVERAGE;
  adc_cfg.inputMode      = ADC_INPUT_SINGLE_END;
  adc_cfg.v18Sel         = ADC_V18_SEL_1P72V;
  adc_cfg.v11Sel         = ADC_V11_SEL_1P1V;
  adc_cfg.gain1          = ADC_PGA_GAIN_NONE;
  adc_cfg.gain2          = ADC_PGA_GAIN_NONE;
  adc_cfg.chopMode       = ADC_CHOP_MOD_ALL_OFF;
  adc_cfg.biasSel        = ADC_BIAS_SEL_MAIN_BANDGAP;
  adc_cfg.vcm            = ADC_PGA_VCM_1P6V;
  adc_cfg.offsetCalibEn  = ENABLE;
  adc_cfg.offsetCalibVal = 0;

And then reading the values from the FiFo via interrupts.

Edit:
Should note that I'm using the mcu sdk; from commit 8742503a9e9aaa36462767b300f3c22b2935cc5e.
I'm not using the hal layer as the vfs indirection adds too much overhead, so I'm working with the drivers directly.

    Hello, please show your whole codes about adc init and read , you can send your code to my email: jzlv@bouffalolab.com,thank you!

      I have sent you an email, but for reference for anyone else following along, this is the code that was sent.

      
      
      ///////////// This is the setup code
      
      const ADC_Chan_Type adc_tip_pos_chans[] = {ADC_CHAN8, ADC_CHAN9,  ADC_CHAN9,
                                                 ADC_CHAN9, ADC_CHAN9,  ADC_CHAN10,
                                                 ADC_CHAN8, ADC_CHAN10, ADC_CHAN8};
      const ADC_Chan_Type adc_tip_neg_chans[] = {
          ADC_CHAN_GND, ADC_CHAN_GND, ADC_CHAN_GND, ADC_CHAN_GND, ADC_CHAN_GND,
          ADC_CHAN_GND, ADC_CHAN_GND, ADC_CHAN_GND, ADC_CHAN_GND};
      static_assert(sizeof(adc_tip_pos_chans) == sizeof(adc_tip_neg_chans));
      
      void setup_adc(void) {
        //
        ADC_CFG_Type adc_cfg = {};
        ADC_FIFO_Cfg_Type adc_fifo_cfg = {};
      
        CPU_Interrupt_Disable(GPADC_DMA_IRQn);
      
        ADC_IntMask(ADC_INT_ALL, MASK);
      
        adc_cfg.clkDiv = ADC_CLK_DIV_4;
        adc_cfg.vref = ADC_VREF_3P2V;
        adc_cfg.resWidth = ADC_DATA_WIDTH_16_WITH_128_AVERAGE;
        adc_cfg.inputMode = ADC_INPUT_SINGLE_END;
        adc_cfg.v18Sel = ADC_V18_SEL_1P72V;
        adc_cfg.v11Sel = ADC_V11_SEL_1P1V;
        adc_cfg.gain1 = ADC_PGA_GAIN_NONE;
        adc_cfg.gain2 = ADC_PGA_GAIN_NONE;
        adc_cfg.chopMode = ADC_CHOP_MOD_ALL_OFF;
        adc_cfg.biasSel = ADC_BIAS_SEL_MAIN_BANDGAP;
        adc_cfg.vcm = ADC_PGA_VCM_1P6V;
        adc_cfg.offsetCalibEn = ENABLE;
        adc_cfg.offsetCalibVal = 0;
      
        ADC_Disable();
        ADC_Enable();
        ADC_Reset();
      
        ADC_Init(&adc_cfg);
        adc_fifo_cfg.dmaEn = DISABLE;
        adc_fifo_cfg.fifoThreshold = ADC_FIFO_THRESHOLD_4;
        ADC_FIFO_Cfg(&adc_fifo_cfg);
        ADC_MIC_Bias_Disable();
        ADC_Tsen_Disable();
      
        // Enable FiFo IRQ
        Interrupt_Handler_Register(GPADC_DMA_IRQn, adc_fifo_irq);
        ADC_IntMask(ADC_INT_FIFO_READY, UNMASK);
        CPU_Interrupt_Enable(GPADC_DMA_IRQn);
        ADC_Stop();
        ADC_FIFO_Clear();
        ADC_Scan_Channel_Config(adc_tip_pos_chans, adc_tip_neg_chans,
                                sizeof(adc_tip_pos_chans) / sizeof(ADC_Chan_Type),
                                DISABLE);
      }
      
      void adc_fifo_irq(void) {
      
        if (ADC_GetIntStatus(ADC_INT_FIFO_READY) == SET) {
          // Read out all entries in the fifo
          while (ADC_Get_FIFO_Count()) {
            volatile uint32_t reading = ADC_Read_FIFO();
            // As per manual, 26 bit reading; lowest 16 are the ADC
            uint16_t sample = reading & 0xFFFF;
            uint8_t source = (reading >> 21) & 0b11111;
            switch (source) {
            case ADC_CHAN10:
              printf("ADC ADC_CHAN10 %d\n", (int)sample);
              break;
            case ADC_CHAN9:
              printf("ADC ADC_CHAN9 %d\n", (int)sample);
              break;
            case ADC_CHAN8:
              printf("ADC ADC_CHAN8 %d\n", (int)sample);
              break;
      
            default:
              break;
            }
          }
        }
        // Clear IRQ
        ADC_IntClr(ADC_INT_ALL);
      }
        Write a Reply...
        @ 2025 Bouffalo Lab (Nanjing) Co., Ltd. All rights reserved.