Part Number: TMS320F28377S
代码如上 我使能SPIB的dma功能 单独使用SPI的fifo模式 能够实现通信,local_D_INTCH6_ISR接收中断能进入,但从结果看只能单纯的搬运sdata中的数据到rdata,spi似乎根本没参与,使能dma后 无法接收信息,SPIB的SpibRegs.SPITXBUF值也是空的,是否是配置问题 请大神指教
Part Number: TMS320F28377S
代码如上 我使能SPIB的dma功能 单独使用SPI的fifo模式 能够实现通信,local_D_INTCH6_ISR接收中断能进入,但从结果看只能单纯的搬运sdata中的数据到rdata,spi似乎根本没参与,使能dma后 无法接收信息,SPIB的SpibRegs.SPITXBUF值也是空的,是否是配置问题 请大神指教
您好,
已经收到了您的案例,调查需要些时间,感谢您的耐心等待。
//###########################################################################
//
// FILE: Example_2837xS_Spi_dma.c
//
// TITLE: SPI Digital Loop Back with DMA Example.
//
//! \addtogroup cpu01_example_list
//! <h1>SPI Digital Loop Back with DMA (spi_loopback_dma)</h1>
//!
//! This program uses the internal loop back test mode of the peripheral.
//! Other then boot mode pin configuration, no other hardware configuration
//! is required. Both DMA Interrupts and the SPI FIFOs are used.
//!
//! A stream of data is sent and then compared to the received stream.
//! The sent data looks like this: \n
//! 0000 0001 \n
//! 0001 0002 \n
//! 0002 0003 \n
//! .... \n
//! 007E 007F \n
//!
//! \b Watch \b Variables \n
//! - \b sdata - Data to send
//! - \b rdata - Received data
//! - \b rdata_point - Used to keep track of the last position in
//! the receive stream for error checking
//!
//
//###########################################################################
// $TI Release: F2837xS Support Library v3.10.00.00 $
// $Release Date: Tue May 26 17:16:51 IST 2020 $
// $Copyright:
// Copyright (C) 2014-2020 Texas Instruments Incorporated - http://www.ti.com/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the
// distribution.
//
// Neither the name of Texas Instruments Incorporated nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// $
//###########################################################################
//
// Included Files
//
#include "F28x_Project.h"
#include "hd_fpga_internal.h"
//
// Defines
//
#define BURST (FIFO_LVL-1) // burst size should be less than 8
#define TRANSFER 15 // [(MEM_BUFFER_SIZE/FIFO_LVL)-1]
#define FIFO_LVL 8 // FIFO Interrupt Level
#if CPU_FRQ_200MHZ
#define SPI_BRR ((200E6 / 4) / 500E3) - 1
#endif
#if CPU_FRQ_150MHZ
#define SPI_BRR ((150E6 / 4) / 500E3) - 1
#endif
#if CPU_FRQ_120MHZ
#define SPI_BRR ((120E6 / 4) / 500E3) - 1
#endif
#define FPGA_READ_CMD 0x20
//
// Globals
//
#pragma DATA_SECTION(sdata, "ramgs0"); // map the TX data to memory
#pragma DATA_SECTION(rdata, "ramgs1"); // map the RX data to memory
Uint16 sdata[128]; // Send data buffer
Uint16 rdata[128]; // Receive data buffer
Uint16 rdata_point; // Keep track of where we are
// in the data stream to check received data
volatile Uint16 *DMADest;
volatile Uint16 *DMASource;
volatile Uint16 done;
#define SET_SPI_NSS_LOW GpioDataRegs.GPACLEAR.bit.GPIO27 = 1
#define SET_SPI_NSS_HIGH GpioDataRegs.GPASET.bit.GPIO27 = 1
//
// Function Prototypes
//
__interrupt void local_D_INTCH5_ISR(void);
__interrupt void local_D_INTCH6_ISR(void);
void delay_loop(void);
void dma_init(void);
void spi_fifo_init(void);
void error();
void InitSpib(void)
{
// Initialize SPI-B
// Set reset low before configuration changes
// Clock polarity (0 == rising, 1 == falling)
// 16-bit character
// Enable loop-back
// SpiaRegs.SPICCR.all =0x000F; // Reset on, rising edge, 16-bit char bits
// SpiaRegs.SPICTL.all =0x0006; // Enable master mode, normal phase,
// enable talk, and SPI int disabled.
// SpiaRegs.SPIBRR =0x0009;
// SpiaRegs.SPICCR.all =0x008F; // Relinquish SPI from Reset
// SpiaRegs.SPIPRI.bit.FREE = 1; // Set so breakpoints don't disturb xmission
SpibRegs.SPICCR.bit.SPISWRESET = 0;
SpibRegs.SPICCR.bit.CLKPOLARITY = 0;
SpibRegs.SPICCR.bit.SPICHAR = (16-1);
SpibRegs.SPICCR.bit.SPILBK = 1;
//SpiaRegs.SPICCR.bit.SPILBK = 1;
// Enable master (0 == slave, 1 == master)
// Enable transmission (Talk)
// Clock phase (0 == normal, 1 == delayed)
// SPI interrupts are disabled
SpibRegs.SPICTL.bit.MASTER_SLAVE = 1;
SpibRegs.SPICTL.bit.TALK = 1;
SpibRegs.SPICTL.bit.CLK_PHASE = 0;
SpibRegs.SPICTL.bit.SPIINTENA = 0;
// Set the baud rate
SpibRegs.SPIBRR.bit.SPI_BIT_RATE = SPI_BRR;
// Set FREE bit
// Halting on a breakpoint will not halt the SPI
SpibRegs.SPIPRI.bit.FREE = 1;
// SpibRegs.SPIFFTX.all=0xE040;
// SpibRegs.SPIFFRX.all=0x2041;
// SpibRegs.SPIFFCT.all=0x0;
// SpibRegs.SPIFFTX.bit.SPIFFENA = 1; // 使能 FIFO 增强 → 开启 DMA 请求
// SpibRegs.SPIFFTX.bit.TXFFIL = 0; // FIFO 空触发 TX DMA
// SpibRegs.SPIFFRX.bit.RXFFIL = 1; // FIFO 有数据触发 RX DMA
//
// //SpibRegs.SPIFFTX.bit.TXFIFORESET = 1; // 复位 TX FIFO
// SpibRegs.SPIFFRX.bit.RXFIFORESET = 1; // 复位 RX FIFO
// Release the SPI from reset
SpibRegs.SPICCR.bit.SPISWRESET = 1;
}
void GpioInit(void)
{
//Gpio初始化
EALLOW;
GpioCtrlRegs.GPAPUD.all=0xFFFFFFFF;
GpioCtrlRegs.GPBPUD.all=0xFFFFFFFF;
GpioCtrlRegs.GPCPUD.all=0xFFFFFFFF;
GpioCtrlRegs.GPADIR.all=0x00000000;
GpioCtrlRegs.GPBDIR.all=0x00000000;
GpioCtrlRegs.GPCDIR.all=0x00000000;
GpioCtrlRegs.GPAMUX1.all = 0;
GpioCtrlRegs.GPAMUX2.all = 0;
GpioCtrlRegs.GPBMUX1.all= 0;
GpioCtrlRegs.GPBMUX2.all= 0;
GpioCtrlRegs.GPCMUX1.all= 0;
GpioCtrlRegs.GPCMUX2.all= 0;
GpioCtrlRegs.GPDMUX1.bit.GPIO99 = 0;
GpioCtrlRegs.GPEMUX1.bit.GPIO133 = 0;
GpioCtrlRegs.GPADIR.all=0x80000820;
GpioCtrlRegs.GPBDIR.all=0x00438030;
GpioCtrlRegs.GPCDIR.all=0x002E0800;
GpioCtrlRegs.GPDDIR.bit.GPIO99 = 0;
GpioCtrlRegs.GPEDIR.bit.GPIO133 = 0;
GpioDataRegs.GPACLEAR.all= 0x80000820;
GpioDataRegs.GPASET.bit.GPIO11=1;
GpioDataRegs.GPBCLEAR.all= 0x00438030;
GpioDataRegs.GPCCLEAR.all= 0x002E0800;
GpioCtrlRegs.GPBGMUX2.bit.GPIO62 = 1; //
GpioCtrlRegs.GPBGMUX2.bit.GPIO63 = 1;
GpioCtrlRegs.GPBMUX2.bit.GPIO62 = 2;
GpioCtrlRegs.GPBMUX2.bit.GPIO63 = 2;
GpioCtrlRegs.GPBPUD.bit.GPIO63 = 0;
GpioCtrlRegs.GPBQSEL2.bit.GPIO62 = 3;
GpioCtrlRegs.GPAGMUX1.bit.GPIO13 = 0; //
GpioCtrlRegs.GPAGMUX1.bit.GPIO12 = 0;
GpioCtrlRegs.GPAMUX1.bit.GPIO13 = 2;
GpioCtrlRegs.GPAMUX1.bit.GPIO12 = 2;
GpioCtrlRegs.GPAPUD.bit.GPIO12 = 0;
GpioCtrlRegs.GPAQSEL1.bit.GPIO13 = 3;
///////////////////////////////SPI B GPIO设置///////////////////////////////////////////////////
GpioCtrlRegs.GPAPUD.bit.GPIO24 = 0; // Enable pull-up on GPIO16 (SPISIMOA)
GpioCtrlRegs.GPAPUD.bit.GPIO25= 0; // Enable pull-up on GPIO17 (SPISOMIA)
GpioCtrlRegs.GPAPUD.bit.GPIO26 = 0; // Enable pull-up on GPIO18 (SPICLKA)
GpioCtrlRegs.GPAPUD.bit.GPIO27 = 0; // Enable pull-up on GPIO19 (SPISTEA)
GpioCtrlRegs.GPAQSEL2.bit.GPIO24 = 3; // Asynch input GPIO16 (SPISIMOA)
GpioCtrlRegs.GPAQSEL2.bit.GPIO25 = 3; // Asynch input GPIO17 (SPISOMIA)
GpioCtrlRegs.GPAQSEL2.bit.GPIO26 = 3; // Asynch input GPIO18 (SPICLKA)
GpioCtrlRegs.GPAQSEL2.bit.GPIO27 = 3; // Asynch input GPIO19 (SPISTEA)
GpioCtrlRegs.GPAGMUX2.bit.GPIO24 = 1; // Configure GPIO16 as SPISIMOA
GpioCtrlRegs.GPAMUX2.bit.GPIO24 = 2; // Configure GPIO16 as SPISIMOA
GpioCtrlRegs.GPAGMUX2.bit.GPIO25 = 1; // Configure GPIO17 as SPISOMIA
GpioCtrlRegs.GPAMUX2.bit.GPIO25 = 2; // Configure GPIO17 as SPISOMIA
GpioCtrlRegs.GPAGMUX2.bit.GPIO26 = 1; // Configure GPIO3 as SPISOMIA
GpioCtrlRegs.GPAMUX2.bit.GPIO26 = 2; // Configure GPIO18 as SPICLKA
GpioCtrlRegs.GPAGMUX2.bit.GPIO27 = 1;
GpioCtrlRegs.GPAMUX2.bit.GPIO27 = 2; // Configure GPIO19 as SPISTEA
EDIS;
}
// 确保全局定义
#define TRANSFER_WORDS 4 // 必须等于 FIFO 阈值
Uint32 spi_read_fpga_reg_dma_16bit(Uint16 addr)
{
Uint16 i;
Uint32 result = 0;
// 1. 准备数据 (必须填满 4 个 Uint16,否则 SPI 不会启动,因为 FIFO 不满 4)
// 假设协议:Cmd+AddrH, AddrL+Dummy, Dummy+DataH, Dummy+DataL
sdata[0] = ((Uint16)FPGA_READ_CMD << 8) | ((addr >> 8) & 0xFF);
sdata[1] = ((Uint16)(addr & 0xFF) << 8) | 0xFF;
sdata[2] = 0xFFFF; // Dummy
sdata[3] = 0xFFFF; // Dummy
// 清空 RX 缓冲
for(i = 0; i < TRANSFER_WORDS; i++) rdata[i] = 0;
done = 0;
// 2. 硬件流控:确保 FIFO 是空的,防止上次残留数据干扰
SpibRegs.SPIFFTX.bit.TXFFINTCLR = 1;
SpibRegs.SPIFFRX.bit.RXFFINTCLR = 1;
SpibRegs.SPIFFRX.bit.RXFIFORESET = 1; // 复位 RX FIFO 指针
SpibRegs.SPIFFRX.bit.RXFIFORESET = 0;
SpibRegs.SPIFFRX.bit.RXFIFORESET = 1;
// SpibRegs.SPIFFTX.bit.TXFIFORESET = 1; // 复位 TX FIFO 指针
// SpibRegs.SPIFFTX.bit.TXFIFORESET = 0;
// SpibRegs.SPIFFTX.bit.TXFIFORESET = 1;
// 3. 拉低片选
SET_SPI_NSS_LOW;
DELAY_US(1);
// 4. 启动 DMA (先 RX 后 TX,防止 RX 溢出)
StartDMACH6();
StartDMACH5();
if (DmaRegs.CH5.CONTROL.bit.RUNSTS == 0) {
// CH5 根本没跑起来!
// 可能原因:PERINTSEL 配置错误,或者源/目的地址非法
}
// 稍微延时一下再读 SPITXBUF,给 DMA 一点时间
DELAY_US(1);
// 现在读 SPITXBUF,理论上应该能看到 tx_buffer[0] 的值
Uint16 tx_val = SpibRegs.SPITXBUF;
// 5. 等待完成 (加超时保护)
volatile Uint32 timeout = 1000000;
while(done == 0)
{
if(timeout-- == 0) {
SET_SPI_NSS_HIGH;
return 0xFFFFFFFF; // 超时错误
}
}
SET_SPI_NSS_HIGH;
// 6. 解析数据
// 根据你的 FPGA 时序,数据通常在 rx_buffer[2] 和 [3] 中
// 注意:这里是 16-bit 字,需要提取有效字节
Uint16 high_word = rdata[2];
Uint16 low_word = rdata[3];
// 假设数据在低 8 位 (根据实际波形调整)
result = ((Uint32)(high_word & 0xFF) << 8) | (low_word & 0xFF);
return result;
}
// 最终修复版本 - 使用软件强制触发,确保时序正确
Uint32 spi_read_fpga_reg_dma_fixed(Uint16 addr)
{
Uint32 timeout;
Uint16 i;
// 准备命令帧
sdata[0] = ((Uint16)FPGA_READ_CMD << 8) | ((addr >> 8) & 0xFF);
sdata[1] = ((Uint16)(addr & 0xFF) << 8) | 0xFF;
sdata[2] = 0xFFFF;
sdata[3] = 0xFFFF;
// 清空接收缓冲
for(i=0; i<4; i++) rdata[i] = 0;
done = 0;
// 复位FIFO
SpibRegs.SPIFFTX.bit.TXFIFO = 1;
SpibRegs.SPIFFTX.bit.TXFIFO = 0;
SpibRegs.SPIFFRX.bit.RXFIFORESET = 1;
SpibRegs.SPIFFRX.bit.RXFIFORESET = 0;
// 清除DMA标志
EALLOW;
DmaRegs.CH5.CONTROL.bit.PERINTCLR = 1;
DmaRegs.CH6.CONTROL.bit.PERINTCLR = 1;
EDIS;
// 【关键】先拉低片选!
SET_SPI_NSS_LOW;
DELAY_US(1);
// 启动DMA(CH6先,CH5后)
StartDMACH6();
StartDMACH5();
// 【终极修复】软件强制触发DMA传输!
// 不使用外设触发,直接强制DMA开始传输
EALLOW;
DmaRegs.CH5.CONTROL.bit.PERINTFRC = 1; // 强制触发CH5
EDIS;
// 等待CH5完成(数据已搬到TX FIFO)
timeout = 10000;
while((DmaRegs.CH5.CONTROL.bit.RUNSTS == 1) && timeout--);
// 【关键】现在数据在TX FIFO中,SPI应该自动发送了
// 等待SPI发送完成(通过RX FIFO判断)
timeout = 100000;
while((SpibRegs.SPIFFRX.bit.RXFFST < 4) && timeout--) {
DELAY_US(1);
}
// 强制触发CH6(搬运RX FIFO数据到内存)
EALLOW;
DmaRegs.CH6.CONTROL.bit.PERINTFRC = 1;
EDIS;
// 等待CH6完成
timeout = 100000;
while((DmaRegs.CH6.CONTROL.bit.RUNSTS == 1) && timeout--);
// 拉高片选
DELAY_US(1);
SET_SPI_NSS_HIGH;
if(timeout == 0) return 0xFFFFFFFF;
// 解析结果
return ((Uint32)rdata[2] << 16) | rdata[3];
}
//
// Main
//
void main(void)
{
Uint16 i;
//
// Step 1. Initialize System Control:
// PLL, WatchDog, enable Peripheral Clocks
// This example function is found in the F2837xS_SysCtrl.c file.
//
InitSysCtrl();
//
// Step 2. Initialize GPIO:
// This example function is found in the F2837xS_Gpio.c file and
// illustrates how to set the GPIO to it's default state.
// Setup only the GP I/O only for SPI-A functionality
//
// InitSpiaGpio();
//
// Step 3. Initialize PIE vector table:
// Disable and clear all CPU interrupts
//
DINT;
IER = 0x0000;
IFR = 0x0000;
//
// Initialize PIE control registers to their default state:
// This function is found in the F2837xS_PieCtrl.c file.
//
InitPieCtrl();
//
// Initialize the PIE vector table with pointers to the shell Interrupt
// Service Routines (ISR).
// This will populate the entire table, even if the interrupt
// is not used in this example. This is useful for debug purposes.
// The shell ISR routines are found in F2837xS_DefaultIsr.c.
// This function is found in F2837xS_PieVect.c.
//
InitPieVectTable();
//
// Interrupts that are used in this example are re-mapped to
// ISR functions found within this file.
//
EALLOW; // This is needed to write to EALLOW protected registers
PieVectTable.DMA_CH5_INT= &local_D_INTCH5_ISR;
PieVectTable.DMA_CH6_INT= &local_D_INTCH6_ISR;
EDIS; // This is needed to disable write to EALLOW protected registers
//
// Step 4. Initialize the Device Peripherals:
//
dma_init(); // Set up DMA for SPI configuration
spi_fifo_init(); // Initialize the SPI only
//
// Ensure DMA is connected to Peripheral Frame 2 bridge (EALLOW protected)
//
EALLOW;
CpuSysRegs.SECMSEL.bit.PF2SEL = 1;
EDIS;
//
// Step 5. User specific code, enable interrupts:
//
//
// Initialize the data buffers
//
//
// Enable interrupts required for this example
//
PieCtrlRegs.PIECTRL.bit.ENPIE = 1; // Enable the PIE block
PieCtrlRegs.PIEIER7.bit.INTx5 = 1; // Enable PIE Group 7, INT 1 (DMA CH1)
PieCtrlRegs.PIEIER7.bit.INTx6 = 1; // Enable PIE Group 7, INT 2 (DMA CH2)
IER= M_INT7; // Enable CPU INT6
EINT; // Enable Global Interrupts
//spi_read_fpga_reg_dma_16bit(0x8000);
spi_read_fpga_reg_dma_fixed(0x8000);
StartDMACH6(); // Start SPI RX DMA channel
StartDMACH5(); // Start SPI TX DMA channel
done = 0; // Test is not done yet
while(!done); // wait until the DMA transfer is
// complete
//
// when the DMA transfer is complete the program will stop here
//
ESTOP0;
}
//
// delay_loop - Function to add delay
//
void delay_loop()
{
long i;
for (i = 0; i < 1000000; i++) {}
}
//
// error - Halt debugger when error received
//
void error(void)
{
asm(" ESTOP0"); //Test failed!! Stop!
for (;;);
}
//
// spi_fifo_init - Initialize SPIA FIFO
//
void spi_fifo_init()
{
//
// Initialize SPI FIFO registers
//
SpibRegs.SPIFFTX.bit.SPIFFENA = 1;
SpibRegs.SPIFFRX.all=0x2040; // RX FIFO enabled, clear FIFO int
SpibRegs.SPIFFRX.bit.RXFFIL = FIFO_LVL; // Set RX FIFO level
SpibRegs.SPIFFTX.all=0xE040; // FIFOs enabled, TX FIFO released,
SpibRegs.SPIFFTX.bit.TXFFIL = FIFO_LVL; // Set TX FIFO level
//fpga_gpio_init_by_spi();
//fpga_spi_init();
//
// Initialize core SPI registers
//
//InitSpi();
// 4. 使能 FIFO 中断 (DMA 依赖此位)
SpibRegs.SPIFFTX.bit.TXFFIENA = 1;
SpibRegs.SPIFFRX.bit.RXFFIENA = 1;
// 5. 清除标志位
SpibRegs.SPIFFTX.bit.TXFFINTCLR = 1;
SpibRegs.SPIFFRX.bit.RXFFINTCLR = 1;
GpioInit();
InitSpib();
}
void spi_fifo_init_16bit(void)
{
// 1. 复位 FIFO 状态机
SpibRegs.SPIFFTX.all = 0xE040; // Reset TX FIFO
SpibRegs.SPIFFRX.all = 0x2040; // Reset RX FIFO
SpibRegs.SPIFFCT.all = 0x0;
// 2. 【关键】必须开启 FIFO 增强模式,否则 DMA 无触发源
SpibRegs.SPIFFTX.bit.SPIFFENA = 1;
// 3. 设置阈值 (Threshold Level)
// 策略:设为 4。意味着 FIFO 里有 4 个字时,触发一次中断/DMA请求
SpibRegs.SPIFFTX.bit.TXFFIL = FIFO_LVL;
SpibRegs.SPIFFRX.bit.RXFFIL = FIFO_LVL;
// 4. 使能 FIFO 中断 (DMA 依赖此位)
SpibRegs.SPIFFTX.bit.TXFFIENA = 1;
SpibRegs.SPIFFRX.bit.RXFFIENA = 1;
// 5. 清除标志位
SpibRegs.SPIFFTX.bit.TXFFINTCLR = 1;
SpibRegs.SPIFFRX.bit.RXFFINTCLR = 1;
// 6. 初始化 SPI 核心 (16-bit, Master, etc.)
GpioInit();
InitSpib();
}
void dma_init_16bit(void)
{
DMAInitialize();
volatile Uint16 *src = (volatile Uint16 *)sdata;
volatile Uint16 *dest = (volatile Uint16 *)rdata;
// --- CH5 (TX): Memory -> SPI_TXBUF ---
DMACH5AddrConfig(&SpibRegs.SPITXBUF, src);
// 【关键匹配】Burst Size = 4 (对应 TXFFIL=4)
// Step: Src=2 (16-bit), Dest=0 (固定寄存器地址)
DMACH5BurstConfig(3, 2, 0);
// Transfer Count: 0 (表示 1 次 Burst,即总共传 4 个字)
// 如果你要传 8 个字,这里改为 1 (1+1=2次 Burst),且 TXFFIL 保持 4
DMACH5TransferConfig(0, 2, 0);
DMACH5ModeConfig(DMA_SPIBTX, PERINT_ENABLE, ONESHOT_DISABLE, CONT_DISABLE,
SYNC_DISABLE, SYNC_SRC, OVRFLOW_DISABLE, SIXTEEN_BIT,
CHINT_END, CHINT_ENABLE);
// --- CH6 (RX): SPI_RXBUF -> Memory ---
DMACH6AddrConfig(dest, &SpibRegs.SPIRXBUF);
// 【关键匹配】Burst Size = 4 (对应 RXFFIL=4)
// Step: Src=0 (固定), Dest=2 (16-bit)
DMACH6BurstConfig(3, 0, 2);
DMACH6TransferConfig(0, 0, 2);
DMACH6ModeConfig(DMA_SPIBRX, PERINT_ENABLE, ONESHOT_DISABLE, CONT_DISABLE,
SYNC_DISABLE, SYNC_SRC, OVRFLOW_DISABLE, SIXTEEN_BIT,
CHINT_END, CHINT_ENABLE);
}
//
// dma_init - DMA setup for both TX and RX channels.
//
void dma_init()
{
//
// Initialize DMA
//
DMAInitialize();
DMASource = (volatile Uint16 *)sdata;
DMADest = (volatile Uint16 *)rdata;
//
// configure DMACH5 for TX
//
DMACH5AddrConfig(&SpibRegs.SPITXBUF,DMASource);
DMACH5BurstConfig(BURST,1,0); // Burst size, src step, dest step
DMACH5TransferConfig(TRANSFER,1,0); // transfer size, src step, dest step
DMACH5ModeConfig(DMA_SPIBTX,PERINT_ENABLE,ONESHOT_DISABLE,CONT_DISABLE,
SYNC_DISABLE,SYNC_SRC,OVRFLOW_DISABLE,SIXTEEN_BIT,
CHINT_END,CHINT_ENABLE);
//
// configure DMA CH2 for RX
//
DMACH6AddrConfig(DMADest,&SpibRegs.SPIRXBUF);
DMACH6BurstConfig(BURST,0,1);
DMACH6TransferConfig(TRANSFER,0,1);
DMACH6ModeConfig(DMA_SPIBRX,PERINT_ENABLE,ONESHOT_DISABLE,CONT_DISABLE,
SYNC_DISABLE,SYNC_SRC,OVRFLOW_DISABLE,SIXTEEN_BIT,
CHINT_END,CHINT_ENABLE);
}
//
// local_D_INTCH5_ISR - DMA Channel 5 ISR
//
__interrupt void local_D_INTCH5_ISR(void)
{
EALLOW; // NEED TO EXECUTE EALLOW INSIDE ISR !!!
DmaRegs.CH5.CONTROL.bit.HALT=1;
PieCtrlRegs.PIEACK.all = PIEACK_GROUP7; // ACK to receive more interrupts
// from this PIE group
EDIS;
return;
}
//
// local_D_INTCH6_ISR - DMA Channel 6 ISR
//
__interrupt void local_D_INTCH6_ISR(void)
{
Uint16 i;
EALLOW; // NEED TO EXECUTE EALLOW INSIDE ISR !!!
DmaRegs.CH6.CONTROL.bit.HALT = 1;
PieCtrlRegs.PIEACK.all = PIEACK_GROUP7; // ACK to receive more interrupts
// from this PIE group
EDIS;
// for( i = 0; i<128; i++ )
// {
// //
// // check for data integrity
// //
// if(rdata[i] != i)
// {
// error();
// }
// }
done = 1; // test done.
return;
}
//
// End of file
//