Part Number: CC1310
我没有找到对应的demo,自己写的有点问题,卡死在urat忙,
若在 UART_DMASend(dmaTxBuffer, numLen); 后面添加 UART_write能够正常dma输出,但输出结束立刻卡死?
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#include <string.h>
#include <unistd.h>
#include <ti/drivers/GPIO.h>
#include <ti/drivers/UART.h>
#include <ti/devices/cc13x0/driverlib/udma.h>
#include <ti/devices/cc13x0/driverlib/uart.h>
#include <ti/devices/cc13x0/driverlib/prcm.h>
#include <ti/devices/cc13x0/inc/hw_memmap.h>
#include <ti/devices/cc13x0/inc/hw_uart.h>
#include "Board.h"
#define DMA_CONTROL_TABLE_SIZE 32
#pragma DATA_ALIGN(g_pDMAControlTable, 1024)
static tDMAControlTable g_pDMAControlTable[DMA_CONTROL_TABLE_SIZE];// 发送缓冲区
static uint8_t dmaTxBuffer[128];
// 用于调试输出的 UART 句柄(普通模式)
static UART_Handle uart;
// 辅助调试打印(使用普通 UART_write)
static void dbg_print(const char *s) {
UART_write(uart, (uint8_t*)s, strlen(s));
}
// 初始化 µDMA 控制器
static void DMA_Init(void) {
// 检查控制表对齐
if ((uint32_t)g_pDMAControlTable & 0x3FF) {
while (1); // 对齐失败,应检查链接脚本
}
// 使能 µDMA 外设时钟
PRCMPeripheralRunEnable(PRCM_PERIPH_UDMA);
PRCMLoadSet();
while (!PRCMLoadGet());
// 设置 DMA 控制表基址
uDMAControlBaseSet(UDMA0_BASE, g_pDMAControlTable);
uDMAEnable(UDMA0_BASE);
// 配置 UART TX 通道属性
uDMAChannelAttributeEnable(UDMA0_BASE, UDMA_CHAN_UART0_TX, UDMA_ATTR_HIGH_PRIORITY);
uDMAChannelControlSet(UDMA0_BASE, UDMA_PRI_SELECT | UDMA_CHAN_UART0_TX,
UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARB_8);
}
// DMA 发送函数(阻塞,带固定延时,不依赖中断)
static void UART_DMASend(const uint8_t *data, uint32_t len) {
// 1. 等待前一次 UART 完全空闲(防止冲突)
while (HWREG(UART0_BASE + UART_O_FR) & (1 << 3)); // BUSY
// 2. 确保 UART TX DMA 请求使能(bit1 = 0x02)
HWREG(UART0_BASE + UART_O_DMACTL) |= 0x02;
// 3. 配置 DMA 传输(BASIC 模式 + 软件触发)
uDMAChannelTransferSet(UDMA0_BASE, UDMA_PRI_SELECT | UDMA_CHAN_UART0_TX,
UDMA_MODE_BASIC,
(void*)data,
(void*)(UART0_BASE + UART_O_DR),
len);
uDMAChannelEnable(UDMA0_BASE, UDMA_CHAN_UART0_TX);
uDMAChannelRequest(UDMA0_BASE, UDMA_CHAN_UART0_TX);
// 4. 固定延时等待 DMA 完成(115200bps 每个字节约87us,加2ms余量)
uint32_t delay_us = len * 100 + 2000;
usleep(delay_us);
// 5. 等待 UART 真正发送完毕(FIFO 空 + 不忙),带短超时避免卡死
uint32_t timeout = 10000;
while (!(HWREG(UART0_BASE + UART_O_FR) & (1 << 7))) { // TX FIFO 空
if (--timeout == 0) break;
}
timeout = 10000;
while (HWREG(UART0_BASE + UART_O_FR) & (1 << 3)) { // BUSY
if (--timeout == 0) break;
}
// 6. 禁用 DMA 通道,为下次发送准备
// uDMAChannelDisable(UDMA0_BASE, UDMA_CHAN_UART0_TX);
}
//============================================================================
// 主线程(TI-RTOS 任务)
//============================================================================
void *mainThread(void *arg0) {
// 初始化基础驱动
GPIO_init();
UART_init();
// 配置 LED(指示运行状态)
GPIO_setConfig(Board_GPIO_LED0, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
GPIO_write(Board_GPIO_LED0, Board_GPIO_LED_ON);
// 打开 UART(普通模式,用于调试输出)
UART_Params uartParams;
UART_Params_init(&uartParams);
uartParams.baudRate = 115200;
uartParams.writeDataMode = UART_DATA_BINARY;
uartParams.readDataMode = UART_DATA_BINARY;
uart = UART_open(Board_UART0, &uartParams);
if (uart == NULL) while (1);
dbg_print("\r\n=== UART DMA Final Version ===\r\n");
// 初始化 DMA
DMA_Init();
dbg_print("DMA initialized.\r\n");
// 准备发送数据(复制到 SRAM 缓冲区)
const char *helloMsg = "Hello from UART DMA!\r\n";
uint32_t msgLen = strlen(helloMsg);
memcpy(dmaTxBuffer, helloMsg, msgLen);
// 主循环:每隔一秒发送一次
uint32_t counter = 0;
while (1) {
// 发送固定消息
UART_DMASend(dmaTxBuffer, msgLen);
// 发送计数器数值(仍使用 dm aTxBuffer)
char numBuf[32];
snprintf(numBuf, sizeof(numBuf), "Counter: %lu\r\n", counter++);
uint32_t numLen = strlen(numBuf);
memcpy(dmaTxBuffer, numBuf, numLen);
UART_DMASend(dmaTxBuffer, numLen);
// 延时 1 秒
sleep(1);
}
}