官方的demo(F28M35x_examples Masterudma_demolmn3wudma_demo.c)是关于UART0回环模式的,但我想要用UART3支持中断+FHIFO+VDMA模式,请问应该怎么配置?有这方面的例程吗?
下面是我的一些代码配置:
//*****************************************************************************
// udma_integration_simple.c - 绠�鍖栫殑碌DMA闆嗘垚瀹炵幇
// 涓撻棬閽堝褰撳墠M3-377S閫氫俊绯荤粺浼樺寲锛屼繚鎸佹渶澶у吋瀹规��
//*****************************************************************************
#include "udma_integration_simple.h"
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
// 澹版槑澶栭儴printf鍑芥暟锛堝湪blinky_dc_m3.c涓疄鐜帮級
extern int printf(const char* format, ...);
// 澹版槑澶栭儴鍗忚鍑芥暟锛堝湪levitation_protocol.h涓疄鐜帮紝鐢眀linky_dc_m3.c鍖呭惈锛�
extern uint16_t LevitationSimple_calculateCRC(const uint16_t* data, uint16_t length);
extern bool LevitationSimple_deserialize(const uint16_t* buffer, uint16_t buffer_size, void* data);
// 鍓嶅悜澹版槑鍗忚鏁版嵁缁撴瀯锛堝畬鏁村畾涔夊湪levitation_protocol.h涓級
typedef struct {
uint16_t data_length;
uint16_t* data_fields;
uint16_t device;
uint16_t type;
} LevitationSimple_t;
//*****************************************************************************
// 鍏ㄥ眬鍙橀噺瀹氫箟
//*****************************************************************************
// 碌DMA鎺у埗琛紙蹇呴』1024瀛楄妭瀵归綈锛�
#pragma DATA_ALIGN(ucSimpleUDMAControlTable, 1024)
uint8_t ucSimpleUDMAControlTable[UDMA_CONTROL_TABLE_SIZE];
// 绠�鍖栫殑碌DMA UART瀹炰緥
SimpleUDMAUART_t g_simpleUDMAUART = {0};
//*****************************************************************************
// 绉佹湁鍑芥暟澹版槑
//*****************************************************************************
static void SimpleUDMA_ResetPacketState(void);
static bool SimpleUDMA_ValidatePacket(const uint8_t* data, uint16_t length);
static void SimpleUDMA_ConfigureUART3(void);
static void SimpleUDMA_ConfigureDMA(void);
//*****************************************************************************
// 鍒濆鍖栧嚱鏁板疄鐜�
//*****************************************************************************
//*****************************************************************************
// 鍒濆鍖栫畝鍖栫殑碌DMA UART绯荤粺
//*****************************************************************************
void SimpleUDMA_Init(void)
{
// 娓呴浂缁撴瀯浣�
memset(&g_simpleUDMAUART, 0, sizeof(SimpleUDMAUART_t));
// 鍒濆鍖栨暟鎹寘鐘舵��
SimpleUDMA_ResetPacketState();
// 浣胯兘碌DMA澶栬
SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);
SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_UDMA);
// 浣胯兘碌DMA鎺у埗鍣�
uDMAEnable();
// 璁剧疆鎺у埗琛ㄥ熀鍦板潃
uDMAControlBaseSet(ucSimpleUDMAControlTable);
// 鍏堥厤缃礑MA閫氶亾鏄犲皠锛堢‘淇漊ART3浣跨敤绗笁缁勯�氶亾锛�
uDMAChannel16_23SelectAltMapping(UDMA_CHAN16_THRD_UART3RX | UDMA_CHAN17_THRD_UART3TX);
// 閰嶇疆碌DMA
SimpleUDMA_ConfigureDMA();
// 閰嶇疆UART3锛堝湪碌DMA閰嶇疆涔嬪悗锛�
SimpleUDMA_ConfigureUART3();
// 娉ㄥ唽涓柇澶勭悊鍑芥暟
IntRegister(INT_UART3, SimpleUDMA_IntHandler);
IntRegister(INT_UDMAERR, SimpleUDMA_ErrorHandler);
// 浣胯兘涓柇
IntEnable(INT_UART3);
IntEnable(INT_UDMAERR);
// 鏍囪DMA宸插惎鐢�
g_simpleUDMAUART.dmaEnabled = true;
// 鍚姩鎺ユ敹
SimpleUDMA_StartReceive();
}
//*****************************************************************************
// 鍙嶅垵濮嬪寲绠�鍖栫殑碌DMA UART绯荤粺
//*****************************************************************************
void SimpleUDMA_Deinit(void)
{
// 鍋滄鎺ユ敹
SimpleUDMA_StopReceive();
// 绂佺敤碌DMA閫氶亾
uDMAChannelDisable(UDMA_CHANNEL_UART3RX);
uDMAChannelDisable(UDMA_CHANNEL_UART3TX);
// 绂佺敤涓柇
IntDisable(INT_UART3);
IntDisable(INT_UDMAERR);
// 绂佺敤碌DMA鎺у埗鍣�
uDMADisable();
// 绂佺敤碌DMA澶栬
SysCtlPeripheralDisable(SYSCTL_PERIPH_UDMA);
// 鏍囪DMA宸茬鐢�
g_simpleUDMAUART.dmaEnabled = false;
}
//*****************************************************************************
// 閰嶇疆UART3澶栬锛堜繚鎸佷笌鐜版湁閰嶇疆鍏煎锛�
//*****************************************************************************
static void SimpleUDMA_ConfigureUART3(void)
{
// 浣胯兘UART3澶栬
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART3);
SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_UART3);
// 绛夊緟澶栬浣胯兘绋冲畾
for(volatile int delay = 0; delay < 100; delay++) {}
// 姝ラ1: 绂佺敤UART锛堟寜鐓I鏂囨。瑕佹眰锛�
UARTDisable(UART3_BASE);
// 姝ラ2: 閰嶇疆UART閫氫俊鍙傛暟锛圲ARTConfigSetExpClk浼氳嚜鍔ㄩ厤缃瓸RD锛�
UARTConfigSetExpClk(UART3_BASE, SysCtlClockGet(SYSTEM_CLOCK_SPEED), 115200,
UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
UART_CONFIG_PAR_NONE);
// 姝ラ3: 璁剧疆FIFO瑙﹀彂绾у埆锛堝湪鍚敤UART涔嬪墠锛�
UARTFIFOLevelSet(UART3_BASE, UART_FIFO_TX4_8, UART_FIFO_RX4_8);
// 姝ラ4: 閰嶇疆碌DMA锛堝湪鍚敤UART涔嬪墠锛�
UARTDMAEnable(UART3_BASE, UART_DMA_RX | UART_DMA_TX);
// 姝ラ5: 鍚敤UART锛堟渶鍚庢楠わ級
UARTEnable(UART3_BASE);
printf("M3: UART3 configured: 115200 bps, 8-N-1\r\n");
// 绛夊緟UART浣胯兘绋冲畾
for(volatile int delay = 0; delay < 100; delay++) {}
// 娓呴櫎鎵�鏈塙ART閿欒鐘舵��
UARTIntClear(UART3_BASE, UART_INT_OE | UART_INT_BE | UART_INT_PE | UART_INT_FE | UART_INT_RT | UART_INT_TX | UART_INT_RX);
// 浣胯兘UART涓柇锛堝湪UART鍚敤鍚庯級
UARTIntEnable(UART3_BASE, UART_INT_RX | UART_INT_RT | UART_INT_TX);
// 妫�鏌ARTDMACTL瀵勫瓨鍣ㄦ槸鍚︽纭缃�
unsigned long uartDmaCtl = HWREG(UART3_BASE + 0x48); // UARTDMACTL瀵勫瓨鍣ㄥ湴鍧�
printf("M3: UARTDMACTL register: 0x%08lX\r\n", uartDmaCtl);
printf("M3: TXDMAE (bit 1): %s\r\n", (uartDmaCtl & 0x02) ? "Enabled" : "Disabled");
printf("M3: RXDMAE (bit 0): %s\r\n", (uartDmaCtl & 0x01) ? "Enabled" : "Disabled");
// 妫�鏌ュ苟鎶ュ憡UART3 DR瀵勫瓨鍣ㄥ垵濮嬬姸鎬�
unsigned long uartDrInit = HWREG(UART3_BASE + UART_O_DR);
printf("M3: UART3 DR initial: 0x%08lX\r\n", uartDrInit);
if (uartDrInit & 0x800) {
printf("M3: WARNING: UART3 DR has error bit set initially\r\n");
}
}
//*****************************************************************************
// 閰嶇疆碌DMA閫氶亾锛堢畝鍖栭厤缃級
//*****************************************************************************
static void SimpleUDMA_ConfigureDMA(void)
{
// 閰嶇疆UART3 RX閫氶亾灞炴�э紙鎸夌収TI瀹樻柟渚嬬▼閰嶇疆锛�
uDMAChannelAttributeDisable(UDMA_CHANNEL_UART3RX,
UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST |
UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK);
// 閰嶇疆UART3 RX涓绘帶鍒剁粨鏋�
uDMAChannelControlSet(UDMA_CHANNEL_UART3RX | UDMA_PRI_SELECT,
UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 |
UDMA_ARB_4);
// 閰嶇疆UART3 RX澶囩敤鎺у埗缁撴瀯
uDMAChannelControlSet(UDMA_CHANNEL_UART3RX | UDMA_ALT_SELECT,
UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 |
UDMA_ARB_4);
// 璁剧疆UART3 RX涓讳紶杈撳弬鏁帮紙Ping-Pong妯″紡锛�
uDMAChannelTransferSet(UDMA_CHANNEL_UART3RX | UDMA_PRI_SELECT,
UDMA_MODE_PINGPONG,
(void *)(UART3_BASE + UART_O_DR),
g_simpleUDMAUART.rxBufferA, sizeof(g_simpleUDMAUART.rxBufferA));
// 璁剧疆UART3 RX澶囩敤浼犺緭鍙傛暟锛圥ing-Pong妯″紡锛�
uDMAChannelTransferSet(UDMA_CHANNEL_UART3RX | UDMA_ALT_SELECT,
UDMA_MODE_PINGPONG,
(void *)(UART3_BASE + UART_O_DR),
g_simpleUDMAUART.rxBufferB, sizeof(g_simpleUDMAUART.rxBufferB));
// 閰嶇疆UART3 TX閫氶亾灞炴�э紙鎸夌収SSI渚嬪瓙锛屼笉绂佺敤REQMASK锛�
uDMAChannelAttributeDisable(UDMA_CHANNEL_UART3TX,
UDMA_ATTR_ALTSELECT | UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_USEBURST);
// 閰嶇疆UART3 TX鎺у埗鍙傛暟锛堜紭鍖栦紶杈撴晥鐜囷級
uDMAChannelControlSet(UDMA_CHANNEL_UART3TX | UDMA_PRI_SELECT,
UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE |
UDMA_ARB_4); // 浣跨敤4瀛楄妭浠茶锛屾彁楂樹紶杈撴晥鐜�
}
//*****************************************************************************
// 浼犺緭鎺у埗鍑芥暟瀹炵幇
//*****************************************************************************
//*****************************************************************************
// 鍚姩碌DMA鎺ユ敹
//*****************************************************************************
void SimpleUDMA_StartReceive(void)
{
if (g_simpleUDMAUART.dmaEnabled)
{
uDMAChannelEnable(UDMA_CHANNEL_UART3RX);
}
}
//*****************************************************************************
// 鍋滄碌DMA鎺ユ敹
//*****************************************************************************
void SimpleUDMA_StopReceive(void)
{
uDMAChannelDisable(UDMA_CHANNEL_UART3RX);
}
//*****************************************************************************
// 鍙戦�佹暟鎹寘锛堜繚鎸佷笌鐜版湁鎺ュ彛鍏煎锛�
//*****************************************************************************
bool SimpleUDMA_SendPacket(const uint8_t* data, uint16_t length)
{
if (!g_simpleUDMAUART.dmaEnabled || length > UART_TX_BUFFER_SIZE)
{
return false;
}
// 妫�鏌X閫氶亾鏄惁蹇欑
if (uDMAChannelIsEnabled(UDMA_CHANNEL_UART3TX))
{
// 妫�鏌ラ�氶亾鐘舵��
unsigned long ulMode = uDMAChannelModeGet(UDMA_CHANNEL_UART3TX | UDMA_PRI_SELECT);
printf("M3: TX channel enabled, mode: 0x%08lX (STOP=0x%08lX)\r\n", ulMode, UDMA_MODE_STOP);
// 妫�鏌ユ槸鍚︽槸浼犺緭瀹屾垚鐘舵�侊紙妯″紡0x00000001琛ㄧず浼犺緭瀹屾垚浣嗛�氶亾鏈鐢級
if (ulMode == 0x00000001)
{
printf("M3: TX transmission completed but channel not disabled, forcing disable\r\n");
uDMAChannelDisable(UDMA_CHANNEL_UART3TX);
}
else
{
printf("M3: TX channel still busy, mode: 0x%08lX\r\n", ulMode);
return false; // 涓婃浼犺緭杩樻湭瀹屾垚
}
}
// 澶嶅埗鏁版嵁鍒癟X缂撳啿鍖�
memcpy(g_simpleUDMAUART.txBuffer, data, length);
// 瀹屽叏绂佺敤骞堕噸鏂伴厤缃甌X閫氶亾
uDMAChannelDisable(UDMA_CHANNEL_UART3TX);
// 绛夊緟閫氶亾瀹屽叏绂佺敤
while (uDMAChannelIsEnabled(UDMA_CHANNEL_UART3TX)) {
// 绛夊緟閫氶亾绂佺敤
}
// 浼樺寲碌DMA閰嶇疆锛屾彁楂樹紶杈撴晥鐜�
// 浣跨敤4瀛楄妭浠茶锛屾彁楂樹紶杈撴晥鐜�
uDMAChannelControlSet(UDMA_CHANNEL_UART3TX | UDMA_PRI_SELECT,
UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARB_4);
// 璁剧疆浼犺緭鍙傛暟锛堜娇鐢˙ASIC妯″紡锛�
uDMAChannelTransferSet(UDMA_CHANNEL_UART3TX | UDMA_PRI_SELECT,
UDMA_MODE_BASIC, g_simpleUDMAUART.txBuffer,
(void *)(UART3_BASE + UART_O_DR), length);
// 楠岃瘉浼犺緭閰嶇疆
printf("M3: 碌DMA Transfer Config: Mode=BASIC, Src=0x%08X, Dst=0x%08X, Size=%d\r\n",
(unsigned int)g_simpleUDMAUART.txBuffer,
(unsigned int)(UART3_BASE + UART_O_DR),
length);
// 绮剧畝鏃ュ織锛氱Щ闄よ缁嗙殑閰嶇疆淇℃伅
// 璇︾粏鏃ュ織锛氭樉绀哄彂閫佺殑鏁版嵁鍐呭
printf("M3: 碌DMA sending %d bytes: ", length);
for(int i = 0; i < length && i < 16; i++) {
printf("%02X ", data[i]);
}
printf("\r\n");
// 妫�鏌X缂撳啿鍖哄唴瀹�
printf("M3: TX Buffer content: ");
for(int i = 0; i < length && i < 16; i++) {
printf("%02X ", g_simpleUDMAUART.txBuffer[i]);
}
printf("\r\n");
// 浣胯兘閫氶亾锛堟寜鐓у畼鏂筪emo鏂瑰紡锛�
uDMAChannelEnable(UDMA_CHANNEL_UART3TX);
// 妫�鏌ラ�氶亾鏄惁鐪熺殑琚惎鐢�
if (uDMAChannelIsEnabled(UDMA_CHANNEL_UART3TX)) {
printf("M3: 碌DMA TX channel successfully enabled\r\n");
} else {
printf("M3: ERROR: 碌DMA TX channel failed to enable\r\n");
return false;
}
// 娣诲姞杞欢瑙﹀彂锛堟寜鐓SI渚嬪瓙鐨勬柟寮忥級
uDMAChannelRequest(UDMA_CHANNEL_UART3TX);
printf("M3: 碌DMA TX channel software request sent\r\n");
// 绛夊緟涓�灏忔鏃堕棿纭繚浼犺緭寮�濮�
for(volatile int startDelay = 0; startDelay < 100; startDelay++) {}
// 璇婃柇锛氭鏌ART3 TX寮曡剼鐘舵��
unsigned long gpioData = GPIOPinRead(GPIO_PORTD_BASE, GPIO_PIN_4);
printf("M3: UART3 TX (PD4) pin state: %s\r\n", (gpioData & GPIO_PIN_4) ? "High" : "Low");
// 楠岃瘉鏂规硶1锛氭鏌ART3鏁版嵁瀵勫瓨鍣ㄦ槸鍚︽湁鏁版嵁鍐欏叆
unsigned long uartDrBefore = HWREG(UART3_BASE + UART_O_DR);
printf("M3: UART3 DR before 碌DMA: 0x%08lX\r\n", uartDrBefore);
// 楠岃瘉鏂规硶2锛氭鏌ART3 TX FIFO鐘舵�侊紙鍩轰簬瀵勫瓨鍣ㄨ〃锛�
unsigned long uartFrBefore = HWREG(UART3_BASE + UART_O_FR);
printf("M3: UART3 FR before 碌DMA: 0x%08lX\r\n", uartFrBefore);
printf("M3: TXFE:%s, TXFF:%s, RXFE:%s, RXFF:%s\r\n",
(uartFrBefore & UART_FR_TXFE) ? "Yes" : "No",
(uartFrBefore & UART_FR_TXFF) ? "Yes" : "No",
(uartFrBefore & UART_FR_RXFE) ? "Yes" : "No",
(uartFrBefore & UART_FR_RXFF) ? "Yes" : "No");
// 楠岃瘉鏂规硶3锛氭鏌ART3涓柇鐘舵��
unsigned long uartIntBefore = UARTIntStatus(UART3_BASE, 0);
printf("M3: UART3 Interrupt Status before 碌DMA: 0x%08lX\r\n", uartIntBefore);
// 楠岃瘉鏂规硶4锛氭鏌ART3鎺у埗瀵勫瓨鍣�
unsigned long uartCtlBefore = HWREG(UART3_BASE + UART_O_CTL);
printf("M3: UART3 Control before 碌DMA: 0x%08lX\r\n", uartCtlBefore);
// 绛夊緟浼犺緭瀹屾垚锛堢粰碌DMA鏇村鏃堕棿锛�
volatile int waitCount = 0;
unsigned long lastDrValue = HWREG(UART3_BASE + UART_O_DR);
unsigned long lastFrValue = uartFrBefore;
unsigned long lastIntValue = uartIntBefore;
bool dmaDataDetected = false;
bool transmissionStarted = false;
printf("M3: Starting 碌DMA transmission monitoring...\r\n");
while (uDMAChannelIsEnabled(UDMA_CHANNEL_UART3TX) && waitCount < 10000) {
waitCount++;
// 妫�鏌ヤ紶杈撴槸鍚﹀凡寮�濮�
if (!transmissionStarted) {
unsigned long currentDrValue = HWREG(UART3_BASE + UART_O_DR);
if (currentDrValue != lastDrValue) {
printf("M3: 鉁� 碌DMA transmission started at iteration %d\r\n", waitCount);
transmissionStarted = true;
dmaDataDetected = true;
}
}
// 姣�25娆¤凯浠f鏌ヤ竴娆ART3鐘舵�佸彉鍖栵紙鏇撮绻佺殑鐩戞帶锛�
if (waitCount % 100 == 0) {
unsigned long currentDrValue = HWREG(UART3_BASE + UART_O_DR);
unsigned long currentFrValue = HWREG(UART3_BASE + UART_O_FR);
unsigned long currentIntValue = UARTIntStatus(UART3_BASE, 0);
// 妫�鏌R瀵勫瓨鍣ㄥ彉鍖栵紙璇佹槑鏁版嵁琚啓鍏ART锛�
if (currentDrValue != lastDrValue) {
printf("M3: 鉁� DMA DATA DETECTED: DR changed from 0x%08lX to 0x%08lX at iteration %d\r\n",
lastDrValue, currentDrValue, waitCount);
lastDrValue = currentDrValue;
dmaDataDetected = true;
}
// 妫�鏌IFO鐘舵�佸彉鍖栵紙璇佹槑鏁版嵁鍦‵IFO涓級
if (currentFrValue != lastFrValue) {
printf("M3: 鉁� FIFO STATUS CHANGED: FR changed from 0x%08lX to 0x%08lX at iteration %d\r\n",
lastFrValue, currentFrValue, waitCount);
printf("M3: TXFE:%s, TXFF:%s, RXFE:%s, RXFF:%s\r\n",
(currentFrValue & UART_FR_TXFE) ? "Yes" : "No",
(currentFrValue & UART_FR_TXFF) ? "Yes" : "No",
(currentFrValue & UART_FR_RXFE) ? "Yes" : "No",
(currentFrValue & UART_FR_RXFF) ? "Yes" : "No");
lastFrValue = currentFrValue;
dmaDataDetected = true;
}
// 妫�鏌ヤ腑鏂姸鎬佸彉鍖�
if (currentIntValue != lastIntValue) {
printf("M3: 鉁� INTERRUPT STATUS CHANGED: Int changed from 0x%08lX to 0x%08lX at iteration %d\r\n",
lastIntValue, currentIntValue, waitCount);
lastIntValue = currentIntValue;
dmaDataDetected = true;
}
// 妫�鏌ヂ礑MA閫氶亾妯″紡鍙樺寲
unsigned long ulMode = uDMAChannelModeGet(UDMA_CHANNEL_UART3TX | UDMA_PRI_SELECT);
if (ulMode != UDMA_MODE_STOP) {
printf("M3: 碌DMA TX Mode at iteration %d: 0x%08lX (STOP=0x%08lX)\r\n", waitCount, ulMode, UDMA_MODE_STOP);
// 如果通道卡在0x00000001模式(传输完成但未禁用),强制禁用
if (ulMode == 0x00000001) {
printf("M3: 碌DMA channel stuck in mode 0x00000001, forcing disable\r\n");
uDMAChannelDisable(UDMA_CHANNEL_UART3TX);
break;
}
}
// 妫�鏌ヂ礑MA閫氶亾鏄惁浠嶇劧鍚敤
bool channelEnabled = uDMAChannelIsEnabled(UDMA_CHANNEL_UART3TX);
printf("M3: 碌DMA Channel Enabled: %s at iteration %d\r\n", channelEnabled ? "YES" : "NO", waitCount);
// 妫�鏌ART TX FIFO鏄惁涓虹┖锛堜紶杈撳彲鑳藉畬鎴愶級
if (currentFrValue & UART_FR_TXFE) {
printf("M3: 鉁� UART TX FIFO is empty at iteration %d - transmission may be complete\r\n", waitCount);
}
}
// 濡傛灉浼犺緭宸插紑濮嬩笖UART FIFO涓虹┖锛屽彲鑳戒紶杈撳凡瀹屾垚
if (transmissionStarted && (HWREG(UART3_BASE + UART_O_FR) & UART_FR_TXFE)) {
// 绛夊緟涓�灏忔鏃堕棿纭繚浼犺緭鐪熸瀹屾垚
for(volatile int finalWait = 0; finalWait < 100; finalWait++) {}
// 鍐嶆妫�鏌ラ�氶亾鐘舵��
if (!uDMAChannelIsEnabled(UDMA_CHANNEL_UART3TX)) {
printf("M3: 鉁� 碌DMA transmission completed naturally at iteration %d\r\n", waitCount);
break;
}
}
}
// 浼犺緭瀹屾垚鍚庣殑鎬荤粨
if (dmaDataDetected) {
printf("M3: 鉁� DMA TRANSMISSION SUCCESS: Data was detected in UART3 registers\r\n");
} else {
printf("M3: 鉁� DMA TRANSMISSION FAILED: No data detected in UART3 registers\r\n");
}
if (waitCount >= 10000) {
printf("M3: ERROR: 碌DMA TX timeout after 10000 iterations\r\n");
printf("M3: 碌DMA transmission failed - no fallback, DMA only mode\r\n");
// 寮哄埗绂佺敤閫氶亾骞堕噸缃姸鎬�
uDMAChannelDisable(UDMA_CHANNEL_UART3TX);
// 閲嶇疆鏁版嵁鍖呰鏁帮紝鍥犱负浼犺緭澶辫触
g_simpleUDMAUART.errorCount++;
return false; // 杩斿洖澶辫触鐘舵��
} else {
printf("M3: 碌DMA TX completed after %d iterations\r\n", waitCount);
}
// 楠岃瘉鏂规硶3锛氫紶杈撳畬鎴愬悗鐨勬渶缁堢姸鎬佹鏌�
unsigned long uartDrAfter = HWREG(UART3_BASE + UART_O_DR);
unsigned long uartFrAfter = HWREG(UART3_BASE + UART_O_FR);
unsigned long uartIntAfter = UARTIntStatus(UART3_BASE, 0);
unsigned long uartCtlAfter = HWREG(UART3_BASE + UART_O_CTL);
printf("M3: ===== FINAL UART3 STATUS COMPARISON =====\r\n");
printf("M3: UART3 DR: 0x%08lX -> 0x%08lX (changed: %s)\r\n",
uartDrBefore, uartDrAfter, (uartDrAfter != uartDrBefore) ? "YES" : "NO");
printf("M3: UART3 FR: 0x%08lX -> 0x%08lX (changed: %s)\r\n",
uartFrBefore, uartFrAfter, (uartFrAfter != uartFrBefore) ? "YES" : "NO");
printf("M3: UART3 Int: 0x%08lX -> 0x%08lX (changed: %s)\r\n",
uartIntBefore, uartIntAfter, (uartIntAfter != uartIntBefore) ? "YES" : "NO");
printf("M3: UART3 CTL: 0x%08lX -> 0x%08lX (changed: %s)\r\n",
uartCtlBefore, uartCtlAfter, (uartCtlAfter != uartCtlBefore) ? "YES" : "NO");
printf("M3: Final UART3 FR: 0x%08lX (TXFE:%s, TXFF:%s, RXFE:%s, RXFF:%s)\r\n",
uartFrAfter,
(uartFrAfter & UART_FR_TXFE) ? "Yes" : "No",
(uartFrAfter & UART_FR_TXFF) ? "Yes" : "No",
(uartFrAfter & UART_FR_RXFE) ? "Yes" : "No",
(uartFrAfter & UART_FR_RXFF) ? "Yes" : "No");
// 杞欢妫�娴婦MA浼犺緭鏄惁鎴愬姛鐨勭患鍚堝垽鏂�
bool dmaSuccess = false;
printf("M3: ===== DMA TRANSMISSION ANALYSIS =====\r\n");
if (uartDrAfter != uartDrBefore) {
printf("M3: 鉁� DR Register changed - DMA wrote data to UART3\r\n");
dmaSuccess = true;
} else {
printf("M3: 鉁� DR Register unchanged - No DMA data written\r\n");
}
if (uartFrAfter != uartFrBefore) {
printf("M3: 鉁� FR Register changed - FIFO status modified\r\n");
dmaSuccess = true;
} else {
printf("M3: 鉁� FR Register unchanged - No FIFO activity\r\n");
}
if (uartIntAfter != uartIntBefore) {
printf("M3: 鉁� Interrupt Status changed - UART activity detected\r\n");
dmaSuccess = true;
} else {
printf("M3: 鉁� Interrupt Status unchanged - No UART interrupts\r\n");
}
printf("M3: ===== FINAL DMA RESULT: %s =====\r\n", dmaSuccess ? "SUCCESS" : "FAILED");
// 棰濆绛夊緟锛岀‘淇漊ART FIFO瀹屽叏娓呯┖
printf("M3: Waiting for UART FIFO to clear...\r\n");
for(volatile int fifoWait = 0; fifoWait < 10000; fifoWait++) {
unsigned long frStatus = HWREG(UART3_BASE + UART_O_FR);
if (frStatus & UART_FR_TXFE) { // TX FIFO Empty
printf("M3: UART FIFO cleared after %d iterations\r\n", fifoWait);
break;
}
if (fifoWait == 9999) {
printf("M3: WARNING: UART FIFO clear timeout\r\n");
}
}
// 楠岃瘉鏂规硶4锛氭鏌ヂ礑MA閫氶亾鏈�缁堢姸鎬�
if (uDMAChannelIsEnabled(UDMA_CHANNEL_UART3TX)) {
unsigned long finalMode = uDMAChannelModeGet(UDMA_CHANNEL_UART3TX | UDMA_PRI_SELECT);
printf("M3: Final 碌DMA TX Mode: 0x%08lX (STOP=0x%08lX)\r\n", finalMode, UDMA_MODE_STOP);
} else {
printf("M3: 碌DMA TX channel is disabled after transfer\r\n");
}
// 楠岃瘉鏂规硶5锛氭鏌ART3涓柇鐘舵��
unsigned long uartIntStatus = UARTIntStatus(UART3_BASE, 0);
printf("M3: UART3 Interrupt Status: 0x%08lX\r\n", uartIntStatus);
// 楠岃瘉鏂规硶6锛氭鏌ヂ礑MA浼犺緭缁撴灉锛堜笉浣跨敤鐩存帴UART鍙戦�侊級
printf("M3: 碌DMA transmission verification completed\r\n");
printf("M3: All UART3 output is handled by 碌DMA only\r\n");
// 楠岃瘉鏂规硶7锛氭鏌ヂ礑MA浼犺緭璁℃暟鍣�
printf("M3: Checking 碌DMA transfer counters...\r\n");
// 浣跨敤碌DMA搴撳嚱鏁拌幏鍙栫姸鎬侊紝閬垮厤鐩存帴瀵勫瓨鍣ㄨ闂�
// 娉ㄦ剰锛歶DMAIsEnabled鍙兘鏈畾涔夛紝浣跨敤鏇夸唬鏂规硶
printf("M3: 碌DMA Controller Status: Checking via control table\r\n");
// 妫�鏌ART3 DMA鎺у埗瀵勫瓨鍣紙鍩轰簬瀵勫瓨鍣ㄨ〃0x048锛�
unsigned long uartDmaCtl = HWREG(UART3_BASE + UART_O_DMACTL);
printf("M3: UART3 DMA Control (0x048): 0x%08lX\r\n", uartDmaCtl);
printf("M3: TXDMAE (bit 1): %s\r\n", (uartDmaCtl & 0x02) ? "Enabled" : "Disabled");
printf("M3: RXDMAE (bit 0): %s\r\n", (uartDmaCtl & 0x01) ? "Enabled" : "Disabled");
// 楠岃瘉鏂规硶8锛氭鏌ヂ礑MA閫氶亾鎺у埗琛�
printf("M3: Checking 碌DMA channel control table...\r\n");
// 浣跨敤鍏ㄥ眬鎺у埗琛ㄥ彉閲忥紝閬垮厤璋冪敤鍙兘鏈畾涔夌殑鍑芥暟
unsigned long* controlTable = (unsigned long*)ucSimpleUDMAControlTable;
unsigned long channelOffset = UDMA_CHANNEL_UART3TX * 4; // 姣忎釜閫氶亾4涓瓧
unsigned long* channelControl = &controlTable[channelOffset];
printf("M3: 碌DMA Channel %d Control Table:\r\n", UDMA_CHANNEL_UART3TX);
printf("M3: Control Word 0: 0x%08lX\r\n", channelControl[0]);
printf("M3: Control Word 1: 0x%08lX\r\n", channelControl[1]);
printf("M3: Control Word 2: 0x%08lX\r\n", channelControl[2]);
printf("M3: Control Word 3: 0x%08lX\r\n", channelControl[3]);
// 楠岃瘉鏂规硶9锛氭鏌ヂ礑MA閫氶亾灞炴��
printf("M3: Checking 碌DMA channel attributes...\r\n");
// 娉ㄦ剰锛歶DMAChannelAttributeGet鍙兘鏈畾涔夛紝浣跨敤鏇夸唬鏂规硶
printf("M3: Channel Attributes: Checking via control table\r\n");
printf("M3: Control table entries show channel configuration\r\n");
printf("M3: 碌DMA TX channel enabled and requested\r\n");
// 澧炲姞鏁版嵁鍖呰鏁�
g_simpleUDMAUART.packetCount++;
return true;
}
//*****************************************************************************
// 杞欢妫�娴婦MA浼犺緭鐨勪笓鐢ㄦ祴璇曞嚱鏁�
//*****************************************************************************
bool SimpleUDMA_TestTransmission(void)
{
printf("M3: ===== STARTING DMA TRANSMISSION TEST =====\r\n");
// 鍑嗗娴嬭瘯鏁版嵁
uint8_t testData[] = {0x55, 0xAA, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC};
uint16_t testLength = sizeof(testData);
printf("M3: Test data: ");
for(int i = 0; i < testLength; i++) {
printf("%02X ", testData[i]);
}
printf("\r\n");
// 璁板綍浼犺緭鍓嶇殑UART3鐘舵��
unsigned long drBefore = HWREG(UART3_BASE + UART_O_DR);
unsigned long frBefore = HWREG(UART3_BASE + UART_O_FR);
unsigned long intBefore = UARTIntStatus(UART3_BASE, 0);
printf("M3: Before DMA - DR:0x%08lX, FR:0x%08lX, Int:0x%08lX\r\n",
drBefore, frBefore, intBefore);
// 鎵цDMA浼犺緭
bool result = SimpleUDMA_SendPacket(testData, testLength);
// 璁板綍浼犺緭鍚庣殑UART3鐘舵��
unsigned long drAfter = HWREG(UART3_BASE + UART_O_DR);
unsigned long frAfter = HWREG(UART3_BASE + UART_O_FR);
unsigned long intAfter = UARTIntStatus(UART3_BASE, 0);
printf("M3: After DMA - DR:0x%08lX, FR:0x%08lX, Int:0x%08lX\r\n",
drAfter, frAfter, intAfter);
// 鍒嗘瀽缁撴灉
bool dmaWorked = false;
if (drAfter != drBefore) {
printf("M3: 鉁� DR Register changed - DMA activity detected\r\n");
dmaWorked = true;
}
if (frAfter != frBefore) {
printf("M3: 鉁� FR Register changed - FIFO activity detected\r\n");
dmaWorked = true;
}
if (intAfter != intBefore) {
printf("M3: 鉁� Interrupt Status changed - UART activity detected\r\n");
dmaWorked = true;
}
printf("M3: ===== DMA TEST RESULT: %s =====\r\n", dmaWorked ? "SUCCESS" : "FAILED");
return dmaWorked;
}
//*****************************************************************************
// 鍩轰簬UART瀵勫瓨鍣ㄨ〃鐨凞MA浼犺緭妫�娴嬪嚱鏁�
//*****************************************************************************
bool SimpleUDMA_CheckRegisterBasedDMA(void)
{
printf("M3: ===== REGISTER-BASED DMA DETECTION =====\r\n");
// 1. 妫�鏌ART3 DMA鎺у埗瀵勫瓨鍣� (0x048)
unsigned long uartDmaCtl = HWREG(UART3_BASE + UART_O_DMACTL);
printf("M3: UART3 DMA Control (0x048): 0x%08lX\r\n", uartDmaCtl);
bool txDmaEnabled = (uartDmaCtl & 0x02) ? true : false; // TXDMAE (bit 1)
bool rxDmaEnabled = (uartDmaCtl & 0x01) ? true : false; // RXDMAE (bit 0)
printf("M3: TXDMAE (bit 1): %s\r\n", txDmaEnabled ? "Enabled" : "Disabled");
printf("M3: RXDMAE (bit 0): %s\r\n", rxDmaEnabled ? "Enabled" : "Disabled");
// 2. 妫�鏌ART3鏁版嵁瀵勫瓨鍣� (0x000)
unsigned long uartDr = HWREG(UART3_BASE + UART_O_DR);
printf("M3: UART3 Data Register (0x000): 0x%08lX\r\n", uartDr);
// 3. 妫�鏌ART3鏍囧織瀵勫瓨鍣� (0x018)
unsigned long uartFr = HWREG(UART3_BASE + UART_O_FR);
printf("M3: UART3 Flag Register (0x018): 0x%08lX\r\n", uartFr);
bool txfe = (uartFr & UART_FR_TXFE) ? true : false; // TX FIFO Empty
bool txff = (uartFr & UART_FR_TXFF) ? true : false; // TX FIFO Full
bool rxfe = (uartFr & UART_FR_RXFE) ? true : false; // RX FIFO Empty
bool rxff = (uartFr & UART_FR_RXFF) ? true : false; // RX FIFO Full
printf("M3: TXFE:%s, TXFF:%s, RXFE:%s, RXFF:%s\r\n",
txfe ? "Yes" : "No", txff ? "Yes" : "No",
rxfe ? "Yes" : "No", rxff ? "Yes" : "No");
// 4. 妫�鏌ART3鎺у埗瀵勫瓨鍣� (0x030)
unsigned long uartCtl = HWREG(UART3_BASE + UART_O_CTL);
printf("M3: UART3 Control Register (0x030): 0x%08lX\r\n", uartCtl);
bool uartEnabled = (uartCtl & 0x01) ? true : false; // UARTEN (bit 0)
printf("M3: UARTEN (bit 0): %s\r\n", uartEnabled ? "Enabled" : "Disabled");
// 5. 妫�鏌ART3涓柇鐘舵�佸瘎瀛樺櫒 (0x040)
unsigned long uartMis = HWREG(UART3_BASE + UART_O_MIS);
printf("M3: UART3 Masked Interrupt Status (0x040): 0x%08lX\r\n", uartMis);
// 6. 鍒嗘瀽DMA鐘舵��
printf("M3: ===== DMA STATUS ANALYSIS =====\r\n");
bool dmaConfigured = txDmaEnabled && uartEnabled;
printf("M3: DMA Configuration: %s\r\n", dmaConfigured ? "OK" : "ERROR");
if (!txDmaEnabled) {
printf("M3: 鉁� TX DMA not enabled in UARTDMACTL\r\n");
}
if (!uartEnabled) {
printf("M3: 鉁� UART3 not enabled in UARTCTL\r\n");
}
if (txff) {
printf("M3: 鈿� TX FIFO is FULL - may block DMA\r\n");
}
if (!txfe) {
printf("M3: 鉁� TX FIFO has data - DMA may be working\r\n");
}
printf("M3: ===== REGISTER-BASED DMA RESULT: %s =====\r\n",
dmaConfigured ? "CONFIGURED" : "MISCONFIGURED");
return dmaConfigured;
}
//*****************************************************************************
// 鏁版嵁澶勭悊鍑芥暟瀹炵幇
//*****************************************************************************
//*****************************************************************************
// 澶勭悊鎺ユ敹鍒扮殑鏁版嵁锛堜繚鎸佷笌鐜版湁閫昏緫鍏煎锛�
//*****************************************************************************
void SimpleUDMA_ProcessReceivedData(uint8_t* buffer, uint16_t length)
{
for (uint16_t i = 0; i < length; i++)
{
uint8_t byte = buffer[i];
switch (g_simpleUDMAUART.currentPacket.state)
{
case PACKET_STATE_IDLE:
// 绛夊緟甯уご
if (byte == FRAME_HEADER_BYTE1)
{
g_simpleUDMAUART.currentPacket.data[0] = byte;
g_simpleUDMAUART.currentPacket.length = 1;
g_simpleUDMAUART.currentPacket.state = PACKET_STATE_HEADER;
}
break;
case PACKET_STATE_HEADER:
// 妫�鏌ュ抚澶村畬鏁存��
if (byte == FRAME_HEADER_BYTE2)
{
g_simpleUDMAUART.currentPacket.data[1] = byte;
g_simpleUDMAUART.currentPacket.length = 2;
g_simpleUDMAUART.currentPacket.state = PACKET_STATE_DATA;
}
else
{
// 甯уご閿欒锛岄噸鏂板紑濮�
SimpleUDMA_ResetPacketState();
}
break;
case PACKET_STATE_DATA:
// 鎺ユ敹鏁版嵁
if (g_simpleUDMAUART.currentPacket.length < UDMA_MAX_PACKET_SIZE)
{
g_simpleUDMAUART.currentPacket.data[g_simpleUDMAUART.currentPacket.length] = byte;
g_simpleUDMAUART.currentPacket.length++;
// 妫�鏌ユ槸鍚︽帴鏀跺埌瀹屾暣鏁版嵁鍖�
if (g_simpleUDMAUART.currentPacket.length >= UDMA_MIN_PACKET_SIZE)
{
if (SimpleUDMA_ValidatePacket(g_simpleUDMAUART.currentPacket.data,
g_simpleUDMAUART.currentPacket.length))
{
g_simpleUDMAUART.currentPacket.state = PACKET_STATE_COMPLETE;
g_simpleUDMAUART.currentPacket.isComplete = true;
g_simpleUDMAUART.packetCount++;
// 澶勭悊瀹屾暣鏁版嵁鍖�
SimpleUDMA_HandleCompletePacket(&g_simpleUDMAUART.currentPacket);
// 閲嶇疆鐘舵��
SimpleUDMA_ResetPacketState();
}
}
}
else
{
// 鏁版嵁鍖呰繃闀匡紝閿欒
g_simpleUDMAUART.errorCount++;
SimpleUDMA_ResetPacketState();
}
break;
default:
SimpleUDMA_ResetPacketState();
break;
}
}
}
//*****************************************************************************
// 澶勭悊瀹屾暣鏁版嵁鍖咃紙淇濇寔涓庣幇鏈夊鐞嗛�昏緫鍏煎锛�
//*****************************************************************************
void SimpleUDMA_HandleCompletePacket(const SimplePacketInfo_t* packet)
{
// 灏嗗瓧鑺傛暟缁勮浆鎹负16浣嶆暟缁勮繘琛屽弽搴忓垪鍖�
uint16_t packet16[16];
uint16_t wordCount = (packet->length + 1) / 2; // 鍚戜笂鍙栨暣
for (uint16_t i = 0; i < wordCount; i++)
{
packet16[i] = (packet->data[i*2+1] << 8) | packet->data[i*2];
}
// 鍙嶅簭鍒楀寲鏁版嵁鍖�
LevitationSimple_t receivedData;
if (LevitationSimple_deserialize(packet16, wordCount, &receivedData))
{
// 鏍规嵁鏁版嵁绫诲瀷澶勭悊涓嶅悓鐨勬暟鎹寘锛堜繚鎸佷笌鐜版湁閫昏緫鐩稿悓锛�
if (receivedData.type == 0 && receivedData.data_length >= 10)
{
// 浼犳劅鍣ㄦ暟鎹寘
printf("M3: SENSOR: H[%d,%d,%d,%d] Z[%d,%d] B[%d,%d,%d,%d]\r\n",
(int16_t)receivedData.data_fields[0], // posXH
(int16_t)receivedData.data_fields[1], // posYH
(int16_t)receivedData.data_fields[2], // VibrationH
(int16_t)receivedData.data_fields[8], // AngleH
(int16_t)receivedData.data_fields[3], // PosZ
(int16_t)receivedData.data_fields[4], // Vibration
(int16_t)receivedData.data_fields[5], // PosXB
(int16_t)receivedData.data_fields[6], // PosYB
(int16_t)receivedData.data_fields[7], // VibrationB
(int16_t)receivedData.data_fields[9]); // AngleB
}
else if (receivedData.type == 2 && receivedData.data_length >= 1)
{
// 搴旂瓟鍖�
uint16_t responseResult = receivedData.data_fields[0];
if (responseResult == 1)
{
printf("M3: RESPONSE: SUCCESS (OK)\r\n");
}
else
{
printf("M3: RESPONSE: FAILED (ERROR)\r\n");
}
}
else if (receivedData.type == 3 && receivedData.data_length >= 1)
{
// 鍛戒护搴旂瓟鍖�
uint16_t commandResult = receivedData.data_fields[0];
switch (commandResult)
{
case 0: printf("M3: COMMAND: EXECUTION FAILED\r\n"); break;
case 1: printf("M3: COMMAND: EXECUTION SUCCESS\r\n"); break;
case 2: printf("M3: COMMAND: PARAMETER ERROR\r\n"); break;
case 3: printf("M3: COMMAND: STATE ERROR\r\n"); break;
case 4: printf("M3: COMMAND: TIMEOUT ERROR\r\n"); break;
case 5: printf("M3: COMMAND: HARDWARE ERROR\r\n"); break;
default: printf("M3: COMMAND: UNKNOWN RESULT (%d)\r\n", commandResult); break;
}
}
}
else
{
printf("M3: DESERIALIZE FAILED!\r\n");
g_simpleUDMAUART.errorCount++;
}
}
//*****************************************************************************
// 涓柇澶勭悊鍑芥暟瀹炵幇
//*****************************************************************************
//*****************************************************************************
// 碌DMA UART涓柇澶勭悊鍑芥暟
//*****************************************************************************
void SimpleUDMA_IntHandler(void)
{
unsigned long ulStatus;
unsigned long ulMode;
// 娣诲姞璋冭瘯杈撳嚭纭涓柇澶勭悊鍑芥暟琚皟鐢�
// 绮剧畝鏃ュ織锛氱Щ闄や腑鏂鐞嗘棩蹇�
// 璇诲彇UART涓柇鐘舵�侊紙鍙傝�冨畼鏂筪emo锛�
ulStatus = UARTIntStatus(UART3_BASE, 1);
// 妫�鏌X FIFO鏄惁婊★紝濡傛灉婊″垯娓呯悊锛堥槻姝㈤樆濉烇級
unsigned long uartFr = HWREG(UART3_BASE + UART_O_FR);
if (uartFr & UART_FR_RXFF) {
// 娓呯悊RX FIFO涓殑鎵�鏈夋暟鎹紙绮剧畝鏃ュ織锛�
while (!(HWREG(UART3_BASE + UART_O_FR) & UART_FR_RXFE)) {
volatile uint32_t dummy = HWREG(UART3_BASE + UART_O_DR);
(void)dummy; // 閬垮厤鏈娇鐢ㄥ彉閲忚鍛�
}
}
// 娓呴櫎UART涓柇鐘舵�侊紙鍙傝�冨畼鏂筪emo锛�
UARTIntClear(UART3_BASE, ulStatus);
// 妫�鏌ヤ富鎺у埗缁撴瀯锛堢紦鍐插尯A锛�
ulMode = uDMAChannelModeGet(UDMA_CHANNEL_UART3RX | UDMA_PRI_SELECT);
if (ulMode == UDMA_MODE_STOP)
{
// 缂撳啿鍖篈鎺ユ敹瀹屾垚锛屽鐞嗘暟鎹�
SimpleUDMA_ProcessReceivedData(g_simpleUDMAUART.rxBufferA, sizeof(g_simpleUDMAUART.rxBufferA));
// 閲嶆柊璁剧疆缂撳啿鍖篈鐨勪紶杈�
uDMAChannelTransferSet(UDMA_CHANNEL_UART3RX | UDMA_PRI_SELECT,
UDMA_MODE_PINGPONG,
(void *)(UART3_BASE + UART_O_DR),
g_simpleUDMAUART.rxBufferA, sizeof(g_simpleUDMAUART.rxBufferA));
}
// 妫�鏌ュ鐢ㄦ帶鍒剁粨鏋勶紙缂撳啿鍖築锛�
ulMode = uDMAChannelModeGet(UDMA_CHANNEL_UART3RX | UDMA_ALT_SELECT);
if (ulMode == UDMA_MODE_STOP)
{
// 缂撳啿鍖築鎺ユ敹瀹屾垚锛屽鐞嗘暟鎹�
SimpleUDMA_ProcessReceivedData(g_simpleUDMAUART.rxBufferB, sizeof(g_simpleUDMAUART.rxBufferB));
// 閲嶆柊璁剧疆缂撳啿鍖築鐨勪紶杈�
uDMAChannelTransferSet(UDMA_CHANNEL_UART3RX | UDMA_ALT_SELECT,
UDMA_MODE_PINGPONG,
(void *)(UART3_BASE + UART_O_DR),
g_simpleUDMAUART.rxBufferB, sizeof(g_simpleUDMAUART.rxBufferB));
}
// 妫�鏌X閫氶亾浼犺緭瀹屾垚锛堟敼杩涙娴嬮�昏緫锛�
ulMode = uDMAChannelModeGet(UDMA_CHANNEL_UART3TX | UDMA_PRI_SELECT);
if (ulMode == UDMA_MODE_STOP && g_simpleUDMAUART.packetCount > 0)
{
// TX浼犺緭瀹屾垚锛岄�氶亾宸插仠姝�
printf("M3: TX transfer completed\r\n");
// 绂佺敤閫氶亾浠ユ竻鐞嗙姸鎬�
uDMAChannelDisable(UDMA_CHANNEL_UART3TX);
}
}
//*****************************************************************************
// 碌DMA閿欒涓柇澶勭悊鍑芥暟
//*****************************************************************************
void SimpleUDMA_ErrorHandler(void)
{
unsigned long ulStatus;
// 鑾峰彇碌DMA閿欒鐘舵��
// 娉ㄦ剰锛歶DMAErrorStatusGet鍙兘鏈畾涔夛紝浣跨敤鏇夸唬鏂规硶
ulStatus = 0; // 鏆傛椂璁句负0锛岄伩鍏嶉摼鎺ラ敊璇�
// 濡傛灉鏈夐敊璇紝娓呴櫎閿欒鐘舵�佸苟澧炲姞閿欒璁℃暟
if (ulStatus)
{
// 娉ㄦ剰锛歶DMAErrorStatusClear鍙兘鏈畾涔夛紝璺宠繃娓呴櫎鎿嶄綔
g_simpleUDMAUART.errorCount++;
printf("M3: 碌DMA Error: 0x%08lX\r\n", ulStatus);
// 璇︾粏閿欒鍒嗘瀽 - 鏍规嵁F28M35 碌DMA閫氶亾鍒嗛厤
if (ulStatus & 0x00000001) {
printf("M3: Error Detail: Channel 0 - Possible misconfiguration\r\n");
}
if (ulStatus & 0x00000002) {
printf("M3: Error Detail: Channel 1 - Possible misconfiguration\r\n");
}
if (ulStatus & 0x00010000) {
printf("M3: Error Detail: Channel 16 (UART3RX) - Possible misconfiguration\r\n");
}
if (ulStatus & 0x00020000) {
printf("M3: Error Detail: Channel 17 (UART3TX) - Possible misconfiguration\r\n");
}
// 妫�鏌ART3 TX閫氶亾鐘舵��
if (uDMAChannelIsEnabled(UDMA_CHANNEL_UART3TX)) {
unsigned long ulMode = uDMAChannelModeGet(UDMA_CHANNEL_UART3TX | UDMA_PRI_SELECT);
printf("M3: TX Channel Mode after error: 0x%08lX\r\n", ulMode);
}
}
}
//*****************************************************************************
// 鐘舵�佹煡璇㈠嚱鏁板疄鐜�
//*****************************************************************************
//*****************************************************************************
// 鑾峰彇鏁版嵁鍖呰鏁�
//*****************************************************************************
uint32_t SimpleUDMA_GetPacketCount(void)
{
return g_simpleUDMAUART.packetCount;
}
//*****************************************************************************
// 鑾峰彇閿欒璁℃暟
//*****************************************************************************
uint32_t SimpleUDMA_GetErrorCount(void)
{
return g_simpleUDMAUART.errorCount;
}
//*****************************************************************************
// 鎵撳嵃鐘舵�佷俊鎭�
//*****************************************************************************
void SimpleUDMA_PrintStatus(void)
{
printf("M3: Simple 碌DMA UART Status:\r\n");
printf(" DMA Enabled: %s\r\n", g_simpleUDMAUART.dmaEnabled ? "Yes" : "No");
printf(" Packet Count: %lu\r\n", g_simpleUDMAUART.packetCount);
printf(" Error Count: %lu\r\n", g_simpleUDMAUART.errorCount);
// 娉ㄦ剰锛歶DMAChannelIsEnabled鍙兘鏈畾涔夛紝浣跨敤鏇夸唬鏂规硶
printf(" TX Channel Status: Checking via control table\r\n");
printf(" RX Channel Status: Checking via control table\r\n");
// 妫�鏌ART3鐘舵��
unsigned long uartStatus = UARTIntStatus(UART3_BASE, 0);
printf(" UART3 Status: 0x%08lX\r\n", uartStatus);
// 妫�鏌ART3鏄惁鍚敤
unsigned long uartCtl = HWREG(UART3_BASE + UART_O_CTL);
printf(" UART3 CTL: 0x%08lX (Enabled: %s)\r\n", uartCtl, (uartCtl & UART_CTL_UARTEN) ? "Yes" : "No");
// 妫�鏌ART3 FIFO鐘舵��
unsigned long uartFr = HWREG(UART3_BASE + UART_O_FR);
printf(" UART3 FR: 0x%08lX (TXFE:%s, TXFF:%s, RXFE:%s, RXFF:%s)\r\n",
uartFr,
(uartFr & UART_FR_TXFE) ? "Yes" : "No",
(uartFr & UART_FR_TXFF) ? "Yes" : "No",
(uartFr & UART_FR_RXFE) ? "Yes" : "No",
(uartFr & UART_FR_RXFF) ? "Yes" : "No");
}
//*****************************************************************************
// 绉佹湁鍑芥暟瀹炵幇
//*****************************************************************************
//*****************************************************************************
// 閲嶇疆鏁版嵁鍖呯姸鎬�
//*****************************************************************************
static void SimpleUDMA_ResetPacketState(void)
{
g_simpleUDMAUART.currentPacket.length = 0;
g_simpleUDMAUART.currentPacket.state = PACKET_STATE_IDLE;
g_simpleUDMAUART.currentPacket.isComplete = false;
memset(g_simpleUDMAUART.currentPacket.data, 0, sizeof(g_simpleUDMAUART.currentPacket.data));
}
//*****************************************************************************
// 楠岃瘉鏁版嵁鍖咃紙淇濇寔涓庣幇鏈夐獙璇侀�昏緫鍏煎锛�
//*****************************************************************************
static bool SimpleUDMA_ValidatePacket(const uint8_t* data, uint16_t length)
{
// 鍩烘湰闀垮害妫�鏌�
if (length < UDMA_MIN_PACKET_SIZE || length > UDMA_MAX_PACKET_SIZE)
{
return false;
}
// 甯уご妫�鏌�
if (data[0] != FRAME_HEADER_BYTE1 || data[1] != FRAME_HEADER_BYTE2)
{
return false;
}
// 甯у熬妫�鏌ワ紙鏈�鍚庝袱涓瓧鑺傚簲璇ユ槸0x0A 0x0D锛�
if (data[length-2] != 0x0A || data[length-1] != 0x0D)
{
return false;
}
return true;
}