Forum: Mikrocontroller und Digitale Elektronik STM32: externes SRAM, FMC und DMA


von Denise T. (Gast)


Lesenswert?

Hallo!

zur Zeit versuche ich Daten eines externen SRAMs (CY62167EV30 MoBL) mit 
FMC zu lesen und zu schreiben. Ich nutze hierfür den STM32F767. Ziel 
wäre es das SRAM mit DMA lesen und schreiben zu können. Da hier leider 
immer der gleiche seltsame Wert zurückkommt (0x4000), habe ich es 
zunächst ohne versucht. Leider funktioniert das ganze auch nicht 
wirklich. Die ersten 113 Werte passen, die darauffolgenden sind wiederum 
0x4000. Ich habe leider keine Ahnung wieso das so ist. Dieser Wert kommt 
mir auch ganz komisch vor. Als Basis habe ich den Code mit dem Cube 
erstellt. Entsprechend "herumprobiert" habe ich mit einem Beispiel, von 
einem Evalboard(ich weiss gerade gar nicht mehr welches das war). Die 
AN4570 habe ich bereits gelesen, hilft aber trotz toller Erklärungen 
nicht weiter. Es wäre toll, wenn mir jemand ein paar Hinweise geben 
könnte, wo es haken könnte, bin gerade etwas frustriert.

Folgender Code wird verwendet (Ausschnitte):

#define BUFFER_SIZE         ((uint32_t)0x800)
#define WRITE_READ_ADDR     ((uint32_t)0x0)
#define WRITING_OFFSET      ((uint32_t)0xC20F)

DMA_HandleTypeDef hdma_memtomem_dma2_stream0;
SRAM_HandleTypeDef hsram1;
/* Read/Write Buffers */
uint16_t aTxBuffer[BUFFER_SIZE];
uint16_t aRxBuffer[BUFFER_SIZE];
__IO uint32_t uwWriteReadStatus = 0;

static void SRAM_Init(void)
{
  /* SRAM device configuration */
  hsram1.Instance = FMC_NORSRAM_DEVICE;
  hsram1.Extended = FMC_NORSRAM_EXTENDED_DEVICE;

  Timing.AddressSetupTime      = 7;
  Timing.AddressHoldTime       = 1;
  Timing.DataSetupTime         = 7;
  //Timing.BusTurnAroundDuration = 1;
  //Timing.CLKDivision           = 2;
  //Timing.DataLatency           = 5;
  Timing.AccessMode            = FMC_ACCESS_MODE_A;

  hsram1.Init.NSBank             = FMC_NORSRAM_BANK3;
  hsram1.Init.DataAddressMux     = FMC_DATA_ADDRESS_MUX_DISABLE;
  hsram1.Init.MemoryType         = FMC_MEMORY_TYPE_SRAM;
  hsram1.Init.MemoryDataWidth    = SRAM_MEMORY_WIDTH;
  hsram1.Init.BurstAccessMode    = FMC_BURST_ACCESS_MODE_ENABLE;
  hsram1.Init.WaitSignalPolarity = FMC_WAIT_SIGNAL_POLARITY_LOW;
  hsram1.Init.WaitSignalActive   = FMC_WAIT_TIMING_DURING_WS;
  hsram1.Init.WriteOperation     = FMC_WRITE_OPERATION_ENABLE;
  hsram1.Init.WaitSignal         = FMC_WAIT_SIGNAL_DISABLE;
  hsram1.Init.ExtendedMode       = FMC_EXTENDED_MODE_DISABLE;
  hsram1.Init.AsynchronousWait   = FMC_ASYNCHRONOUS_WAIT_DISABLE;
  hsram1.Init.WriteBurst         = 
FMC_WRITE_BURST_ENABLE;//FMC_WRITE_BURST_DISABLE;
  hsram1.Init.ContinuousClock    = 
FMC_CONTINUOUS_CLOCK_SYNC_ASYNC;//FMC_CONTINUOUS_CLOCK_SYNC_ONLY;
  hsram1.Init.WriteFifo          = FMC_WRITE_FIFO_ENABLE;

   /* Initialize the SRAM controller */
  if(HAL_SRAM_Init(&hsram1, &Timing, &Timing) != HAL_OK)
  {
    /* Initialization Error */
    Error_Handler();
  }
}

static void MX_DMA_Init(void)
{
  /* DMA controller clock enable */
  __HAL_RCC_DMA2_CLK_ENABLE();

  /* Configure DMA request hdma_memtomem_dma2_stream0 on DMA2_Stream0 */
  hdma_memtomem_dma2_stream0.Instance = DMA2_Stream0;
  hdma_memtomem_dma2_stream0.Init.Channel = DMA_CHANNEL_0;
  hdma_memtomem_dma2_stream0.Init.Direction = DMA_MEMORY_TO_MEMORY;
  hdma_memtomem_dma2_stream0.Init.PeriphInc = DMA_PINC_ENABLE;
  hdma_memtomem_dma2_stream0.Init.MemInc = DMA_MINC_ENABLE;
  hdma_memtomem_dma2_stream0.Init.PeriphDataAlignment = 
DMA_PDATAALIGN_HALFWORD;
  hdma_memtomem_dma2_stream0.Init.MemDataAlignment = 
DMA_MDATAALIGN_HALFWORD;
  hdma_memtomem_dma2_stream0.Init.Mode = DMA_NORMAL;
  hdma_memtomem_dma2_stream0.Init.Priority = DMA_PRIORITY_LOW;
  hdma_memtomem_dma2_stream0.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
  hdma_memtomem_dma2_stream0.Init.FIFOThreshold = 
DMA_FIFO_THRESHOLD_FULL;
  hdma_memtomem_dma2_stream0.Init.MemBurst = DMA_MBURST_INC8;
  hdma_memtomem_dma2_stream0.Init.PeriphBurst = DMA_MBURST_INC8;

  hsram1.hdma = &hdma_memtomem_dma2_stream0;
  hdma_memtomem_dma2_stream0.Parent = &hsram1;

   /* Deinitialize the Stream for new transfer */
   HAL_DMA_DeInit(&hdma_memtomem_dma2_stream0);

  if (HAL_DMA_Init(&hdma_memtomem_dma2_stream0) != HAL_OK)
  {
    _Error_Handler(_FILE_, _LINE_);
  }
/* DMA interrupt init */
  /* DMA2_Stream0_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);
}

static void MX_GPIO_Init(void)
{

  GPIO_InitTypeDef GPIO_InitStruct;

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOE_CLK_ENABLE();
  __HAL_RCC_GPIOF_CLK_ENABLE();
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOG_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();
  __HAL_RCC_GPIOD_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_RESET);

  /*Configure GPIO pin : PB8 */
  GPIO_InitStruct.Pin = GPIO_PIN_8;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

}

static void HAL_FMC_MspInit(void){
  /* USER CODE BEGIN FMC_MspInit 0 */

  /* USER CODE END FMC_MspInit 0 */
  GPIO_InitTypeDef GPIO_InitStruct;
  if (FMC_Initialized) {
    return;
  }
  FMC_Initialized = 1;
  /* Peripheral clock enable */
  __HAL_RCC_FMC_CLK_ENABLE();

  /** FMC GPIO Configuration
  PE3   ------> FMC_A19
  PF0   ------> FMC_A0
  PF1   ------> FMC_A1
  PF2   ------> FMC_A2
  PF3   ------> FMC_A3
  PF4   ------> FMC_A4
  PF5   ------> FMC_A5
  PF12   ------> FMC_A6
  PF13   ------> FMC_A7
  PF14   ------> FMC_A8
  PF15   ------> FMC_A9
  PG0   ------> FMC_A10
  PG1   ------> FMC_A11
  PE7   ------> FMC_D4
  PE8   ------> FMC_D5
  PE9   ------> FMC_D6
  PE10   ------> FMC_D7
  PE11   ------> FMC_D8
  PE12   ------> FMC_D9
  PE13   ------> FMC_D10
  PE14   ------> FMC_D11
  PE15   ------> FMC_D12
  PD8   ------> FMC_D13
  PD9   ------> FMC_D14
  PD10   ------> FMC_D15
  PD11   ------> FMC_A16
  PD12   ------> FMC_A17
  PD13   ------> FMC_A18
  PD14   ------> FMC_D0
  PD15   ------> FMC_D1
  PG2   ------> FMC_A12
  PG3   ------> FMC_A13
  PG4   ------> FMC_A14
  PG5   ------> FMC_A15
  PC7   ------> FMC_NE1
  PD0   ------> FMC_D2
  PD1   ------> FMC_D3
  PD4   ------> FMC_NOE
  PD5   ------> FMC_NWE
  PE0   ------> FMC_NBL0
  PE1   ------> FMC_NBL1
  */
  GPIO_InitStruct.Pin = GPIO_PIN_3|GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9
                          |GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13
                          |GPIO_PIN_14|GPIO_PIN_15;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
  HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);

  GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3
                          |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_12|GPIO_PIN_13
                          |GPIO_PIN_14|GPIO_PIN_15;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
  HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);

  GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3
                          |GPIO_PIN_4|GPIO_PIN_5;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
  HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);

  GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11
                          |GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15
                          |GPIO_PIN_0|GPIO_PIN_1;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
  HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

  GPIO_InitStruct.Pin = GPIO_PIN_7;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.Alternate = GPIO_AF9_FMC;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

  GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_5;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
  HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

  GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
  HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);

  /* USER CODE BEGIN FMC_MspInit 1 */

  /* USER CODE END FMC_MspInit 1 */
}

void DMA2_Stream0_IRQHandler(void)
{
  /* USER CODE BEGIN DMA2_Stream0_IRQn 0 */

  /* USER CODE END DMA2_Stream0_IRQn 0 */
  HAL_DMA_IRQHandler(&hdma_memtomem_dma2_stream0);
  /* USER CODE BEGIN DMA2_Stream0_IRQn 1 */
  /* USER CODE END DMA2_Stream0_IRQn 1 */
}

//zum Testen, deswegen etwas wild ;), aber ich denke man erkennt welche 
Funktionen ich nutze.
uint8_t sram_tests(void)
{
/*##-2- SRAM memory read/write access 
######################################*/
  /* Fill the buffer to write */

/*
  HAL_SRAM_Write_DMA(&hsram1, (uint32_t *)(SRAM_BANK_ADDR + 
WRITE_READ_ADDR), (uint32_t *)aTxBuffer, 1);

  while(hsram1.hdma->State != HAL_DMA_STATE_READY)
  {
    HAL_Delay(50);
  }
  HAL_SRAM_Read_DMA(&hsram1, (uint32_t *)(SRAM_BANK_ADDR + 
WRITE_READ_ADDR), (uint32_t *)aRxBuffer, 1);

  while(hsram1.hdma->State != HAL_DMA_STATE_READY)
    {
    HAL_Delay(50);
    }
  uwWriteReadStatus = Buffercmp(aTxBuffer, aRxBuffer, BUFFER_SIZE);

  */ //HAL_SRAM_Write_16b(&hsram1, (uint32_t *)(SRAM_BANK_ADDR + 
WRITE_READ_ADDR), aTxBuffer, BUFFER_SIZE);
     HAL_SRAM_Read_16b(&hsram1, (uint32_t *)(SRAM_BANK_ADDR + 
WRITE_READ_ADDR), aRxBuffer, BUFFER_SIZE);
 /* uwWriteReadStatus = Buffercmp(aTxBuffer, aRxBuffer, BUFFER_SIZE);
   if(uwWriteReadStatus)
   {
    return 1;
   }
  else
   {
  return 0;
   }*/
}

Vielen Dank schonmal!

von Regeln Erklehrbehr (Gast)


Angehängte Dateien:

Lesenswert?

Denise T. schrieb:
> bin gerade etwas frustriert.

Ich bin gerade sehr frustriert.

Denn du irritierst die Leser mit Nichteinhaltung einer oder
mehrerer einfacher Minimalregeln.

von Denise T. (Gast)


Lesenswert?

Ohje, ja wer lesen kann ist klar im Vorteil. Sorry!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.