打印
[技术问答]

ma35d1的串口pdma的scatter-gather接收无法响应。

[复制链接]
1628|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
classroom|  楼主 | 2024-5-17 16:00 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#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,忘原厂重视下。

使用特权

评论回复
沙发
奔跑的牛| | 2024-6-19 14:01 | 只看该作者
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

407

主题

1939

帖子

1

粉丝