Ingo Electronics


    HOME                                                           Stellaris LM4F120 LaunchPad


  Stellaris LM4F120 LaunchPad.     DMA   modulis - Pirma dalis          Direct Memory Access Examples - First Part     

DMA (Direct Memory Access) modulis leidžia dideliu greičiu persiūsti duomenis tarp atminties buferių ir periferinių įrenginių, į vieną arba kitą pusę.

Kiekvienas periferinis modulis turi jam priskirtus DMA duomenų perdavimo kanalus, ir gali būti suprogramuotas atlikti duomenų siuntimą:

-iš vieno atminties buferio į kitą atminties buferį

-iš atminties buferio į periferinį modulį.

-iš periferinio modulio į atminties modulį.

Viso DMA modulis turi 31 duomenų perdavimo/priėmimo kanalą.

Kiekvienas kanalas gali būti prikirtas vienam iš penkių jam priskirtų periferinių arba programinių modulių.

DMA perdavimo/priėmimo kanalus turi šie periferiniai moduliai:

UART
Taimeriai
USB
ADC
SSI(SPI)
įėjimo/išėjimo portai

 
Pasirinktas periferinis modulis priskiriamas konkrečiam duomenų kanalui naudojant funkciją:

uDMAChannelAssign(unsigned long ulMapping)

Parametras ulMapping pasirinktam periferiniam moduliui, randamas atsidarius driverlib/udma.h failą

Pvz., norim panaudoti UART2 modulį perdavimui (UART2TX), iš udma.h failo matome, kad jam yra priskirtas 13  kanalas, pasirenkame konstantą UDMA_CH13_UART2TX  
//choose 13 Channel to  UART2TX
uDMAChannelAssign(UDMA_CH13_UART2TX);

//**************************************************************************************************

DMA panaudojimas nėra toks sudėtingas kaip gali pasirodyti iš pirmo žvilgsnio.

Svarbiausia yra teisingai sukonfiguruoti šias dvi funkcijas:

uDMAChannelControlSet

uDMAChannelTransferSet

//**************************************************************************************************

Prieš pradedant DMA modulio kanalo konfiguraciją, užblokuojame kai kuriuos kanalo parametrus, naudodami f-ją:

uDMAChannelAttributeDisable

Ši funkcija naudojama laikinai blokuoti funkcijoje nurodytų parametrų naudojimą, kol mikrovaldiklio programa atliks tolimesnį nurodyto kanalo konfiguravimą, vėliau kai kurie, arba visi šie parametrai gali būti deblokuoti, t.y leidžiami arba visai nenaudojami.

uDMAChannelAttributeDisable(unsigned long ulChannelNum, unsigned long ulAttr);

Parametrai:

ulChannelNumkonfiguruojamo kanalo numeris, tai tiesiog skaičius nuo 0 iki 31 kuris parenkamas iš mikrokontrolerio aprašymo kanalų priskyrimo lentelės (Channel Assignments), arba rašoma raidinė reikšmė pagal #define nustatytas konstantas, kurios randamos driverlib/udma.h

ulAttr – kombinuojamas loginių arba ( | ) pagalba iš bet kurių žemiau esančių parametrų kombinacijų:

UDMA_ATTR_USEBURST - perdavimo režimas – duomenys siunčiami tik serijomis(paketais).  Angl. Burst mode

UDMA_ATTR_ALTSELECT – šis parametras nurodo, kad duomenų perdavimui bus naudojamas papildomas atminties buferis, t.y užpildžius pagridinį buferį, duomenys bus siunčiami į papildomą atminties buferį.

UDMA_ATTR_HIGH_PRIORITY – parametras nurodo kad naudojamas kanalas, duomenų pardavimui, turi aukštą prioritetą

UDMA_ATTR_REQMASK - parametras nurodo kad duomenų siuntimas/priėmimas bus valdoma programiniu būdu.

UDMA_ATTR_ALL – visi aukščiau išvardinti parametrai.

PVZ.:

uDMAChannelAttributeDisable(UDMA_CHANNEL_SW, UDMA_ATTR_USEBURST | UDMA_ATTR_ALTSELECT |

                                       (UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK));

 Arba aukščiau parodytą funkciją galima parašyti trumpai:

uDMAChannelAttributeDisable( 30, UDMA_ATTR_ALL );

Tai standartinė f-ja, naudojama daugeliu atveju, keičiant tik konfiguruojamo kanalo numerį.

//**************************************************************************************************

Sekanti labai svarbi DMA kanalo konfiguravimo funkcija, kurioje reikia nustatyti kokio dydžio duomenų paketai bus siunčiami ir kaip jie bus talpinami atminties, arba periferiniame FIFO buferyje.

uDMAChannelControlSet(unsigned long ulChannelStructIndex, unsigned long ulControl)

Parametras:

ulChannelStructIndex konfiguruojamo kanalo numeris kombinuojamas loginiu arba ( | ) su vienu iš dviejų žemiau esančių parametrų:

UDMA_PRI_SELECT – naudojamas pagrindinis duomenų buferis

UDMA_ALT_SELECT – bus naudojamas papildomas duomenų buferis

Jaigu tam pačiam kanalui, perduodant duomenis, bus reikalingi du buferiai, tai reikia rašyti dvi uDMAChannelControlSet funkcijas paeiliui, parametro ulChannelStructIndex vietoje rašant pvz.:

UDMA_CHANNEL_UART1RX | UDMA_PRI_SELECT 

ir kitoje:

UDMA_CHANNEL_UART1RX | UDMA_ALT_SELECT

Parametras:

ulControlyra penkių parametrų kombinacija naudojant loginį arba (|):

data size                     - duomenų paketo dydis(bitais)
source address increment      
– duomenų šaltinio adreso poslinkis(bitais)
destination address increment
- paskirties adreso poslinkis(bitais)
arbitration size             
- tarpinis duomenų perdavimo dydis(duomenų paketais)
use burst flag
               

 
Galima pasirinkti po vieną parametrą iš žemiau išvardintų grupių:

data size
Perduodamų duomenų paketo dydis(bitais) -šį parametrą reikia nurodyti visada.

 UDMA_SIZE_8  – perdavimas vykdomas siunčiant po vieną baitą
 UDMA_SIZE_16 – perdavimas vykdomas siunčiant po du baitus

 UDMA_SIZE_32 – perdavimas vykdomas siunčiant po keturis baitus

 source address increment
Duomenų šaltinio adreso poslinkis(bitais) -šį parametrą reikia nurodyti visada.

Šis parametras yra paprastai lygus (išimtininais atvejais didesnis) perduodamų duomenų paketo dydžiui
 UDMA_SRC_INC_8
 UDMA_SRC_INC_16
 UDMA_SRC_INC_32
 UDMA_SRC_INC_NONE

destination address increment
Paskirties adreso poslinkis(bitais) -šį parametrą reikia nurodyti visada.

Šis parametras yra paprastai lygus (išimtininais atvejais didesnis) perduodamų duomenų paketo dydžiui
 UDMA_DST_INC_8
 UDMA_DST_INC_16
 UDMA_DST_INC_32
 UDMA_DST_INC_NONE

arbitration size 
tarpinis duomenų perdavimo dydis(duomenų paketais) -šį parametrą reikia nurodyti visada.

Šis parametras apsaugo nuo kanalo “užgrobimo“ kai vyksta perdavimas, t.y perdavus nurodytą šiame parametre peketų kiekį, yra leidžiama kitiems kanalams vykdyti perdavimus. Jeigu kitų kanalų nėra, tai šis parametras gali būti lygus perduodamo buferio dydžiui ar perduodamų duomenių kiekiui.
 UDMA_ARB_1
 UDMA_ARB_2
 UDMA_ARB_4
 UDMA_ARB_8
 UDMA_ARB_16
 UDMA_ARB_32
 UDMA_ARB_64
 UDMA_ARB_128
 UDMA_ARB_256
 UDMA_ARB_1024

use burst flag
Rodyklė,  nurodanti duomenis siūsti tik serijomis(paketais).  

Keletas šios funkcijos naudojimo pavyzdžių:

uDMAChannelControlSet(UDMA_CHANNEL_SW|UDMA_PRI_SELECT,UDMA_SIZE_32|UDMA_SRC_INC_32|UDMA_DST_INC_32|UDMA_ARB_8);

uDMAChannelControlSet(UDMA_CHANNEL_UART1RX|UDMA_PRI_SELECT,UDMA_SIZE_8|UDMA_SRC_INC_NONE|UDMA_DST_INC_8|UDMA_ARB_4);                                                                                              

uDMAChannelControlSet(UDMA_CHANNEL_UART1RX | UDMA_ALT_SELECT,UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 | UDMA_ARB_4);

uDMAChannelControlSet(UDMA_CHANNEL_UART1TX | UDMA_PRI_SELECT,UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARB_4);

uDMAChannelControlSet(UDMA_CHANNEL_ADC3|UDMA_PRI_SELECT,UDMA_SIZE_16|UDMA_SRC_INC_NONE|UDMA_DST_INC_16| UDMA_ARB_1);

//**********************************************************************************************************************************

Dar viena labai svarbi DMA kanalo konfiguravimo funkcija, kurioje nurodomas duomenų perdavimo režimas, duomenų šaltinio ir duomenų paskirties atminties buferiai ir perduodamų duomenų kiekis:

 uDMAChannelTransferSet (unsigned long ulChannelStructIndex,

                                         unsigned long ulMode,

                                             void *pvSrcAddr,

                                             void *pvDstAddr,

                               unsigned long ulTransferSize)

 

Parametras:

ulChannelStructIndex konfiguruojamo kanalo numeris kombinuojamas loginiu arba ( | ) su vienu iš dviejų žemiau esančių parametrų:

UDMA_PRI_SELECT – naudojamas pagrindinis duomenų buferis

UDMA_ALT_SELECT – bus naudojamas papildomas duomenų buferis

Jaigu tam pačiam kanalui, perduodant duomenis, bus reikalingi du buferiai, tai reikia rašyti dvi uDMAChannelTransferSet funkcijas paeiliui, parametro ulChannelStructIndex vietoje rašant pvz.:

UDMA_CHANNEL_UART1RX | UDMA_PRI_SELECT 
ir kitoje:
UDMA_CHANNEL_UART1RX | UDMA_ALT_SELECT

Parametrai:
ulMode    – duomenų perdavimo režimas.
pvSrcAddr ­– duomenų perdavimo šaltino buferis.
pvDstAddr – duomenų paskirties buferis.
ulTransferSize – perduodamų duomenų kiekis .

 
ulMode
duomenų perdavimo režimas
Parametras gali būti pasirinktas vienas iš žemiau nurodytų:

UDMA_MODE_STOP – duomenų siuntimas yra sustabdytas. DMA valdymo modulis automatiškai pereina į šį režimą jeigu yra baigtas duomenų siuntimas, t.y buferis pilnai užpildytas arba išsiūstas.

UDMA_MODE_BASIC – pagrindinis, bazinis duomenų perdavimo režimas

UDMA_MODE_AUTO – automatinis dumenų perdavimo režimas, net jeigu ir nėra signalo perduoti duomenis. UDMA_MODE_PINGPONG – duomenų perdavimo režimas, kai vienam kanalui yra naudojami du buferiai: pagrindinis ir papildomas, užpildžius pagrindinį buferį, duomenų siuntimas automatiškai persijungia į papildomą buferį.

UDMA_MODE_MEM_SCATTER_GATHER to set up a memory scatter-gather transfer.

UDMA_MODE_PER_SCATTER_GATHER to set up a peripheral scatter-gather transfer.

 
ulTransferSize – perduodamų duomenų kiekis, šis parametras nėra perduodamų baitų skaičius, tai yra perduodamų paketų skaičius.  Šio paketo dydis data size buvo nurodytas funkcijoje uDMAChannelControlSet  

Maksimali šio parametro reikšmė gali būti 1024

Šios funkcijos naudojimo pavyzdžiai:

PVZ.:
Deklaruoti buferiai:

static unsigned long Source_Buffer[1024];
static unsigned long Destination_Buffer[1024];

uDMAChannelTransferSet(UDMA_CHANNEL_SW | UDMA_PRI_SELECT,

                                          UDMA_MODE_AUTO,

                                           Source_Buffer,

                                      Destination_Buffer,

                                                   1024);

 

static unsigned char Tx_Buf[256];
static unsigned char Rx_Buf_A[256];
static unsigned char Rx_Buf_B[256];

uDMAChannelTransferSet(UDMA_CHANNEL_UART1RX | UDMA_PRI_SELECT,
                                           UDMA_MODE_PINGPONG,
                              (void *)(UART1_BASE + UART_O_DR),
                                                      
Rx_Buf_A,
                                              sizeof(
Rx_Buf_A));

 
uDMAChannelTransferSet(UDMA_CHANNEL_ADC3 | UDMA_PRI_SELECT,
                                           UDMA_MODE_BASIC,
                       (void *)(ADC0_BASE + ADC_O_SSFIFO3), 

                                              pusDMABuffer,
                                                 DMA_SIZE);

 
uDMAChannelTransferSet(UDMA_CHANNEL_ADC3 | UDMA_PRI_SELECT,
                                           UDMA_MODE_BASIC,
 (void *)(ADC0_BASE + ADC_O_SSFIFO3 + (0x20 * UDMA_ARB_1)),
             g_ulADCValues + (UDMA_XFER_MAX * uluDMACount),
                                       ulNextuDMAXferSize);

 
uDMAChannelTransferSet(UDMA_CHANNEL_ADC3 | UDMA_PRI_SELECT,
                                           UDMA_MODE_BASIC,
 (void *)(ADC0_BASE + ADC_O_SSFIFO3 + (0x20 * UDMA_ARB_1)),
                                               g_usDMAping,
                                                 DMA_SIZE);

 
uDMAChannelTransferSet(UDMA_CHANNEL_ADC3 | UDMA_PRI_SELECT,
                                           UDMA_MODE_BASIC,
 (void *)(ADC0_BASE + ADC_O_SSFIFO3 + (0x20 * UDMA_ARB_1)),
                                             g_ulADCValues,
                                            UDMA_XFER_MAX);

 uDMAChannelTransferSet(UDMA_CHANNEL_ADC3 | UDMA_PRI_SELECT,
                                            UDMA_MODE_BASIC,
  (void *)(ADC0_BASE + ADC_O_SSFIFO3 + (0x20 * UDMA_ARB_1)),
                                              g_ulADCValues,
                                               NUM_SAMPLES);

//**************************************************************************************************

Tam kad žinoti kada įvyksta pilnas buferio užpildymas arba jo išsiuntimas reikalinga įjungti DMA modulio pertraukimo rodyklių generavimą.

Naudojame f-ją:

IntEnable(INT_UDMA);

//**************************************************************************************************

uDMAChannelAttributeEnable(unsigned long ulChannelNum, unsigned long ulAttr)

Pvz.:
uDMAChannelAttributeEnable(UDMA_CHANNEL_UART1TX, UDMA_ATTR_USEBURST);

//**************************************************************************************************

Leidžiame sukonfiguruotam kanalui funkcionuoti:

uDMAChannelEnable(unsigned long ulChannelNum)

ulChannelNum  prieš tai sukonfiguruoto kanalo numeris

//**************************************************************************************************

Duomenų siuntimui/priėmimui naudojant periferinį modulį,  siuntimas programiniu būdu inicijuojamas, t.y pradedamas iškart po funkcijos uDMAChannelEnable įvedimo!!!

Norint pakartotinai perduoti duomenis, reikalinga vėl įvesti funkciją uDMAChannelTransferSet ir duoti komandą uDMAChannelEnable (naudojant periferinį modulį).

Kai kuriais atvejais, duomenų siuntimas, naudojant periferinį modulį, gali būti inicijuotas ir su  uDMAChannelRequest,

tam funkcijoje uDMAChannelAttributeEnable reikalinga įvesti parametrą UDMA_ATTR_REQMASK, tačiau tokiu atveju, po kiekvienos uDMAChannelRequest komandos, bus persiunčiamas duomenų kiekis kuris nurodytas funkcijoje  uDMAChannelControlSet parametru arbitration size . Toks panaudojimas praktiškai netenka prasmės, nes tuomet duomenų siuntimo/priėmimo periferinis modulis nebekontroliuoja ir reikia programiniu būdu kartoti uDMAChannelRequest komandą, kol bus persiūstas funkcijoje uDMAChannelTransferSet parametru ulTransferSize nurodytas duomenų kiekis.

Kai yra persiunčiamas arba priimamas funkcijoje uDMAChannelTransferSet parametru ulTransferSize nurodytas duomenų kiekis, naudojant periferinį modulį,  suveikia šio periferinio modulio pertraukimo rodyklė (nors šios pertraukimo rodyklės generavimą vis vien inicijuoja DMA modulis), tai yra šiek tiek neįprasta ir keista, todėl yra būtina įjungti šio periferinio modulio pertraukimo rodyklių generavimą, tam kad būtų galima kontroliuoti duomenų perdavimo pabaigą ir pasiruošti kitam duomenų perdavimui. Yra rašoma periferinio modulio pertraukimų funkcija, kuri deklaruojama projekto startup_ccs.c  faile ir jos vardas nurodomas šio failo pertraukimų vektorių lentelėje.

Pats DMA modulis generuoja tik dvi  pertraukimo rodykles:

-          kai yra užbaigiamas duomenų perdavimas tarp atminties buferių,arba kai yra užbaigtas duomenų perdavimas po uDMAChannelRequest komandos

-          kai įvyksta DMA modulio klaida 

DMA modulis turi savo pertraukimų vektorių lentelę, todėl tam kad netrukdyti DMA modulio darbo, funkcijos IntMasterEnable(); nereikėtų naudoti, arba jeigu ji buvo panaudota, išjungti su f-ja IntMasterDisable(); 

Jeigu nekontroliuojame DMA modulio generuojamas pertraukimo rodykles, tai funkcijos uDMAIntRegister ir IntEnable(INT_UDMA); taip pat yra nereikalingos.

//**************************************************************************************************

Kai duomenys yra siunčiami tarp atminties buferių, duomenų perdavimas pradedamas iškart po funkcijos uDMAChannelRequest įvedimo.

Norint pakartotinai perduoti duomenis, reikalinga vėl įvesti funkciją  uDMAChannelTransferSet ir duoti komandas uDMAChannelEnable ir  uDMAChannelRequest  (perduodant duomenis tarp atminties buferių). 

Šiuo atveju, duomenų perdavimo užbaigimas jau yra kontroliuojamas pertraukimo rodyklėmis, kurias generuoja DMA modulis, tam reikalinga įjungti DMA pertraukimų rodyklių generavimą su funkcija  IntEnable(INT_UDMA); ir parašyti pertraukimų funkciją, kuri deklaruojama su funkcija: 

uDMAIntRegister(kanalo_num, DMA_pertraukimų_funkcijos_vardas);

arba ši pertraukimų funkcija deklaruojama projekto startup_ccs.c  faile ir jos vardas nurodomas šio failo pertraukimų vektorių lentelėje.

//*********************************************************************************************************************************
//*********************************************************************************************************************************
//*********************************************************************************************************************************

                                                DMA programavimo Pavyzdys

Dabar galima parašyti pirmąją programėlę, kur duomenų siuntimui būtų naudojamas DMA modulis.

Tarkime norime norime iš tam tikro buferio, esančio mikrokontrolerio atmintyje išsiūsti duomenis per UART terminalą.

Pasirenkame UART2 modulį, iš mikrokontrolerio pdf aprašymo matome kad UART2TX yra priskirtas 13 kanalas. Konfiguruosime 13 kanalą jam priskirdami UART2TX modulį.

Pilnas šio pavyzdžio programinis kodas: Link

Šio pavyzdžio startup_ccs.c  ir main.c failai parsisiuntimui: Link 

Pavyzdys yra skirtas tik pademonstruoti kaip gali būti naudojamas ir kaip programuojamas DMA modulis duomenų išsiuntimui per periferinius modulius.

UART modulio konfiguravimas praktiškai nieko nesiskiria nuo prieš tai ankstesnėje temoje nagrinėto, išskyrus tai kad dabar reikalinga įjungti UART FIFO buferį naudojant f-ją UARTFIFOLevelSet
 

Tai yra FIFO buferio užpildymo lygio nustatymas, pasiekus šį lygį UART modulis siunčia signalą DMA moduliui paduoti jam sekantį baitų paketą.

FIFO užpildymo lygis gali būti 1/8, 2/8, 4/8, 6/8, 7/8  t.y DMA modulis  privalės siūsti 1,2,4,6 arba 7  baitų paketus priklausomai nuo funkcijoje UARTFIFOLevelSet nurodyto parametro. 

Konfiguruojant UART modulį, reikia reikia nepamiršti įjungti DMA modulio duomenų perdavimo/priėmimo kanalą panaudojant f-ją  UARTDMAEnable

UART konfiguravimo f-ja galėtų atrodyti taip:

//’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’

void uart2_dma_init() {

           SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);

           // Unlock PD7

           HWREG(GPIO_PORTD_BASE + GPIO_O_LOCK) = GPIO_LOCK_KEY_DD;

           HWREG(GPIO_PORTD_BASE + GPIO_O_CR) |=  GPIO_PIN_7;

           HWREG(GPIO_PORTD_BASE + GPIO_O_LOCK) = 0;

           SysCtlPeripheralEnable(SYSCTL_PERIPH_UART2);

           // Set GPIO PD6 RX  and PD7 TX as UART pins.

           GPIOPinConfigure(GPIO_PD6_U2RX);

           GPIOPinConfigure(GPIO_PD7_U2TX);

           GPIOPinTypeUART(GPIO_PORTD_BASE, GPIO_PIN_6 | GPIO_PIN_7);

UARTConfigSetExpClk(UART2_BASE, SysCtlClockGet(), 115200,(UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE|UART_CONFIG_PAR_NONE));

UARTFIFOLevelSet(UART2_BASE, UART_FIFO_TX4_8, UART_FIFO_RX4_8); //nustatome FIFO trigeriavimo lygį 

UARTDMAEnable(UART2_BASE, UART_DMA_TX); //ijungiame DMA kanalą

UARTEnable(UART2_BASE);

IntEnable(INT_UART2);//Enable the UART interrupt.

}

//’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’

Dabar reikia sukonfiguruoti DMA modulio perdavimo kanalą.

Šio kanalo konfiguravimo f-ja turėtų atrodyti taip:

//’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’

void dma_init() {

SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA); //įjungiame DMA modulio taktavimą

uDMAEnable(); // įjungiame DMA modulį

uDMAControlBaseSet(ucControlTable); //ši f-ja visada turi būti konfiguruojant DMA

uDMAChannelAssign(UDMA_CH13_UART2TX); // UART2TX moduliui priskiriam reikiamą kanalą

uDMAChannelAttributeDisable(13, UDMA_ATTR_ALL );

uDMAChannelControlSet(13 | UDMA_PRI_SELECT, //13-as kanalas

                         UDMA_SIZE_8|  //vienas baitas,nes uart siunčia, o FIFO priima tik po 1 baitą   

                     UDMA_SRC_INC_8 |  //vienas baitas, UDMA_SIZE_x turi sutapti su UDMA_SRC_INC_x  

                  UDMA_DST_INC_NONE |  //taip rašom tik pariferijai

                          UDMA_ARB_4); //šis parametras turi sutapti su UART_FIFO_TX4_8

 

uDMAChannelTransferSet(13 | UDMA_PRI_SELECT, //13-as kanalas

                             UDMA_MODE_BASIC, //perdavimo režimas

                              Source_Buffer,

           (void *)(UART2_BASE + UART_O_DR), //taip turi būti rašoma uart tx priferijai

                                       256); //siunčiamų paketų skaičius, šiuo atveju po 1 baitą

}

//’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’

Svarbu, kad funkcijoje uDMAChannelControlSet, parametras arbitration size UDMA_ARB_x sutaptų su parametru “FIFO užpildymo lygis“,  kuris buvo nustatytas konfiguruojant UART modulį funkcijoje UARTFIFOLevelSet.   

Kaip matome, konfiguruojant nėra funkcijos uDMAChannelEnable, dabar jos nerašome, nes ši funkcija iškarto įjungtų duomenų perdavimą.

Duomenų siuntimą šiame pavyzdyje imituojame mygtuko SW1 paspaudimu, kuris yra Stellaris Launchpad plokštėje.

Trumpam paspaudus SW1 mygtuką, per UART terminalą bus išsiunčiami visi 256 baitai esantys buferyje  Source_Buffer[256]; , suveiks pertraukimų funkcija ir užsidegs žalias šviesos diodas signalizuojantis, kad visi 256 baitai buvo išsiūsti.

Dar kartą nuspaudus mygtuką SW1,  bus vėl siunčiami visi 256 baitai, nes pertraukimų funkcijoje pakartotinai yra įvedama komanda  uDMAChannelTransferSet

Buferis  Source_Buffer programiniu būdu yra užpildytas skaičių eilute nuo 0 iki 255.

Funkcijoje uDMAChannelTransferSet, esant reikalui, galima nurodyti ir mažesnį nei 256 perduodamų baitų skaičių, tuomet bus perduodama tik tiek baitų kiek nurodyta šioje funkcijoje, tačiau ne daugiau, už nurodytą buferio Source_Buffer deklaracijoje.

 

                                                                 Tęsinys sekančiame puslapyje  >>