With only 8 possible prescalers, we can just loop over the values
and shift the clock. In addition to being much easier to read, using
shifts over divisions can be a lot faster on CPUs without hardware
division.
In addition an `assert()` is added that checks if the API contract
regarding the SPI frequency is honored. If the requested clock is too
low to be generated, we should rather have a blown assertion than
hard to trace communication errors.
Finally, the term prescaler is used instead of divider, as divider may
imply that the frequency is divided by the given value n, but
in fact is divided by 2^(n+1).
Previously, the /CS signal was performed by enabling / disabling the
SPI peripheral. This had the disadvantage that clock polarity settings
where not applied starting with `spi_acquire()`, as assumed by e.g.
the SPI SD card driver, but only just before transmitting data.
Now the SPI peripheral is enabled on `spi_acquire()` and only disabled
when calling `spi_release()`, and the `SPI_CR2_SSOE` bit in the `CR2`
register is used for hardware /CS handling (as supposed to).
The CR2 register was only written to if the settings differ from the
reset value. This wasn't actually a bug, since it was cleared in
`spi_release()` to the reset value again. Still, it looks like a bug,
may cause a pipeline flush due to the branch, and increased `.text`
size. So let's get rid of this.
The driver previously failed to reliably clear the RXNE bit, resulting
in the next transfer to incorrectly read a stale register value. This
was noticed with the SD card SPI driver on an STM32F4, in which the
0xff byte of the previous byte transfer was returned instead of the
actual status byte, throwing the SD card driver off the rails.
The DMA stream will automatically disable itself as soon as the transfer
is finished. No need to do this an additional time after the transfer is
finished
This combines a number of register writes in the SPI
acquire and transfer code. The DMA enable for SPI is moved to the
acquire function, switching between DMA and regular transfer between
acquires is not possible.