ЛР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.