cancel
Showing results for 
Search instead for 
Did you mean: 

SRAM and DMA in STM32F7

rickard2
Associate III
Posted on October 23, 2017 at 14:00

I am working on a project where I have a STM32F7 which shall read data from an external SRAM using DMA.

The SRAM has 16 bit adressbus and 8 bit databus. I want the data to be copied to a 16bit buffer in the STM32F7 with DMA. However I only get the 8 bit data in the 16 bitbuffer, highest 8 bits are always 0.

The code looks like:

void PF_Init_DMA()

{

s_bTransferComplete = 0;

s_bTransferError = 0;

__HAL_RCC_DMA2_CLK_ENABLE();

s_hDMA.Init.Channel = DMA_CHANNEL_0; //DMA_CHANNEL_0

s_hDMA.Init.Direction = DMA_MEMORY_TO_MEMORY; //M2M transfer mode

s_hDMA.Init.PeriphInc = DMA_PINC_ENABLE; //Peripheral increment mode Enable

s_hDMA.Init.MemInc = DMA_MINC_ENABLE; //Memory increment mode Enable

s_hDMA.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; //Peripheral data alignment : Word

s_hDMA.Init.MemDataAlignment = DMA_PDATAALIGN_HALFWORD; //memory data alignment : Word

s_hDMA.Init.Mode = DMA_NORMAL; //Normal DMA mode

s_hDMA.Init.Priority = DMA_PRIORITY_HIGH; //priority level : high

s_hDMA.Init.FIFOMode = DMA_FIFOMODE_DISABLE; //FIFO mode disabled

s_hDMA.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;

s_hDMA.Init.MemBurst = DMA_MBURST_SINGLE; //Memory burst

s_hDMA.Init.PeriphBurst = DMA_PBURST_SINGLE; //Peripheral burst

s_hDMA.Instance = DMA2_Stream0;

if(HAL_DMA_Init(&s_hDMA) != HAL_OK)

{

}

HAL_DMA_RegisterCallback(&s_hDMA, HAL_DMA_XFER_CPLT_CB_ID, TransferComplete);

HAL_DMA_RegisterCallback(&s_hDMA, HAL_DMA_XFER_ERROR_CB_ID, TransferError);

HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0, 1);

HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);

}

uint8 PF_Init_SRAM()

{

// Init SRAM

/* SRAM device configuration */

__HAL_RCC_FMC_FORCE_RESET();

__HAL_RCC_FMC_RELEASE_RESET();

HAL_SRAM_DeInit(&sramHandle);

sramHandle.Instance = FMC_NORSRAM_DEVICE;

sramHandle.Extended = FMC_NORSRAM_EXTENDED_DEVICE;

/* Timing configuration derived from system clock (up to 216Mhz)

for 72 Mhz as SRAM clock frequency */

Timing.AddressSetupTime = 2;

Timing.AddressHoldTime = 1;

Timing.DataSetupTime = 2;

Timing.BusTurnAroundDuration = 1;

Timing.CLKDivision = 3;

Timing.DataLatency = 2;

Timing.AccessMode = FMC_ACCESS_MODE_A;

sramHandle.Init.NSBank = FMC_NORSRAM_BANK1;

sramHandle.Init.DataAddressMux = FMC_DATA_ADDRESS_MUX_DISABLE;

sramHandle.Init.MemoryType = FMC_MEMORY_TYPE_SRAM;

sramHandle.Init.MemoryDataWidth = FMC_NORSRAM_MEM_BUS_WIDTH_8;

sramHandle.Init.BurstAccessMode = FMC_BURST_ACCESS_MODE_DISABLE;

sramHandle.Init.WaitSignalPolarity = FMC_WAIT_SIGNAL_POLARITY_LOW;

sramHandle.Init.WaitSignalActive = FMC_WAIT_TIMING_BEFORE_WS;

sramHandle.Init.WriteOperation = FMC_WRITE_OPERATION_DISABLE;

sramHandle.Init.WaitSignal = FMC_WAIT_SIGNAL_DISABLE;

sramHandle.Init.ExtendedMode = FMC_EXTENDED_MODE_DISABLE;

sramHandle.Init.AsynchronousWait = FMC_ASYNCHRONOUS_WAIT_ENABLE;

sramHandle.Init.WriteBurst = FMC_WRITE_BURST_DISABLE;

sramHandle.Init.ContinuousClock = FMC_CONTINUOUS_CLOCK_SYNC_ASYNC;

sramHandle.Init.WriteFifo = FMC_WRITE_FIFO_DISABLE;

sramHandle.hdma = PF_DMA_GetHandler();

/* Initialize the SRAM controller */

if(HAL_SRAM_Init(&sramHandle, &Timing, &Timing) != HAL_OK)

{

/* Initialization Error */

printf('SRAM Error\r\n');

SRAMInit = FALSE;

return PF_ERROR;

}

__HAL_RCC_FMC_CLK_ENABLE();

}

void PF_SRAM_Read(uint32_t *pAddress, uint16_t *pDstBuffer, uint32_t BufferSize)

{

HAL_SRAM_Read_DMA(&sramHandle, pAddress, pDstBuffer, BufferSize);

}

I use bank1 and reads data from adress:

#define EMI_START_ADDRESS ((uint32_t)0x60000000)

According to FMC in RM0410 it should be possible to use 8 bit SRAM datawith to 16 bit RAM but either way I try it doesn't work.

Please help me understand what is wrong here.

20 REPLIES 20
Posted on October 23, 2017 at 14:29

Direct mode is not allowed when memory-to-memory is used.

While the HW appears to enable FIFO implicitly in that case, I'd try to set it explicitly, together with setting the peripheral size to halfword.

I'd also try to read the halfwords from the external memory by the processor first.

JW

Posted on October 23, 2017 at 16:49

Have you throughly validated the memory function in normal, non-cached, usage?

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
Posted on October 23, 2017 at 14:58

So it need to be burst mode? And it should be memory to memory, not peripeheral to memory?

I changed accrdoing to your comments:

s_hDMA.Init.Channel = DMA_CHANNEL_0; //DMA_CHANNEL_0

s_hDMA.Init.Direction = DMA_MEMORY_TO_MEMORY; //M2M transfer mode

s_hDMA.Init.PeriphInc = DMA_PINC_ENABLE; //Peripheral increment mode Enable

s_hDMA.Init.MemInc = DMA_MINC_ENABLE; //Memory increment mode Enable

s_hDMA.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; //Peripheral data alignment : Word

s_hDMA.Init.MemDataAlignment = DMA_PDATAALIGN_HALFWORD; //memory data alignment : Word

s_hDMA.Init.Mode = DMA_NORMAL; //Normal DMA mode

s_hDMA.Init.Priority = DMA_PRIORITY_HIGH; //priority level : high

s_hDMA.Init.FIFOMode = DMA_FIFOMODE_DISABLE; //FIFO mode disabled

s_hDMA.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;

s_hDMA.Init.MemBurst = DMA_MBURST_INC16; //Memory burst

s_hDMA.Init.PeriphBurst = DMA_PBURST_INC16; //Peripheral burst

sramHandle.Init.NSBank = FMC_NORSRAM_BANK1;

sramHandle.Init.DataAddressMux = FMC_DATA_ADDRESS_MUX_DISABLE;

sramHandle.Init.MemoryType = FMC_MEMORY_TYPE_SRAM;

sramHandle.Init.MemoryDataWidth = FMC_NORSRAM_MEM_BUS_WIDTH_8;

sramHandle.Init.BurstAccessMode = FMC_BURST_ACCESS_MODE_ENABLE;

sramHandle.Init.WaitSignalPolarity = FMC_WAIT_SIGNAL_POLARITY_LOW;

sramHandle.Init.WaitSignalActive = FMC_WAIT_TIMING_BEFORE_WS;

sramHandle.Init.WriteOperation = FMC_WRITE_OPERATION_DISABLE;

sramHandle.Init.WaitSignal = FMC_WAIT_SIGNAL_DISABLE;

sramHandle.Init.ExtendedMode = FMC_EXTENDED_MODE_DISABLE;

sramHandle.Init.AsynchronousWait = FMC_ASYNCHRONOUS_WAIT_ENABLE;

sramHandle.Init.WriteBurst = FMC_WRITE_BURST_DISABLE;

sramHandle.Init.ContinuousClock = FMC_CONTINUOUS_CLOCK_SYNC_ASYNC;

sramHandle.Init.WriteFifo = FMC_WRITE_FIFO_DISABLE;

When I run it I get the following (Data in SRAM is 0xAAAA at all adresses).

Reading witout DMA (using HAL_SRAM_Read_16b(&sramHandle, 0, SRAMData1, 20);):

Reading SRAM:

[0]: AAAA

[1]: 0

[2]: FFFF

[3]: FFF

[4]: 20

[5]: 0

[6]: 922A

[7]: B73A

[8]: 7EF7

[9]: DED7

[10]: 3F69

[11]: 68FF

[12]: A3FE

[13]: 177A

[14]: 3034

[15]: FA6D

[16]: 2BF3

[17]: BCA

[18]: 12CD

[19]: 6D5F

With DMA:

RAM fail, read AA at 0 expected AAAA...

RAM fail, read AA at 1 expected AAAA...

RAM fail, read AA at 2 expected AAAA...

RAM fail, read AA at 3 expected AAAA...

RAM fail, read AA at 4 expected AAAA...

RAM fail, read AA at 5 expected AAAA...

RAM fail, read AA at 6 expected AAAA...

RAM fail, read AA at 7 expected AAAA...

RAM fail, read AA at 8 expected AAAA...

RAM fail, read AA at 9 expected AAAA...

RAM fail, read AA at A expected AAAA...

RAM fail, read AA at B expected AAAA...

RAM fail, read AA at C expected AAAA...

For me it doesn't make sense

Posted on October 23, 2017 at 15:06

So it need to be burst mode?

No, bursts are not necessary.

I said, enable FIFO.

And it should be memory to memory, not peripeheral to memory?

It *was* mem-to-mem in your first post.

I don't Cube. I also don't understand the data you present us here, how did you obtain them. Do you read from various external memory addresses?

For the DMA case, show us the content of the target (internal) memory.

JW

Posted on October 23, 2017 at 16:07

Data is written by another device into SRAM and read by the F7. The data and adresses are multiplexed between two SRAM. The writing and SRAM has been working when STR912 was connected to the SRAM and now the STR912 is beeing replaced by the F7.

I changed according to:

s_hDMA.Init.Channel = DMA_CHANNEL_0; //DMA_CHANNEL_0

s_hDMA.Init.Direction = DMA_MEMORY_TO_MEMORY; //M2M transfer mode

s_hDMA.Init.PeriphInc = DMA_PINC_ENABLE; //Peripheral increment mode Enable

s_hDMA.Init.MemInc = DMA_MINC_ENABLE; //Memory increment mode Enable

s_hDMA.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; //Peripheral data alignment : Word

s_hDMA.Init.MemDataAlignment = DMA_PDATAALIGN_HALFWORD; //memory data alignment : Word

s_hDMA.Init.Mode = DMA_NORMAL; //Normal DMA mode

s_hDMA.Init.Priority = DMA_PRIORITY_HIGH; //priority level : high

s_hDMA.Init.FIFOMode = DMA_FIFOMODE_ENABLE; //FIFO mode disabled

s_hDMA.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;

s_hDMA.Init.MemBurst = DMA_MBURST_SINGLE; //Memory burst

s_hDMA.Init.PeriphBurst = DMA_PBURST_SINGLE; //Peripheral burst

sramHandle.Init.NSBank = FMC_NORSRAM_BANK1;

sramHandle.Init.DataAddressMux = FMC_DATA_ADDRESS_MUX_DISABLE;

sramHandle.Init.MemoryType = FMC_MEMORY_TYPE_SRAM;

sramHandle.Init.MemoryDataWidth = FMC_NORSRAM_MEM_BUS_WIDTH_8;

sramHandle.Init.BurstAccessMode = FMC_BURST_ACCESS_MODE_DISABLE;

sramHandle.Init.WaitSignalPolarity = FMC_WAIT_SIGNAL_POLARITY_LOW;

sramHandle.Init.WaitSignalActive = FMC_WAIT_TIMING_BEFORE_WS;

sramHandle.Init.WriteOperation = FMC_WRITE_OPERATION_DISABLE;

sramHandle.Init.WaitSignal = FMC_WAIT_SIGNAL_DISABLE;

sramHandle.Init.ExtendedMode = FMC_EXTENDED_MODE_DISABLE;

sramHandle.Init.AsynchronousWait = FMC_ASYNCHRONOUS_WAIT_ENABLE;

sramHandle.Init.WriteBurst = FMC_WRITE_BURST_DISABLE;

sramHandle.Init.ContinuousClock = FMC_CONTINUOUS_CLOCK_SYNC_ASYNC;

sramHandle.Init.WriteFifo = FMC_WRITE_FIFO_DISABLE;

And here is data from JTAGdebugger from uint16 SRAMData1[2048]:

Name : SRAMData1[0]

Details:170

Default:170

Decimal:170

Hex:0xaa

Binary:10101010

Octal:0252

Name : SRAMData1[1]

Details:170

Default:170

Decimal:170

Hex:0xaa

Binary:10101010

Octal:0252

Name : SRAMData1[2]

Details:170

Default:170

Decimal:170

Hex:0xaa

Binary:10101010

Octal:0252

Name : SRAMData1[3]

Details:170

Default:170

Decimal:170

Hex:0xaa

Binary:10101010

Octal:0252

Name : SRAMData1[4]

Details:170

Default:170

Decimal:170

Hex:0xaa

Binary:10101010

Octal:0252

Name : SRAMData1[5]

Details:170

Default:170

Decimal:170

Hex:0xaa

Binary:10101010

Octal:0252

Name : SRAMData1[6]

Details:170

Default:170

Decimal:170

Hex:0xaa

Binary:10101010

Octal:0252

Name : SRAMData1[7]

Details:170

Default:170

Decimal:170

Hex:0xaa

Binary:10101010

Octal:0252

Name : SRAMData1[8]

Details:170

Default:170

Decimal:170

Hex:0xaa

Binary:10101010

Octal:0252

Name : SRAMData1[9]

Details:170

Default:170

Decimal:170

Hex:0xaa

Binary:10101010

Octal:0252

Name : SRAMData1[10]

Details:170

Default:170

Decimal:170

Hex:0xaa

Binary:10101010

Octal:0252

Name : SRAMData1[11]

Details:170

Default:170

Decimal:170

Hex:0xaa

Binary:10101010

Octal:0252

Name : SRAMData1[12]

Details:170

Default:170

Decimal:170

Hex:0xaa

Binary:10101010

Octal:0252

Name : SRAMData1[13]

Details:170

Default:170

Decimal:170

Hex:0xaa

Binary:10101010

Octal:0252

Name : SRAMData1[14]

Details:170

Default:170

Decimal:170

Hex:0xaa

Binary:10101010

Octal:0252

Name : SRAMData1[15]

Details:170

Default:170

Decimal:170

Hex:0xaa

Binary:10101010

Octal:0252

Name : SRAMData1[16]

Details:170

Default:170

Decimal:170

Hex:0xaa

Binary:10101010

Octal:0252
Posted on October 23, 2017 at 17:00

Yeah, running without DMA gives the same result.

Posted on October 23, 2017 at 19:19

Note, that Clive said 'non-cached', not 'non-DMA'.

And manual bit-banging all the address/control signals, and reading the data lines?

And what says the LA?

JW

Posted on October 24, 2017 at 09:28

Please clarify how I run it 'noncached'.

I haven't tested bitbanging yet. Good idea I will try.

What is LA?

Posted on October 24, 2017 at 09:36

Please clarify how I run it 'noncached'.

Switch data cache off. Read AN4838 and AN4839.

What is LA?

Logic Analyzer.

JW