STM32 QuadSPI CS-Frequenz erhöhen

OP #6166396
Lesenswert?
• ▲
▼
Moin,

und zwar möchte ich mit dem STM32F767ZI Chip per QuadSPI einen ADC 
ansprechen (AD4001). Wie im Protokoll definiert, habe ich dafür bereits 
das Turbobit gesetzt, sowie den SPI-Takt auf mind. 70 MHz gesetzt. Der 
Chip läuft mit 216MHz. Mein Problem besteht momentan noch darin, dass 
der CS vom Controller zu lange auf High ist bevor das nächste Sample 
ausgelesen wird (2µs von einer fallenden Flanke zur nächsten). Für die 2 
MSPs Abtastrate müsste dieser Abstand aber bei 500ns liegen.

Initialisierung QSPI:
1
static void MX_QUADSPI_Init(void)
2
{
3
  /* QUADSPI parameter configuration*/
4
  hqspi.Instance = QUADSPI;
5
  hqspi.Init.ClockPrescaler = 2;
6
  hqspi.Init.FifoThreshold = 1;
7
  hqspi.Init.SampleShifting = QSPI_SAMPLE_SHIFTING_NONE;
8
  hqspi.Init.FlashSize = 1;
9
  hqspi.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_2_CYCLE;
10
  hqspi.Init.ClockMode = QSPI_CLOCK_MODE_0;
11
  hqspi.Init.FlashID = QSPI_FLASH_ID_1;
12
  hqspi.Init.DualFlash = QSPI_DUALFLASH_DISABLE;
13
  if (HAL_QSPI_Init(&hqspi) != HAL_OK)
14
  {
15
    Error_Handler();
16
  }
17
}

Und hier die Konfiguration zum Auslesen der Daten im Indirect Read Mode.
1
    //Configure QSPI for receiving
2

3
    QSPI_CommandTypeDef qspicommand = {0};
4
    qspicommand.DdrMode = QSPI_DDR_MODE_DISABLE;
5
    qspicommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
6
    qspicommand.SIOOMode = QSPI_SIOO_INST_ONLY_FIRST_CMD;
7
    qspicommand.DataMode = QSPI_DATA_1_LINE;
8
    qspicommand.DummyCycles = 0;
9
    qspicommand.AlternateBytes = QSPI_ALTERNATE_BYTES_8_BITS;
10
    qspicommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
11
    qspicommand.AddressSize = QSPI_ADDRESS_8_BITS;
12
    qspicommand.AddressMode = QSPI_ADDRESS_NONE;
13
    qspicommand.InstructionMode = QSPI_INSTRUCTION_NONE;
14
    qspicommand.NbData = 2;
15

16
    HAL_QSPI_Command(&hqspi, &qspicommand, 0xFFFF);

Innerhalb meiner Main Methode erfolgt dann der Aufruf der Funktion zum 
Auslesen der Daten:
1
uint8_t tmp[2] = {0};
2
while(1){
3
HAL_QSPI_Receive(&hqspi, (uint8_t*)&tmp, 0x0000);
4
}

Da die HAL-Funktion ziemlich aufgebläht mit Statusabfragen und ähnlichem 
ist, habe ich die Methode etwas verkürzt:
1
HAL_StatusTypeDef HAL_QSPI_Receive(QSPI_HandleTypeDef *hqspi, uint8_t *pData, uint32_t Timeout)
2
{
3
  HAL_StatusTypeDef status = HAL_OK;
4
  uint32_t tickstart = HAL_GetTick();
5
  uint32_t addr_reg = READ_REG(hqspi->Instance->AR);
6
  __IO uint32_t *data_reg = &hqspi->Instance->DR;
7

8
  /* Configure counters and size of the handle */
9
  hqspi->RxXferCount = 2;
10
  hqspi->RxXferSize = 2;
11
  hqspi->pRxBuffPtr = pData;
12

13
      /* Configure QSPI: CCR register with functional as indirect read */
14
      MODIFY_REG(hqspi->Instance->CCR, QUADSPI_CCR_FMODE, QSPI_FUNCTIONAL_MODE_INDIRECT_READ);
15

16
      /* Start the transfer by re-writing the address in AR register */
17
      WRITE_REG(hqspi->Instance->AR, addr_reg);
18

19
      while(hqspi->RxXferCount > 0U)
20
      {
21
        /* Wait until FT or TC flag is set to read received data */
22
        status = QSPI_WaitFlagStateUntilTimeout(hqspi, (QSPI_FLAG_FT | QSPI_FLAG_TC), SET, tickstart, Timeout);
23

24
        *hqspi->pRxBuffPtr = *((__IO uint8_t *)data_reg);
25
        hqspi->pRxBuffPtr++;
26
        hqspi->RxXferCount--;
27
      }
28

29
     
30
        /* Wait until TC flag is set to go back in idle state */
31

32
        status = QSPI_WaitFlagStateUntilTimeout(hqspi, QSPI_FLAG_TC, SET, tickstart, Timeout);
33

34
          /* Clear Transfer Complete bit */
35
          __HAL_QSPI_CLEAR_FLAG(hqspi, QSPI_FLAG_TC);
36

37

38
  return status;
39
}

Damit habe ich die CS-Frequenz inzwischen auf 1 MHz erhöhen können, 
höher ging es bisher nicht. Ich habe auch schon versucht, den CS Pin 
ohne Alternate Function direkt anzusprechen und zu setzen, jedoch ohne 
nennenswerte Zeitersparnis. Die Compilerflags sind auch auf O3 gesetzt.
Gast #6166751
Lesenswert?
• ▲
▼
Da ist vielleicht immer noch viel zu viel Drumherum ... Das Abfragen der 
Flags kann man sich auch schenken, am besten gleich die 2 Bytes mit 
einem Halfword-Zugriff aus dem FIFO lesen. Wenn noch keine Daten da 
sind, blockiert der Zugriff so lange ...

Das ist ja auch ziemlich am Sinn dieses QSPI-Interfaces vorbei: Da ist 
darauf optimiert, mit einer CS-Aktivierung gleich einen großen 
Datenblock zu lesen/zu schreiben, deshalb ja auch ein FIFO. Für immer 
nur zwei kümmerliche Bytes ist wie Fahren mit angezogener Handbremse.

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.