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.

[参考译文] MSP430FR5989-EP:重现勘误表 DMA7

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1247877/msp430fr5989-ep-reproduce-errata-dma7

器件型号:MSP430FR5989-EP
主题中讨论的其他器件:MSP430FR5989

您好!

我尝试重现 MSP430FR5989微控制器的勘误表 DMA7中描述的错误、 该声明:如果 DMA 请求在使用读取-修改-写入指令访问包含中断标志的模块寄存器期间开始执行、则同一模块新到达的中断可能会丢失。

到目前为止,我所做的是:

__root const UCHAR DmaSrcData[] = {
	0x02, 0x00
};
void main( void )
{
	InitializeHardware(); // initialize ports, clocks, pmm, etc.	
	
	// -------------- INIT TA1 ----------------------
	
	TA1CTL = TASSEL__ACLK
	         | ID__1
	         | MC__UP
	         | TACLR;

	TA1CCTL0 = !CAP	
		       | OUTMOD_0
		       | !CCIE;	

	TA1EX0 = TAIDEX_0;	/* divider /1 */

	// -------------- END INIT TA1 -------------------
	
	
	// -------------- INIT TB0 -----------------------
	TB0CTL = TBSSEL__ACLK
	         | ID__1
	         | MC__CONTINUOUS
	         | TBCLGRP_0
	         | CNTL_0
	         | TBCLR;

	TB0CCTL0 = !CAP	
	           | OUTMOD_0	
	           | CLLD_0
	           | !CCIE;

	TB0EX0 = TBIDEX_0;

	// -------------- END INIT TB0 -------------------
	

	// -------------- INIT DMA -----------------------
	// DMA is triggered by TA1CCR0 every 250ms. 
	// Source data has two values (0x02 and 0x00) used to alternate the destination port output value (P4.1)
	
	DMA1CTL_bit.DMAEN = false;

	DMACTL4_bit.DMARMWDIS = true;			

	DMACTL0 = ( DMACTL0 & ~DMA1TSEL_31 )
	          | DMA1TSEL__TA1CCR0;			

	DMA1CTL |= DMADT2							// Repeated single transfer
	           |  !DMADSTINCR0 | !DMADSTINCR1	// Destination address is not incremented
	           |  DMASRCINCR0 | DMASRCINCR1		// Source address is incremented
	           |  DMASRCBYTE
	           |  DMADSTBYTE
	           |  !DMALEVEL	
	           |  !DMAIFG
	           |  !DMAIE
	           |  !DMAABORT	
	           |  !DMAREQ;

	DMA1SA = ( void * )&DmaSrcData[0];
	DMA1DA = ( void * )&P4OUT;	
	DMA1SZ = 2;
	
	// -------------- END INIT DMA -----------------------	
	
	
	TA1CCTL0_bit.CCIFG = false;

	TB0CCR0 = TB0R + 2;	
	TB0CCTL0_bit.CCIFG = false;
	while ( !TB0CCTL0_bit.CCIFG ){
	}	
	
	// DMA trigger timer and TB0.0 synchronization
	TA0CTL |= TACLR;	// clears DMA timer counter
	TB0CCR0 += 8192 - 1; // 8192 ticks = 250ms. A tick is sutracted to start clearing the TB0CCTL0 30us before the DMA request
	TB0CCTL0_bit.CCIFG = false;
	
	// DMA is triggered every 250ms
	TA1CCR0 = 8192; // 8192 ticks = 250ms
	DMA1CTL_bit.DMAEN = true;	// starts DMA
	
	for (;;) {
		while ( !TB0CCTL0_bit.CCIFG ){
		}
		TB0CCR0 += 8192 + 1;
		P3OUT = 0x80;	// trace P3.7
		
		// Continuously clears the TB0CCTL0 interruption flag from 30 us before the dma trigger to about 30us after.
		// The idea of this is to perform a read-modify-write operation on a register containing 
		// an interruption flag at the same moment that the DMA is triggered.
		TB0CCTL0_bit.CCIFG = false; TB0CCTL0_bit.CCIFG = false; TB0CCTL0_bit.CCIFG = false; TB0CCTL0_bit.CCIFG = false;
		TB0CCTL0_bit.CCIFG = false; TB0CCTL0_bit.CCIFG = false; TB0CCTL0_bit.CCIFG = false; TB0CCTL0_bit.CCIFG = false;
		TB0CCTL0_bit.CCIFG = false; TB0CCTL0_bit.CCIFG = false; TB0CCTL0_bit.CCIFG = false; TB0CCTL0_bit.CCIFG = false;
		TB0CCTL0_bit.CCIFG = false; TB0CCTL0_bit.CCIFG = false; TB0CCTL0_bit.CCIFG = false; TB0CCTL0_bit.CCIFG = false;
		TB0CCTL0_bit.CCIFG = false; TB0CCTL0_bit.CCIFG = false; TB0CCTL0_bit.CCIFG = false; TB0CCTL0_bit.CCIFG = false;
		TB0CCTL0_bit.CCIFG = false; TB0CCTL0_bit.CCIFG = false; TB0CCTL0_bit.CCIFG = false; TB0CCTL0_bit.CCIFG = false;
		TB0CCTL0_bit.CCIFG = false; TB0CCTL0_bit.CCIFG = false; TB0CCTL0_bit.CCIFG = false; TB0CCTL0_bit.CCIFG = false;
		TB0CCTL0_bit.CCIFG = false; TB0CCTL0_bit.CCIFG = false; TB0CCTL0_bit.CCIFG = false; TB0CCTL0_bit.CCIFG = false;
		TB0CCTL0_bit.CCIFG = false; TB0CCTL0_bit.CCIFG = false; TB0CCTL0_bit.CCIFG = false; TB0CCTL0_bit.CCIFG = false;
		TB0CCTL0_bit.CCIFG = false; TB0CCTL0_bit.CCIFG = false; TB0CCTL0_bit.CCIFG = false; TB0CCTL0_bit.CCIFG = false;
		TB0CCTL0_bit.CCIFG = false; TB0CCTL0_bit.CCIFG = false; TB0CCTL0_bit.CCIFG = false; TB0CCTL0_bit.CCIFG = false;
		TB0CCTL0_bit.CCIFG = false; TB0CCTL0_bit.CCIFG = false; TB0CCTL0_bit.CCIFG = false; TB0CCTL0_bit.CCIFG = false;
		TB0CCTL0_bit.CCIFG = false; TB0CCTL0_bit.CCIFG = false; TB0CCTL0_bit.CCIFG = false; TB0CCTL0_bit.CCIFG = false;
		TB0CCTL0_bit.CCIFG = false; TB0CCTL0_bit.CCIFG = false; TB0CCTL0_bit.CCIFG = false; TB0CCTL0_bit.CCIFG = false;
		TB0CCTL0_bit.CCIFG = false; TB0CCTL0_bit.CCIFG = false; TB0CCTL0_bit.CCIFG = false; TB0CCTL0_bit.CCIFG = false;
		P3OUT = 0x00;	// trace P3.7
	}
}

该测试的想法是每250ms 触发一个 DMA (参见图像1)并连续执行读取-修改-写入操作(在这种情况下、清除 TB0CCTL0中断标志) 从 DMA 触发前的30us 到触发后的大约30us、以确保在访问寄存器的同时有 DMA 请求。 在开始读取-修改-写入操作之前设置跟踪、并在该过程结束时清除跟踪(请参阅图1和图2)。 如果在任何时候、跟踪周期大约为2秒而不是250ms、这意味着丢失了一个中断标志。

在以下各图中、CH1 (橙色)是跟踪信号(P3.7)、CH2 (蓝色)是 DMA 目标端口(P4.1)。

图 1:  

  

图 2:

读取-修改-写入操作在 DMA 触发前30us 开始、在 DMA 触发后30us 停止。

我已经让代码运行了大约1天、运气不好、这让我觉得可能不符合勘误表的条件。

此测试是否正确? 如果没有、我还可以尝试复制勘误表吗?

谢谢。  

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

    您好!

    建议使用以下任一方法来避免此问题。

    • 使用读取中断向量寄存器来清除中断标志、不要使用读取-修改-写入指令。  
    • 当这些中断被激活时、在包含中断标志的特定模块寄存器的读取-修改-写入指令期间、禁用所有 DMA 通道。

    为什么要 重现 勘误表?  我没有找到任何额外的说明来重现问题,因为似乎说某些条件是足够的。

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

    您好!

    感谢您的答复。

    复制勘误表的目的是为了证明我们有一个错误是由于这个原因,所以我们可以排除其他理论。

    您是否认为我所描述的测试足以满足勘误表的条件?

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

    您好!

    您是否尝试过更多的时间点? 例如、 读-修改-写操作在 DMA 触发前40us 开始、在触发后20us 停止。

    恐怕我没有更好的建议了。

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

    您好!

    是的、我已经尝试更改启动读取-修改-写入操作的时间。 我还尝试了使用所有 DMA 通道和计时器来提高发生的可能性、但仍然什么都没有。

    此勘误表的问题是、我们无法使用 DMA、因为 在本例中无法使用所述的任何权变措施。  

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

    我已经让新测试器件运行了几天 、这里使用了由 SMCLK 计时器触发的所有三个 DMA 通道、但没有任何变化。  

    我确信我已经满足勘误表中的条件、现在可能已经达到了数千次、并且没有一个中断标志丢失。  勘误表中必须未描述另一个不符合要求的条件。