ЛР9 > Передача даних через канал DMA DSP-процесора C55x

Тема: В даній роботі розглянуто приклад передачі даних по DMA-каналу DSP-процесора. Дані передаються з вхідного до вихідного буферу розміром N комірок.

Завантажити Матеріали до лабораторної работи по ЦСП С55х №9.

Для роботи з DMA- каналом використовується бібліотека підтримки кристала (CSL).

Бібліотека підтримки кристала (CSL) забезпечує інтерфейс прикладного програмування (API), який використовується для налаштування і керування периферійних пристроїв DSP-процесору (детальний опис цієї бібліотеки наведено у документі SPRU433).

Для її використання в даній роботі необхідно підключити наступні бібліотеки:

 

#include <csl.h>

#include <csl_irq.h>

#include <csl_dma.h>

 

Вхідний (src) і вихідний (dst) буфер розташовані в окремій ділянці пам’яті, в програмі це задається наступним чином:

 

#pragma DATA_SECTION(src,”dmaMem”)

Uint16 src[N];

 

#pragma DATA_SECTION(dst, “dmaMem”)

Uint16 dst[N];

 

Для початкової конфігурації DMA-каналу використовується наступний масив (більш детально він розглядається у описі бібліотеки CSL):

DMA_Config dma_config_array = {

DMA_DMACSDP_RMK(

DMA_DMACSDP_DSTBEN_NOBURST,

DMA_DMACSDP_DSTPACK_OFF,

DMA_DMACSDP_DST_DARAM,

DMA_DMACSDP_SRCBEN_NOBURST,

DMA_DMACSDP_SRCPACK_OFF,

DMA_DMACSDP_SRC_DARAM,

DMA_DMACSDP_DATATYPE_16BIT

), /* DMACSDP */

DMA_DMACCR_RMK(

DMA_DMACCR_DSTAMODE_POSTINC,

DMA_DMACCR_SRCAMODE_POSTINC,

DMA_DMACCR_ENDPROG_OFF,

DMA_DMACCR_REPEAT_OFF,

DMA_DMACCR_AUTOINIT_OFF,

DMA_DMACCR_EN_STOP,

DMA_DMACCR_PRIO_HI,

DMA_DMACCR_FS_ENABLE,

DMA_DMACCR_SYNC_NONE

), /* DMACCR */

DMA_DMACICR_RMK(

DMA_DMACICR_BLOCKIE_OFF,

DMA_DMACICR_LASTIE_OFF,

DMA_DMACICR_FRAMEIE_ON,

DMA_DMACICR_FIRSTHALFIE_OFF,

DMA_DMACICR_DROPIE_OFF,

DMA_DMACICR_TIMEOUTIE_OFF

), /* DMACICR */

(DMA_AdrPtr) &src, /* DMACSSAL */

0, /* DMACSSAU */

(DMA_AdrPtr)&dst, /* DMACDSAL */

0, /* DMACDSAU */

N, /* DMACEN */

1, /* DMACFN */

0, /* DMACSFI */

0, /* DMACSEI */

0, /* DMACDFI */

0 /* DMACDEI */

};

Нижче приведено програму функції start_transfer(), яка безпосередньо копіює дані з вхідного до вихідного буферу за допомогою каналу DMA (з відповідними коментарями).

 

void start_transfer(void) {

/* Відкриваємо DMA-канал 0 */

dma_handler = DMA_open(DMA_CHA0, 0);

 

/* За замовчуванням, компілятор TMS320C55xx оперує з адресами у форматі */

/* слова (2 байта). Натомість, DMA оперує адресами у форматі байтів. */

/* Таким чином, ми повинні збільшити адресу вдвічі для того, щоб змінити */

/* формат адреси зі слова на байт для здійснення передачі даних по DMA */

 

/* Конфігуруємо регістри молодшої адреси */

dma_config_array.dmacssal= (DMA_AdrPtr)(((Uint32)(dma_config_array.dmacssal)<<1)&0xFFFF);

dma_config_array.dmacdsal= (DMA_AdrPtr)(((Uint32)(dma_config_array.dmacdsal)<<1)&0xFFFF);

 

/* Конфігуруємо регістри старшої адреси */

dma_config_array.dmacssau = (((Uint32) &src) >> 15) & 0xFFFF;

dma_config_array.dmacdsau = (((Uint32) &dst) >> 15) & 0xFFFF;

 

/* Записуємо конфігураційний масив до керуючих регістрів DMA */

DMA_config(dma_handler, &dma_config_array);

 

/* Починаємо передачу даних через DMA-канал */

DMA_start(dma_handler);

 

/* Чекаємо, поки не встановиться біт FRAME у регістрі статусу DMA, */

/* який свідчить про те, що передача даних закінчена. */

while (!DMA_FGETH(dma_handler,DMACSR,FRAME)) {;}

 

/* Перевіряємо, чи коректно відбулася передача даних, для цього звіряємо значення вхідного та вихідного буферу */

for (i = 0; i <= (N – 1); i++) {

if (dst[i] != src[i]) {

++err;

break;

}

} printf(“%s”, err ? “TEST FAILED” : “TEST PASSED”);

 

DMA_close(dma_handler); /* Передача по DMA закінчена, закриваємо канал. */

}

Головна точка входу в програму – функція main() має наступний вигляд:

 

void main(void)

{

/* Ініціалізуємо бібліотеку підтримки кристала (CSL) */

CSL_init();

 

/* Ініціалізуємо генератор випадкових чисел початковим значенням, що міститься за адресою dst[0] */

srand((unsigned int)dst[0]);

 

/* Ініціалізуємо вхідний та вихідний буфер */

for (i = 0; i <= (N – 1); i++) {

dst[i] = 0;

src[i] = (rand() & 0xffff) + i + 1;

}

 

/* Викликаємо функцію передачі даних по DMA-каналу */

start_transfer();

}

 

 

Для перевірки роботи програми зробіть наступні кроки:

 

1. Створіть новий проект у середовищі CCS; назвіть його dma та збережіть його у відповідній директорії. Додайте до проекту файли main_dma1.с, командний файл лінкера dma1.cmd. Підключить бібліотеку засобів динамічної підтримки rts55.lib та бібліотеку підтримки кристалу csl5510PG2_2.lib. У вікні Build Options перейдіть до закладки Compiler. Виберіть категорію Basic , та вкажіть значення 5510:2 в графі Custom Target (-v). Виберіть категорію Preprocessor , та вкажіть значення CHIP_5510PG2_0 в графі Pre-Define Symbol (-d). Це необхідно для коректного підключення бібліотеки CSL.Запустіть програму на компіляцію.

2. Завантажте програму до процесора.

3. Відкрийте вікно карти пам’яті (Memory Window). Для цього знайдіть в коді позначення вхідного буфера (src), та натисніть на ньому правою клавішею миші. У меню, що з’явилося, оберіть пункт Open memory window (рис.1).

 

 

 

Рис.1. Відкриття вікна карти пам’яті (Memory Window).

 

Вікно карти пам’яті, що з’явиться, матиме наступний вигляд (рис.2):

 


Рис. 2. Вікно карти пам’яті

 

4. Встановіть одну точку зупинки в строчці з командою


DMA_start(dma_handler);

Встановіть іншу точку зупинки в строчці з командою

for (i = 0; i <= (N – 1); i++) {

5. Запустіть програму на виконання командою Run. При досягненні першої точки зупинки перевірте зміну значень масиву src.

6. При досягненні другої точки зупинки перевірте значення масиву dst.

Як бачимо, вісім (при N=8) випадкових 16-розрядних значень, що містяться в вхідному буфері src, були скопійовані через DMA канал до вихідного буферу dst.

Таким чином, дані були коректно передані по каналу DMA.