cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H723 MDAM not getting OCTOSPI1 request

Visques
Associate II

Hi,

I'm trying to use MDMA to send some data over OCTOSPI1 in indirect mode but so far I haven't been successful. Here is my OCTOSPI1 initialization code:

// ---- OCTOSPI1 peripheral ----
RCC->AHB3ENR |= RCC_AHB3ENR_OSPI1EN;
OCTOSPI1->DCR1 = 0x0000;
OCTOSPI1->DCR1 |= (0xFFFA << OCTOSPI_DCR1_DEVSIZE_Pos);
OCTOSPI1->DCR2 = 0x0000;
OCTOSPI1->DCR2 |= (0x4 << OCTOSPI_DCR2_PRESCALER_Pos); // Divide AHB clock by 5
OCTOSPI1->DLR = 0x0000;
OCTOSPI1->DLR |= N_BYTES - 1; // 40 bytes
OCTOSPI1->CCR = 0x0000;
OCTOSPI1->CCR |= (0x4 << OCTOSPI_CCR_DMODE_Pos); // Just data, no address, no instruction, no alternate bytes
OCTOSPI1->CR = 0x0000;
OCTOSPI1->CR |= (0x7 << OCTOSPI_CR_FTHRES_Pos) | // FTF is set when space is at least 8 bytes
OCTOSPI_CR_DMAEN;

 And here is my MDMA initialization:

// ---- DMA ----
RCC->AHB3ENR |= RCC_AHB3ENR_MDMAEN;

MDMA_Channel0->CCR &= ~MDMA_CCR_EN;
MDMA_Channel0->CCR = 0x0000;
MDMA_Channel0->CCR |= (0x3 << MDMA_CCR_PL_Pos);
MDMA_Channel0->CTCR = 0x0000;
MDMA_Channel0->CTCR |= (0x0 << MDMA_CTCR_SSIZE_Pos) |
(0x0 << MDMA_CTCR_DSIZE_Pos) |
// MDMA_CTCR_SWRM |
(0x7 << MDMA_CTCR_TLEN_Pos); // Transmit 8 bytes
MDMA_Channel0->CSAR = (uint32_t) pData;
MDMA_Channel0->CDAR = (uint32_t)&(OCTOSPI1->DR);
MDMA_Channel0->CTBR |= (MDMA_REQUEST_OCTOSPI1_FIFO_TH << MDMA_CTBR_TSEL_Pos); // mdmda_str22: OCTOSPI1 FIFO threshold

MDMA_Channel0->CIFCR = 0xFFFFFFFF;
MDMA_Channel0->CCR |= MDMA_CCR_EN;

After this, I enable OCTOSPI1 and the FTF flag gets set, but nothing happens with the MDMA peripheral. I'm checking its register in debug mode but I see no changes after enabling OCTOSPI1. I'm not sure if the MDMA request is being generated by OCTOSPI1 or received by MDMA.

The OCTOSPI1 peripheral sends data without issue if I manually write to the DR register.

Is there anything I'm missing in the initialization code above?

Thanks

3 REPLIES 3
LCE
Principal

I thought I'm doing the same, but I checked my source and found that I'm actually using DMA1 to move data from internal SRAM1/2 to OCTOSPI (using the HyperRam in memory mapped mode on the H735 Discovery Kit).

That's working...

Visques
Associate II

I ran a more basic test without involving the OCTOSPI peripheral, just trying to copy from memory to memory. I'm triggering the request through software. Still no movement on the MDMA controller. This is my code:

uint8_t testSrc[8] = {1,2,3,4,5,6,7,8};
uint8_t testDst[8] = {0,0,0,0,0,0,0,0};

RCC->AHB3ENR |= RCC_AHB3ENR_MDMAEN;

MDMA_Channel0->CCR &= ~MDMA_CCR_EN;
MDMA_Channel0->CCR = 0x0000;
MDMA_Channel0->CCR |= (0x3 << MDMA_CCR_PL_Pos);
MDMA_Channel0->CTCR = 0x0000;
MDMA_Channel0->CTCR |= (0x0 << MDMA_CTCR_SSIZE_Pos) |
(0x0 << MDMA_CTCR_DSIZE_Pos) |
MDMA_CTCR_SWRM |
(0x7 << MDMA_CTCR_TLEN_Pos); // Transmit 8 bytes
MDMA_Channel0->CSAR = (uint32_t) &testSrc[0];
MDMA_Channel0->CDAR = (uint32_t) &testDst[0];

MDMA_Channel0->CIFCR = 0xFFFFFFFF;
MDMA_Channel0->CCR |= MDMA_CCR_EN;

MDMA_Channel0->CCR |= MDMA_CCR_SWRQ;

After executing the last line nothing seems to happen.This is the state of relevant registers:

Visques_0-1689265979891.png

SWRQ is not changed, nor CRCQA0. I suspect there is something in the MDMA init that I'm missing because it doesn't even give me an error flag.

Any input is greatly appreciated.

Visques
Associate II

Got the MDMA to work transferring from memory to memory. Will add the OCTOSPI later.

I'm sure this will be useful for someone so here is the code:

void testMDMA(uint32_t *src, uint32_t *dst){

// ---- DMA ----
RCC->AHB3ENR |= RCC_AHB3ENR_MDMAEN;

MDMA_Channel0->CCR = 0x0000;
MDMA_Channel0->CCR |= (0x3 << MDMA_CCR_PL_Pos);
MDMA_Channel0->CTCR = 0x0000;
MDMA_Channel0->CTCR |= (0x2 << MDMA_CTCR_SSIZE_Pos) | // Source size 4 bytes
(0x2 << MDMA_CTCR_DSIZE_Pos) | // Destination size 4 bytes
MDMA_CTCR_SWRM | // Software requests
(0x2 << MDMA_CTCR_TRGM_Pos) | // Block transfers
(0x7 << MDMA_CTCR_TLEN_Pos) | // Transmit 8 bytes per buffer
(0x2 << MDMA_CTCR_SINCOS_Pos) | // 32 bit address increments for source
(0x2 << MDMA_CTCR_DINCOS_Pos) | // 32 bit address increments for dst
(0x2 << MDMA_CTCR_SINC_Pos) | // Increment source address
(0x2 << MDMA_CTCR_DINC_Pos); // Increment destination address
MDMA_Channel0->CSAR = (uint32_t) src; // Source address
MDMA_Channel0->CDAR = (uint32_t) dst; // Destination address
MDMA_Channel0->CBNDTR |= (0x8 << MDMA_CBNDTR_BNDT_Pos) | // 8 bytes per block
(0x3 << MDMA_CBNDTR_BRC_Pos); // Number of blocks

// MDMA_Channel0->CIFCR = 0xFFFFFFFF;
MDMA_Channel0->CCR |= MDMA_CCR_EN;

MDMA_Channel0->CCR |= MDMA_CCR_SWRQ;
}

This functions copies 8 words from src to dst upon generating a software request. I'm using block transfers since I did not find a way to trigger a single buffer transfer without adding info to the BNDTR register. Careful with the src and dst array locations, they need to be available to the MDMA controller (otherwise use DMA1/2 to make it so)