2017-10-23 05:00 AM
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 bursts_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.
2017-10-24 02:41 AM
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.
2017-10-24 08:04 AM
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] = 02017-10-24 11:07 AM
Is there a question?
Did you fix the address mismatch problem?
JW
2017-10-25 12:57 AM
The setup says adress_data_mux_disable
And what do the registers say?
JW
2017-10-25 01:59 AM
Sorry panic mode :-).....
I now connect LA and will check signal by signal by reading one byte at a time
2017-10-25 02:50 AM
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?
2017-10-25 03:28 AM
I am not really sure where to find this. Which adress should I look at?
2017-10-25 04:11 AM
I get the followings reading
[0] = 30DB
[8] = 30D2[16] = 30D2[24] = 30D2when using this code
for(i = 0; i < 0x1C; i += 8)
{ 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?
2017-10-25 04:43 AM
These are the reset values.
Draw your own conclusions.
Have no debugger?
JW
2017-10-25 04:48 AM
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();