cancel
Showing results for 
Search instead for 
Did you mean: 

stm32f429i-discovery dcmi->sdram address 0xD0000000

prothan
Associate II
Posted on June 09, 2015 at 06:58

Hello,

I am working with stm32f429 using with a ov7670 camera with the dcmi using dma. It works fine if I do a capture into sram. I have also successfully initialized and tested the 8mb sdram @ 0xD0000000. What I would like to do is capture the image directly into sdram @ 0xD0000000. However, I am having issues with this. When I call HAL_DCMI_Start_DMA(&hdcmi, DCMI_MODE_SNAPSHOT, (uint32_t) 0xD0000000,38400/4) (**I understand this image isn't large, but I would like to do larger, so need sdram). I read the buffer after the capture is done, looks like the 1st word is transferred, but the rest of frame is not present. Is this due to the code handling not incrementing the sdram address properly? I suppose I could do the dma transfer to sram and use the line interrupt to transfer to sdram, but I would like to a direct transfer to 0xD0000000 if possible, if anybody could provide guidance, I would appreciate it. I example in a peripheral lib or cube would be helpful. 

Thanks

#stm32f429 #dcmi
3 REPLIES 3
stm322399
Senior
Posted on June 10, 2015 at 20:14

Moving from SRAM to DRAM as DMA target should be transparent, simply change the address and you're done.

Unfortunately this is not true. DRAM is not physically accessed the same way than SRAM. DMA configuration matters, in particular regarding FIFO burst and thresholds.

Post here more data about your configuration:

* DMA channel initialization values

* Speed of the DCMI interface

* Speed of the DRAM

Can you make sure that DMA return without any error ?

Are you using DRAM for another purpose, during the pixel data transfer (network buffer, thread stack, code execution ...) ?

prothan
Associate II
Posted on June 12, 2015 at 07:09

Gonzalez,

I played around a little more and got it working, I was able to get an image, but it was distorted, so it looks like I need to optimize my parameters. I am running the stm32f429 with a clock of 168 mhz, so I should be getting a clock at the sdram of 84mhz. The REFRESH_COUNT is 856, but I am pretty sure I need to change that to 922. I answered your questions below. I am supplying the camera with a 12mhz clock, which is configured for a 24mhz pixel clock output. Can you recommend optimum settings sdram for this application?

Thanks

* DMA channel initialization values

    hdma_dcmi.Instance = DMA2_Stream7;

    hdma_dcmi.Init.Channel = DMA_CHANNEL_1;

    hdma_dcmi.Init.Direction = DMA_PERIPH_TO_MEMORY;

    hdma_dcmi.Init.PeriphInc = DMA_PINC_DISABLE;

    hdma_dcmi.Init.MemInc = DMA_MINC_ENABLE;

    hdma_dcmi.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;

    hdma_dcmi.Init.MemDataAlignment = DMA_PDATAALIGN_WORD;

    hdma_dcmi.Init.Mode = DMA_NORMAL;

    hdma_dcmi.Init.Priority = DMA_PRIORITY_HIGH;

    hdma_dcmi.Init.FIFOMode = DMA_FIFOMODE_DISABLE;

    hdma_dcmi.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_1QUARTERFULL;

    hdma_dcmi.Init.MemBurst = DMA_PBURST_INC4;

    hdma_dcmi.Init.PeriphBurst = DMA_PBURST_SINGLE;

* Speed of the DCMI interface

  hdcmi.Instance = DCMI;

  hdcmi.Init.SynchroMode = DCMI_SYNCHRO_HARDWARE;

  hdcmi.Init.PCKPolarity = DCMI_PCKPOLARITY_RISING;

  hdcmi.Init.VSPolarity = DCMI_VSPOLARITY_HIGH;

  hdcmi.Init.HSPolarity = DCMI_HSPOLARITY_LOW;

  hdcmi.Init.CaptureRate = DCMI_CR_ALL_FRAME;

  hdcmi.Init.ExtendedDataMode = DCMI_EXTEND_DATA_8B;

  hdcmi.Init.JPEGMode = DCMI_JPEG_DISABLE;

* Speed of the DRAM

Not precisely sure what you are asking for so I will give you what I have. I am using

ISSI IS42S16400

included with the board. Init params are as follows

        SDRAM_Timing.LoadToActiveDelay    = 2;

        /* TXSR: min=70ns (6x11.90ns) */

        SDRAM_Timing.ExitSelfRefreshDelay = 7;

        /* TRAS: min=42ns (4x11.90ns) max=120k (ns) */

        SDRAM_Timing.SelfRefreshTime      = 4;

        /* TRC:  min=63 (6x11.90ns) */

        SDRAM_Timing.RowCycleDelay        = 7;

        /* TWR:  2 Clock cycles */

        SDRAM_Timing.WriteRecoveryTime    = 2;

        /* TRP:  15ns => 2x11.90ns */

        SDRAM_Timing.RPDelay              = 2;

        /* TRCD: 15ns => 2x11.90ns */

        SDRAM_Timing.RCDDelay             = 2;

        hsdram.Init.SDBank             = FMC_SDRAM_BANK2;

        hsdram.Init.ColumnBitsNumber   = FMC_SDRAM_COLUMN_BITS_NUM_8;

        hsdram.Init.RowBitsNumber      = FMC_SDRAM_ROW_BITS_NUM_12;

        hsdram.Init.MemoryDataWidth    = FMC_SDRAM_MEM_BUS_WIDTH_16;

        hsdram.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4;

        hsdram.Init.CASLatency         = FMC_SDRAM_CAS_LATENCY_3;

        hsdram.Init.WriteProtection    = FMC_SDRAM_WRITE_PROTECTION_DISABLE;

        hsdram.Init.SDClockPeriod      = FMC_SDRAM_CLOCK_PERIOD_2;

        hsdram.Init.ReadBurst          = FMC_SDRAM_RBURST_DISABLE;

        hsdram.Init.ReadPipeDelay      = FMC_SDRAM_RPIPE_DELAY_1;

static void SDRAM_Initialization_Sequence(SDRAM_HandleTypeDef *hsdram, FMC_SDRAM_CommandTypeDef *Command)

{

  __IO uint32_t tmpmrd =0;

  /* Step 3:  Configure a clock configuration enable command */

  Command->CommandMode              = FMC_SDRAM_CMD_CLK_ENABLE;

  Command->CommandTarget          = FMC_SDRAM_CMD_TARGET_BANK2;

  Command->AutoRefreshNumber      = 1;

  Command->ModeRegisterDefinition = 0;

  /* Send the command */

  HAL_SDRAM_SendCommand(hsdram, Command, 0x1000);

  /* Step 4: Insert 100 ms delay */

  HAL_Delay(100);

  /* Step 5: Configure a PALL (precharge all) command */

  Command->CommandMode              = FMC_SDRAM_CMD_PALL;

  Command->CommandTarget          = FMC_SDRAM_CMD_TARGET_BANK2;

  Command->AutoRefreshNumber      = 1;

  Command->ModeRegisterDefinition = 0;

  /* Send the command */

  HAL_SDRAM_SendCommand(hsdram, Command, 0x1000);

  /* Step 6 : Configure a Auto-Refresh command */

  Command->CommandMode              = FMC_SDRAM_CMD_AUTOREFRESH_MODE;

  Command->CommandTarget          = FMC_SDRAM_CMD_TARGET_BANK2;

  Command->AutoRefreshNumber      =4;  //was 4

  Command->ModeRegisterDefinition = 0;

  /* Send the command */

  HAL_SDRAM_SendCommand(hsdram, Command, 0x1000);

  /* Step 7: Program the external memory mode register */

  tmpmrd = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_2          |

                     SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL   |

                     SDRAM_MODEREG_CAS_LATENCY_3           |

                     SDRAM_MODEREG_OPERATING_MODE_STANDARD |

                     SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;

  Command->CommandMode = FMC_SDRAM_CMD_LOAD_MODE;

  Command->CommandTarget          = FMC_SDRAM_CMD_TARGET_BANK2;

  Command->AutoRefreshNumber      = 1;

  Command->ModeRegisterDefinition =tmpmrd;

  /* Send the command */

  HAL_SDRAM_SendCommand(hsdram, Command, 0x1000);

  /* Step 8: Set the refresh rate counter */

  /* (15.62 us x Freq) - 20 */

  /* Set the device refresh counter */

  HAL_SDRAM_ProgramRefreshRate(hsdram, REFRESH_COUNT);

}

Can you make sure that DMA return without any error ?

It is returning.

Are you using DRAM for another purpose, during the pixel data transfer (network buffer, thread stack, code execution ...) ?

No, just a frame buffer.

stm322399
Senior
Posted on June 12, 2015 at 18:01

If you get an image, that is *only* distorted, I guess that the DRAM is correctly initialized.

You must be careful when you deal with image width (number of pixels) and image stride (including some blank pixels).

Regarding the DMA, my successful configuration differs from yours as follow:

* FIFOMode is enabled

* MemBurst is single

Note that you apparently do not suffer from those differences. Enabling FIFO is a smart choice anyway.

Have fun.