Other Parts Discussed in Thread: MSP430FR5969, MSP430F6779
Tool/software:
I'm trying to assign the full 20-bits of the DMAxSA register. The user manual specifies, "Reading or writing bits 19-16 requires the use of extended instructions".
This is already confusing because the MSP430FR5XX_6XX DMA code example uses the __data20_write_long() intrinsic, which is implemented using two standard MOV.W instructions which are not part of the extended instructions (CPU430X). When I attempt to assign a 20-bit value to DMA0SA using __data20_write_long(&DMA0SA, 0x10000) I get a register value of 0x0.
After reading the MSP documentation further and this form discussion, I learned that i need to use __data16_write_addr() instead.
When compiled, this intrinsic actually uses the MOVX.A or POPX.A instructions which are extended address assignment instructions and I can now see that it successfully assigns the full 20-bit registers.
However, after keeping my application running for a few days, it still breaks because of a failed DMA address assignment operation. Once every few ten thousand DMA address assignments, the bits 19-16 are wrongfully cleared.
I have verified that both parameters to __data16_write_addr() are correct, and the DMA channel is disabled, so the issue is not with the application software itself. Furthermore, I have disabled interrupts as advised by the Compiler User Guide.
Replacing __data16_write_addr with my own assembly code does not change the situation.
__asm( "PUSHM.W #2, R15\n"
"POPX.A 0(R12)");
The only way that I can fix this issue is by reading back the DMA register value and reassign it in a loop.
#pragma optimize=none
void Dma_WriteAddress(uint32_t destination, uint32_t source)
{
__disable_interrupt();
do
{
__data16_write_addr(static_cast<uint16_t>(destination), source);
}
while(__data16_read_addr(static_cast<uint16_t>(destination)) != source);
__enable_interrupt();
}
When I add logging to this function, I can see that the assignment fails only once every 5.000 to 50.000 times that this function is called.
Of course this solution is not optimal and should not be necessary. Could this be a hardware bug (it is not in the errata)? Am i missing something? Does anyone else have this problem?
This was tested on three MSP430FR5964 ICs, hardware revision C
Compiler: IAR MSP430 7.21.1
Data/Code model: Small