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.

[参考译文] CCS/TM4C123GH6PM:使用收发器和接收器进行 UDMA Ping Pong 传输

Guru**** 2350610 points
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/607284/ccs-tm4c123gh6pm-udma-ping-pong-transfer-with-transceiver-and-receiver

器件型号:TM4C123GH6PM

工具/软件:Code Composer Studio

我´m 的项目是使用乒乓缓冲器传输数据。 两个用于接收的缓冲器和两个用于接收的缓冲器。 我不n´t 乒乓传输的收发端是否正好位于"hwi_SSI_ISR()"中。 有人可以告诉我吗? 如果 ping (收发)已满、DMA 将切换到 pong 缓冲区(收发)、我如何测试它? 是否有必要在 SSIDR (SSI 数据寄存器)中进行传输?

#define TARGET_IS_TM4C123_RA1

#include 
#include 

#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
//#include "inc/hw_uart.h"
#include "uart/hw_ssi.h"

#include "driverlib/driverlib/gpio.h"#include -"driverlib-"driverh-/driverline.h-#include
-"driverlib-#-"driverlib-/driver.h"









// BIOS 头文件
//---------------
#include //mand强制-对于 BIOS 类型
#include、必须首先包含 //mandedis-如果您调用诸如 BIOS_start()
#include 之类的 API 用于静态定义的对象/句柄
#include 的//头文件 //用于 Log_info()调用
#include 

//缓冲区定义
#define SSI_TX_buffer_size 256
#define SSI_RX_buffer_size 256
static uint8_t g_ui8SSITxPing[SSI_TX_buffer_size];
static uint8_t g_ui8SSITxPong[SS_TX_buffer_size];
static uint8_t g_ui8SSIRxPing[SS_RX_buffer_size];static u32_uTS0_ui32
uTS_uiRxCount]





;static uTS0_ui32 uTS_ui32 uTS_uTS_ui32 uiRxCOUNTER





=静态计数=静态计数器 uTS0_uTS0_ui32 uTS_ui32 uTS_ui32 uTSxt_ui32 uiRxt_u_uiSrg_uiRxt_uiSrg_uiTh =静态计数;静态计数=静态计数=静态计数;ui32 ui32 uTS0_ui32 ui32 uiSrg_uiSrg_u


// uDMA 控制表与1024字节边界
#pragma DATA_ALIGN (ucControlTable、1024)
uint8_t ucControlTable[1024];

//库错误例程
#ifdef debug
void
__error__(char * pcFilename、uint32_t ui32Line)
{
}
#endif

// Uwi 错误处理程序#if_isr
(u_dma void)

uint32_t ui32Status;

ui32Status = ROM_uDMAErrorStatusGet ();

if (ui32状态)
{
ROM_uDMAErrorStatusClear ();
G_ui32DMAErrCount++;
}
}

// SSI 中断处理程序。 在 UDMA 传输完成
时调用 void hwi_SSI_ISR (void)
{
i16ToggleCount += 1; //跟踪#toggleLog_Info1

("LED 切换[%u]次"、i16ToggleCount); //将切换计数发送到 UIA

uint32_t ui32Status;
uint32_t ui32模式;

ui32Status = ROM_SSIIntStatus (SSI0_BASE、1);

ROM_SSIIntClear (SSI0_BASE、ui32Status);

// g_ui8SSITxPing[0]= g_ui32SSITxPingCount;
// g_ui8SSITxPong[0]= g_ui32SSITxPingCount + 10;

ui32Mode = ROM_uDMAChannelModeGet (UDMA_CHANGE_SSI0RX | UDMA_PRI_SELECT);

if (ui32Mode = uDMA_MODE_STOP)
{
G_ui32SSIRxPingCount++;

ROM_uDMAChannelTransferSet (UDMA_CHANGE_SSI0RX | UDMA_PRI_SELECT、
UDMA_MODE_PINGONG、
(void *)(SSI0_BASE + SSI_O_DR)、
g_ui8SSIRxPing、sizeof (g_ui8SSIRxPing);

ROM_uDMAChannelEnable (UDMA_CHANGE_SSI0RX);
}


ui32Mode = ROM_uDMAChannelModeGet (UDMA_CHANGE_SSI0RX | UDMA_ALT_SELECT);

if (ui32Mode = uDMA_MODE_STOP)
{
G_ui32SSIRxPongCount++;

ROM_uDMAChannelTransferSet (UDMA_CHANGE_SSI0RX | UDMA_ALT_SELECT、
UDMA_MODE_PINGONG、
(void *)(SSI0_BASE + SSI_O_DR)、
g_ui8SSIRxPong、sizeof (g_ui8SSIRxPong));

ROM_uDMAChannelEnable (UDMA_CHANGE_SSI0RX);
}

if (!ROM_uDMAChannelIsEnabled (UDMA_CHANGE_SSI0TX))
{

ui32Mode = ROM_uDMAChannelModeGet (UDMA_CHANGE_SSI0TX | UDMA_PRI_SELECT);

if (ui32Mode = uDMA_MODE_STOP)
{
G_ui32SSITxPingCount++;

ROM_uDMAChannelTransferSet (UDMA_CHANGE_SSI0TX | UDMA_PRI_SELECT、
UDMA_MODE_pingpong、g_ui8SSITxPing、
(void *)(SSI0_BASE + SSI_O_DR)、
sizeof (g_ui8SSITxPing);

ROM_uDMAChannelEnable (UDMA_CHANGE_SSI0TX);
}


ui32Mode = ROM_uDMAChannelModeGet (UDMA_CHANGE_SSI0TX | UDMA_ALT_SELECT);

if (ui32Mode = uDMA_MODE_STOP)
{
G_ui32SSITxPongCount++;

ROM_uDMAChannelTransferSet (UDMA_CHANGE_SSI0TX | UDMA_ALT_SELECT、
UDMA_MODE_Pingpong、g_ui8SSITxPong、
(void *)(SSI0_BASE + SSI_O_DR)、
sizeof (g_ui8SSITxPong));

ROM_uDMAChannelEnable (UDMA_CHANGE_SSI0TX);
}

}

// if (!ROM_uDMAChannelIsEnabled (UDMA_CHANGE_SSI0TX | UDMA_ALT_SELECT)
//{
//g_ui32SSITxPongCount++;
//
ROM_uDMAChannelTransferSet (UDMA_CHANGE_SSI0TX | UDMA_ALT_SELECT、
//UDMA_MODE_Pingpong、g_ui8SSITxPong、
//(void *)(SSI0_BASE + SSI_O_DR)、
//sizeof (g_ui8SSITxPong));
//
ROM_uDMAChannelEnable (UDMA_CHANGE_SSI0TX);
//}


//初始化 SSI UDMA 传输
空 InitSPITransfer (空)
{
uint_fast16_t ui16Idx;

//
//用简单的数据模式填充 TX 缓冲区。
//
对于(ui16Idx = 0;ui16Idx < SSI_TX_buffer_size;ui16Idx++)
{
G_ui8SSITxPing[ui16Idx]= 2;
G_ui8SSITxPong[ui16Idx]= 4;
}

//
//为 TX 和 RX 通道启用 uDMA 接口。
//
ROM_SSIDMAEnable (SSI0_BASE、SSI_DMA_RX | SSI_DMA_TX);

//
//该寄存器写入将 SSI0设置为在环回模式下运行。 任何
//在 TX 输出上发送的数据将在 RX 输入上接收。
//
HWREG (SSI0_BASE + SSI_O_CR1)|= SSI_CR1_LBM;


//
//uDMA SSI0 RX Ping
//

//
//将 UDMA SSI0RX 通道的属性置于已知状态。 这些
默认情况下、//应已禁用。
//
ROM_uDMAChannelAttributeDisable (UDMA_CHANGE_SSI0RX、
UDMA_ATTR_USEBURST | UDMA_ATTR_ALTSELECT |
(UDMA_ATTR_HIGH_PRIOR|
uDMA_attr_REQMASK);

//
//为配置主控制结构体的控制参数
// SSIORX 通道。
//
ROM_uDMAChannelControlSet (UDMA_CHANGE_SSI0RX | UDMA_PRI_SELECT、
UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 |
UDMA_ARB_4);
//
//设置 SSI0RX 通道的传输参数
//
ROM_uDMAChannelTransferSet (UDMA_CHANGE_SSI0RX | UDMA_PRI_SELECT、
UDMA_MODE_PINGONG、
(void *)(SSI0_BASE + SSI_O_DR)、
g_ui8SSIRxPing、sizeof (g_ui8SSIRxPing);


//
//uDMA SSI0 RX 信号
//

//
//为的替代控制结构配置控制参数
// SSIORX 通道。
//
ROM_uDMAChannelControlSet (UDMA_CHANGE_SSI0RX | UDMA_ALT_SELECT、
UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 |
UDMA_ARB_4);
//
//设置 SSI0RX 通道的传输参数
//
ROM_uDMAChannelTransferSet (UDMA_CHANGE_SSI0RX | UDMA_ALT_SELECT、
UDMA_MODE_PINGONG、
(void *)(SSI0_BASE + SSI_O_DR)、
g_ui8SSIRxPong、sizeof (g_ui8SSIRxPong));

//
//uDMA SSI0 TX Ping
//

//
//将 UDMA SSI0TX 通道的属性置于已知状态。 这些
默认情况下、//应已禁用。
//
ROM_uDMAChannelAttributeDisable (UDMA_CHANGE_SSI0TX、
UDMA_ATTR_ALTSELECT |
UDMA_ATTR_HIGH_PRIOR|
UDMA_ATTR_REQMASK);


//
//设置 UDMA SSI0TX 通道的 USEBURST 属性。 这将会
//强制控制器在传输数据时始终使用突发
//将 TX 缓冲器连接到 SSI0。 这是比较有效的总线使用
//不是允许单次或突发传输的默认值。
//
ROM_uDMAChannelAttributeEnable (UDMA_CHANGE_SSI0TX、UDMA_ATTR_USEBURST);

//
//配置 SSI0 TX 的控制参数。
//
ROM_uDMAChannelControlSet (UDMA_CHANGE_SSI0TX | UDMA_PRI_SELECT、
UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE |
UDMA_ARB_4);


//
//设置 uDMA SSI0 TX 通道的传输参数。 这将会
//配置传输源和目的以及传输大小。
//使用基本模式是因为外设正在进行 UDMA 传输
//请求。 源是 TX 缓冲区、目的是 SSI0
//数据寄存器。
//
ROM_uDMAChannelTransferSet (UDMA_CHANGE_SSI0TX | UDMA_PRI_SELECT、
UDMA_MODE_pingpong、g_ui8SSITxPing、
(void *)(SSI0_BASE + SSI_O_DR)、
sizeof (g_ui8SSITxPing);

//
//uDMA SSI0 TX 信号
//

//
//配置 SSI0 TX 的控制参数。
//
ROM_uDMAChannelControlSet (UDMA_CHANGE_SSI0TX | UDMA_ALT_SELECT、
UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE |
UDMA_ARB_4);


//
//设置 uDMA SSI0 TX 通道的传输参数。 这将会
//配置传输源和目的以及传输大小。
//使用基本模式是因为外设正在进行 UDMA 传输
//请求。 源是 TX 缓冲区、目的是 SSI0
//数据寄存器。
//
ROM_uDMAChannelTransferSet (UDMA_CHANGE_SSI0TX | UDMA_ALT_SELECT、
UDMA_MODE_Pingpong、g_ui8SSITxPong、
(void *)(SSI0_BASE + SSI_O_DR)、
sizeof (g_ui8SSITxPong));


//
//现在,UDMA SSI0 TX 和 RX 通道都要以启动 A 为底
//传输。 一旦启用通道、外设将会启动
//发出传输请求,数据传输将开始。
//
ROM_uDMAChannelEnable (UDMA_CHANGE_SSI0RX);
ROM_uDMAChannelEnable (UDMA_CHANGE_SSI0TX);

//
//启用 SSI0 DMA TX/RX 中断。
//
ROM_SSIIntEnable (SSI0_BASE、SSI_DMATX | SSI_DMARX);

//
//启用 SSI0外设中断。
//
ROM_IntEnable (INT_SSI0);

}

void configSSI0 (void)
{
//uint32_t trashbin[1]={0};

SSI 的// GPIO 设置
ROM_SysCtlPeripheralEnable (SYSCTL_Periph_SSI0);
ROM_SysCtlPeripheralEnable (SYSCTL_Periph_GPIOA);
ROM_SysCtlPeripheralSlepEnable (SYSCTL_Periph_SSI0);
ROM_GPIOPinConfigure (GPIO_PA2_SSI0CLK);
ROM_GPIOPinConfigure (GPIO_PA3_SSI0FSS);
ROM_GPIOPinConfigure (GPIO_PA4_SSI0RX);
ROM_GPIOPinConfigure (GPIO_PA5_SSI0TX);
ROM_GPIOPinTypeSSI (GPIO_Porta_base、GPIO_PIN_5|GPIO_PIN_4|GPIO_PIN_3|GPIO_PIN_2);

ROM_SSIConfigSetExpClk (SSI0_BASE、ROM_SysCtlClockGet ()、SSI_FRF_MOTO_MOTO_0、SSI_MODE_MASTER、100000、 8);
ROM_SSIEnable (SSI0_BASE);

/*清除 SSI0 RX 缓冲器*/
// while (SSIDataGetNonBlocking (SSI0_BASE、&trashbin[0])){}



//主代码
int main (void)
{

ROM_FPULazyStackingEnable ();

ROM_SysCtlClockSet (SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSC_MAIN | SYSC_UST_OSCL
SYSCTL_XTAL_16MHz);

ROM_SysCtlPeripheralClockGating (真);

configSSI0();

//启用 uDMA
ROM_SysCtlPeripheralEnable (SYSCTL_Periph_UDMA);
ROM_SysCtlPeripheralSlepEnable (SYSCTL_Periph_UDMA);
ROM_IntEnable (INT_UDMAERR);
ROM_uDMAEnable();
ROM_uDMAControlBaseSet (ucControlTable);

//初始化 UDMA/SSI 传输
InitSPITransfer();

BIOS_start();

}

感谢您的回答!