2023-10-06 08:23 AM - edited 2023-10-06 08:27 AM
Every time the HAL_ library read functions are called they automatically disable the PSSI peripheral itself. This is done in accordance with the Reference manuals callout that the CR cannot be changed while the device is enabled, to allow for the below block to change the CR every time the read is called.
/* Configure BusWidth */
if (hpssi->hdmatx->Init.PeriphDataAlignment == DMA_PDATAALIGN_BYTE)
{
MODIFY_REG(hpssi->Instance->CR, PSSI_CR_DMAEN | PSSI_CR_OUTEN | PSSI_CR_CKPOL, PSSI_CR_DMA_ENABLE |
((hpssi->Init.ClockPolarity == HAL_PSSI_RISING_EDGE) ? PSSI_CR_CKPOL : 0U));
}
else
{
MODIFY_REG(hpssi->Instance->CR, PSSI_CR_DMAEN | PSSI_CR_OUTEN | PSSI_CR_CKPOL,
PSSI_CR_DMA_ENABLE | hpssi->Init.BusWidth |
((hpssi->Init.ClockPolarity == HAL_PSSI_RISING_EDGE) ? PSSI_CR_CKPOL : 0U));
}
RM Quote:
Bit 14 ENABLE: PSSI enable
0: PSSI disabled
1: PSSI enabled
The contents of the FIFO are flushed when ENABLE is cleared to 0.
Note: When ENABLE=1, the content of PSSI_CR must not be changed, except for the
ENABLE bit itself. All configuration bits can change as soon as ENABLE changes from
0 to 1.
The DMA controller and all PSSI configuration registers must be programmed correctly
before setting the ENABLE bit to 1.
The ENABLE bit and the DCMI ENABLE bit (bit 15 of DCMI_CR) must not be set to 1 at
the same time.
This is pretty self defeating of the "PSSI_RDY" signal which the RM suggests can be used to backpressure external devices because (as the reference manual also shows) disabling it dumps the 32 byte FIFO on the PSSI. This forces a 4 byte read from the PSSI block to cause a 36 byte read on the physical interface, as the "PSSI_RDY" signal isn't a read flag, its a "FIFO empty" flag. 32 bytes are then lost forever, because instead of reading the FIFO for already received data, the first thing the `HAL_PSSI_Receive*` calls do is dump the FIFO. This means that you cant actually use the PSSI_RDY signal for backpressuring a FPGA or processor on the other side, because the RDY signal is inherently invalid.
I have verified this on an oscilloscope. As someone who doesn't change the CR (not modifying the output direction, clock polarity or bus-width) every time I read, but was trying to backpressure an external interface, I have reimplemented my own version of the HAL read functions for now.
I don't believe this is intended functionality, but the HAL_ implementation means the peripheral cannot be used as the RM or datasheet suggests it is without a debugging and re-implementation effort. Possible change to the HAL_ implementation is to drop the CR touch and replace it with error checks?