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