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.

[参考译文] MSP430F5659:使用2个DMA通道将数据发送到UCA0 SPI,不完整。

Guru**** 2589245 points


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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/619402/msp430f5659-using-2-dma-channels-to-send-data-to-uca0-spi-doesn-t-complete

部件号:MSP430F5659

大家好,

我有此例程写入UCA0 SPI上的外部闪存:

Int StartBlock_R2F (结构FlashMemoryBlockXferSetup *xfer)

{



block_xfer_in_progress = 1; //锁定其它传输



AssertFlashMemoryChipSelect(); // init/enable flash



// set up flash命令和地址

UCA0TXBUF__SPI = fmc_page_program; //

发送命令while (!UCA0IFG__SPI_bit.UCRXIFG); //等待完成

temp_read[520]= UCA0RXBUF__SPI; //读取以清除错误位



UCA0TXBUF__SPI = xfer->FMC_Addr2; //同时发送addr2

(!UCA0IFG__SPI_bit.UCRXIFG); //等待完成

temp_read[521]= UCA0RXBUF__SPI; //读取以清除错误位



UCA0TXBUF__SPI = xfer->FMC_Addr1; //同时发送addr1

(!UCA0IFG__SPI_bit.UCRXIFG); //等待完成

temp_read[522]= UCA0RXBUF__SPI; //读取以清除错误位





//设置DMA传输

//需要2个DMA通道将数据写入USCI

//通道1将读取RXBUF并将其写入名为dummy写入数据

//触发器为UCRXIFG的位置。 这将清除RX IFG位。 完成后,它会生成DMA1_IFG

//通道2将数据从RAM_Addr的阵列传输到UCA0TXBUF,

//触发器为DMA1_IFG

//

//对UCA0TXBUF的伪写入启动通道1

////

dummy写入数据= 0xff;



//设置DMA通道1

DMA1CTL = 0;

//DMACTL0 |= DMA1TSEL_17; // UCA0TXIFG

DMACTL0 |= DMA1TSEL_16;// UCA0RXIFG

//DMACTL0 |= DMA1TSEL_30; // DMA2IFG

__data16_write_addr ((unsigned short)&DMA1SA,(unsigned long)&UCA0RXBUF__SPI); //源数组地址

__data16_write_addr ((unsigned short)&DMA1DA,(unsigned long)&dummy_write_data);//目标数组地址

DMA1SZ =1; //块传输长度

DMAIV &=~0x04;// DMA1IFG中断

DMA1CTL = DMADT_4 | DMASBDB | DMAEN;//

//目的地未更改

//源地址不变

//源字节,目标字节访问





//设置DMA通道2

DMA2CTL =0;

DMACTL1 |= DMA2TSEL_30;// DMA1IFG

__data16_write_addr ((unsigned short)&DMA2SA,(&LONGE) xfer->RAM_Addr);__data16_write_addr (unsigned spi_d10;

unsigned dma_dxf)

//块传输长度

DMAIV &=~0x06;//清除DMA2IFG中断标志

DMA2CTL = DMADT_4 | DMASRCINCR_3 | DMASBDB | DMAEN | DMAIE;

//单次传输

//源将递增

//目的地未更改

//字节访问

//在块



_NOP()结束时中断;

UCA0TXBUF__SPI = xfer->FMC_Addr0; //发送addr0作为启动DMA

_NOP()的“虚拟字节”;



返回(1);

}//



代码:



StartBlock_R2F(&TEST_xfer);

i=500;

while (I-){_NOP()};

_NOP();//此处有断点



//中断:

案例DMAIV_DMA2IFG: // DMA2IFG = DMA通道2

//此DMA通道用于Flash只读

DeassertFlashMemoryChipSelect(); //完成块传输

block_xfer_in_progress = 0; //清除标志以允许下一个

DMA1CTL = 0; //禁用DMA-1和2传输

DMA2CTL = 0;

_NOP(); 

 

 

我期待的是DMA-1在伪写入后获取读取IFG,读取字节并设置DMA-1 IFG, 这会触发DMA3从数组中抓取下一个字节并发送, 这会生成另一个读取IFG–然后整个过程应该来回来回来回来回来回来回来回来回,直到计数耗尽,我从DMA2IFG得到中断。 块长度设置为10进行调试,但最终将为512。

 

看着SPI引脚,我从伪字节获得一个传输,然后是数组中第一个字节的第二个传输,然后它停止,我在while循环的末尾遇到了一个断点。 UCA0STAT上没有错误。  因此,我似乎从伪字节得到了一个读取触发器,一个发送第一个字节的写入触发器,另一个防止超限的读取触发器,但没有DMA-1 IFG来保持进程继续。

 

是否有人成功地完成了这项工作? 有什么问题吗?

 

谢谢!

Mike。

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

    为供将来参考,在向论坛发布代码时,请使用左下角的"使用丰富格式"链接。 在此视图中,编写您的帖子,然后通过按钮插入代码,以便正确格式化它。 我已经修改了您的帖子,以反映这些行动。

    我不确定您的问题在哪里,但众所周知,DMA很难调试。 确保在Free Run (自由运行)模式下运行,这样EEM就不会妨碍运行。 此外,我建议使用GPIO标志来查看DMA在代码中的哪些位置正在丢失跟踪。 尽管GPIO调试可能受到限制,因为在传输完成之前,您并不真正使用DMA中断。 正在进行此转接/您在LPM0中等待时,您正在主代码中执行什么操作?

    可能是DMA1IFG未得到重置,因此未触发DMA3。 DMA1IFG通过读取DMAIV或在DMAxCTL内手动清除进行重置。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好,Mike:

    您是否能够解决您的问题? 如果没有响应,我将很快关闭此线程。