TI中文支持网
TI专业的中文技术问题咨询交流网站

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)
{
;
}

yunfei ma:

调整了以下代码,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);}voidUART1_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) { ; }}

,

yunfei ma:

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

,

yunfei ma:

设置也设置了

,

yunfei ma:

设置好以后,

uDMAChannelEnable(UDMA_CHANNEL_UART1TX);

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

,

yunfei ma:

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

,

Green Deng:

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

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

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

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

,

yunfei ma:

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

,

Green Deng:

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

赞(0)
未经允许不得转载:TI中文支持网 » F28M35H52C: udma不启动
分享到: 更多 (0)