I have a custom designed PCB with headers to slot in an Electron and uses GPIOs (Carrier Board). We have developed firmware and in that firmware GPIO pin mappings are defined as const’s. For the sake of this post and simplicity, assume we are driving an LED on pin C0.
Now we are looking to make changes to the PCB design and want to use C0 as a hardware UART, which means reassigning the LED to another pin to free up UART5. I know there are other UARTs but lets assume the other UARTs are already in use and the only one we can use is UART5. We have to reassign the LED from C0 to another pin.
BUT we already have many units out in the field, so when we update the firmware it will likely break those units (i.e. not backwards compatible).
What is the best way to future proof pin assignments between PCB revisions? I know when creating a product via the platform it asks for a hardware version number. Is there a way to access this version number in the firmware and therefore use IFDEFs or do logic based pin assignments?
Following… I also want to include some sort of PCB revision tracking on a project I’m working on and intend on including a 16KBit EEPROM on the board. Either before or after soldering, I want to program the EEPROM with a PCB model, revision and serial number. Probably after soldering using some sort of test/programming jig with spring pins. But I haven’t yet contemplated how to handle in firmware yet. I might also want to include some basic configuration information on that EEPROM such as the number of relays on the PCB and perhaps the I2C addresses for critical components in case they change when selecting future I2C components.
If my memory is correct, someone else posted a similar situation on this community. They were using the E-Series and used two different products to differentiate if they were using the 3G or the LTE version of the E-Series (and with slightly different firmware on each). That technique could work nicely if you are limiting the hardware versions.
If you expect to have numerous hardware versions, then @ninjatill’s idea of using EEPROM and storing a configuration record on it would make sense. You do not necessarily need to add an external EEPROM to your PCB. If the Electron will be installed in only one PCB and stay there, then you could use the built-in simulated EEPROM (it is actually FLASH): https://docs.particle.io/reference/firmware/electron/#eeprom
To get this going for the units in the field, you could do an OTA firmware update to the whole product fleet of a special firmware that creates the configuration record on EEPROM.
Once the configuration record is created, then do another OTA firmware update to the new firmware that reads the configuration.
For new PCB versions, create the configuration record as part of the manufacturing process (could be done using a special firmware). Then load in the new firmware that reads the configuration.
If you want to be able to mix and match the electron in any version of the PCB, you are probably best to use an external EEPROM. That way, the configuration will stay with the PCB. However, the firmware will be a little bit tricky since it will have to use a default configuration (that matches the existing PCB version) when no external EEPROM is detected. If an EEPROM is detected on a newer PCB version, then read the configuration record from there.
I was thinking along the same lines with a hardware version flag in EEPROM.
Pin declarations are made before Setup() and Loop(), so I would perhaps need to declare placeholder variable uint8_t with nothing initialised (currently is const uint8_t … would need to remove the const).
In Setup() I could then read in the EEPROM hardware version flag and assign pin numbers to the placeholder variables accordingly.
I like the external EEPROM idea because if the Electron were to die at some stage and be replaced, the hardware version flag persists. Future revision might include FRAM.
The other idea I had was to set DIP switches and read via GPIO as kind of a serial number, but that would tie up GPIO’s and PCB real estate.
Similar to the EEPROM idea, I would use SPI Flash if you’re already using SPI or don’t need those pins for GPIO. It’s really cheap and small, less than $0.50 in single quantities for 8-SOIC.
In addition to the handy extra storage, the Winbond W25Q32JV, for example, has 3 extra 256 byte security registers. These are preserved even if the flash chip is erased in software. These would be a great place to put board-specific information.
A much simpler way to go here is to pick an unused GPIO pin on the both old and new boards and tie it high or low through 10k on the new one (or apply a resistor divider to an analog pin for more possibilities on fewer pins)
You would read these GPIO or analog pins to determine what kind of hardware you’re running on.
Great idea, love it! In the end I went with the external FRAM approach. I used a 128k chip which I use for logging, etc. and also version numbering of various settings.