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-23 05:29 AM
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
2017-10-23 07:49 AM
Have you throughly validated the memory function in normal, non-cached, usage?
2017-10-23 07:58 AM
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 burstsramHandle.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]: 6D5FWith 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
2017-10-23 08:06 AM
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
2017-10-23 09:07 AM
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:0252Name : SRAMData1[1]
Details:170 Default:170 Decimal:170 Hex:0xaa Binary:10101010 Octal:0252Name : SRAMData1[2]
Details:170 Default:170 Decimal:170 Hex:0xaa Binary:10101010 Octal:0252Name : SRAMData1[3]
Details:170 Default:170 Decimal:170 Hex:0xaa Binary:10101010 Octal:0252Name : SRAMData1[4]
Details:170 Default:170 Decimal:170 Hex:0xaa Binary:10101010 Octal:0252Name : SRAMData1[5]
Details:170 Default:170 Decimal:170 Hex:0xaa Binary:10101010 Octal:0252Name : SRAMData1[6]
Details:170 Default:170 Decimal:170 Hex:0xaa Binary:10101010 Octal:0252Name : SRAMData1[7]
Details:170 Default:170 Decimal:170 Hex:0xaa Binary:10101010 Octal:0252Name : SRAMData1[8]
Details:170 Default:170 Decimal:170 Hex:0xaa Binary:10101010 Octal:0252Name : SRAMData1[9]
Details:170 Default:170 Decimal:170 Hex:0xaa Binary:10101010 Octal:0252Name : SRAMData1[10]
Details:170 Default:170 Decimal:170 Hex:0xaa Binary:10101010 Octal:0252Name : SRAMData1[11]
Details:170 Default:170 Decimal:170 Hex:0xaa Binary:10101010 Octal:0252Name : SRAMData1[12]
Details:170 Default:170 Decimal:170 Hex:0xaa Binary:10101010 Octal:0252Name : SRAMData1[13]
Details:170 Default:170 Decimal:170 Hex:0xaa Binary:10101010 Octal:0252Name : SRAMData1[14]
Details:170 Default:170 Decimal:170 Hex:0xaa Binary:10101010 Octal:0252Name : SRAMData1[15]
Details:170 Default:170 Decimal:170 Hex:0xaa Binary:10101010 Octal:0252Name : SRAMData1[16]
Details:170 Default:170 Decimal:170 Hex:0xaa Binary:10101010 Octal:02522017-10-23 10:00 AM
Yeah, running without DMA gives the same result.
2017-10-23 12:19 PM
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
2017-10-24 02:28 AM
Please clarify how I run it 'noncached'.
I haven't tested bitbanging yet. Good idea I will try.
What is LA?
2017-10-24 02:36 AM
Please clarify how I run it 'noncached'.
Switch data cache off. Read AN4838 and AN4839.
What is LA?
Logic Analyzer.
JW