mirror of
https://github.com/raspberrypi/pico-sdk.git
synced 2025-12-10 07:14:36 +01:00
Improve SPI set-up: Don't change the config whilst it is enabled (#1227)
Co-authored-by: David Thacher <davidethacher@gmail.com>
This commit is contained in:
parent
6d336e04be
commit
0121007c85
2 changed files with 23 additions and 0 deletions
|
|
@ -180,6 +180,11 @@ static inline void spi_set_format(spi_inst_t *spi, uint data_bits, spi_cpol_t cp
|
|||
invalid_params_if(SPI, order != SPI_MSB_FIRST);
|
||||
invalid_params_if(SPI, cpol != SPI_CPOL_0 && cpol != SPI_CPOL_1);
|
||||
invalid_params_if(SPI, cpha != SPI_CPHA_0 && cpha != SPI_CPHA_1);
|
||||
|
||||
// Disable the SPI
|
||||
uint32_t enable_mask = spi_get_hw(spi)->cr1 & SPI_SSPCR1_SSE_BITS;
|
||||
hw_clear_bits(&spi_get_hw(spi)->cr1, SPI_SSPCR1_SSE_BITS);
|
||||
|
||||
hw_write_masked(&spi_get_hw(spi)->cr0,
|
||||
((uint)(data_bits - 1)) << SPI_SSPCR0_DSS_LSB |
|
||||
((uint)cpol) << SPI_SSPCR0_SPO_LSB |
|
||||
|
|
@ -187,6 +192,9 @@ static inline void spi_set_format(spi_inst_t *spi, uint data_bits, spi_cpol_t cp
|
|||
SPI_SSPCR0_DSS_BITS |
|
||||
SPI_SSPCR0_SPO_BITS |
|
||||
SPI_SSPCR0_SPH_BITS);
|
||||
|
||||
// Re-enable the SPI
|
||||
hw_set_bits(&spi_get_hw(spi)->cr1, enable_mask);
|
||||
}
|
||||
|
||||
/*! \brief Set SPI master/slave
|
||||
|
|
@ -199,10 +207,17 @@ static inline void spi_set_format(spi_inst_t *spi, uint data_bits, spi_cpol_t cp
|
|||
* \param slave true to set SPI device as a slave device, false for master.
|
||||
*/
|
||||
static inline void spi_set_slave(spi_inst_t *spi, bool slave) {
|
||||
// Disable the SPI
|
||||
uint32_t enable_mask = spi_get_hw(spi)->cr1 & SPI_SSPCR1_SSE_BITS;
|
||||
hw_clear_bits(&spi_get_hw(spi)->cr1, SPI_SSPCR1_SSE_BITS);
|
||||
|
||||
if (slave)
|
||||
hw_set_bits(&spi_get_hw(spi)->cr1, SPI_SSPCR1_MS_BITS);
|
||||
else
|
||||
hw_clear_bits(&spi_get_hw(spi)->cr1, SPI_SSPCR1_MS_BITS);
|
||||
|
||||
// Re-enable the SPI
|
||||
hw_set_bits(&spi_get_hw(spi)->cr1, enable_mask);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ uint spi_init(spi_inst_t *spi, uint baudrate) {
|
|||
|
||||
// Finally enable the SPI
|
||||
hw_set_bits(&spi_get_hw(spi)->cr1, SPI_SSPCR1_SSE_BITS);
|
||||
|
||||
return baud;
|
||||
}
|
||||
|
||||
|
|
@ -43,6 +44,10 @@ uint spi_set_baudrate(spi_inst_t *spi, uint baudrate) {
|
|||
uint prescale, postdiv;
|
||||
invalid_params_if(SPI, baudrate > freq_in);
|
||||
|
||||
// Disable the SPI
|
||||
uint32_t enable_mask = spi_get_hw(spi)->cr1 & SPI_SSPCR1_SSE_BITS;
|
||||
hw_clear_bits(&spi_get_hw(spi)->cr1, SPI_SSPCR1_SSE_BITS);
|
||||
|
||||
// Find smallest prescale value which puts output frequency in range of
|
||||
// post-divide. Prescale is an even number from 2 to 254 inclusive.
|
||||
for (prescale = 2; prescale <= 254; prescale += 2) {
|
||||
|
|
@ -61,6 +66,9 @@ uint spi_set_baudrate(spi_inst_t *spi, uint baudrate) {
|
|||
spi_get_hw(spi)->cpsr = prescale;
|
||||
hw_write_masked(&spi_get_hw(spi)->cr0, (postdiv - 1) << SPI_SSPCR0_SCR_LSB, SPI_SSPCR0_SCR_BITS);
|
||||
|
||||
// Re-enable the SPI
|
||||
hw_set_bits(&spi_get_hw(spi)->cr1, enable_mask);
|
||||
|
||||
// Return the frequency we were able to achieve
|
||||
return freq_in / (prescale * postdiv);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue