readVcc function using new UNO R4 RA4M1 ADC

Modified readVcc function I am currently using between Uno R3 and R4 boards below. Accuracy / reproducibility of readVcc still seems a bit better for R3 (spot on, within accuracy of ADC) than R4 (10 - 20 mV variation). I only used 9V or USB for the power supply and tested as-is, I did not do extensive testing with variable power supplies etc. to see how everything would perform in a draining-battery scenario for example.

For R3, intVREF, stored in EEPROM location 0, represents the exact value of the 1.1 V bandgap reference (after calibration with DMM).
For R4, intVREF, stored in EEPROM location 0, represents a correction factor of around 1 which is used for the (more or less stable/fixed?) offset of the (unknown) internal reference of the RA4M1 (also after calibration with DMM).

A big thanks to everyone for their valuable input!

long readVcc()
{ // function to read actual supply voltage Vcc (in mV) of Arduino - adapted to also work with new UNO R4
  long result;
  // setting correct bits in ADMUX register to read internal 1.1 V ref against AVcc (based on which AVR chip, e.g. Uno R3: REFS1 = 0, REFS0 = 1, MUX3:0 = 1110),
  // or directly read Vcc if newer Uno R4 (RA4M1 chip)
  #if defined(ARDUINO_ARCH_AVR)  // for AVR boards (such as Arduino Uno R3)
  
    #if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328__) || defined(__AVR_ATmega328P__)  // if e.g. (very) old Arduino, or Nano, or Uno R3 is used
      ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
    #elif defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) // if e.g. Arduino Leonardo, or Mega is used
      ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
    #elif defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) // if using different kinds of ATtiny 
      ADMUX = _BV(MUX5) | _BV(MUX0);
    #elif defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) // if using different kinds of ATtiny
      ADMUX = _BV(MUX3) | _BV(MUX2);
    #else
      result = 0;                         // return result Vcc of 0 if chip is not supported by this function
      return result;
    #endif  

      delay(2);                           // Wait 2 ms for Vref to settle after change
      ADCSRA |= _BV(ADSC);                // Write ADSC bit to 1 in "ADC Control and Status Register A" for starting single ADC conversion

      while (bit_is_set(ADCSRA, ADSC));   // when ADC conversion is over, ADSC bit will go back to 0
      // ADC generates 10-bit result (containing measurement of 1.1V int. ref.) in ADC data registers: ADCH (high) and ADCL (low)
      result = ADCL;                      // if result is left adjusted & requires <=8-bit precision, ADCH is sufficient, otherwise: ADCL read first (important!), then ADCH
      result |= ADCH << 8;                // ADCL, then ADCH (to ensure registers hold data of same conversion), 8-place bit shift to left: obtain full-precision 10 bit result
      result = intVREFbin / result;       // Calculate Vcc (in mV); intVREFbin = ~1100 mV * 1024
      return result;                      // long result (Vcc in mV) is returned as a result of readVcc function as soon as conversion is over (ADSC = 0 again)
  
  #elif defined(ARDUINO_ARCH_RENESAS)     // for RA4M1 boards (such as Arduino Uno R4)
    float Vcc = analogReference();        // analogReference() reads Vcc, based on internal reference, and returns value as a float
    result = Vcc * intVREF * 1000;        //  intVREF * 1000;   // result is corrected for incorrect internal reference (fixed factor) and converted to mV
    return result;                        // long result (Vcc in mV) is returned as a result of readVccUnoR4 function
  
  #else
      result = 0;                         // return result Vcc of 0 if chip is not supported by this function
      return result;

  #endif
}