cancel
Showing results for 
Search instead for 
Did you mean: 

STM32G441 SPI1 transmit with DMA1 and DMAMUX cannot get it to transmit

Nickelgrass
Senior

I am trying to send some bytes over an SPI via DMA on bare metal STM32G441. But there is nothing being sent and I cant find why. I only used DMA on ST32F devices that do not have the DMAMUX. Please note that SCK and MISO are not used here. I looked at a generated code from CubeIDE which does not seem to do anything else. I expected the SPI to send 1000 bytes.

Here is my code. The comment shows what is happening in each line as I am not using CMSIS. The bit definitions are corresponding to the bits: bit5 = (1<<5) for example. 

 

 

 

 

volatile uint8_t buf[1000] = {0b11001000};

// initialize
RCC->AHB1ENR |= bit0|bit2;		// enable DMA1 and DMAMUX clocks
RCC->AHB2ENR |= bit0; // enable GPIOA clock
RCC->APB2ENR |= bit12; // enable SPI1 clock

GPIOA->MODER &= ~(0b11<<14);
GPIOA->MODER |= (0b10<<14); // PA7 alternate function
GPIOA->AFRL |= (5<<28); // PA7 SPI1 MOSI
GPIOA->OSPEEDR |= (0b11<<14); // MOSI speed high

DMA1_Channel1->CCR = 0; // disable DMA
DMA1_Channel1->CPAR = (uint32_t)&SPI1->DR; // peripheral SPI1
DMA1_Channel1->CMAR = (uint32_t)&buf; // memory array
DMA1_Channel1->CCR |= (bit4|bit7|(0b11<<12)); // memory to peripheral, memory increment, very high priority

DMAMUX1_Channel0->CCR = 11; // DMAMUX SPI1TX

SPI1->CR1 |= (bit2|(0b100<<3)|bit8|bit9|bit14); // SPI1 master, f/32, SSI, SSM, bidirectional mode
SPI1->CR2 |= bit1;        // SPITX DMA enable

// send bytes
SPI1->CR1 &= ~bit6; // SPI1 disable
DMA1_Channel1->CCR &= ~bit0;	// disable DMA
DMA1_Channel1->CNDTR = 1000; // reload amount
DMA1_Channel1->CCR |= bit0; // DMA1 enable
SPI1->CR1 |= bit6; // SPI1 enable

 

 

 

 


How can I trigger the DMA? The SPI on its own works fine. Am thankfull for any tip.

1 ACCEPTED SOLUTION

Accepted Solutions
Nickelgrass
Senior

Thanks everyone for the replies. It turns out the problem seems to have been the datawidth set in the DMA. I set it to 16 bit both and now it works. Its just a minor adjustment to use 16 instead of 8 bits. So all fine now. 

View solution in original post

9 REPLIES 9
TDK
Guru
DMA1_Channel1->CCR |= (bit4|bit7|(0b11<<12)); // memory to peripheral, memory increment, very high priority

DMAMUX1_Channel0->CCR = 11; // DMAMUX SPI1TX

SPI1->CR1 |= (bit2|(0b100<<3)|bit8|bit9|bit14); // SPI1 master, f/32
SPI1->CR2 |= bit1;

// send bytes
SPI1->CR1 &= ~bit6; // SPI1 disable
DMA1_Channel1->CCR = 0; // disable DMA

The second write to CCR undoes everything you wrote to it up above, so it's no longer configured. Probably you wanted to clear bit 0 (which was already off anyway), not all of them.

Using standard CMSIS header defines will make your code a lot easier to read and debug.

 

If you feel a post has answered your question, please click "Accept as Solution".

Thanks for the answer. Corrected the second write but still no output. Does the DMAMUX have to be triggerd somehow differently?

TDK
Guru

No, just what you have should work. Might want to recheck all your bits. Might want to look at the register values/field in a debugger to verify they look correct. This is where the CMSIS definitions would be helpful.

If you feel a post has answered your question, please click "Accept as Solution".

> there is nothing being sent

How do you know?

Polled (nonDMA) operation works?

Read our and check/post content of SPI, DMAMUX, DMA and relevant GPIO registers, just before enabling transmission, and also after it.

JW

Thanks for the reply. I looked with a logicanalyzer. Sending without DMA works. With DMA nothing is transmitted. 

I will check the contents of the registers if they are what they should be. 

TDK
Guru

Could also be that your buffer is not accessible by DMA, but again, looking at register flags would indicate an error.

If you feel a post has answered your question, please click "Accept as Solution".
Nickelgrass
Senior

Thanks everyone for the replies. It turns out the problem seems to have been the datawidth set in the DMA. I set it to 16 bit both and now it works. Its just a minor adjustment to use 16 instead of 8 bits. So all fine now. 

I don't think this is it. While the FIFO and data packing makes SPI a bit more complex than in the older STM32 and the description in RM is far from being clean and concise, I can find nothing which would justify 8-bit PSIZE in DMA not to work with SPI set to 8-bit. IMO you've inadvertently changed also something else which made it working.

JW

 

Hm... yes that could very well be. Although I am afraid I cannot recall what it may have been.