Closed AlexeyB-developer closed 3 years ago
Thanks for the bug report. The bug has been fixed. I'd like a test (I don't have an L4 family chip).
This option doesn't work. Still not taken into account -1 (in L4 channel numbering from 1). The expressions in the original post were used for testing. The TX process works fine with them. But the RX process does not go at all, even without DMA. Duplex mode was used. Attached are oscillograms of the pixel reading subroutine execution: `uint16_t ili9341_ReadPixel(uint16_t Xpos, uint16_t Ypos)
The first pair - signals SPI_SCK, SPI_MOSI for F4 (all Ok). The second pair - signals SPI_SCK, SPI_MISO for F4 (all Ok). On oscillograms:
The third pair - signals SPI_SCK, SPI_MOSI for L4 - no reception clock. When the "software SPI driver" is set, clocking appears, but the data is not read correctly (this is the material for another topic). I understand that you do not have the required processor, but if possible, try to find the reason for the incorrectness. You have a very specific approach to working with interfaces. By the way, it is not clear what it is for 8 cycles, following 24 reading cycles, during which the speed also changes.
For L4: SPI TX + DMA mode functions normally. Software SPI RX also works. The following inaccuracies were found in the "Hardware SPI RX" implementation:
SPI RX DMA does not work, I did not go into details, most likely there is also something with the RXONLY flag. The same flag is used in L0.
Version 2021.01.07 in SPI RX mode and LCD_SPI_MODE = 2 still requires correction. By analogy with the working version for F4, before switching to receive mode, it is necessary to clear the receive buffer. Also, a feature of L4 in comparison with F4 is that the interface must be stopped to generate clocks from the RXONLY flag.
Full view of the tested function:
inline void LcdDirRead(uint32_t d)
{
GPIOX_MODER(MODE_OUT, LCD_SCK);
while(d--)
{
GPIOX_CLR(LCD_SCK);
LCD_READ_DELAY;
GPIOX_SET(LCD_SCK);
}
GPIOX_MODER(MODE_ALTER, LCD_SCK);
while(SPIX->SR & SPI_SR_RXNE) d = SPIX->DR;
SPIX->CR1 &= ~SPI_CR1_SPE;
SPIX->CR1 = (SPIX->CR1 & ~SPI_CR1_BR) | (LCD_SPI_SPD_READ << SPI_CR1_BR_Pos) | SPI_CR1_RXONLY;
SPIX->CR1 |= SPI_CR1_SPE;
}
In any case, you should turn off the interface when switching to transmission, although it works without it.
inline void LcdDirWrite(void)
{
SPIX->CR1 &= ~SPI_CR1_SPE;
SPIX->CR1 = (SPIX->CR1 & ~(SPI_CR1_BR | SPI_CR1_RXONLY)) | (LCD_SPI_SPD_WRITE << SPI_CR1_BR_Pos);
SPIX->CR1 |= SPI_CR1_SPE;
}
The implementation of the RX DMA mode remains open. Although for displays this is not very relevant.
On this topic, SPI for SIM32L4 is closed.
I am delighted with your driver, everything is done very carefully. Tested F4, SPI + DMA, FSMC16 + DMA, ILI9341. No complaints, thank you very much. Also tested SPI on L4 (STM32L433, STM32F452), DMA does not work due to an error - the request channel is not taken into account. For definitions LCD_DMA_TX, LCD_DMA_RX there must be 4 parameters: DMA number, DMA channel, DMA request, DMA priority (similar to the L0 family). For L4 I made the following modifications:
in the same file lcd_io_spi.c in the LCD_IO_Init () function added the following code:
if DMANUM(LCD_DMA_TX) > 0
DMAX_CSELR(LCD_DMA_TX)->CSELR = (DMAX_CSELR(LCD_DMA_TX)->CSELR & ~(0xF << (4 (DMACHN(LCD_DMA_TX) - 1)))) | DMAREQ(LCD_DMA_TX) << (4 (DMACHN(LCD_DMA_TX) - 1));
endif
if DMANUM(LCD_DMA_RX) > 0
DMAX_CSELR(LCD_DMA_RX)->CSELR = (DMAX_CSELR(LCD_DMA_RX)->CSELR & ~(0xF << (4 (DMACHN(LCD_DMA_RX) - 1)))) | DMAREQ(LCD_DMA_RX) << (4 (DMACHN(LCD_DMA_RX) - 1));
endif
The TX process is now running fine. The RX process has not been tested. The numbering of channels in L0 and L4 is 1...7, so -1 in the given code must be taken into account for L0 as well. Please update your driver accordingly.