Except for really complex stacks like USB I prefer to roll my own peripheral libraries for MCUs.
That way I know the code intimately and only implement features that I need and use. A good example of the latter is the I2C driver in the STM32F4 HAL. It's over 5000 lines. My own driver is 487 lines.
This.
The problem with abstracting the simpler peripherals is that "frameworks" (God, I hate that word!) or more generically peripheral libraries try to be a jack of all trades but master of none. As new hardware comes out with new features, the APIs are rarely fit for purpose, so they change and you lose backwards compatibility.
Then, of course, every few years, the vendor will re-invent their APIs.
Much more key is that you have little choice anyway but to understand reasonably well how the hardware works, so you might as well write and test your own.
It's also not at all unusual for APIs to have bugs in them, and to correct them you'll often have to hack the vendor libraries leading to version control nightmares.
USB and Ethernet, nah, I just suck up the vendor libraries, but there are brave souls out there who hack stacks onto bare metal, but that's not my idea of fun.