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 24, 2017 at 09:41

Aha. We tested with LA. Read signal looks ok, but adress seems a bit wierd. It looks like the adresses A12, A13, A14, A15 seem to be out of order. Thus it looks like adressorder is:

A0, A12, A13, A14, A15, A1, A2, A3 etc....

I am running a sequential reading and looking how fast the signal change.

rickard2
Associate III
Posted on October 24, 2017 at 17:04

I changed everything to just run on 8 bit values:

__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_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_ONLY;

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;

}

__FMC_NORSRAM_ENABLE(FMC_NORSRAM_DEVICE, FMC_NORSRAM_BANK1);

__HAL_RCC_FMC_CLK_ENABLE();

SRAMInit = TRUE;

And then I print directly from memory:

#define EMI_START_ADDRESS ((uint32_t)0x60000000)

for(i = 0; i < 10; i++)

{

printf('[%d] = %X\r\n', i, *(__IO uint8_t *)(EMI_START_ADDRESS + i));

}

And now I get every second value 0:

[0] = AA

[1] = 0

[2] = AA

[3] = 0

[4] = AA

[5] = 0

[6] = AA

[7] = 0

[8] = AA

[9] = 0
Posted on October 24, 2017 at 18:07

Is there a question?

Did you fix the address mismatch problem?

JW

Posted on October 25, 2017 at 09:57

The setup says adress_data_mux_disable

And what do the registers say?

JW

Posted on October 25, 2017 at 08:59

Sorry panic mode :-).....

I now connect LA and will check signal by signal by reading one byte at a time

Posted on October 25, 2017 at 09:50

I see now that when I do one reading:

printf('[%d] = %X\r\n', i, *(__IO uint8_t *)(EMI_START_ADDRESS + i));

the STM32F7 will read 16 bytes (using LA), thus the readings are cached.

I read the notes but couldn't find how to just disable the caching on external SRAM? How can this be done with HAL?

Adress signal looks ok BUT it seem that the the F7 will try to drive the signals D1 and D3 towards ground on every odd reading causing the reading of 0 when the SRAM try to drive it high on 0xAAAA this bits should be high all the time. The setup says adress_data_mux_disable otherwise this would seem like a the cause.

Any other ideas what could cause this?

Posted on October 25, 2017 at 10:28

I am not really sure where to find this. Which adress should I look at?

Posted on October 25, 2017 at 11:11

I get the followings reading

[0] = 30DB

[8] = 30D2

[16] = 30D2

[24] = 30D2

when using this code

for(i = 0; i < 0x1C; i += 😎

{

printf('[%d] = %X\r\n', i, *(__IO uint32_t *)(0xA0000000 + i));

}

So I guess this means (ref man RM0410 at page 404)

FMC_BCR1 = 

30DB, which menas MUX is enable

FMC_BCR2 = 

30D2, which menas MUX is

enable

FMC_BCR3= 

30D2, which menas MUX is

enable

FMC_BCR3 = 

30D2, which menas MUX is

enable

So I think mux is enabled on SRAM bank1?? Correcr?

Posted on October 25, 2017 at 11:43

These are the reset values.

Draw your own conclusions.

Have no debugger?

JW

Posted on October 25, 2017 at 11:48

I have and then I get the followng when debugging HAL library

 Device->BTCR[Init->NSBank] = tmpr;

Where tmpr = 0x200000 which seem to be the values I try to set...but it doesn't seem to get into the registers as they look reset when reading them

Device is 0xa0000000 accoring to debugger.

Ok when enabling the clock the regiesets are reset:

_HAL_RCC_FMC_CLK_ENABLE();