Задача из массива типа
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;
}
#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;
}