My tip: try to separate out device-specific code from SDK-specific code.
By “device”, I mean any physical piece of hardware like a DS3231 real-time clock, or an SSD1306 OLED display. Something that you attach to your mcu (microcontroller).
By “SDK” I mean whatever API may be used to implement a protocol such as I2C, SPI, etc.. Every mcu likely has a selection of APIs to choose from: Arduino, mbed, CMSIS, ST HAL, libopencm3, etc..
Ideally, keep these two sides separate. Otherwise, you will have a difficult time porting code between different mcus.
I’m not here to pour scorn on Arduino code, but you will see that, time and time again, libraries to control devices are intertwined with protocol code. This makes things hard to port.
The protocol code written for the Arduino generally does a good job, but it is not always consistent. You need to use the TinyWire library for an ATtiny85, whereas for an Uno a hardware library is used.
So ideally, to program a device you would be to write a library that initialised variables, returned initialisation code, and ways to interact with the specific device. It shouldn’t know how I2C works, for example, although it will need to be designed to be easy to use with I2C. Then, as a separate piece of code, write adapters for calling I2C.
I searched for “poor microcontroller api design”. The second match was “7 Tips for Developing Great APIs”. I won’t link to the website because I don’t want to publicise such shoddy writing.
My first problem is with the headline itself. It uses the word “Great”. The use of superlatives and hyperbole is a red flag that the article is mostly going to be fluff. This has no place in technical writing. Save that garbage for buzzfeed articles.
Anyway, I’m off for a walk. My apologies for any broken formatting. WordPress is turning into an unfixable dumpster fire.