Merge pull request #12393 from benpicco/sam0-spi_reconfig
sam0/spi: Don't re-configure SPI device when not needed
This commit is contained in:
commit
6ec6aaf4b0
@ -104,29 +104,40 @@ void spi_init_pins(spi_t bus)
|
|||||||
int spi_acquire(spi_t bus, spi_cs_t cs, spi_mode_t mode, spi_clk_t clk)
|
int spi_acquire(spi_t bus, spi_cs_t cs, spi_mode_t mode, spi_clk_t clk)
|
||||||
{
|
{
|
||||||
(void) cs;
|
(void) cs;
|
||||||
/* get exclusive access to the device */
|
|
||||||
mutex_lock(&locks[bus]);
|
|
||||||
/* power on the device */
|
|
||||||
poweron(bus);
|
|
||||||
|
|
||||||
/* disable the device */
|
|
||||||
dev(bus)->CTRLA.reg &= ~(SERCOM_SPI_CTRLA_ENABLE);
|
|
||||||
while (dev(bus)->SYNCBUSY.reg & SERCOM_SPI_SYNCBUSY_ENABLE) {}
|
|
||||||
|
|
||||||
/* configure bus clock, in synchronous mode its calculated from
|
/* configure bus clock, in synchronous mode its calculated from
|
||||||
* BAUD.reg = (f_ref / (2 * f_bus) - 1)
|
* BAUD.reg = (f_ref / (2 * f_bus) - 1)
|
||||||
* with f_ref := CLOCK_CORECLOCK as defined by the board */
|
* with f_ref := CLOCK_CORECLOCK as defined by the board */
|
||||||
dev(bus)->BAUD.reg = (uint8_t)(((uint32_t)CLOCK_CORECLOCK) / (2 * clk) - 1);
|
const uint8_t baud = (((uint32_t)CLOCK_CORECLOCK) / (2 * clk) - 1);
|
||||||
|
|
||||||
/* configure device to be master and set mode and pads,
|
/* configure device to be master and set mode and pads,
|
||||||
*
|
*
|
||||||
* NOTE: we could configure the pads already during spi_init, but for
|
* NOTE: we could configure the pads already during spi_init, but for
|
||||||
* efficiency reason we do that here, so we can do all in one single write
|
* efficiency reason we do that here, so we can do all in one single write
|
||||||
* to the CTRLA register */
|
* to the CTRLA register */
|
||||||
dev(bus)->CTRLA.reg = (SERCOM_SPI_CTRLA_MODE(0x3) | /* 0x3 -> master */
|
const uint32_t ctrla = SERCOM_SPI_CTRLA_MODE(0x3) /* 0x3 -> master */
|
||||||
SERCOM_SPI_CTRLA_DOPO(spi_config[bus].mosi_pad) |
|
| SERCOM_SPI_CTRLA_DOPO(spi_config[bus].mosi_pad)
|
||||||
SERCOM_SPI_CTRLA_DIPO(spi_config[bus].miso_pad) |
|
| SERCOM_SPI_CTRLA_DIPO(spi_config[bus].miso_pad)
|
||||||
(mode << SERCOM_SPI_CTRLA_CPHA_Pos));
|
| (mode << SERCOM_SPI_CTRLA_CPHA_Pos);
|
||||||
|
|
||||||
|
/* get exclusive access to the device */
|
||||||
|
mutex_lock(&locks[bus]);
|
||||||
|
|
||||||
|
/* power on the device */
|
||||||
|
poweron(bus);
|
||||||
|
|
||||||
|
/* configuration did not change */
|
||||||
|
if (dev(bus)->BAUD.reg == baud && dev(bus)->CTRLA.reg == ctrla) {
|
||||||
|
return SPI_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* disable the device */
|
||||||
|
dev(bus)->CTRLA.reg &= ~(SERCOM_SPI_CTRLA_ENABLE);
|
||||||
|
while (dev(bus)->SYNCBUSY.reg & SERCOM_SPI_SYNCBUSY_ENABLE) {}
|
||||||
|
|
||||||
|
dev(bus)->BAUD.reg = baud;
|
||||||
|
dev(bus)->CTRLA.reg = ctrla;
|
||||||
|
|
||||||
/* also no synchronization needed here, as CTRLA is write-synchronized */
|
/* also no synchronization needed here, as CTRLA is write-synchronized */
|
||||||
|
|
||||||
/* finally enable the device */
|
/* finally enable the device */
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user