STM32 timing critical ADC outline code
the simplest would be to set up a timer and in the timer start the adc.

you can set the timer interrupt to the highest / higher priority.


  In 8bit a 'library' is little more than some labels for registers, 


plenty of libraries are used in the 8-bit world as well. you may be thinking about macros vs. libraries.


  they seem much more commonly used in ARM... 


due to their complexity and much steeper learning curve.


  Should I just accept using the HAL from ST, try and restrict to the CMSIS or really try and continue to poke memory as in 8bit?


it is very difficult to NOT use cmsis to start up the device.

as to library, give it a shot and it may help you get started sooner / quicker.

I typically start with oem libraries but box them in a way that in the future I can replace them with my own code if I so desire.

with an oem library, you typically get quality code + working examples. they do come with a little bit overhead (1-2KB typical) but that's nothing for a typical ARM chip.

edit: here is what I typically do for all of my timer related routines -> they are identically structured but differently implemented on 8/16/32 chips:

ISR:
  clear the flag;
  _isrptr(); //execute the user handler

timer initialization (prescaler, period)
  stop the timer
  initialize the timer for user-specified prescaler and period
  start the timer - interrupt still disabled

timer activation (isrptr)
  _isrptr = isrptr; //install user handler
  clear the flag
  enable the interrupt


it allow the installation of a user-specified routine in the timer isr. in your case, that user installed routine could be turning on / off the adc, saving / processing the data, setting up a flag ...

this set of routines will be generic and can be ported from chip to chip. it can be implemented via libraries or you can roll your own - completely transparent to the user space code, meaning that you can switch between implementations freely without the need to change user code.

edit 2: here is an example. the following code,

tim1_init(1000, 1000);                  //run tim1 at 1000 prescaler + 1000 period = 1M
tim1_act(led_flp);                      //install user handler


runs on STM8S -> it sets up timer1 to overflow every 1M cycles and then on timer1 overflow it executes led_flp(), installed by tim1_act().

Substantially the same code runs on PIC, AVR, MSP430, PIC24, and various ARM chips. Some versions of it runs of ST's SPL (for STM8 and STM32), others run off Luminary's driverlib, and others run off hard coded code -> in the case of STM8, some off IAR's header files and others off the stm8s.h from the SPL, without actually using the SPL.

This is to show that the question of whether a vendor library should be used is quite moot, if you structure your code appropriately. To the user code, it doesn't make one bit of a difference whether those routines were implemented off a vendor library or rolled by modifying the registers. End of the day, it gets the job done, hopefully done right.

So instead of wasting time on if you should take a particular approach, just take one approach and make sure you do it right.