LinkedIn YouTube Facebook
Szukaj

Wstecz
Artykuły

DMA i bramkowane PIT w mikrokontrolerach Kinetis

W przykładzie interfejs DMA jest wykorzystywany do zasilania przetwornika analogowo-cyfrowego za pomocą słowa rozkazu kanału oraz przeniesienia wyniku konwersji A/C do wewnętrznej pamięci SRAM. Słowo rozkazu kanału A/C przechowuje wszystkie informacje, których przetwornik A/C potrzebuje do przeprowadzenia przetwarzania, więc dzięki wykorzystywaniu DMA do zapewniania słów rozkazu kanału, moduł może zostać poinformowany o przeprowadzeniu przetwarzania bez interwencji jednostki centralnej. Po przeniesieniu przez eDMA wyniku do wewnętrznej pamięci SRAM, aplikacja może przeprowadzić dalszą analizę danych.
Wejście ADC0 musi być próbkowane co milisekundę. Żeby to osiągnąć, 32-bitowe słowo rozkazu kanału A/C musi być dostarczane do ADC0_SC1A (0x4003B000) w każdej milisekundzie, jeśli tylko przetwornik jest zdolny do przyjęcia rozkazu. Słowo rozkazu kanału jest zlokalizowane w wewnętrznej pamięci SRAM. Poniższy przykład wymaga jedynie pojedynczego słowa rozkazu kanału przekazanego do modułu A/C. Jest ono przechowywane w zmiennej nazwanej command. Po tym, gdy moduł A/C zakończy przetwarzanie, rezultat jest przenoszony z rejestru wynikowego ADC0_RA modułu A/C, zlokalizowanego w adresie 0x4003B010, do adresu 0x1FFF9000 w wewnętrznej pamięci SRAM. Funkcjonowanie tego przykładu przedstawiono na rysunku 1.


 


Rys. 1. Przedstawienie przykładu 2.

Rys. 1. Przedstawienie przykładu 2.


 


Do zaimplementowania tego przykładu potrzebne są dwa kanały eDMA: jeden do transferu słowa rozkazu kanału, a drugi do transferu wyniku. Żądanie transferu rozkazu wymaga 1 ms wyzwalania PIT oraz zawsze aktywnego wyzwalacza. Multiplekser DMA musi być skonfigurowany do bramkowanej PIT aktywacji kanału. Do przeprowadzenia tego transferu skonfigurowany jest kanał 1.
Kanał 0 jest wykorzystywany do transferu wyniku A/C do pamięci RAM. Transfer ten jest aktywowany, gdy flaga gotowego wyniku A/C jest ustawiona. Standardowy arbitraż kanałów przydziela kanałowi 1 priorytet wyższy od kanału 0. Konfiguracja ta gwarantuje, że moduł A/C otrzymuje słowo rozkazy kanału w każdej mikrosekundzie. Jednakże może to spowodować nadpisanie wyników w rejestrze wynikowym zanim zostaną one przeniesione przez eDMA, jako że kanał odczytujący wynik nie ma przydzielonego priorytetu. Ustawienia te mogą zostać zmienione, w celu zagwarantowania, że każdy rezultat jest przechwytywany, aby przydzielić wyższy priorytet kanałowi odczytującemu wyniki. Konfiguracja multipleksera DMA dla kanałów 0 oraz 1 jest następująca:


 

/* Konfiguracja DMAMux dla kanału 0. */
DMAMUX_CHCONFIG0 = (0
| DMAMUX_ENABLE /* Włączenie prowadzenia żądania DMA. */
| DMAMUX_SOURCE(40)); /* Źródło aktywacji kanału: wynik AD_A. */
/* Konfiguracja DMAMux dla kanału 1. */
DMAMUX_CHCONFIG1 = (0
| DMAMUX_ENABLE /* Włączenie prowadzenia żądania DMA. */
| DMAMUX_TRIG /* Tryb wyzwalania: okresowy. */
| DMAMUX_SOURCE(54)); /* Źródło aktywacji kanału: rozkaz AD_A. */

 


Kanał pierwszy jest skonfigurowany do używania okresowego wyzwalacza – PIT1. Moduł PIT1 musi być uruchomiony oraz skonfigurowany na pożądany interwał czasowy.
Przed rozpoczęciem transferu DMA (uruchomieniem PIT1), dane rozkazów modułu A/C muszą być przygotowane zgodnie z definicją rejestru rozkazów A/C. Każdy kanał w tym przykładzie przeprowadza transfer danych do lub z adresu statycznego, odpowiednio 32-bitowego rozkazu lub rejestru wynikowego. Z tego powodu konieczne jest odzyskiwanie wskaźników adresów w TCD, gdy zakończona jest główna lub pomocnicza pętla transferu. Przykład ten nie ma do przetransferowania tabeli danych, co sprawia, że tylko jedna pojedyncza pętla pomocnicza jest potrzebna do zakończenia głównej pętli transferu. Adresy źródła i miejsca przeznaczenia są zatem odzyskiwane po ukończeniu głównej pętli. Konfiguracja TCD dla kanałów 0 i 1 wygląda następująco:


 

/* Konfiguracja TCD kanału 0 DMA. */
EDMAC_TCD0_W0 = EDMAC_SADDR(0x4003B010);/* Adres źródła = Rejestr wynikowy A/C. */
EDMAC_TCD0_W1 = (0
| EDMAC_SMOD(0x0) /* Moduł źródła, funkcja wyłączona. */
| EDMAC_SSIZE(0x2) /* Rozmiar źródła = 0x2 -> 32-bitowe transfery. */
| EDMAC_DMOD(0x0) /* Moduł miejsca przeznaczenia, funkcja wyłączona. */
| EDMAC_DSIZE(0x2) /* Rozmiar miejsca przeznaczenia = 0x2 -> 32-bitowe transfery. */
| EDMAC_SOFF(0x0)); /* Offset adresu źródła = 0x0, bez inkrementacji. */
EDMAC_TCD0_W2 = EDMAC_NBYTES(0x4); /* Transfer 4 bajtów na jedną aktywację kanału. */
EDMAC_TCD0_W3 = EDMAC_SLAST(0x0); /* Bez regulacji SADDR przy zakończeniu kanału. */
EDMAC_TCD0_W4 = EDMAC_DADDR(0x1FFF9000); /* Adres miejsca przeznaczenia = 0x500, Zewnętrzna pamięć RAM. */
EDMAC_TCD0_W5 = (0
/*| EDMAC_CITER_E_LINK /* Brak ustawienia bitu ELINK, brak powiązania kanałów. */
| EDMAC_CITER(0x1) /* Licznik aktualnej iteracji -> 1 transfer „NBYTES”. */
| EDMAC_DOFF(0x0)); /* Offset adresu miejsca przeznaczenia = 0x0, brak inkrementacji. */
EDMAC_TCD0_W6 = EDMAC_DLAST(0x0); /* Bez regulacji DADDR przy zakończeniu kanału. */
EDMAC_TCD0_W7 = (0
| EDMAC_BITER(0x1) /* Rozpoczęcie zliczania iteracji = 1 = CITER. */
| EDMAC_BWC(0x0) /* Kontrola przepustowości = 0 -> brak blokad eDMA. */
| EDMAC_MAJOR_LINKCH(0x0)); /* Ignorowane, brak powiązania kanałów. */
/* Konfiguracja TCD kanału 1 DMA. */
EDMAC_TCD1_W0 = EDMAC_SADDR((uint32)&command);/* Source Addr = address of command var */
EDMAC_TCD1_W1 = (0
| EDMAC_SMOD(0x0) /* Moduł źródła, funkcja wyłączona. */
| EDMAC_SSIZE(0x2) /* Rozmiar źródła = 0x2 -> 32-bitowe transfery. */
| EDMAC_DMOD(0x0) /* Moduł miejsca przeznaczenia, funkcja wyłączona. */
| EDMAC_DSIZE(0x2) /* Rozmiar miejsca przeznaczenia = 0x2 -> 32-bitowe transfery. */
| EDMAC_SOFF(0x0)); /* Offset adresu źródła = 0x0, bez inkrementacji. */
EDMAC_TCD1_W2 = EDMAC_NBYTES(0x4); /* Transfer 4 bajtów na jedną aktywację kanału. */
EDMAC_TCD1_W3 = EDMAC_SLAST(0x0); /* Bez regulacji SADDR przy zakończeniu kanału. */
EDMAC_TCD1_W4 = EDMAC_DADDR(0x4003B000);/* Adres miejsca przeznaczenia = rejestr słowa rozkazu kanału ATD. */
EDMAC_TCD1_W5 = (0
/*| EDMAC_CITER_E_LINK /* Brak ustawienia bitu ELINK, brak powiązania kanałów. */
| EDMAC_CITER(0x1) /* Licznik aktualnej iteracji -> 1 transfer „NBYTES”. */
| EDMAC_DOFF(0x0)); /* Offset adresu miejsca przeznaczenia = 0x0, brak inkrementacji. */
EDMAC_TCD1_W6 = EDMAC_DLAST(0x0); /* Bez regulacji DADDR przy zakończeniu kanału. */
EDMAC_TCD1_W7 = (0
/*| EDMAC_BITER_E_LINK /* Brak ustawienia bitu ELINK, brak powiązania kanałów. */
| EDMAC_BITER(0x1) /* Rozpoczęcie zliczania iteracji = 1 = CITER */
| EDMAC_BWC(0x0) /* Kontrola przepustowości = 0 -> Brak blokad eDMA. */
| EDMAC_MAJOR_LINKCH(0x0)); /* Ignorowane, brak powiązania kanałów. */

Tagi: ADC, DMA