This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

F28M35H52C: udma不启动

Part Number: F28M35H52C


原来uart收发采用中断的方式实现,嫌中断太频繁,现在想改dma,使用的串口1,用的是udma_demo,只开了uart发送的dma,接收部分以及ram to ram部分注释掉了,我理解udma配置好了,通道使能就可以发送了,需要其他操作吧,使能部分我尝试读了,都是faulse

代码flash运行,管脚配置正确,时钟都正确*(单测试串口发送可以用测试代码发送数据到上位机显示。)

大致过程参考了demo,同时对着spru22i手册查看了16.4.3部分寄存器的设置,

代码 如下:

void UART1IntHandler(void)
{
unsigned long ulStatus;


ulStatus = UARTIntStatus(UART1_BASE, 1);

UARTIntClear(UART1_BASE, ulStatus);


if(!uDMAChannelIsEnabled(UDMA_CHANNEL_UART1TX))
{
uDMAChannelTransferSet(UDMA_CHANNEL_UART1TX | UDMA_PRI_SELECT,
UDMA_MODE_BASIC, g_ucTxBuf,
(void *)(UART1_BASE + UART_O_DR),
sizeof(g_ucTxBuf));

// The uDMA TX channel must be re-enabled.
uDMAChannelEnable(UDMA_CHANNEL_UART1TX);
/////// 怎么读都是没有使能
// uDMAChannelIsEnabled(UDMA_CHANNEL_UART1TX);

}
}


//*****************************************************************************
void
InitUART1Transfer(void)
{
unsigned int uIdx;
for(uIdx = 0; uIdx < UART_TXBUF_SIZE; uIdx++)
{
g_ucTxBuf[uIdx] = uIdx;
}

SysCtlPeripheralEnable(SYSCTL_PERIPH_UART1);
SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_UART1);


UARTConfigSetExpClk(UART1_BASE, SysCtlClockGet(SYSTEM_CLOCK_SPEED), 115200,
UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
UART_CONFIG_PAR_NONE);

UARTFIFOLevelSet(UART1_BASE, UART_FIFO_TX4_8, UART_FIFO_RX4_8);

UARTEnable(UART1_BASE);
UARTDMAEnable(UART1_BASE, UART_DMA_TX);

IntEnable(INT_UART1);

uDMAChannelAttributeDisable(UDMA_CHANNEL_UART1TX,
UDMA_ATTR_ALTSELECT |
UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK);


uDMAChannelAttributeEnable(UDMA_CHANNEL_UART1TX, UDMA_ATTR_USEBURST);

uDMAChannelControlSet(UDMA_CHANNEL_UART1TX | UDMA_PRI_SELECT,
UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE |
UDMA_ARB_4);


uDMAChannelTransferSet(UDMA_CHANNEL_UART1TX | UDMA_PRI_SELECT,
UDMA_MODE_BASIC, g_ucTxBuf,
(void *)(UART1_BASE + UART_O_DR),
sizeof(g_ucTxBuf));

////测试串口配置,管脚是否正确,能接到计算机上正常收到数据
// UARTCharPutNonBlocking(UART1_BASE,0xaa);
// UARTCharPutNonBlocking(UART1_BASE,0xaa);
// UARTCharPutNonBlocking(UART1_BASE,0xaa);
// UARTCharPutNonBlocking(UART1_BASE,0xaa);
// UARTCharPutNonBlocking(UART1_BASE,0xaa);

uDMAChannelEnable(UDMA_CHANNEL_UART1TX);
}


int main(void)
{
HWREG(SYSCTL_MWRALLOW) = 0xA5A5A5A5;
// Sets up PLL, M3 running at 75MHz and C28 running at 150MHz
SysCtlClockConfigSet(SYSCTL_USE_PLL | (SYSCTL_SPLLIMULT_M & 0xF) |
SYSCTL_SYSDIV_1 | SYSCTL_M3SSDIV_2 |
SYSCTL_XCLKDIV_4);

#ifdef _FLASH
memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize);
FlashInit();
#endif
////配置管脚
PinoutSet();
// Disable clock supply for the watchdog modules
SysCtlPeripheralDisable(SYSCTL_PERIPH_WDOG1);
SysCtlPeripheralDisable(SYSCTL_PERIPH_WDOG0);
// Unlock the register to change the commit register value for Port B Pin 7
// This disables the NMI functionality on the pin and allows other muxing
// options to be used
HWREG(GPIO_PORTB_BASE+GPIO_O_LOCK) = GPIO_LOCK_KEY_DD;
// Write to commit register
HWREG(GPIO_PORTB_BASE+GPIO_O_CR) |= 0x000000FF;
// Delay
for (i=0;i<20;i++){};

// Enable peripherals to operate when CPU is in sleep.
SysCtlPeripheralClockGating(true);
// Register interrupt handlers in the RAM vector table
IntRegister(INT_UART1, UART1IntHandler);
// Enable the uDMA controller at the system level. Enable it to continue
// to run while the processor is in sleep.
SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);
SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_UDMA);

// Enable the uDMA controller error interrupt. This interrupt will occur
// if there is a bus error during a transfer.
IntEnable(INT_UDMAERR);

// Enable the uDMA controller.
uDMAEnable();

// Point at the control table to use for channel control structures.
uDMAControlBaseSet(ucControlTable);

// Initialize the uDMA UART transfers.
InitUART1Transfer();

// Loop until the button is pressed. The processor is put to sleep
// in this loop so that CPU utilization can be measured.
while(1)
{
;
}

  • 调整了以下代码,loopback模式的,还是不行,收不到数据

    #pragma DATA_ALIGN(ucControlTable, 1024)
    unsigned char ucControlTable[1024];
    void uDMAErrorHandler(void);
    void setup_uart1_dma(void);
    void UART1_Link_IntDmaHandler(void);
    void DownLinkSendDma(void);
    void udma_demo(void);
    static unsigned char g_ucTxBuf[256];
    static unsigned char g_ucRxBufA[256];
    static unsigned char g_ucRxBufB[256];
    static unsigned long g_ulRxBufACount = 0;
    static unsigned long g_ulRxBufBCount = 0;

    void setup_uart1_dma(void)
    {
    ////dma
    unsigned int uIdx;

    // Fill the TX buffer with a simple data pattern.
    for(uIdx = 0; uIdx < 256; uIdx++)
    {
    g_ucTxBuf[uIdx] = uIdx;
    }
    //dma
    // Enable the peripherals used by this example.
    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART1);
    SysCtlPeripheralEnable(GPIO_PORTC_BASE);
    //UART1 Setup
    GPIOPinTypeUART(GPIO_PORTC_BASE, GPIO_PIN_6 | GPIO_PIN_7);
    GPIOPinConfigure(GPIO_PC7_U1TX);
    GPIOPinConfigure(GPIO_PC6_U1RX);

    SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_UART1);///dma

    // // Configure the UART1 for 115,200, 8-N-1 operation.
    // High-Speed Enable
    // Note: System clock used is also dependent on the baud-rate divisor configuration (see
    // Section 22.3.2).
    // 0 The UART is clocked using the system clock divided by 16.
    // 1 The UART is clocked using the system clock divided by 8.
    UARTConfigSetExpClk(UART1_BASE, SysCtlClockGet(SYSTEM_CLOCK_SPEED), 115200,
    (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
    UART_CONFIG_PAR_NONE));
    ////////////////////////////////////////////////////////////
    ////////////////////////////////////
    // UARTConfigSetExpClk(UART1_BASE, (unsigned long)10000000, 9600,
    // (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
    // UART_CONFIG_PAR_NONE));
    UARTFIFOLevelSet(UART1_BASE,UART_FIFO_TX4_8,UART_FIFO_RX4_8);//UART_FIFO_RX7_8);//UART_FIFO_RX4_8);
    // UARTTxIntModeSet(UART1_BASE,UART_TXINT_MODE_EOT);

    UARTEnable(UART1_BASE);

    // UARTDMAEnable(UART1_BASE,UART_DMA_TX);

    UARTDMAEnable(UART1_BASE,UART_DMA_RX | UART_DMA_TX);

    // This register write will set the UART to operate in loopback mode. Any
    // data sent on the TX output will be received on the RX input.
    HWREG(UART1_BASE + UART_O_CTL) |= UART_CTL_LBE;

    // Enable the UART interrupt.
    IntEnable(INT_UART1);

    uDMAChannel16_23SelectDefault(UDMA_CHAN22_DEF_UART1RX_M | UDMA_CHAN23_DEF_UART1TX_M);

    // Put the attributes in a known state for the uDMA UART0RX channel. These
    // should already be disabled by default.
    uDMAChannelAttributeDisable(UDMA_CHANNEL_UART1RX,
    UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST |
    UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK);


    uDMAChannelControlSet(UDMA_CHANNEL_UART1RX | UDMA_PRI_SELECT,
    UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 |
    UDMA_ARB_4);


    uDMAChannelControlSet(UDMA_CHANNEL_UART1RX | UDMA_ALT_SELECT,
    UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 |
    UDMA_ARB_4);


    uDMAChannelTransferSet(UDMA_CHANNEL_UART1RX | UDMA_PRI_SELECT,
    UDMA_MODE_PINGPONG,
    (void *)(UART1_BASE + UART_O_DR),
    g_ucRxBufA, sizeof(g_ucRxBufA));


    uDMAChannelTransferSet(UDMA_CHANNEL_UART1RX | UDMA_ALT_SELECT,
    UDMA_MODE_PINGPONG,
    (void *)(UART1_BASE + UART_O_DR),
    g_ucRxBufB, sizeof(g_ucRxBufB));


    // Put the attributes in a known state for the uDMA UART1TX channel. These
    // should already be disabled by default.
    uDMAChannelAttributeDisable(UDMA_CHANNEL_UART1TX,
    UDMA_ATTR_ALTSELECT |
    UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK);



    uDMAChannelAttributeEnable(UDMA_CHANNEL_UART1TX, UDMA_ATTR_USEBURST | UDMA_ATTR_HIGH_PRIORITY);//);


    uDMAChannelControlSet(UDMA_CHANNEL_UART1TX | UDMA_PRI_SELECT,
    UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE |
    UDMA_ARB_4);


    uDMAChannelTransferSet(UDMA_CHANNEL_UART1TX | UDMA_PRI_SELECT,
    UDMA_MODE_BASIC, g_ucTxBuf,
    (void *)(UART1_BASE + UART_O_DR),
    sizeof(g_ucTxBuf));

    UARTCharPutNonBlocking(UART1_BASE,0xaa);
    UARTCharPutNonBlocking(UART1_BASE,0xaa);
    UARTCharPutNonBlocking(UART1_BASE,0xaa);
    UARTCharPutNonBlocking(UART1_BASE,0xaa);
    UARTCharPutNonBlocking(UART1_BASE,0xaa);
    UARTCharPutNonBlocking(UART1_BASE,0xaa);
    UARTCharPutNonBlocking(UART1_BASE,0xaa);
    UARTCharPutNonBlocking(UART1_BASE,0xaa);


    uDMAChannelEnable(UDMA_CHANNEL_UART1TX);
    uDMAChannelEnable(UDMA_CHANNEL_UART1RX);
    }

    void
    UART1_Link_IntDmaHandler(void)
    {
    unsigned long ulStatus;
    unsigned long ulMode;
    tBoolean ch_en;

    // Read the interrupt status of the UART.
    ulStatus = UARTIntStatus(UART1_BASE, 1);


    UARTIntClear(UART1_BASE, ulStatus);


    ulMode = uDMAChannelModeGet(UDMA_CHANNEL_UART1RX | UDMA_PRI_SELECT);


    if(ulMode == UDMA_MODE_STOP)
    {

    g_ulRxBufACount++;


    uDMAChannelTransferSet(UDMA_CHANNEL_UART1RX | UDMA_PRI_SELECT,
    UDMA_MODE_PINGPONG,
    (void *)(UART1_BASE + UART_O_DR),
    g_ucRxBufA, sizeof(g_ucRxBufA));
    }


    ulMode = uDMAChannelModeGet(UDMA_CHANNEL_UART1RX | UDMA_ALT_SELECT);


    if(ulMode == UDMA_MODE_STOP)
    {

    g_ulRxBufBCount++;


    uDMAChannelTransferSet(UDMA_CHANNEL_UART1RX | UDMA_ALT_SELECT,
    UDMA_MODE_PINGPONG,
    (void *)(UART1_BASE + UART_O_DR),
    g_ucRxBufB, sizeof(g_ucRxBufB));
    }


    if(!uDMAChannelIsEnabled(UDMA_CHANNEL_UART1TX))
    {
    // Start another DMA transfer to UART0 TX.
    uDMAChannelTransferSet(UDMA_CHANNEL_UART1TX | UDMA_PRI_SELECT,
    UDMA_MODE_BASIC, g_ucTxBuf,
    (void *)(UART1_BASE + UART_O_DR),
    sizeof(g_ucTxBuf));

    // The uDMA TX channel must be re-enabled.
    uDMAChannelEnable(UDMA_CHANNEL_UART1TX);
    ch_en = uDMAChannelIsEnabled(UDMA_CHANNEL_UART1TX);

    }
    }

    void udma_demo(void)
    {
    // Setup main clock tree for 75MHz - M3 and 150MHz - C28x//该设置复位
    SysCtlClockConfigSet(SYSCTL_SYSDIV_1 | SYSCTL_M3SSDIV_2 | SYSCTL_USE_PLL |
    (SYSCTL_SPLLIMULT_M & 0x0F));

    memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize);

    // Call Flash Initialization to setup flash waitstates
    // This function must reside in RAM
    FlashInit();
    // Enable peripherals to operate when CPU is in sleep.
    SysCtlPeripheralClockGating(true);

    // Enable all GPIOs
    PinoutSet();
    set_v7_pin_wpu();

    IntRegister(INT_UART1, UART1_Link_IntDmaHandler);

    IntRegister(INT_UDMAERR, uDMAErrorHandler);

    // Enable the uDMA controller at the system level. Enable it to continue
    // to run while the processor is in sleep.
    SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);
    SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_UDMA);

    IntEnable(INT_UDMAERR);

    // Enable the uDMA controller.
    uDMAEnable();

    // Point at the control table to use for channel control structures.
    uDMAControlBaseSet(ucControlTable);

    setup_uart1_dma();

    while(1)
    {
    ;
    }
    }

  • 查了寄存器的值没看出来啥问题

  • 设置也设置了

  • 设置好以后,

    uDMAChannelEnable(UDMA_CHANNEL_UART1TX);

    使能通道就应该启动发送了,设置后,寄存器没有任何变化,不知道是不是正常

  • uart1里面的dr里面值还是0xaa,没有读,也没写

  • 抱歉啊,对这款芯片不太熟悉,包括uDMA模块也是。

    这边建议你把问题发布到英文E2E论坛,英文论坛会有专门支持这款芯片的工程师为你解答。

    另外,发布代码的话建议只附上关键的DMA+GPIO配置部分代码,否则这么大段代码应该很难给你一一审阅。且代码用编辑框下方“插入”中的“代码”来添加,不要直接粘贴在文本框内。

    英文论坛链接:e2e.ti.com/.../c2000-microcontrollers-forum

  • 没有公司邮箱,不让发:)

  • 可以注册一个钉钉邮箱,是可以发布帖子的