#include "com.h"
//linux->uart7 arm->uart9
#define PDMA ((PDMA_T *) PDMA3_BASE)
#define PDMA_TEST_LENGTH 30
void pdma_init(void);
void com_init(void)
{
SYS_UnlockReg();
CLK_SetModuleClock(UART6_MODULE, CLK_CLKSEL2_UART6SEL_HXT, CLK_CLKDIV2_UART6(1));
CLK_EnableModuleClock(UART6_MODULE);
CLK_EnableModuleClock(PDMA3_MODULE);
/*---------------------------------------------------------------------------------------------------------*/
/* Init I/O Multi-function */
/*---------------------------------------------------------------------------------------------------------*/
/* Set multi-function pins for Debug UART RXD and TXD */
SYS->GPN_MFPH &= ~(SYS_GPN_MFPH_PN14MFP_Msk | SYS_GPN_MFPH_PN15MFP_Msk);
SYS->GPN_MFPH |= SYS_GPN_MFPH_PN14MFP_UART6_RXD | SYS_GPN_MFPH_PN15MFP_UART6_TXD;
SYS_LockReg();
UART_Open(UART6, 115200);
pdma_init();
}
uint32_t g_u32DMAConfig = 0;
typedef struct dma_desc_t
{
uint32_t ctl;
uint32_t src;
uint32_t dest;
uint32_t offset;
} DMA_DESC_T;
DMA_DESC_T DMA_DESC[2];
volatile uint8_t rx[PDMA_TEST_LENGTH];
static uint8_t g_u8Tx_Buffer[PDMA_TEST_LENGTH]={1,2,3,4,5,6,7,8};
void pdma_init(void)
{
UART_PDMA_ENABLE(UART6,UART_INTEN_RXPDMAEN_Msk);
SYS_ResetModule(PDMA3_RST);
PDMA_Open(PDMA,1 << 1); // Channel 1 for UART1 RX
PDMA_SetTransferMode(PDMA,1, PDMA_UART6_RX, TRUE, (uint32_t)&DMA_DESC[0]);
g_u32DMAConfig = \
((PDMA_TEST_LENGTH/2 -1)<< PDMA_DSCT_CTL_TXCNT_Pos) | /* Transfer count is 1 */ \
PDMA_WIDTH_8 | /* Transfer width is 8 bits(one word) */ \
PDMA_SAR_FIX | /* Source increment size is fixed(no increment) */ \
PDMA_DAR_INC | /* Destination increment size is increment(increment) */ \
PDMA_REQ_SINGLE | /* Transfer type is burst transfer type */ \
PDMA_BURST_1 | /* Burst size is 128. No effect in single transfer type */ \
/* PDMA_TBINTDIS_DISABLE | Disable transfer done and table empty interrupt */
PDMA_OP_SCATTER; /* Operation mode is scatter-gather mode */
DMA_DESC[0].ctl = g_u32DMAConfig;
/* Configure source address */
DMA_DESC[0].src = UART6_BASE; /* Ping-Pong buffer 1 */
/* Configure destination address */
DMA_DESC[0].dest = (uint32_t)(&rx[0]);
/* Configure next descriptor table address */
DMA_DESC[0].offset = (uint32_t)&DMA_DESC[1]; /* next operation table is table 2 */
DMA_DESC[1].ctl = g_u32DMAConfig;
/* Configure source address */
DMA_DESC[1].src = UART6_BASE; /* Ping-Pong buffer 1 */
/* Configure destination address */
DMA_DESC[1].dest = (uint32_t)(&rx[PDMA_TEST_LENGTH/2]);
/* Configure next descriptor table address */
DMA_DESC[1].offset = (uint32_t)&DMA_DESC[0]; /* next operation table is table 2 */
printf("%d %d\r\n",(uint32_t)&DMA_DESC[0],PDMA->CURSCAT[1]);
/* Enable transfer done interrupt */
PDMA_EnableInt(PDMA3,1, PDMA_INT_TRANS_DONE);
NVIC_EnableIRQ(PDMA3_IRQn);
}
void PDMA3_IRQHandler(void)
{
/* Check channel transfer done status */
if (PDMA_GET_TD_STS(PDMA3) == PDMA_TDSTS_TDIF1_Msk)
{
/* When finished a descriptor table then g_u32TransferredCount increases 1 */
pdma_test();
/* Clear transfer done flag of channel 4 */
PDMA_CLR_TD_FLAG(PDMA3,PDMA_TDSTS_TDIF1_Msk);
PDMA_SetTransferCnt(PDMA,1, PDMA_WIDTH_8, PDMA_TEST_LENGTH);
// printf("%x,pdma ok\r\n",PDMA3->DSCT[1].CTL);
}
}
static void SendChar_ToUART(int ch)
{
while(UART6->FIFOSTS & UART_FIFOSTS_TXFULL_Msk);
UART6->DAT = ch;
}
void pdma_test(void)
{
int i;
for(i=0;i<PDMA_TEST_LENGTH;i++)
{
printf("%x ",rx);
}
printf("\r\n");
// SendChar_ToUART('O');
// SendChar_ToUART('K');
}
代码参考如上,测试串口6接收DAT寄存器可以读到数据,但是pdma的scatter-gather模式无法自动搬运数据到sram中,无法触发pdma中断。也尝试使用pdma的普通模式,能成功搬运,但是奇怪的是收到的第二到第7字节都是0,第一字节和第8字节后面都是正常,搬运结束也能正常进入pdma中断,但也是有一个问题,只能启动一次,在中断里面清除了中断标记和重新赋值搬运个数,也无法触发第二次pdma接收。串口换了几个,pdma也尝试使用pdma2,最终结果都是一样,感觉这个芯片有bug,忘原厂重视下。 |