added spi_get_baudrate() + some consistency changes (#395)

* added spi_get_baudrate()
This commit is contained in:
Rene 2021-06-01 18:12:15 +02:00 committed by GitHub
parent c573775f86
commit 42cbdcb13a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 38 additions and 15 deletions

View File

@ -132,13 +132,23 @@ void spi_deinit(spi_inst_t *spi);
*/
uint spi_set_baudrate(spi_inst_t *spi, uint baudrate);
/*! \brief Get SPI baudrate
* \ingroup hardware_spi
*
* Get SPI baudrate which was set by \see spi_set_baudrate
*
* \param spi SPI instance specifier, either \ref spi0 or \ref spi1
* \return The actual baudrate set
*/
uint spi_get_baudrate(const spi_inst_t *spi);
/*! \brief Convert SPI instance to hardware instance number
* \ingroup hardware_spi
*
* \param spi SPI instance
* \return Number of SPI, 0 or 1.
*/
static inline uint spi_get_index(spi_inst_t *spi) {
static inline uint spi_get_index(const spi_inst_t *spi) {
invalid_params_if(SPI, spi != spi0 && spi != spi1);
return spi == spi1 ? 1 : 0;
}
@ -148,6 +158,11 @@ static inline spi_hw_t *spi_get_hw(spi_inst_t *spi) {
return (spi_hw_t *)spi;
}
static inline const spi_hw_t *spi_get_const_hw(const spi_inst_t *spi) {
spi_get_index(spi); // check it is a hw spi
return (const spi_hw_t *)spi;
}
/*! \brief Configure SPI
* \ingroup hardware_spi
*
@ -197,27 +212,30 @@ static inline void spi_set_slave(spi_inst_t *spi, bool slave) {
* \ingroup hardware_spi
*
* \param spi SPI instance specifier, either \ref spi0 or \ref spi1
* \return 0 if no space is available to write. Non-zero if a write is possible
*
* \note Although the controllers each have a 8 deep TX FIFO, the current HW implementation can only return 0 or 1
* rather than the space available.
* \return false if no space is available to write. True if a write is possible
*/
static inline size_t spi_is_writable(spi_inst_t *spi) {
// PL022 doesn't expose levels directly, so return values are only 0 or 1
return (spi_get_hw(spi)->sr & SPI_SSPSR_TNF_BITS) >> SPI_SSPSR_TNF_LSB;
static inline bool spi_is_writable(const spi_inst_t *spi) {
return (spi_get_const_hw(spi)->sr & SPI_SSPSR_TNF_BITS);
}
/*! \brief Check whether a read can be done on SPI device
* \ingroup hardware_spi
*
* \param spi SPI instance specifier, either \ref spi0 or \ref spi1
* \return Non-zero if a read is possible i.e. data is present
*
* \note Although the controllers each have a 8 deep RX FIFO, the current HW implementation can only return 0 or 1
* rather than the data available.
* \return true if a read is possible i.e. data is present
*/
static inline size_t spi_is_readable(spi_inst_t *spi) {
return (spi_get_hw(spi)->sr & SPI_SSPSR_RNE_BITS) >> SPI_SSPSR_RNE_LSB;
static inline bool spi_is_readable(const spi_inst_t *spi) {
return (spi_get_const_hw(spi)->sr & SPI_SSPSR_RNE_BITS);
}
/*! \brief Check whether SPI is busy
* \ingroup hardware_spi
*
* \param spi SPI instance specifier, either \ref spi0 or \ref spi1
* \return true if SPI is busy
*/
static inline bool spi_is_busy(const spi_inst_t *spi) {
return (spi_get_const_hw(spi)->sr & SPI_SSPSR_BSY_BITS);
}
/*! \brief Write/Read to/from an SPI device

View File

@ -26,7 +26,6 @@ uint spi_init(spi_inst_t *spi, uint baudrate) {
spi_set_format(spi, 8, SPI_CPOL_0, SPI_CPHA_0, SPI_MSB_FIRST);
// Always enable DREQ signals -- harmless if DMA is not listening
hw_set_bits(&spi_get_hw(spi)->dmacr, SPI_SSPDMACR_TXDMAE_BITS | SPI_SSPDMACR_RXDMAE_BITS);
spi_set_format(spi, 8, SPI_CPOL_0, SPI_CPHA_0, SPI_MSB_FIRST);
// Finally enable the SPI
hw_set_bits(&spi_get_hw(spi)->cr1, SPI_SSPCR1_SSE_BITS);
@ -66,6 +65,12 @@ uint spi_set_baudrate(spi_inst_t *spi, uint baudrate) {
return freq_in / (prescale * postdiv);
}
uint spi_get_baudrate(const spi_inst_t *spi) {
uint prescale = spi_get_const_hw(spi)->cpsr;
uint postdiv = ((spi_get_const_hw(spi)->cr0 & SPI_SSPCR0_SCR_BITS) >> SPI_SSPCR0_SCR_LSB) + 1;
return clock_get_hz(clk_peri) / (prescale * postdiv);
}
// Write len bytes from src to SPI. Simultaneously read len bytes from SPI to dst.
// Note this function is guaranteed to exit in a known amount of time (bits sent * time per bit)
int __not_in_flash_func(spi_write_read_blocking)(spi_inst_t *spi, const uint8_t *src, uint8_t *dst, size_t len) {