Finally, payoff for a feature that's been in low-level development for over a year, and in heavy development for the past few weeks! Port arrays are now advanced enough to implement an abstract microcontroller class, and the end-to-end demo is apparent from the source-measure unit example layout:
It looks mostly the same - which means that everything I did before, is still supported, all the way down to the manually assigned pinnings. The parts that have changed (the parts scattered across the top) are changes in names, both from the refactoring of the microcontroller block to incorporate the programming header and crystal, and a prior refactor of power converters.
So... why all this work to end up with more of the same? What does all this give us?
- A more encapsulated microcontroller abstract block. The idea behind the new microcontroller block is that you give it power and IOs, and it figures out the rest. Have frequency requirements, as inferred from connected USB or CAN ports? It'll automatically generate a crystal for you. You almost certainly need a programming port, so it'll automatically create that too.
- This also provides the ability to switch microcontrollers from the refinements system... and eventually have microcontrollers be part of the search space when we get around to design space exploration. No need to go into your system description, change out the microcontroller, and perhaps deal with ripple effects like changing the programming header.
- A completely revamped pin mapper. The prior pin mapper wasn't very principled, largely based around pin numbers without a concept of pin models, but the new one models individual pins, including when part of a bundle (like SPI or I2C) and when different (like when some, but not all, are 5v tolerant). Furthermore, it also defines the pin name, so in the future we can auto-generate header files for firmware that define the pins and interfaces.
- Flexible IOs, instantiated on-demand. Previously, the system had to instantiate every possible port provided, even in impossible combinations; now we dynamically generate pins according to how many are requested, up to what can be allocated from the pin pool.
- Cleaner syntax for pin assignment. Previously, it relied on net naming, which resulted in a nasty top-level syntax where we had to name all the nets. Under the new syntax, allocations can be given a name, and the pin assignment specifier can directly refer to that.
- ... and because we've obsoleted the above, a lot of cruft code can be removed. Always nice when it's possible to have more deleted lines than added lines!
Continuing work will need to refactor all the other examples (which should be more straightforward given what is one of the more complex proof-of-concepts), then we can move onto array-to-array connections (probably 2-3 weeks), multipack devices (hopefully more straightforward, but probably 2-3 weeks too), and another iteration of example devices that is more optimized and cleaner.