主题中讨论的其他器件: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天、运气不好、这让我觉得可能不符合勘误表的条件。
此测试是否正确? 如果没有、我还可以尝试复制勘误表吗?
谢谢。
