Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Транспонировать массив с помощью EDMA (проверялось на TMS320C6416)
Форум разработчиков электроники ELECTRONIX.ru > Цифровая обработка сигналов - ЦОС (DSP) > Алгоритмы ЦОС (DSP)
qxov
Появилась необходимость транспонировать массивчики. После некоторых изысканий получилось что-то рабочее. Поиск показал, что подобная тема уже поднималась, но не нашла ответа.

Задача из массива типа

12
34
56

(123456)

получить

135
246

(135246)

Пример, как можно реализовать с помощью EDMA. На оптимальность не претендую, работает для 8,16,32 битных элементов массива. Поскольку это мой первый опыт работы с EDMA, то критика с объяснением причины и указанием "как надо" - приветствуется.

Спасибо за проявленный интерес к теме.

Код
#define CHIP_6416
#include <csl_edmahal.h>

#pragma DATA_ALIGN(32)
short src[42]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,
               22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42};

#pragma DATA_ALIGN(32)
short dest[42];

#define EDMA_CH(channel,option) (((volatile Uint32*)(_EDMA_BASE_PRAM+(channel)*_EDMA_ENTRY_SIZE))[_EDMA_##option##_OFFSET])

void startTranspose(void *src, void *dst, int rows, int cols, int elSize)
{
    int optESize=(elSize==4) ? EDMA_OPT_ESIZE_32BIT : (elSize==2) ? EDMA_OPT_ESIZE_16BIT : EDMA_OPT_ESIZE_8BIT;

    EDMA_CH(63, OPT) = EDMA_OPT_RMK(EDMA_OPT_PRI_HIGH, optESize, EDMA_OPT_2DS_NO, EDMA_OPT_SUM_IDX, EDMA_OPT_2DD_NO,
                                    EDMA_OPT_DUM_INC, EDMA_OPT_TCINT_YES, EDMA_OPT_TCC_OF(62&0xf), EDMA_OPT_TCCM_OF(62>>4),
                                    EDMA_OPT_ATCINT_YES, EDMA_OPT_ATCC_OF(63), EDMA_OPT_PDTS_DISABLE, EDMA_OPT_PDTD_DISABLE,  
                                    EDMA_OPT_LINK_NO, EDMA_OPT_FS_YES);
    EDMA_CH(63, SRC) = EDMA_SRC_OF(src);
    EDMA_CH(63, CNT) = EDMA_CNT_RMK(EDMA_CNT_FRMCNT_OF(cols-1),EDMA_CNT_ELECNT_OF(rows));
    EDMA_CH(63, DST) = EDMA_DST_OF(dest);
    EDMA_CH(63, IDX) = EDMA_IDX_RMK(EDMA_IDX_FRMIDX_OF(elSize),EDMA_IDX_ELEIDX_OF(elSize*cols));
    EDMA_CH(63, RLD) = 0;   // не используем, можно убрать вроде

    EDMA_RSET(CIPRH,(1<<31));
    EDMA_RSET(CCERH,(1<<31));
    EDMA_RSET(ESRH,(1<<31));
}

bool isTransposeDone(void)
{
    return (EDMA_RGET(CIPRH)&(1<<30));
}

int main()
{
    for(int i=0;i<42;i++)
        dest[i]=123;

    startTranspose(src,dest,14,3,sizeof(src[0]));
    while(!isTransposeDone());

    return 0;
}
serwz
Вот бы еше замерить и сравнить скорость выполнения из L2
с функцией DSPlib DSP_mat_trans(....).
qxov
Цитата(serwz @ Apr 13 2007, 11:05) *
Вот бы еше замерить и сравнить скорость выполнения из L2
с функцией DSPlib DSP_mat_trans(....).

Эта реализация позволяет во время транспонирования заниматься каким-нибудь полезным делом и свободна от некоторых ограничений DSP_mat_trans. Поэтому сравнивать будет несколько затруднительно smile.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.