OTP whitelabel options for RP2350 boards

P.S. On one of my BP6, there are definitely rows that show a flipped bit.

EDIT: incorrect ... see nextpost

I’m going to have to presume that the ECC bits reported are correct, as I don’t see where the ECC correction algorithm is listed, nor where they document the other two bits’ purpose.

Row 0x010: 2BC9 === 2BC9 === C9 2B [22] (.+)
Row 0x011: 7F51 === 7F51 === 51 7F [09] (Q.)
Row 0x018: 0030 === 0030 === 30 00 [03] (0.)
Row 0x036: 7425 === 7425 === 25 74 [15] (%t)
Row 0x037: 6DE2 === 6DE2 === E2 6D [1C] (.m)
Row 0xF80: 3F37 === 3F37 =?= 3F 3F [3F] (7?)
Row 0xF81: 1505 === 1505 =?= 15 15 [15] (..)
Row 0xF83: 0504 === 0504 =?= 04 04 [04] (..)
Row 0xF85: 0504 === 0504 =?= 04 04 [04] (..)
Row 0xFFD: 0504 === 0504 =?= 04 04 [04] (..)
Row 0xFFF: 1410 === 1410 =?= 14 14 [14] (..)
2 Likes

Figured out why these mismatches occur.


TLDR: Those pages aren't using ECC.

Page 0xF80…0xFFF store the lock bits for the OTP pages 0…63. Since the lock bits must be programmable multiple times (to go from read/write → read-only → no-access), they do not use the harware ECC support. Instead, they are read (and written) in raw form only. Instead, each row stores 3x copies of a single byte. This allows a later programming request to set additional bits, which would be prevented when using ECC codes.

I will have to update the code to show rows 0xF80…0xFFF as 100% OK when they store three identical bytes. Moreover, the ECC-corrected reads do not have valid meaning, so I will update those to be masked from the output.

I also found the SDK code (and adapted it) to verify the ECC from the data read in raw form, and verified its functionality on godbolt.org. Thus, can simplify the code further.

There is still a few edge cases which make it impossible to 100% reliably auto-detect that the data was stored in triplicate vs. stored with ECC. Specifically, there are two values that, when stored as triple-encoded bytes, have valid ECC byte. If allowing for the OTP row to have a single-bit error, then there are an additional sixteen (16) values that, when read from the OTP row with a single-bit error, might be either valid ECC stored values, or a triple-encoded byte.

The situations I considered can be found on godbolt.org. This shows a very strong indicator can be determined, just from the raw data, as to whether the data was intended to be stored with ECC, or intended to be stored as a triple-encoded single byte.


Raw OTP data that needs special consideration.

Pages from 0xF800xFFF are always 3x-byte encoded.
User pages will need a “best guess”?

Raw 24 bits 3x byte Bitflip needed
0x000000 0x00 ECC is correct
0x171717 0x17 ECC is correct
0x020212 0x02 0x000010
0x010501 0x01 0x000400
0x040504 0x04 0x000100
0x070747 0x07 0x000040
0x101050 0x10 0x000040
0x131213 0x13 0x000100
0x161216 0x16 0x000400
0x151505 0x15 0x000010
0x2a282a 0x2a 0x000200
0x212929 0x29 0x080000
0x2c2c0c 0x2c 0x000020
0x2f2faf 0x2f 0x000080
0x3838b8 0x38 0x000080
0x3b3b1b 0x3b 0x000020
0x363e3e 0x3e 0x080000
0x3d3f3d 0x3d 0x000200

Expect more changes incoming…

2 Likes

Interesting that you have some data and I don’t seem to. The board I’m using is green, so the chip is from unreeled samples. I wonder if this is the difference. Also possible that I just messed up my read function.

Interesting. What results do you get when you read OTP row 0xF80?

It should be three identical values. And since it protects page 0, it should be non-zero. In fact, if it’s anything other than 0x3F 0x3F [0x3F], that would make me have to dig deeper, as that page is said to be set at the factory.

If any chips you have show OTP row 0xF80 as zero, could you please send me a couple of those chips (with or without boards attached)?

2 Likes
HiZ> otpdump -r 0xf80 -c 5
Row 0x000: 0000 === 0000 === 00 00 [00] (..)
Row 0x001: 0000 === 0000 === 00 00 [00] (..)
Row 0x002: 0000 === 0000 === 00 00 [00] (..)
Row 0x003: 0000 === 0000 === 00 00 [00] (..)
Row 0x004: 0000 === 0000 === 00 00 [00] (..)

Not sure if the row numbering is a bug or the wrong rows are actually read.

HiZ> otpdump -r 0x00 -c 0xfff -s
Row 0x400: 6579 === 6579 =?= 78 65 [09] (ye)
Row 0x401: 6C6C === 6C6C === 6C 6C [39] (ll)
Row 0x402: 206F === 206F === 6F 20 [15] (o )
Row 0x403: 7266 === 7266 === 66 72 [39] (fr)
Row 0x404: 6D6F === 6D6F === 6F 6D [32] (om)
Row 0x405: 4F20 === 4F20 === 20 4F [03] ( O)
Row 0x406: 5054 === 5054 =?= 74 50 [02] (TP)
Row 0x410: 6F7E === 6F7E === 7E 6F [7E] (~o)
Row 0x411: 6F7E === 6F7E === 7E 6F [7E] (~o)
Row 0x412: 7E7A === 7E7A =?= 7E 7E [6F] (z~)
Row 0x413: 7EEF === 7EEF =?= 6F 7E [6F] (.~)
Row 0x414: 7E6E === 7E6E =?= 7E 7E [00] (n~)

Searching whole range for only finds the data I wrote to the OTP with the demo.

  • The ECC errors are correct. Some are recoverable, some are not. This is part of the demo.
  • I like your way of handing addresses and displaying the rows much better than the awful thing I created
  • parse_otp_command_line is infected with some of my hastily done code. r_flag is actually looking for c, s_flag is looking for ‘a’. Changing r to a above did not yield the correct row numbers in the list.
  • It looks like =?= should be warning colored, but it is not and I can’t figure out why, ui_term_color_warning looks correct to me

Next I will hunt down a rev6 with the production chip and see if it has anything preprogrammed.

1 Like
HiZ> otpdump -r 0x000 -c 0xfff -s
Row 0x000: B4B8 === B4B8 === B8 B4 [33] (..)
Row 0x001: F87E === F87E === 7E F8 [3D] (~.)
Row 0x002: 6290 === 6290 === 90 62 [2C] (.b)
Row 0x003: 4E1A === 4E1A === 1A 4E [2F] (.N)
Row 0x004: 28D9 === 28D9 === D9 28 [08] (.()
Row 0x005: E76F === E76F === 6F E7 [18] (o.)
Row 0x006: 0C85 === 0C85 === 85 0C [37] (..)
Row 0x007: 7892 === 7892 === 92 78 [04] (.x)
Row 0x008: 0E9E === 0E9E === 9E 0E [11] (..)
Row 0x009: B861 === B861 === 61 B8 [07] (a.)
Row 0x00A: 39EA === 39EA === EA 39 [32] (.9)
Row 0x00B: EE5F === EE5F === 5F EE [27] (_.)
Row 0x010: 2D39 === 2D39 === 39 2D [27] (9-)
Row 0x011: 731B === 731B === 1B 73 [3E] (.s)
Row 0x018: 0030 === 0030 === 30 00 [03] (0.)
Row 0x036: 6036 === 6036 === 36 60 [27] (6`)
Row 0x037: 7B83 === 7B83 === 83 7B [0D] (.{)
Row 0xF80: 3F37 === 3F37 =?= 3F 3F [3F] (7?)
Row 0xF81: 1505 === 1505 =?= 15 15 [15] (..)
Row 0xF83: 0504 === 0504 =?= 04 04 [04] (..)
Row 0xF85: 0504 === 0504 =?= 04 04 [04] (..)
Row 0xFFD: 0504 === 0504 =?= 04 04 [04] (..)

Well, well, well… Would you look at that :slight_smile: The OTP wasn’t programmed on the engineering sample chips. I suppose this could be used for some nefarious purpose :wink: Perhaps cloning our own cert based on unique ID from the other thread.

I cannot find the 5XL prototype to test. We’ll have to wait for spring festival to be over, but there should be at least two other prototypes with the blank OTP chips at the office and I’ll send you one.

1 Like

Non-personalized chips!

:tada: That’s awesome, thanks for checking! Maybe I’ll program it to have serial 68656E7279676162, or maybe I’ll keep it around unprogrammed as a piece of history. I don’t have a 5XL, so … that’ll also complete my collection of internal-flash models.


Row number bug?

Looking at the code, the most likely cause (by way of elimination) is that the parse_otp_command_line() function is setting the start address to zero (when it should not)? I am unlikely to be able to debug this work week, but will have it on my list.


ECC generation & testing ready

It was neat to read the values three ways, but I now can validate the ECC code directly (the SDK’s ECC generation function works correctly). Thus, there is only a need to read using bootrom API if the ECC is not correct.

Also, I want to update the display to indicate when it’s highly probable that the data is being stored as 3x copies of the same byte (with up to 1 bit error permitted). I have exhaustively checked the possibilities, and found only 18x 24-bit patterns where the values could be both 3x-stored single byte (with up to 1 bit error), and could also be ECC-stored data (with up to 1 bit error). So, that’s pretty good basis for a heuristic flag to be displayed.


Edge-cases to be tested

I also want to force a few edge cases, to test & verify the code.

Burn 256 rows …

  1. Write RAW all 256 possible triple-encoded single-byte values.
  2. Read those same sectors back as if they were ECC-corrected.
  3. Determine what the hardware ECC correction is doing, and verify it reports errors

Force use of BRBP (and test our dumping of the same)

  1. Choose 16-bit value to write to the OTP (e.g., 0x6D6F)
  2. Write a single bit that should be zero in that intended value. In this example, maybe this could be 0x0080.
  3. Using RAW OTP write method (to prevent ECC from being written), use bootrom API or picotool to write that single bit (0x000080)to an OTP row.
  4. Using ECC OTP write method (to cause ECC to be used when writing to the row), use bootrom API or picotool to write the chosen value to that same OTP row (0x6D6F). This should succeed.
  5. Read back the result using RAW mode.

Expected data:
0x00 0x90 0x92 0xFD
Since the correction byte’s top two bits are set to one, the value should be inverted to get actual data:
0x00 0x6F 0x6D 0x32


Delays and next steps

Unfortunately, there was a delay getting the Pico boards shipped, so they won’t be here until next week. I don’t want to burn fuses on my BP6 boards for experimentation, so … I will also delayed doing the above edge-case tests.

NOTE: I have code for the above edge cases essentially written. Once verified how the hardware responds, I can simplify the code significantly, and ensure the display is outputing reasonable data (even in the BRBP cases).

  • Force use of, and test reading of, OTP written using BRBP.
  • Write function to calculate (and thus detect) single-bit and dual-bit errors.
  • Write various bit patterns (using RAW) and read back (using ECC) to verify hardware reports two-bit errors.
  • Modify command to be otp dump (two words), so can add other OTP sub-commands later.

1 Like

Unexpected writes to some OTP rows

It appears picotool silently (automagically?) writes to multiple rows, when asking it to write to a row that is RBIT-3 (voting algorithm amongst multiple rows) … or maybe it’s the bootrom itself?

As an example, when using picotool to write to Row 0x59, it appears to also automatically write to rows 0x5A and 0x5B.


Other failures

I’ve messed up two RP2350 board’s OTP thus far:

  • In one, I accidentally writing to reserved areas of the OTP (Rows 0x064 onwards) … so while the settings worked in bootrom, no telling what settings I destroyed, so it’s only usable for OTP testing in bootrom.
  • In the other, I forgot to update whitelabel address offsets after re-arranging the string order. Oops. Works, but with some unexpected / odd / null-enclosing strings in places.

Progress at last!

I should have an update in the next couple days, with a focus on verifying the steps to be taken during manufacturing.

I have verified a simple way to program all but one string (the manufacturing details) per-product line (e.g., BP5XL, BP6, BP7), and to add the string containing the manufacturing details later.

Thus, a first script can run identically on all devices (of a given type), causing the USB white label of the bootrom to be tested as part of QA.

A second script can be run after QA, to store the variable portions of the data, and lock the USB whitelabel page.
This reduces the complexity of the script for the variable data portion, which I consider a “Good Thing ™”.


Todo...

  • Modify command to be otp dump (two words), so can add other OTP sub-commands later
  • Add directory entry for the portions of the OTP used for the whitelabel customization. (yes, even though it’s duplicative of Rows 0x59…0x5C, … it’s a start).
  • document edge cases when reading OTP having various errors using bootrom vs. memory-mapped regions … do all methods report errors?
    • Reading non-ECC pages as ECC protected
    • Reading ECC-protected pages with 1-bit error
    • Reading ECC-protected pages with 2-bit errors
    • Reading ECC-protected pages with Bit Recovery By Polarity (BRBP)
    • Manual recovery of original data from raw BRBP ECC row

1 Like

Very nice!

I would really stick with internal functions we know won’t become crapware. Pico tool seems problematic.

My current thought is if the OTP is empty, unique serial port number is disabled, and a not usually available binmode is default for device testing and burning the otp.

This is where we get the “birth certificate”, do the self test, burn the white label details, and request/burn the cert.

1 Like

You have some great ideas, Ian! Let me make a plan for your consideration:


I recommend the following...

  1. BP6 firmware is updated with a new function that automatically programs the common (per-product) USB whitelabel OTP structures.

    • Enabled with compilation switch (“Factory Mode”) which should be used for factory firmware
    • This helps avoid accidentally writing OTP on in-the-field BusPirate 6 / 5XL devices.
    • The factory can ship the device with the “Factory Mode” firmware … as those devices will have the OTP fields already set … so no extra firmware flash required.
    • Note that the whitelabel values have no effect on the firmware’s own execution, as those settings apply only to the UF2 bootrom.
  2. Per-device unique data is added during or after QA.

    • I recommend distinct scripts for each type of unique data.
    • ( a ) Add INFO_UF2_TXT_BOARD_ID string and lock the OTP page used by whitelabel data (e.g., Page 3).
    • ( b ) Add x.509 certificate showing device provenance and OTP directory entry.
    • ( c ) … anything else that comes up …
  3. Update default for use of USB serial number.

    • Limited to “Factory Mode” firmware on RP2350 devices, add some additional logic.
    • If the OTP whitelabel structures are NOT finalized, then device is presumed to be on the factory floor
      • If on factory floor, then override setting to always use the single common “fake” USB serial number
    • bool is_whitelabel_finalized()
      • Read OTP row 0x59 USB_BOOT_FLAGS
      • Verify WHITE_LABEL_ADDR_VALID is set
      • Verify WL_INFO_UF2_TXT_BOARD_ID_STRDEF_VALID
      • e.g., raw_OTP & 0x408000u == 0x408000u
    • Else the existing logic is used.

The certificate of provenance (that’s my name … let’s see if it sticks) is a separate, but entirely supported, part of personalization.


If that aligns with your vision, then great! Otherwise, let’s keep hashing it out here…

1 Like

That seems like the ticket!

Maybe the cert could be the trigger for ending manufacturing mode. This way the firmware can program white label info on first startup. I’m sure these details will be more clear when we start building it out.

1 Like

Just to get this into the record. Who knows, maybe my computer will crash (or other bad event). This shows the hacks I used to enable the entire USB_WHITE_LABEL structure (+ strings) fit into a single OTP page. Recommend to rename from .txt to .md and view where you can collapse sections.

It includes command-line instructions to do everything the firmware will do, including splitting the constants from the manufacturing data string. Thus, conversion into a (mostly) static set of const data will be easily done. It can also be easily adjusted for the BP7 prototypes … just a one byte change!

otp_history.txt (25.6 KB)

I’ll basically be working from the above as the guideline for implementation.

@ian … I won’t be able to test this on actual buspirate hardware. Therefore, I’ll first be coding this into a stand-alone firmware that will run on a pico2 … much less expensive to handle mistakes ($5 << $70+).

I will then be able to integrate it as a compile-time-enabled option per above discussion, but will need the final (careful) review and validation to be done by your team.

Maybe you’ll even do something fancy (e.g., solder some sort of mount hardware to allow easily swapping the RP2350 chip? ).

After all, the BOM of the full board is much higher than the cost of the bare chip …

2 Likes

Yeah, I think it’s time for me to get some pico2 boards as well :slight_smile: Purchased.

The .json file mentioned - does pico tool use that to verify the OTP data? I didn’t catch how that fit in there.

    struct otp_contents_t{
        uint16_t row;
        uint16_t len;
        bool is_ecc;
        uint8_t *data;
    };

    //row 0x00C0-0x00C1
    uint8_t data0[] = {0x09, 0x12, 0x32, 0x73};
    // row 0x00C4-0x00C5
    uint8_t data1[]= {0x0A, 0x10, 0x0C, 0x10};
    //rows 0x00c8-0x00df
    uint8_t data2[]={0x08, 0x1B, 0x08, 0x1F, 0x0C, 0x23, 0x16, 0x2B, 0x0D, 0x36, 0x0C, 0x3D, 0x1B, 0x43, 'h', 't', 't', 'p', 's', ':', '/', '/', 'b', 'u', 's', 'p', 'i', 'r', 'a', 't', 'e', '.', 'c', 'o', 'm', '/', 'B', 'P', '_', '_', 'B', 'O', 'O', 'T'};

    struct otp_contents_t otp_contents[] = {
        {0x00C0, sizeof(data0), true, data0},
        {0x00C4, sizeof(data1), true, data1},
        {0x00C8, sizeof(data2), true, data2},
    };

For burning from the chip: we could do something sort of like this but obviously more inspired.

picotool supports loading a JSON file containing whitelabel data.

I am testing the bootrom API vs. memory mapped regions … there may be additional “gotcha!” situations that need handling.

rambling

It’s inefficient, and their code is scary-bad… both in trying to comprehend it, and the lack of edge case support. I have lots of code I’m testing on real Pico2 boards right now.

The commands at the end work to whitelabel a Pico2 board. Since it bootrom that is affected, it should smoothly transition to the BP6.

I’m hoping to get this in a semi-working state quickly for you. Real life will limit my contributions next week. I have useful utility routines already … just need to test and put it together into a semi-presentable state.

As for the data structure … I have a slightly different approach in mind for the whitelabel. Also, I recommend avoiding fields named len … that is just asking for trouble. Does it mean count of bytes? count of rows? Also, OTP has different data size per row, depending on how the row is used. :slight_smile: I’ll give you a nice function for burning the whitelabel data … AND it will all fit in the OTP rows 0x0c0 ... 0x0FF … so only a single OTP page is used.

Oh… and caution may be needed … the bootrom API may behave differently than the memory-mapped regions. I’m investigating and will share results.

1 Like

I don’t think my PICO2 boards are going to come today, hopefully tomorrow.

OK, I was able to confirm that the ECC used for the RP2350 does NOT act as documented in the datasheet. Specifically, the text describing how an ECC read detects and corrects errors appears to be flat-out wrong.


Three missing pieces of info to recover from a single bit flip

Reconstructing how the bootrom recovers from single bit errors was based on the following sections of the datasheet:

  • Section 13.6.1 Bit Repair By Polarity @ page 1264
  • Section 13.6.2 Modified Hamming ECC @ page 1265

However, there were three key pieces of information omitted. Two of those were not even hinted at (i.e., the datasheet appears to be wrong).

  1. Read the 24-bit value raw.
  2. If both the Bit Recovery By Polarity bits are set, invert all 24 bits. The ECC recovery function NEVER sees pre-BRBP values.
    • See section 13.6.1 Bit Repair By Polarity @ page 1264:
      • When you read an OTP value through an ECC alias,
        BRBP checks for two ones in bits 23:22. When both
        bits 23 and 22 are set, BRBP inverts the entire row
        before passing it to the modified Hamming code stage.
  3. Using only the least significant 16 bits as read, calculate
    the six error correction bits again.
    • In code, can just pass the full 32-bit value to the ECC calculation function, as it automatically truncates to 16-bit.
    • See section 13.6.2 Modified Hamming ECC @ page 1265
      • When you read an OTP value through an ECC alias,
        ECC recalculates the six parity bits based on the
        value read from the OTP row.
  4. Now XOR the recalculated ECC vs. the read value.
    • Note: this is post-brbp inversion, if needed.
    • In code, can just XOR the full 32-bit value, since high byte is always zero and low two bytes are always identical.
    • See section 13.6.2 Modified Hamming ECC @ page 1265
      • Then, ECC XORs the original six (6) parity bits with
        the newly-calculated parity bits.
        This generates six (6) new bits:
        • the five (5) LSBs are the syndrome, a unique
        bit pattern that corresponds to each possible
        bit flip in the data value
        • the MSB distinguishes between odd and even
        numbers of bit flips
  5. If the XOR’d value is zero, no errors detected … just return low 16 bits
  6. NEW: If the XOR’d value has exactly one set bit … the single-bit error was in bits 23…16, so no change of the low 16 bits is required. Just return those low 16 bits.
  7. NEW: If the XOR’d syndrome (5 bits) have an odd number of set bits, toggle the parity bit.
  8. If the parity bit is zero, report multi-bit error.
    • See section 13.6.2 Modified Hamming ECC @ page 1265
      • If the [parity bit] is 0, but the syndrome contains a value other than 0, the ECC detected an unrecoverable multi-bit error.
  9. Else, use the syndrome to determine which bit to flip to correct the error.
    • See section 13.6.2 Modified Hamming ECC @ page 1265
      • If the [parity bit] is 1, the syndrome should indicate a single-bit error. ECC flips the corresponding data bit to recover from the error.
  10. NEW: Here’s the table to map from the 5-bit syndrome to the correction:
static const uint16_t sdk_otp_syndrom_to_bitflip[32] = {
    [ 3] = 0x0001,
    [ 5] = 0x0002,
    [ 6] = 0x0004,
    [ 7] = 0x0008,
    [ 9] = 0x0010,
    [10] = 0x0020,
    [11] = 0x0040,
    [12] = 0x0080,
    [13] = 0x0100,
    [14] = 0x0200,
    [15] = 0x0400,
    [17] = 0x0800,
    [18] = 0x1000,
    [19] = 0x2000,
    [20] = 0x4000,
    [21] = 0x8000,
};

Pending an exhaustive validation (2^24 iterations to test)…

Good news

I now have code that appears to properly correct any single-bit ECC error!


Why this matters

If you use the ECC alias to read OTP values, you are given a 32-bit value corresponding to two adjacent OTP rows. If the first of those rows has a detected two-bit error, then either:

  1. The detectable error is hidden when read using the ECC memory-mapped alias, -OR-
  2. The detectable error faults on each 32-bit read, making the adjacent OTP row unreadable even if its data is correct or correctable.

With the ability to manually correct the single-bit errors, firmware now has a way to recover the data from *ALL correctable ECC OTP rows, while simultaneously being notified of detected errors.


Once this major block is validated, the rest of the pieces should quickly fall into place. :tada:

1 Like

My pico2 just arrived :slight_smile:

1 Like

And I just completed exhaustive testing.

  • All 16-bit values encode correctly to 24-bit (raw) values.
  • Those all decode as expected.
  • They also decode as expected with any single bit flipped.
  • The inverted form (BRBP) also decodes as expected.
  • The inverted form also decodes with any single bit flipped.
  • There is zero overlap in generated 24-bit values for any of the above (yes, I generated a 24-bit bitmap to keep track of this).
  • All other 24-bit values are properly detected as erroneous.

There’s more, but again, the key thing is this means is that the edge cases and related unexpected behavior can now be avoided. Thus, it’s safer to use.

Next up: I’ll write up the whitelabel personalization function.

1 Like

TLDR; Whitelabel personalization functions written, but not yet tested.

If you want the details...

OK, I now have a hacked-up input and menu system over RTT, so I don’t have to mess with any USB connection except power. This is good.

I’ve run the OTP ECC correction code on actual BP2350 hardware, and performed an exhaustive test of correctly-coded and single-bit-flip data.

I’ve also written all interesting variations of OTP data onto a single RP2350, for checking bootrom / memory mapped alias behavior.

I’ve now got the functions written for:

  • Automatically applying the whitelabel data (except board ID aka manufacturing string).

    • This function will hard_assert() on failure, as I’m not aware of any good recovery.
    • That said, it was written to allow manual recovery (at alternate address), at least until the WHITE_LABEL_ADDRESS row (0x5C) is written.
    • This function uses a #define for the string portion that follows "Bus Pirate " … so for BP6 it should be "6", for BP5XL it should be "5XL", etc. Can be up to 7 characters in length.
  • Applying a variable-length manufacturing data string.

    • Up to 40 characters are allowed.
    • Verbose output via printf … as expected this will run based on user input from console.

I’ll push these files to a branch shortly…

1 Like

And the functions have been tested in a stand-alone firmware, on PICO2 boards.

Body count: 4 (two are entirely unusable; two have wrong bootrom strings, but are still usable other OTP for testing)

One PICO2 board has been fully updated from fresh-from factory, in two stages, per goals above. First stage updated everything except the manufacturing string, and can run on every boot without major impact. Second stage added only the board id string into the \INFO_UF2.TXT file, intended for the manufacturing data.

Due to time constraints I am under for the next two weeks, I may make zero progress over the next two weeks. therefore, I have attached the directory. This can be extracted in the SDK examples otp directory (and add its subdirectory to its CMakefiles.txt).
learn_otp.zip (96.7 KB)

The firmware in the attached uses RTT exclusively. (Set local echo on for easier use.)

The functions were designed to be usable directly from the buspirate firmware with minimal changes (e.g., change the debug print functions).

To use:

  1. Unzip into SDK samples otp subdirectory.
  2. Add the learn_otp subdirectory to the CMakefiles.txt in the parent.
  3. Update CMake…
  4. Build …
  5. Write firmware to PICO2 board using OpenOCD with RTT enabled
  6. In telnet to RTT channel 0, choose option #4 (Initialize whitelabel).
  7. When it’s done, disconnect and reconnect PICO2 with button held to enter UF2 bootloader.
  8. Note all settings, except INFO_UF2.TXT doesn’t have manufacturing data string
  9. Reload with RTT, and choose option #5 (add whitelabel manufacturing string)
  10. When it’s done, disconnect and reconnect PICO2 with button held to enter UF2 bootloader.
  11. Note that INFO_UF2.TXT now shows the requested manufacturing string.

That’s all from me for a couple weeks, I think. Please feel free to do absolutely nothing with this file; I will integrate it into the firmware when the short-term time pressures relent (e.g., 2-3 weeks).

Oh … and you can test modifying it for the BP5XL or BP7 … there’s a #define at the top of the bp_whitelabel.c file … It would become part of the platform-specific headers in the firmware.

On my last board, I was unable to lock the configuration page. I don’t know why this is, although PAGE3_LOCK1 has multiple bits set. Between that and the earlier fuse problems in OTP Row 0x5B, I had to add abstractions for both RBIT-3 and 3x_byte redundancy options. On the plus side, the code now handles imperfect OTP banks correctly.

Again, happy to do the merging into the real firmware later … just thought you might like to play with this earlier, @ian .

2 Likes