Board Hardware Revision using one ADC pin (REV1️⃣, REV2️⃣, REV3️⃣)

Summary

When you design a board mostly you have several iterations, when you fix bugs and make improvements 😄

Image

But if board has programming side you might want to have only one firmware for all released boards (especially if it's not just engineering samples, but already 

Electrical Schematic

Image

As you can see it's just a voltage divider, that can be connected to the same power rail voltage, as you MCU (e.g. 3.3V).

The required voltage could be easily obtained using standard E24 5% resistors.

Tip: For battery powered-device connect it to the switchable bus (load switch or LDO with EN pin) to turn off during low power mode and enabling only when do revision reading)

For this purposes you can use this simplest high-side load switch: https://refcircuit.com/articles/842-high-side-p-channel-load-switch-on-discrete-components.html

ImageImage

Simulation

Using Microcap 12 (really powerful schematic simulator) you can see how different resistor values affect on output voltage, that represent board revision.

REV5, ADC=1016

REV8, ADC=1737

REV14, ADC=3325

ImageImageImage

Board

If you use two 0603/0402 resistors doesn't take up much space (approximately 1.89 mm x 1.86 mm with using 0402 (1005 metric) resistors):

Image

Code implementation (C language)

  1. #include <stdio.h>
  2. #include <stdint.h>
  3.  
  4. /* HW Revision configuration BEGIN */
  5. #define HW_REV_NUM 16
  6. #define HW_REV_ADC_MAX 4095 /* 12-bit ADC ((2^12)-1) */
  7. #define HW_REV_STEP (HW_REV_ADC_MAX/HW_REV_NUM)
  8. /* HW Revision configuration END */
  9.  
  10. int round_number(double n);
  11. uint8_t getHwRev (uint16_t adc_val);
  12.  
  13. int main ()
  14. {
  15. /* Enter value 0-4095 */
  16. uint8_t hwrev = getHwRev (4000);
  17. printf("BOARD REVISION: %d\n", hwrev);
  18. /*
  19. e.g. in case of 12-bit ADC:
  20. REV1 - 0; REV2 - 256; REV3 - 512; REV4 - 768
  21. REV5 - 1024; REV6 - 1280; REV7 - 1536 ;REV8 - 1792
  22. REV9 - 2048; REV10 - 2304; REV11 - 2560; REV12 - 2816
  23. REV13 - 3072; REV14 - 3328; REV15 - 3584; REV16 - 3840; REV17 - 4095
  24. */
  25. }
  26. /**
  27.   * @brief Identify board revision using ADC value
  28.   * @note Should be configurated using defines
  29.   * @retval 1-255; 0 - error
  30.   */
  31. uint8_t getHwRev (uint16_t adc_val)
  32. {
  33. uint8_t hw_rev = 0;
  34.  
  35. hw_rev = round_number((adc_val/256.0)) + 1;
  36.  
  37. return hw_rev;
  38. }
  39.  
  40. int round_number(double n){
  41. int trunc = (int) n;
  42. double diff = n - (double) trunc;
  43. if(diff < 0.5){
  44. return trunc;
  45. } else {
  46. return trunc+1;
  47. }
  48. }
  49.  
  50.  

Code implementation (C++ language)

  1. #include <iostream>
  2.  
  3. /* HW Revision configuration BEGIN */
  4. #define HW_REV_NUM 16
  5. #define HW_REV_ADC_MAX 4095 /* 12-bit ADC ((2^12)-1) */
  6. #define HW_REV_STEP (HW_REV_ADC_MAX/HW_REV_NUM)
  7. /* HW Revision configuration END */
  8.  
  9. using namespace std;
  10.  
  11. int round_number(double n);
  12. uint8_t getHwRev (uint16_t adc_val);
  13.  
  14. int main ()
  15. {
  16. /* Enter value 0-4095 */
  17. uint8_t hwrev = getHwRev (4000);
  18. printf("BOARD REVISION: %d\n", hwrev);
  19. /*
  20. e.g. in case of 12-bit ADC:
  21. REV1 - 0; REV2 - 256; REV3 - 512; REV4 - 768
  22. REV5 - 1024; REV6 - 1280; REV7 - 1536 ;REV8 - 1792
  23. REV9 - 2048; REV10 - 2304; REV11 - 2560; REV12 - 2816
  24. REV13 - 3072; REV14 - 3328; REV15 - 3584; REV16 - 3840; REV17 - 4095
  25. */
  26. }
  27. /**
  28.   * @brief Identify board revision using ADC value
  29.   * @note Should be configurated using defines
  30.   * @retval 1-255; 0 - error
  31.   */
  32. uint8_t getHwRev (uint16_t adc_val)
  33. {
  34. uint8_t hw_rev = 0;
  35.  
  36. hw_rev = round_number((adc_val/256.0)) + 1;
  37.  
  38. return hw_rev;
  39. }
  40.  
  41. int round_number(double n){
  42. int trunc = (int) n;
  43. double diff = n - (double) trunc;
  44. if(diff < 0.5){
  45. return trunc;
  46. } else {
  47. return trunc+1;
  48. }
  49. }
  50.  

The difference between C and C++ only in included libraries.

Tip: load ADC value (0-4095) to getHwRev function and it return revision number.

Code tests

It works good, you can test it with any online code service, even without MCU:

Test 1 (REV5)Test 2 (REV8)Test 3 (REV14)
ImageImageImage

Conclusions

  • Using hardware revision give a chance to clearly and easy identify board version using code, which is could be very useful for the programming.
  • Hardware revision give a chance to maintain different board revisions (releases) using only one firmware
  • Connection resistors divider to the controlled power bus to give a change of turn off it from powering, when device powered from battery

Image

66
No comments yet. Be the first to add a comment!
Cookies?