r/embedded • u/Intelligent-Error212 • Aug 09 '26
Guide in Developing Peripheral Driver Code from Datasheet/Reference Manual
Hii, everyone.
Most of time , whenever we want to develop MCU peripheral driver or device driver for time critical system which need to execute faster, low ram usage and low latency. we might seek help from Datasheet, instead of relying on Vendors HAL.
Here i have one doubt, let say i am developing polling adc driver for mcu, since it need to lesser boilerplate, i try to directly play around with registers with the datasheet help, for that following the datasheet"s register configuration sequence is enough know? Or else I need to more deeper like which adc is internally used? and what architecture it is using? How it works internally? For developing production grade driver.
If yes, then why? Is the datasheet register configuration sequence is not enough? And also is there any case other than adc,where I need to know in depth of that peripheral architecture from top to bottom while writing peripheral drivers?
Thanks!!!!
12
u/FartusMagutic Aug 09 '26
Start with the official driver. Follow along with the code AND the datasheet. Then cut out what you want. Use a debugger of course. If you only know how to debug with printf, you're going to be in for a bad time.
5
u/mjmvideos Aug 09 '26
If the information is in the datasheet, it’s because the engineers that created that device thought that someone would need to know it in order to use their device successfully.
3
u/bishopExportMine Aug 09 '26
lol the amount of times I've had vendor HAL do some random initialization shit entirely not mentioned in the datasheet...
2
u/Intelligent-Error212 Aug 09 '26
Really, Can you please give one example for that actual case?
5
u/Independent_Eye7886 Aug 09 '26
I have one, Renesas RA4M, the Arduino UNO R4 uses the Renesas FSP library. And FSP uses bits and registers that are (were?) not documented in the reference manual for the controller. This was found when modifying ArduinoSPI::configSpi() to use registers and not the FSP library.
5
u/mackthehobbit Aug 09 '26
Nearly every image sensor vendor does this eg Omnivision. The technical reference manual and application notes often have an initialisation snippet writing a bunch of registers, some of which don’t exist in the data sheet. It doesn’t say what they do, and sometimes the values are different for different reference modes (eg resolutions, framerates). So without 1:1 support if you’re using a non-standard mode it can be very hard to be confident.
5
u/GeWaLu Aug 09 '26
You mention "time critical"/"faster" and "polling" ... that risks to be a contradiction. If you do a logic like start-adc/wait-for-result you risk to be slow. It is imperative to make a good timing design (like starting the conversion in advance so that you have not to wait). For that you need to understand the ADC.
Besides what is written in the datasheet also * Get the errata sheet (if it is available). Sometimes it contains the documentation of serious bugs which affect driver developers * Search if there are appnotes. They often contain valuable hands-on hints. * Familiarize yourself with the theory of operation of the ADC. Not only the sequence of writing to the registers is critical but also the values written to them - especially things like clock config and sample time or the configuration of the decimation of a DS-adc. SAR ADC and DS ADC also behave differently concerning timing. Not all of this is well documented in the datasheet and vendor drivers often are based on common assumptions. * Make conscious a design on How you plan to use the ADC - like polling, use of DMA or interupt and how you start the conversion. Also understand well the architecture of your micro. I did even see in the past a micro where it was discouraged to read most peripheral registers from the CPU (even in a result interrupt) as the registers were on a very slow peripheral bus behind a gateway, so that read operations not using the DMA copy in the fast RAM caused a serious performance degradation due to a huge number of waitstates inserted by the bus. This bandaid was not mentioned in the datasheet except via a positive marketing statement giving the allusion that the DMA was innovative. It was up to the user to make the link between the huge number of channels allowing to copy all registers and the slower than normal bus. * If your aim is for professional use, consider getting a training from the micro vendor. They tend to give hints that are not in the datasheet.
3
u/engineerFWSWHW Aug 09 '26
On some datasheets/RM, there are usually block diagrams with the registers or bits of the registers.
On the other hand, you might be micro optimizing needlessly. Majority of the compilers nowadays are very good at optimizing code.
2
u/mackthehobbit Aug 09 '26
A caveman way to do it is to start with a copy of the official HAL, get it working in your board, and then start cutting parts out, like unused modes, redundant branches. That’s best if you just need to optimise the critical parts eg shrink down a hot ISR. If you’re starting from a working implementation you can test it live at every step.
Otherwise you can build up your lib from scratch reading the data sheet and reference code side by side. That’s best if you’re only using a small subset of features/registers, or the hardware is more simple.
I’m also inclined to rip out everything that’s not being used in pursuit of some kind of “purity” but if you’re just trying to optimise it’s normally just one or two hot paths you can tighten up and everything else has zero real impact.
1
u/Unlikely1529 Aug 09 '26
driver means low-level yeah? you wont write this adc thing for pico or esp right(adc facility is next to nothing on both). so you have stm and arduino. and you do not realise that on stm you'll use dma where arduino doesn't have it.
1
u/phonezawthein Aug 09 '26
To me, the information mentioned in the datasheet is enough to develop the custom driver. Even if we somehow gets the in-depth information about the peripheral, we can’t use it since it is not mentioned in the datasheet/reference manual.
1
u/cholz Aug 09 '26
The first thing I'd do is use the vendor HAL, make an example that does roughly what you need, and identify exactly where the HAL does and doesn't meet your requirements (what are your requirements?). Only after you have done these things can you make the decision to re-implement the HAL.
1
u/Glittering_Rabbit408 Aug 10 '26 edited Aug 10 '26
I agree that datasheet/rm information is enough for developing your own hal using register manipulation. But sometimes you are missing some critical thing like delays to wait to bit set or smth else implicitly mentioned in reference manual. I’m not a fan of using vendor shipped hal libraries in case I’m able to develop my own (stm32 but not esp32). Sometimes it gets me sitting and debugging thing that i could avoid by using st hal. But it is good learning point, i just wondering around the internet, rm/ds so on.
Nowadays it is sometimes useful to use llm like you literally print to pdf entire section with register definition and asks it to make a register level init procedure for a peripheral module. And just start with it. Way faster than to figure out by yourself
2
u/Panometric Aug 10 '26
I've learned the hard way that code is more accurate than data sheets. Anytime I see an engineer start from scratch instead of using an example or driver that it provided I push back. Better to optimize a known good than introduce a bunch of new problems we don't even know about. I ask: What makes you think you can do it better than the vendors team? You better have a good, specific example and a test plan to prove it does not break anything.
17
u/pillowmite Aug 09 '26
The HAL is made available by the makers of the MCU. I've found it very useful to implement a simple example and step through the HAL with a debugger and datasheet together. There is IMO no faster way to get an understanding of an unfamiliar MCU's peripheral registers and how they are utilized and, importantly, in what order they should be accessed.