Other Parts Discussed in Thread: MSP430FR5969, MSP430WARE
I have encountered a couple of problems. I am using the MSP430FR5969 LaunchPad. I have a simple program that transfers contents of an array to the UART Tx buffer using DMA. At the same time, the main loop wakes up periodically from LPM3 using Timer A.
The first, and less troubling problem, is that the DMA initiates without ever sending an initial trigger. The DMA trigger source is set to the UCA1TXIFG. I should have to manually write the first byte to the UART Tx Buffer to trigger the DMA, but somehow the DMA gets triggered without doing this.
The second, and more concerning problem, is that the mcu resets. The shorter the Timer A period and the faster the UART baud rate the faster the reset occurs. I have tried a number of baud rates and timer periods, and the reset always eventually occurs.
The WDT is disabled. I have tried including an ISR for every vector, but the reset still occurs. I am using the MSP430Ware driverLib. It makes no difference if the project is build with the TI or GNU compiler.
The only enabled interrupt is the Timer A interrupt. All that is done in the ISR is clearing the interrupt flag and exiting LPM3. I have tried a number of variations with no change.
Any help, suggestions, ideas would be greatly appreciated. This appears to be a significant problem. Code follows.
Thanks,
Warren
int main(void)
{
uint8_t s1, s2;
WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer
// look for S1 (to catch unexpected reset)
InitPushbuttons(PUSHBUTTON_BOTH, 0);
getPushbuttons(&s1, &s2);
Init_GPIO();
Init_Clock();
Init_Serial();
Init_DMA();
// catch unexpected reset if S1 was not pressed
if(s1 != 0)
ABORT;
// enable source DMA
DMA_enableTransfers(DMA_CHANNEL_0);
// kick off dma by manually sending first byte
//EUSCI_A_UART_transmitData(EUSCI_A1_BASE, 0x99);
// configure Timer A (at 32.768 KHz clock)
TIMER_A_configureUpMode( TIMER_A3_BASE,
TIMER_A_CLOCKSOURCE_ACLK ,
TIMER_A_CLOCKSOURCE_DIVIDER_1,
0x0080,
TIMER_A_TAIE_INTERRUPT_ENABLE,
TIMER_A_CCIE_CCR0_INTERRUPT_DISABLE,
TIMER_A_DO_CLEAR);
greenLedOn();
// start the timer
TIMER_A_startCounter(
TIMER_A3_BASE,
TIMER_A_UP_MODE);
while(1)
{
// Enter LPM3
__bis_SR_register(LPM3_bits | GIE);
greenLedToggle();
redLedToggle();
// if timer was stopped in ISR, restart timer
TIMER_A_startCounter(
TIMER_A3_BASE,
TIMER_A_UP_MODE);
}
return(0);
}
#if defined (__TI_COMPILER_VERSION__) || defined (__IAR_SYSTEMS_ICC__)
#pragma vector=TIMER3_A1_VECTOR
__interrupt void TIMER3_A1_ISR(void)
#elif defined(__GNUC__)
void TIMER3_A1_ISR(void) __attribute__ ((interrupt(TIMER3_A1_VECTOR)));
void TIMER3_A1_ISR(void)
#else
#error Compiler not supported!
#endif
{
unsigned int taxiv;
// stop the timer
TIMER_A_stop(TIMER_A3_BASE);
// clear the interrupt
taxiv = HWREG16(TA3IV);
// exit LPM3
__bic_SR_register_on_exit(LPM3_bits);
}
Support code:
#define DMA_SIZE 128
const unsigned char gBits[DMA_SIZE] = {
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55
};
void Init_GPIO()
{
// Set all GPIO pins to output low for low power
GPIO_setOutputLowOnPin(GPIO_PORT_P1, GPIO_PIN0|GPIO_PIN1|GPIO_PIN2|GPIO_PIN3|GPIO_PIN4|GPIO_PIN5|GPIO_PIN6|GPIO_PIN7);
GPIO_setOutputLowOnPin(GPIO_PORT_P2, GPIO_PIN0|GPIO_PIN1|GPIO_PIN2|GPIO_PIN3|GPIO_PIN4|GPIO_PIN5|GPIO_PIN6|GPIO_PIN7);
GPIO_setOutputLowOnPin(GPIO_PORT_P3, GPIO_PIN0|GPIO_PIN1|GPIO_PIN2|GPIO_PIN3|GPIO_PIN4|GPIO_PIN5|GPIO_PIN6|GPIO_PIN7);
GPIO_setOutputLowOnPin(GPIO_PORT_P4, GPIO_PIN0|GPIO_PIN1|GPIO_PIN2|GPIO_PIN3|GPIO_PIN4|GPIO_PIN5|GPIO_PIN6|GPIO_PIN7);
GPIO_setOutputLowOnPin(GPIO_PORT_PJ, GPIO_PIN0|GPIO_PIN1|GPIO_PIN2|GPIO_PIN3|GPIO_PIN4|GPIO_PIN5|GPIO_PIN6|GPIO_PIN7|GPIO_PIN8|GPIO_PIN9|GPIO_PIN10|GPIO_PIN11|GPIO_PIN12|GPIO_PIN13|GPIO_PIN14|GPIO_PIN15);
GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN0|GPIO_PIN1|GPIO_PIN2|GPIO_PIN3|GPIO_PIN4|GPIO_PIN5|GPIO_PIN6|GPIO_PIN7);
GPIO_setAsOutputPin(GPIO_PORT_P2, GPIO_PIN0|GPIO_PIN1|GPIO_PIN2|GPIO_PIN3|GPIO_PIN4|GPIO_PIN5|GPIO_PIN6|GPIO_PIN7);
GPIO_setAsOutputPin(GPIO_PORT_P3, GPIO_PIN0|GPIO_PIN1|GPIO_PIN2|GPIO_PIN3|GPIO_PIN4|GPIO_PIN5|GPIO_PIN6|GPIO_PIN7);
GPIO_setAsOutputPin(GPIO_PORT_P4, GPIO_PIN0|GPIO_PIN1|GPIO_PIN2|GPIO_PIN3|GPIO_PIN4|GPIO_PIN5|GPIO_PIN6|GPIO_PIN7);
GPIO_setAsOutputPin(GPIO_PORT_PJ, GPIO_PIN0|GPIO_PIN1|GPIO_PIN2|GPIO_PIN3|GPIO_PIN4|GPIO_PIN5|GPIO_PIN6|GPIO_PIN7|GPIO_PIN8|GPIO_PIN9|GPIO_PIN10|GPIO_PIN11|GPIO_PIN12|GPIO_PIN13|GPIO_PIN14|GPIO_PIN15);
// Set PJ.4 and PJ.5 as Primary Module Function Input, LFXT.
GPIO_setAsPeripheralModuleFunctionInputPin(
GPIO_PORT_PJ,
GPIO_PIN4 + GPIO_PIN5,
GPIO_PRIMARY_MODULE_FUNCTION
);
// Disable the GPIO power-on default high-impedance mode
// to activate previously configured port settings
PMM_unlockLPM5();
}
void Init_Clock()
{
// Set DCO frequency to 8 MHz
CS_setDCOFreq(CS_DCORSEL_0, CS_DCOFSEL_6);
//Set external clock frequency to 32.768 KHz
CS_setExternalClockSource(32768, 0);
//Set ACLK=LFXT
CS_clockSignalInit(CS_ACLK, CS_LFXTCLK_SELECT, CS_CLOCK_DIVIDER_1);
// Set SMCLK = DCO with frequency divider of 1
CS_clockSignalInit(CS_SMCLK, CS_DCOCLK_SELECT, CS_CLOCK_DIVIDER_1);
// Set MCLK = DCO with frequency divider of 1
CS_clockSignalInit(CS_MCLK, CS_DCOCLK_SELECT, CS_CLOCK_DIVIDER_1);
//Start XT1 with no time out
CS_LFXTStart(CS_LFXTDRIVE_0);
}
void Init_DMA()
{
DMA_init(DMA_CHANNEL_0,
DMA_TRANSFER_REPEATED_SINGLE,
DMA_SIZE,
DMA_TRIGGERSOURCE_17, //UCA1TXIFG
DMA_SIZE_SRCBYTE_DSTBYTE,
DMA_TRIGGER_RISINGEDGE
);
DMA_setSrcAddress(DMA_CHANNEL_0,
&gBits[0],
DMA_DIRECTION_INCREMENT);
DMA_setDstAddress(DMA_CHANNEL_0,
EUSCI_A1_BASE + OFS_UCAxTXBUF, //0x05EE, //UCA1TXBUF,
DMA_DIRECTION_UNCHANGED);
DMA_clearInterrupt(DMA_CHANNEL_0);
}
//#define BAUD_9600
//#define BAUD_38400
#define BAUD_115200
void Init_Serial()
{
// Configure UART 115200
if ( STATUS_FAIL == EUSCI_A_UART_initAdvance(EUSCI_A1_BASE,
EUSCI_A_UART_CLOCKSOURCE_SMCLK,
#ifdef BAUD_9600
52, // clock prescalar
1, // firstModReg
0x49, // secondModReg
#endif
#ifdef BAUD_38400
13, // clock prescalar
0, // firstModReg
0x84, // secondModReg
#endif
#ifdef BAUD_115200
4, // clock prescalar
5, // firstModReg
85, // secondModReg
#endif
EUSCI_A_UART_NO_PARITY,
EUSCI_A_UART_LSB_FIRST,
EUSCI_A_UART_ONE_STOP_BIT,
EUSCI_A_UART_MODE,
EUSCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION ))
return;
EUSCI_A_UART_enable(EUSCI_A1_BASE);
// Select UART TXD on P2.5
GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P2, GPIO_PIN5, GPIO_SECONDARY_MODULE_FUNCTION);
}

