Part Number: MSP430FR6043Dear all,
we would like to implement the Multi Tone Generation in which a certain amount of pulses are sent with 2 different frequencies, e.g., 6 pulses with 500 kHz, followed by 12 pulses with 1 MHz, 8 pulses with 500 kHz, 10 pulses with 1 MHz, etc.
We decided on using the EVM430FR6043 for this matter by starting with the application note saph_a_ex3_pulseGenerationDMA.c
We currently use DMA2 and DMA3, both triggered at the transition from E-Pulse to X-Pulse and vice versa, to update the values in the registers of the USS-Module. The MSP430 is never put into any sleep mode in our application.
The MSP430 runs at 16 MHz (MCLK) and we allow for enough pulses to be transmitted first to guarantee for the maximum time the DMAs take to complete their transfer to the register for a change in the amount of pulses according to table 11-3 page 350 of the family's user guide.
Let's assume we would like to have following sequence of x- and e-pules to be transmitted
uint16_t epulse[4] = {8, 10, 12, 14}; // -> Freq 1
uint16_t xpulse[4] = {7, 9, 11, 13}; // -> Freq 2
then the first amount of pulses is generated exactly to the amount we specified it with, tho we "preload" these values before starting the transmission of the sequence . In contrast, our last two ones are each repeated once more than they are supposed to.
In our case the sequence reads:
7 x-pulses, followed by 8 e-pulses, 9 x-pulses, 10 e-pulses, 11 x-pulses, 12 e-pulses, 11 x-pulses, 12 e-pulses, 13 x-pulses, 14 e-pulses, 13 x-pulses, 14 e-pulses.
We suppose there is an issue with the DMA transfer we implemented but simply cannot spot the error. I attached the code below of the DMAs' setup.
Any help would be highly appreciated! If we are mistaken and such an application is not possible with the MSP430FR6043, please let us know as well.
Thanks in advance!
uint16_t DMA_chan3_config[80];
uint16_t RAM_XE[10];
unsigned int i;
unsigned long SAPHPGC_addr, SAPHXPGCTL_addr;
SAPHPGC_addr = (unsigned long)(uintptr_t)(&SAPHPGC); // EPULSE
SAPHXPGCTL_addr = (unsigned long)(uintptr_t)(&SAPHXPGCTL); // XPULSE, XMOD, ETY
DMACTL1 = DMA2TSEL_27|DMA3TSEL_27;
DMA_initParam dmaParam = {0};
dmaParam.channelSelect = DMA_CHANNEL_2; // select the channel with PPG trigger
dmaParam.transferModeSelect = DMA_TRANSFER_REPEATED_SINGLE; // DMAEN stays enabled, each trigger one block of blocksize
DMA_init(&dmaParam);
// XPULSE, EPULSE preset
DMA_setSrcAddress(DMA_CHANNEL_2, (uint32_t)(uintptr_t)&RAM_XE, DMA_DIRECTION_UNCHANGED);
DMA_setDstAddress(DMA_CHANNEL_2, (uint32_t)(uintptr_t)&SAPHXPGCTL, DMA_DIRECTION_UNCHANGED);
DMA_setTransferSize(DMA_CHANNEL_2, 1); // 1 register (word) per block
DMA_enableTransfers(DMA_CHANNEL_2);
// Write new SA and DA of DMA2
// crucial for proper function - DMA buffers new SA, DA in temporary variables -- addresses need to be available one round earlier
DMA_setSrcAddress(DMA_CHANNEL_2, (uint32_t)(uintptr_t)RAM_XE+1, DMA_DIRECTION_INCREMENT);
DMA_setDstAddress(DMA_CHANNEL_2, (uint32_t)(uintptr_t)&SAPHPGC, DMA_DIRECTION_UNCHANGED);
// Repeated block transfer, increase src address and dst address
dmaParam.channelSelect = DMA_CHANNEL_3;
dmaParam.transferModeSelect = DMA_TRANSFER_REPEATED_BLOCK;
DMA_init(&dmaParam);
// X-Puls
DMA_setSrcAddress(DMA_CHANNEL_3, (uint32_t)(uintptr_t)&DMA_chan3_config, DMA_DIRECTION_INCREMENT);
DMA_setDstAddress(DMA_CHANNEL_3, (uint32_t)(uintptr_t)&DMA2SA, DMA_DIRECTION_INCREMENT);
DMA_setTransferSize(DMA_CHANNEL_3, 9); // 9 register per block
DMA_enableTransfers(DMA_CHANNEL_3);
// Setup RAM
// RAM to be transfered to DMA2 and DMA3
for (i = 0; i < 7; i++)
{
*(DMA_chan3_config+i*9) = (unsigned int)((unsigned long)(uintptr_t)(RAM_XE + i + 2)); // DMA2SA
*(DMA_chan3_config+1+i*9) = (unsigned int)(((unsigned long)(uintptr_t)(RAM_XE + i + 2))>>16); // DMA2SAH
if (i % 2 == 0){
*(DMA_chan3_config + 2 + i*9) = (unsigned int)(SAPHXPGCTL_addr); // DMA2DA low bits von SAPHPGC (0x0E40) -> EPULS;
}else{
*(DMA_chan3_config + 2 + i*9) = (unsigned int)(SAPHPGC_addr); // DMA2DA low bits von SAPHXPGCTL (0x0E4A) -> XPULS;
}
*(DMA_chan3_config+3+i*9) = 0x0000; // DMA2DAH
*(DMA_chan3_config+4+i*9) = 0x0001; // DMA2SZ
*(DMA_chan3_config+5+i*9) = 0x0000; // dummy -- see datasheet 3 words between DMA2SZ and DMA3CTL
*(DMA_chan3_config+6+i*9) = 0x0000; // dummy
*(DMA_chan3_config+7+i*9) = 0x5000|DMASRCINCR|DMADSTINCR|DMAEN; // DMA3CTL
*(DMA_chan3_config+8+i*9) = (unsigned int)(unsigned long)(uintptr_t)(DMA_chan3_config + (i + 1) * 9); // DMA3SA
}
//Set XMOD_2 in last cycle
for (i = 0; i < 4; i++){ //4
if (i == 3){ // last loop iteration
*(RAM_XE + 0 + i*2) = 0x6000; // X_MOD 2, XPULSE
*(RAM_XE + 1 + i*2) = 0x0000; // EPULSE
}else{
*(RAM_XE + 0 + i*2) = xpulse[i+1] | 0x7000; // X_MOD 3, XPULSE
*(RAM_XE + 1 + i*2) = epulse[i+1]; // EPULSE
}
}
DMACTL1 = DMA2TSEL_27|DMA3TSEL_27; // -- something seems to clear DMATRIIG27-- setting it once more
}