Funny you should ask, I've been doing much the same myself with an STM32F2 device this week.
STM32Cube is new, and I think the graphical assistance to work out which functions can go on which pins is useful, no question there. As a tool to help design a schematic and ensure that any conflicts between pin functions can be resolved, it's definitely handy.
I also like the fact that it will spit out everything you need to get a project started, with a lot of the essential device configuration already done: clock sources defined, PLL multipliers set, caches enabled and so on. For this reason if nothing else, I do think it's worth building your first design based on the main.c which STM32cube produces.
That said, I renamed ST's main() function, removed the user code from it, and put it into a separate file. That way I'm not putting a lot of effort into modifying an auto-generated file that might get lost if I need to regenerate it to update something. I created my own main() which calls ST's function at the start.
So far so good, but I also struggled to get to grips with all the HAL_* functions that configure the peripherals. If there's a proper manual then I didn't find it, only a rather cryptic reference guide listing the functions and their parameters, but offering no real description of how to use them. Stepping through the code, I also found a lot of bloat and overhead that's just not needed in my application.
There's example code available too - confusingly also included as "part of STM32cube" even though it's a separate download from the GUI software and only really shares a name. But this code is a set of stand-alone examples for each peripheral, and if there isn't one that happens to set up the hardware as you want it, it's a game of guess-the-function all over again.
It wasn't until I decided to start poking the hardware directly that I really started to get to grips with the device and make progress. The STM32's peripherals are complex and capable, and although the reference manual is (in many places) desperately in need of a re-write, at least all the information is there. I found it much quicker, more intuitive, and ultimately clearer to simply set all the device registers, using the macros in the ST header files to identify the bits, than to try and work out what function call(s) were needed and what their parameters should be.
For example: here's how I set up USART1 for a simple command line interface to a host PC:
__USART1_CLK_ENABLE();
HAL_NVIC_SetPriority(USART1_IRQn, 0, 1);
HAL_NVIC_EnableIRQ(USART1_IRQn);
USART1->BRR = (32 << 4) | 9; // set 115200 baud. (60M / 16) / 115200 equals 32 + 9/16ths
USART1->CR2 = 0;
USART1->CR3 = 0;
USART1->CR1 = USART_CR1_UE | USART_CR1_RXNEIE | USART_CR1_TE | USART_CR1_RE; // enable transmitter, receiver and receive interrupts
Note, I'm still using a couple of HAL function calls, where they're nice and simple and clearly do what's needed. There's no rule that says it's "all or nothing". I used the HAL to set up the GPIOs too. I may replace everything with direct hardware access at some point, if it feels worthwhile at the time.
IMHO the purpose of the HAL should be to make accessing and using the underlying hardware easier and the resulting code more portable - but ST has failed on both counts...
- lack of proper, clear documentation explaining how to use the supplied functions, and what they're doing, means using the HAL doesn't actually make it easier. It's more like an additional layer of obfuscation.
- portability isn't really an issue between devices in the same family, as they share the same peripherals and reference manual anyway. I'll address the issue of portability between families if and when it becomes an issue, which I strongly suspect will be "never".
- using the HAL is no guarantee of portability anyway. I spent a fair bit of time last year learning to use one of the smaller STM32s (a Cortex-M0 device), and the libraries that ST provided for that device aren't compatible with the ones they now supply.
My advice? Start with STM32cube, base your code on what it produces, but don't feel compelled to use the HAL for the new code you add on top. And unless your application has time to waste every time a timer interrupt goes off, start by ditching ST's ISR.