cancel
Showing results for 
Search instead for 
Did you mean: 

Why would DMA behave differently on two NUCLEO devices (F446RE/L432KC) ?

Vex1
Associate III

Hey,

I have both a NUCLEO-L432KC and a NUCLEO-F446RE. I'm using them to interface with an ili9163c based display.

When I hook up the display to the L432KC it works great and I get a single image that fills the whole display. However, I'm trying to transfer the project over to a F446RE but when I run the program on the F446RE it only draws on the top half of the display and repeats the image i.e. if you were to divide the display into 4 quarters it is only drawing in the top two quarters and each of the top quarters are a repeat of the image I want to fill the whole display. I've tried using the same clock speeds on the F446RE as the L432KC just to see if it was something to do with timing but it doesn't appear to be the case.

I suspect this has something to do with DMA because when I hook it up to a logic analyzer I can see the DMA signal (MOSI) has two repeating versions of the image. Any ideas why the DMA on one device would be behaving differently from the DMA on another?

I am using DMA in circular mode with a HAL_SPI_TxCpltCallback function.

Thanks.

14 REPLIES 14

To avoid further speculations, read out and post content of relevant DMA and SPI registers just before enabling the DMA transfer, for both platforms.

JW

  • F446RE
    • DMA2
      • LISR - 0x0
      • HISR - 0x0
      • LIFCR - 0x0
      • HIFCR - 0x0
      • S3CR - 0x6032d5e
      • S3NDTR - 0xa000 (40960)
      • S3PAR - 0x4001300c
      • S3M0AR - 0x2000003c
      • S3M1AR - 0x0
      • S3FCR - 0x20
    • SPI1
      • CR1 - 0x35c
      • CR2 - 0x0
      • SR - 0x2
      • DR - 0x0
      • CRCPR - 0x7
      • RXCRCR - 0x0
      • TXCRCR - 0x0
      • IS2CFGR - 0x0
      • I2SPR - 0x2

  • L432KC
    • DMA1
      • ISR - 0x0
      • IFCR - NULL
      • CCR3 - 0x35be
      • CNDTR3 - 0x5000 (20480)
      • CPAR3 - 0x4001300c
      • CMAR3 - 0x20000040
      • CSELR - 0x100
    • SPI1
      • CR1 - 0x35c
      • CR2 - 0x1700
      • SR - 0x203
      • DR - 0x0
      • CRCPR - 0x7
      • RXCRCR - 0x0
      • TXCRCR - 0x0

The first thing that strikes me is that the unit counts are different i.e. CNDTR3 (20480) vs S3NDTR (40960). I'm not really sure how that happens though since both function calls to HAL_SPI_Transmit_DMA() are passed the same variables - (hspi1, (unint8_t*) frameBuffer, BUFSIZE * 2). frameBuffer is declared as a uint16_t array of size BUFSIZE and BUFSIZE is 160 * 128.

HAL_SPI_Transmit_DMA(&DISP_SPI, (uint8_t*)frameBuffer, BUFSIZE*2);

Why would that produce two different values for how much data so send. They are both in half-word data width.

F446RE

  • MSIZE = 01 (16 bit half word)
  • PSIZE = 01 (16 bit half word)

L432KC

  • MSIZE = 01 (16 bit half word)
  • PSIZE = 01 (16 bit half word)
Vex1
Associate III

I was busy checking the registers to reply to waclawek.jan and it turns out the initial transfer count on the two devices are different. S3NDRT = 40960 and CNDTR3 - 20480. I'm still not sure why that is the case though given that they are both in half-word mode.

Difference between 'F446 and 'L432 which caught you here is data packing in SPI.

SPI is set to 8-bit frames.

DMA in 'L432 picks a halfword from memory, stores it into SPI which splits it to two 8-bit frames and transmits both.

DMA in 'F446 picks a halfword from memory, stores it into SPI, which ignores the upper 8-bit and transmits one 8-bit frame.

In 'L4 Cube, this is accounted for, that's why half of the Size parameter of HAL_SPI_Transmit_DMA() appears in CNDTR. So, the Size parameter means "number of transmitted SPI frames, whatever size of SPI frames you used. Cube's documentation might've said so as it's surprising and different from what other functions involving DMA do, but that's Cube for you. (Btw. this "automation" would fail would you use 32-bit transfers in DMA).

In 'F4 you need either to change SPI's frames to 16 bits (which would potentially mess with other functions using SPI, so you would need to switch the frame size between 8 and 16 bits dynamically, something I really won't recommend to a novice), or change DMA transfers to 8-bits.

JW

You absolute genius. Changing it from Half-word to Byte fixes it. Thank you so much. It would have taken me months to figure this out on my own. That site is also really cool (EFTON).

I wish I had more time to process all the stuff going on at the lower level of the STM32 chips but I'm just rushing from one thing to the next.