Skocz do zawartości

STM32 SPI-DMA maksymalny rozmiar danych


kakus94

Pomocna odpowiedź

Mam do was pytanie. 
 

Używany procesor to STM32f429zi.

Czy DMA ma fizycznie ograniczony rozmiar ilości kopiowania danych do wartości 2^16 ??

HAL_StatusTypeDef HAL_SPI_Transmit_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)
{
  HAL_StatusTypeDef errorcode = HAL_OK;

  /* Check Direction parameter */
  assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE(hspi->Init.Direction));

  /* Process Locked */
  __HAL_LOCK(hspi);

  if(hspi->State != HAL_SPI_STATE_READY)
  {
    errorcode = HAL_BUSY;
    goto error;
  }

  if((pData == NULL) || (Size == 0))
  {
    errorcode = HAL_ERROR;
    goto error;
  }

  /* Set the transaction information */
  hspi->State       = HAL_SPI_STATE_BUSY_TX;
  hspi->ErrorCode   = HAL_SPI_ERROR_NONE;
  hspi->pTxBuffPtr  = (uint8_t *)pData;
  hspi->TxXferSize  = Size;
  hspi->TxXferCount = Size;

  /* Init field not used in handle to zero */
  hspi->pRxBuffPtr  = (uint8_t *)NULL;
  hspi->TxISR       = NULL;
  hspi->RxISR       = NULL;
  hspi->RxXferSize  = 0U;
  hspi->RxXferCount = 0U;
  .
  .
  .
  ( Fragment )
    
   
    
    typedef struct __SPI_HandleTypeDef
{
  SPI_TypeDef                *Instance;    /* SPI registers base address */

  SPI_InitTypeDef            Init;         /* SPI communication parameters */

  uint8_t                    *pTxBuffPtr;  /* Pointer to SPI Tx transfer Buffer */

  uint16_t                   TxXferSize;   /* SPI Tx Transfer size */

  __IO uint16_t              TxXferCount;  /* SPI Tx Transfer Counter */

  uint8_t                    *pRxBuffPtr;  /* Pointer to SPI Rx transfer Buffer */

  uint16_t                   RxXferSize;   /* SPI Rx Transfer size */

  __IO uint16_t              RxXferCount;  /* SPI Rx Transfer Counter */

  void                       (*RxISR)(struct __SPI_HandleTypeDef * hspi); /* function pointer on Rx ISR */

  void                       (*TxISR)(struct __SPI_HandleTypeDef * hspi); /* function pointer on Tx ISR */

  DMA_HandleTypeDef          *hdmatx;      /* SPI Tx DMA Handle parameters   */

  DMA_HandleTypeDef          *hdmarx;      /* SPI Rx DMA Handle parameters   */

  HAL_LockTypeDef            Lock;         /* Locking object                 */

  __IO HAL_SPI_StateTypeDef  State;        /* SPI communication state */

  __IO uint32_t              ErrorCode;    /* SPI Error code */

}SPI_HandleTypeDef;

   

Jeśli tak to czy można to jakość obejść?

Link do komentarza
Share on other sites

W takich sytuacjach wątpliwości należy zaglądać do RM.

Cytat

Bits 15:0 NDT[15:0]: Number of data items to transfer Number of data items to be transferred

(0 up to 65535).

This register can be written only when the stream is disabled.

When the stream is enabled, this register is read-only, indicating the remaining data items to be transmitted.

This register decrements after each DMA transfer.

Sam nie jestem specjalistą w tej dziedzinie, ale  wg mnie ten zapis z RM manuala potwierdza Twoje wątpliwości. Rejestr DMA->SxNDTR pomimo, że jest 32-bitowy to jednak tylko, 16 bitów jest aktywnych, stąd maksymalna ilości transferów to 65535.

  • Lubię! 1
Link do komentarza
Share on other sites

Cześć,

nie wiem czy dobrze zrozumiałem ale to jest chyba długość bufora transmisji DMA. 65535 to duża wartość (transmisje DMA odbywają się poza kontrolą głównego CPU). Po co potrzebujesz większych wartości długości bufora - te transmisje mogą zajmować sporo czasu.

Pozdrawiam.

  • Lubię! 1
Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Problem można prawdopodobnie obejść ciekawą sztuczką z czasów kart VGA. Tam ograniczenie kontrolera DMA, do 64KB i czasu transferu danych z powodu powrotu pionowego w rozdzielczości 320x240 obchodzono tak że, zamiast wysyłać cały obraz naraz wysyłaj sobie dwa pół obrazy ( wychodzi po ok 39KB w paczce) 50 razy na sek czyli 25 klatek. Oko tego nie zauważy, a jak będziesz na przemian wysyłał linie parzyste i nieparzyste to dodatkowo uzyskasz jeszcze filtr wygładzający. ogólnie programując takie małe mikrokomputery warto czasami znać pewne sztuczki z czasów Commodore i Amigi czy 386 które pozwalały na tym sprzęcie pisać gry.

Edytowano przez BlackJack
  • Lubię! 1
Link do komentarza
Share on other sites

Może jeszcze raz zapytam - czy chodzi o wyświetlacz na płytce Discovery? Bo jeśli tak, to on jest podłączony do wbudowanego sterownika obrazu i tam nie ma problemu z ograniczeniem do 64k transferów.

Natomiast jeśli to zewnętrzny układ, to pytanie jaki ma interfejs i czy posiada wbudowany sterownik oraz pamięć. Jeśli nie to jak w przypadku discovery, moduł LTDC wydaje się najlepszym rozwiązaniem.

Użycie DMA może się mieć sens jeśli wyświetlacz ma wbudowany sterownik oraz własną pamięć. Wówczas warto użyć DMA do przesłania danych obrazu za pomocą powiedzmy SPI. Tylko pytanie, czy trzeba „przepychać” całą ramkę obrazu na raz, może lepiej wysyłać tylko fragment. Będzie szybciej i łatwiej.

Ale zakładając najgorsze - czyli przesłanie całej ramki, najłatwiej jest to zrobić jako dwa lub więcej transferów. Przesyłamy pierwszy, a po jego zakończeniu wywoływane jest przerwanie. W nim uruchamiamy kolejny trasfer dla pozostałych danych.

Gdyby zależało nam na nieprzerwanej transmisji, jest jeszcze możliwość zgłoszenia przerwania w połowie transmisji - ale to raczej niepotrzebna komplikacja.

Jak chodzi o stm32f429 i grafikę, to polecam jeszcze poczytać o module DMA2D.

Edytowano przez Elvis
  • Lubię! 1
Link do komentarza
Share on other sites

Ja przy diodach WS2812B zrobiłem tak:

- tworzę bufor nadawczy powiedzmy 64 bajty

- dzielę go na pół i wsadzam pierwsze dwie pierwsze porcje danych do wysłania po 32 bajty

- uruchamiam transmisję DMA tego bufora w trybie cyklicznym i wykorzystuję dwa przerwania: od połowy wysłania i od zakończenia występują naprzemiennie co 32 bajty

- W każdym z tych przerwań wsadzam kolejne porcje danych do odpowiedniej połówki aż do momentu wysłania wszystkiego - wtedy stopuję transfer

- Dzięki temu bufor nadawczy DMA ma mały rozmiar, a ja teoretycznie mogę wysłać dowolną ilość danych

- Ważne, aby MCU zdążyło wsadzić kolejną porcję danych przed zakończeniem aktualnej, ale to oczywiście nie jest trudne 🙂

  • Lubię! 1
Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.