Вот дошли руки до ДМА и что-то второй день ни в какую не могу заставить это работать. Кое-как из того, что написано в документации (а написано, надо сказать коряво) родил такой код:
CODE
static dmaCtrlData_t dmaCtrlData[16]
__attribute__((aligned(512), section("ahb_lite")));
volatile char tmp1[] = "DMA test string.";
volatile char tmp2[20];
int main(void) {
... инициализация клоков ...
memset(dmaCtrlData, 0x0, sizeof(dmaCtrlData));
// Reset to the initial state.
MDR_DMA->CTRL_BASE_PTR = (uint32_t) dmaCtrlData;
MDR_DMA->CFG = 1U;
MDR_DMA->CHNL_SW_REQUEST = 0U;
MDR_DMA->CHNL_PRI_ALT_CLR = 0xFFFFFFFF;
MDR_DMA->CHNL_PRIORITY_CLR = 0xFFFFFFFF;
MDR_DMA->CHNL_REQ_MASK_SET = 0xFFFFFFFF;
MDR_DMA->CHNL_USEBURST_CLR = 0xFFFFFFFF;
MDR_DMA->CHNL_ENABLE_CLR = 0xFFFFFFFF;
MDR_DMA->ERR_CLR = 1U;
// Configure DMA_CH0
dmaCtrlData[0].dmaSrcEndAddr = (uint32_t) tmp1 + sizeof(tmp1) - 1;
dmaCtrlData[0].dmaDstEndAddr = (uint32_t) tmp2 + sizeof(tmp1) - 1;
dmaCtrlData[0].dmaControl = (0x00 << 30) | // One byte destination increment;
(0x00 << 28) | // Destination transfer unit size;
(0x00 << 26) | // One byte source increment;
(0x00 << 24) | // Source transfer unit size;
(0U << 21) | // dst_prot_ctrl (whatever this is - let it be 0);
(0U << 18) | // src_prot_ctrl;
(15U << 14) | // Acquire the bus and do not release until the transfer complete;
((sizeof(tmp1) - 1) << 4) |
// Transfers count - 1.
(0U << 3) | // next_useburst ??
(1U << 0); // Simple request mode. Auto-request mode does not work either.
MDR_DMA->CHNL_REQ_MASK_CLR = 1U;
MDR_DMA->CHNL_ENABLE_SET = 1U;
MDR_DMA->CHNL_SW_REQUEST = 1U;
... зацикливаемся ...
}
Здесь пытаюсь скопировать строку из tmp1 в tmp2. Собственно для проверки, что все заполнилось правильно:
1. Значения регистров MDR_DMA и dmaCtrlData для 1 канала ДО запуска передачи (MDR_DMA->CHNL_SW_REQUEST = 1U):
CODE
{ STATUS = 0x101f0001,
CFG = 0x0,
CTRL_BASE_PTR = 0x20100000,
ALT_CTRL_BASE_PTR = 0x20100200,
WAITONREQ_STATUS = 0x7fffffff,
CHNL_SW_REQUEST = 0x0,
CHNL_USEBURST_SET = 0x0,
CHNL_USEBURST_CLR = 0x0,
CHNL_REQ_MASK_SET = 0xfffffffe,
CHNL_REQ_MASK_CLR = 0xfffffffe,
CHNL_ENABLE_SET = 0x1,
CHNL_ENABLE_CLR = 0x1,
CHNL_PRI_ALT_SET = 0x0,
CHNL_PRI_ALT_CLR = 0x0,
CHNL_PRIORITY_SET = 0x0,
CHNL_PRIORITY_CLR = 0x0,
RESERVED0 = {0x0, 0x0, 0x0},
ERR_CLR = 0x0 }
{ dmaSrcEndAddr = 0x20000614,
dmaDstEndAddr = 0x20005588,
dmaControl = 0x3c101,
dmaUnused = 0x0 }
2. И ПОСЛЕ:
CODE
{ STATUS = 0x101f0001,
CFG = 0x0,
CTRL_BASE_PTR = 0x20100000,
ALT_CTRL_BASE_PTR = 0x20100200,
WAITONREQ_STATUS = 0x7fffffff,
CHNL_SW_REQUEST = 0x0,
CHNL_USEBURST_SET = 0x0,
CHNL_USEBURST_CLR = 0x0,
CHNL_REQ_MASK_SET = 0xfffffffe,
CHNL_REQ_MASK_CLR = 0xfffffffe,
CHNL_ENABLE_SET = 0x0,
CHNL_ENABLE_CLR = 0x0,
CHNL_PRI_ALT_SET = 0x0,
CHNL_PRI_ALT_CLR = 0x0,
CHNL_PRIORITY_SET = 0x0,
CHNL_PRIORITY_CLR = 0x0,
RESERVED0 = {0x0, 0x0, 0x0},
ERR_CLR = 0x0 }
{ dmaSrcEndAddr = 0x20000614,
dmaDstEndAddr = 0x20005588,
dmaControl = 0x3c000,
dmaUnused = 0x0 }
И казалось бы ДМА отработал (dmaControl перешел в режим "Стоп" и счетчик обнулился, а также сбросился Enable на первом канале)... но фиг там, содержимое tmp2 - как были нули так и остались. Для проверки - адреса:
Код
(volatile char (*)[17]) 0x20000604 <tmp1>
(volatile char (*)[20]) 0x20005578 <tmp2>
(dmaCtrlData_t (*)[16]) 0x20100000 <dmaCtrlData>
Что я забыл/не учел?

Из так называемого даташита - не смог понять что за передачи с кэшированием/буферизацией и как это использовать. Аналогично - не понятно в чем разница между режимами "Основной" и "Авто-запрос".
Сообщение отредактировал IgorKossak - Apr 6 2017, 17:58
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!