mirror of
https://github.com/Rockbox/rockbox.git
synced 2026-10-10 08:03:04 -04:00
stm32h7: spi: fix incorrect early transfer completion
The semaphore was released after all bytes were read/written without waiting for the EOT event, which is why the delay at the end of the transfer needed to be longer than expected. Change-Id: I6b48fc01cda69564c0ec8f843afd1b0c3a9c5a3c
This commit is contained in:
parent
46d644fcd7
commit
006859f16b
2 changed files with 15 additions and 5 deletions
|
|
@ -130,6 +130,7 @@ void stm_spi_init(struct stm_spi *spi,
|
||||||
spi->clock = config->clock;
|
spi->clock = config->clock;
|
||||||
spi->mode = config->mode;
|
spi->mode = config->mode;
|
||||||
spi->set_cs = config->set_cs;
|
spi->set_cs = config->set_cs;
|
||||||
|
spi->eot_delay_us = 1 + (1000000 / config->freq);
|
||||||
|
|
||||||
semaphore_init(&spi->sem, 1, 0);
|
semaphore_init(&spi->sem, 1, 0);
|
||||||
|
|
||||||
|
|
@ -164,7 +165,6 @@ void stm_spi_init(struct stm_spi *spi,
|
||||||
|
|
||||||
stm32_clock_enable(spi->clock);
|
stm32_clock_enable(spi->clock);
|
||||||
|
|
||||||
/* TODO: allow setting MBR here */
|
|
||||||
reg_writelf(spi->regs, SPI_CFG1,
|
reg_writelf(spi->regs, SPI_CFG1,
|
||||||
MBR(mbr),
|
MBR(mbr),
|
||||||
CRCEN(0),
|
CRCEN(0),
|
||||||
|
|
@ -225,6 +225,8 @@ int stm_spi_xfer(struct stm_spi *spi, size_t size,
|
||||||
spi->rx_buf = rx_buf;
|
spi->rx_buf = rx_buf;
|
||||||
spi->rx_size = rx_buf ? size : 0;
|
spi->rx_size = rx_buf ? size : 0;
|
||||||
|
|
||||||
|
membarrier();
|
||||||
|
|
||||||
stm_spi_enable(spi, hd_tx, size);
|
stm_spi_enable(spi, hd_tx, size);
|
||||||
|
|
||||||
semaphore_wait(&spi->sem, TIMEOUT_BLOCK);
|
semaphore_wait(&spi->sem, TIMEOUT_BLOCK);
|
||||||
|
|
@ -236,10 +238,8 @@ int stm_spi_xfer(struct stm_spi *spi, size_t size,
|
||||||
* For 2.22.2 we need to wait at least 1 SCK cycle before starting the
|
* For 2.22.2 we need to wait at least 1 SCK cycle before starting the
|
||||||
* next transaction. For 2.22.6, waiting 1/2 SCK cycle should be enough
|
* next transaction. For 2.22.6, waiting 1/2 SCK cycle should be enough
|
||||||
* since the EOT event is raised on a clock edge.
|
* since the EOT event is raised on a clock edge.
|
||||||
*
|
|
||||||
* TODO: calculate this delay time. doesn't seem to match assumptions above
|
|
||||||
*/
|
*/
|
||||||
udelay(5);
|
udelay(spi->eot_delay_us);
|
||||||
|
|
||||||
stm_spi_disable(spi);
|
stm_spi_disable(spi);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -251,9 +251,13 @@ void stm_spi_irq_handler(struct stm_spi *spi)
|
||||||
{
|
{
|
||||||
uint32_t sr = reg_readl(spi->regs, SPI_SR);
|
uint32_t sr = reg_readl(spi->regs, SPI_SR);
|
||||||
|
|
||||||
if (spi->tx_size == 0 && spi->rx_size == 0)
|
if (spi->tx_size == 0 &&
|
||||||
|
spi->rx_size == 0 &&
|
||||||
|
reg_vreadf(sr, SPI_SR, EOT))
|
||||||
{
|
{
|
||||||
semaphore_release(&spi->sem);
|
semaphore_release(&spi->sem);
|
||||||
|
|
||||||
|
reg_writelf(spi->regs, SPI_IFCR, EOTC(1));
|
||||||
reg_varl(spi->regs, SPI_IER) = 0;
|
reg_varl(spi->regs, SPI_IER) = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -261,6 +265,8 @@ void stm_spi_irq_handler(struct stm_spi *spi)
|
||||||
if (spi->tx_size > 0 && reg_vreadf(sr, SPI_SR, TXP))
|
if (spi->tx_size > 0 && reg_vreadf(sr, SPI_SR, TXP))
|
||||||
{
|
{
|
||||||
uint32_t data = stm_spi_pack(&spi->tx_buf, &spi->tx_size);
|
uint32_t data = stm_spi_pack(&spi->tx_buf, &spi->tx_size);
|
||||||
|
if (spi->tx_size == 0)
|
||||||
|
reg_writelf(spi->regs, SPI_IER, TXPIE(0));
|
||||||
|
|
||||||
reg_varl(spi->regs, SPI_DR) = data;
|
reg_varl(spi->regs, SPI_DR) = data;
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -272,6 +278,9 @@ void stm_spi_irq_handler(struct stm_spi *spi)
|
||||||
uint32_t data = reg_readl(spi->regs, SPI_DR);
|
uint32_t data = reg_readl(spi->regs, SPI_DR);
|
||||||
|
|
||||||
stm_spi_unpack(&spi->rx_buf, &spi->rx_size, data);
|
stm_spi_unpack(&spi->rx_buf, &spi->rx_size, data);
|
||||||
|
if (spi->rx_size == 0)
|
||||||
|
reg_writelf(spi->regs, SPI_IER, RXPIE(0));
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -81,6 +81,7 @@ struct stm_spi
|
||||||
enum stm_spi_mode mode;
|
enum stm_spi_mode mode;
|
||||||
stm_spi_set_cs_t set_cs;
|
stm_spi_set_cs_t set_cs;
|
||||||
uint32_t frame_size;
|
uint32_t frame_size;
|
||||||
|
uint32_t eot_delay_us;
|
||||||
|
|
||||||
const void *tx_buf;
|
const void *tx_buf;
|
||||||
size_t tx_size;
|
size_t tx_size;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue