Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use OTP Feature flag to change ADC reference source #2597

Merged
merged 3 commits into from Dec 2, 2022

Conversation

scott-brust
Copy link
Member

Problem

There are potentially many different platforms that may end up using the richtek DCDC part with the excessive ripple voltage. For already shipped BRN404X platforms, the HW_VERSION OTP field can be used to identify them. For other SKUs, we need a different method.

Solution

The HW Feature Flags bytes of HW INFO in OTP have bits available. However, the tracker platform uses all but one of these bits. We will use the last OTP feature flag bit to denote the presence of the RIchtek part, and thus the need to switch to the internal ADC reference voltage.

Steps to Test

  1. Clear the OTP bit
  2. Reboot, and the ADC should use the internal reference

Example App

#define PARTICLE_USE_UNSTABLE_API
#include "storage_hal.h"

void burnOTP(){
    const uintptr_t HW_DATA_OTP_ADDRESS = 0x00000022;

    uint8_t hwFeatures[] = {0x00, 0x00};
    int r = hal_storage_read(HAL_STORAGE_ID_OTP, HW_DATA_OTP_ADDRESS, hwFeatures, 2);
    Log.info("Read result: %d / %x %x", r, hwFeatures[0], hwFeatures[1]);

    // Clear bit 15 of the HW Feature Flags bytes
    hwFeatures[1] &= 0x7F;
    r = hal_storage_write(HAL_STORAGE_ID_OTP, HW_DATA_OTP_ADDRESS, hwFeatures, 2);
    Log.info("Write result: %d", r);

    r = hal_storage_read(HAL_STORAGE_ID_OTP, HW_DATA_OTP_ADDRESS, hwFeatures, 2);
    Log.info("Read result after writing: %d / %x %x", r, hwFeatures[0], hwFeatures[1]);
}

void setup()
{
    // Init the ADC HAL to force reading of the OTP bits
    hal_adc_read(D0);
}

void loop()
{
    if (!Serial.available()) {
        return;
    }

    auto ch {Serial.read()};

    switch (ch) {
    case '1':
        burnOTP();
        break;
    default:
        Serial.printf("Invalid selection\r\n");
        break;
    }

    hal_device_hw_info hwInfo = {};
    hal_get_device_hw_info(&hwInfo, nullptr);
    Log.info("Feature Bits: %08x Top byte %02x Low Byte %02x", 
        hwInfo.features, 
        (hwInfo.features & 0x0000FF00) >> 8,
        hwInfo.features & 0x000000FF);
}

Burning the bit should show this

0000017308 [app] INFO: Feature Bits: 0000ebfe Top byte eb Low Byte fe
0000017308 [app] INFO: Read result: 2 / fe eb
0000017309 [app] INFO: Write result: 2
0000017309 [app] INFO: Read result after writing: 2 / fe 6b
0000022312 [app] INFO: Feature Bits: 00006bfe Top byte 6b Low Byte fe

After reboot, the ADC source will be internal.


Completeness

  • User is totes amazing for contributing!
  • Contributor has signed CLA (Info here)
  • Problem and Solution clearly stated
  • Run unit/integration/application tests on device
  • Added documentation
  • Added to CHANGELOG.md after merging (add links to docs and issues)

hal/src/nRF52840/adc_hal.cpp Show resolved Hide resolved
@@ -38,6 +38,7 @@ static const nrfx_saadc_config_t saadcConfig = {

static hal_adc_reference_t adcReference = HAL_ADC_REFERENCE_EXTERNAL;
static constexpr uint32_t HAL_VERSION_BRN404X_V003 = 0x03;
static constexpr uint32_t HW_FEATURE_FLAG_USE_INTERNAL_ADC_REFERENCE_BIT = (1<<15);
Copy link
Member

@avtolstoy avtolstoy Dec 1, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Double check endianness. Not saying this is incorrect, but a good idea to confirm it's actually bit 16 in how hal_get_device_hw_info() parses stuff and how things are provisioned.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hal_get_device_hw_info() Puts the bytes in the right spots, I can examine adcReference with debugger after HAL init and can see its detecting the cleared bit in the right spot:

(gdb) p adcReference
$1 = HAL_ADC_REFERENCE_INTERNAL

@scott-brust scott-brust marked this pull request as ready for review December 1, 2022 22:29
@scott-brust scott-brust merged commit 1a5ce55 into develop Dec 2, 2022
@scott-brust scott-brust deleted the fix/adc-reference-bit branch December 2, 2022 17:12
scott-brust added a commit that referenced this pull request Dec 13, 2022
Use OTP Feature flag to change ADC reference source
@scott-brust scott-brust mentioned this pull request Dec 13, 2022
@scott-brust scott-brust added this to the 5.2.0 milestone Dec 16, 2022
@scott-brust scott-brust added the 4.x label Feb 3, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants