Hi!
I'm planning to use dma at spi, sci, scilin to save cpu resources. As a starting point, I'm currently working with sci transmission via dma.
The structure of dma block is 1 frame wih 8 elements so dma is supposed to send 8 bytes in sci. Source is uint8_t array wih 16 elements('0' to 'f').
Dma is supposed to send '01234567'.
#include "sys_common.h"
/* USER CODE BEGIN (1) */
#include "sys_dma.h"
#include "sci.h"
/* USER CODE END */
/** @fn void main(void)
* @brief Application main function
* @note This function is empty by default.
*
* This function is called after startup.
* The user can use this function to implement the application.
*/
/* USER CODE BEGIN (2) */
void setDmaPacket(g_dmaCTRL *packet);
void setDmaSciReceive(g_dmaCTRL *packet);
void setDmaSciTransmit(g_dmaCTRL *packet);
uint8_t p[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
/* USER CODE END */
int main(void)
{
/* USER CODE BEGIN (3) */
g_dmaCTRL dmaPacket = {0};
uint32_t dmaReqlineSciRx = 30;
uint32_t dmaReqlineSciTx = 31;
_enable_interrupt_();
sciInit();
sciSend(sciREG, 6, "init\r\n");
setDmaPacket(&dmaPacket);
setDmaSciTransmit(&dmaPacket);
dmaEnable();
dmaReqAssign(DMA_CH0, dmaReqlineSciTx);
dmaSetCtrlPacket(DMA_CH0, dmaPacket);
dmaSetChEnable(DMA_CH0, DMA_HW);
dmaEnableInterrupt(DMA_CH0, HBC);
dmaEnableInterrupt(DMA_CH0, BTC);
sciREG->SETINT |= (1 << 16);
while(1)
{
}
/* USER CODE END */
}
/* USER CODE BEGIN (4) */
void setDmaSciTransmit(g_dmaCTRL *packet)
{
packet->SADD = (uint32_t)p;
packet->DADD = (uint32_t)(&(sciREG->TD));
}
void setDmaSciReceive(g_dmaCTRL *packet)
{
packet->SADD = (uint32_t)(&(sciREG->RD));
packet->DADD = (uint32_t)p;
}
void setDmaPacket(g_dmaCTRL *packet)
{
packet->CHCTRL = 0;
packet->ELCNT = 8;
packet->ELDOFFSET = 0;
packet->ELSOFFSET = 1;
packet->FRDOFFSET = 0;
packet->FRSOFFSET = 0;
packet->FRCNT = 1;
packet->PORTASGN = 4;
packet->RDSIZE = ACCESS_8_BIT;
packet->WRSIZE = ACCESS_8_BIT;
packet->TTYPE = BLOCK_TRANSFER;
packet->ADDMODERD = ADDR_INC1;
packet->ADDMODEWR = ADDR_FIXED;
packet->AUTOINIT = AUTOINIT_OFF;
}
void dmaGroupANotification(dmaInterrupt_t inttype, uint32 channel)
{
/* enter user code between the USER CODE BEGIN and USER CODE END. */
/* USER CODE BEGIN (54) */
switch(inttype)
{
case HBC:
sciSend(sciREG, 12, "half block\r\n");
break;
case BTC:
sciSend(sciREG, 12, "block done\r\n");
break;
}
Expected result in terminal is:
init
0123half block
4567block done
Place of 0~7 can vary.
Actual result is:
init
7half block
block done
Only last element 7 is sent through sci. When I changed 8th element 7 into different value the result changed accordingly, so dma is reading something but not correctly.
What could be the problem?