I am having a problem with the transmit complete interrupt on the FR5969 Launchpad. I am sending the data to the UART using DMA and I want the interrupt to disable a RS485 driver when the packet of data is complete. The problem is that the driver gets disabled far too soon. I have reduced the code to about the minimum required to demonstrate my problem. Is this a hardware bug or did I misunderstand something? I am using FreeRTOS so alternatives that require polling flags are not really a desirable option.
#include <msp430.h>
#include <string.h>
char message[] = "This is a test\r\n";
#define LED1_ON (P4OUT |= 0x40)
#define LED1_OFF (P4OUT &= ~0x40)
#define LED1_TOGGLE (P4OUT ^= 0x40)
#define LED2_ON (P1OUT |= 1)
#define LED2_OFF (P1OUT &= ~1)
#define LED2_TOGGLE (P1OUT ^= 1)
int main(void)
{
WDTCTL = WDTPW + WDTHOLD;
PMMCTL0 = PMMPW;
PM5CTL0 &= ~LOCKLPM5; // disable GPIO power on default
// Configure I/O ports as outputs, low
P1OUT = P2OUT = P3OUT = P4OUT = PJOUT = 0;
P1DIR = P2DIR = P3DIR = P4DIR = PJDIR = -1;
FRCTL0 = FWPW|NACCESS_1; // set 1 FRAM wait state
FRCTL0_H = 0; // lock FRAM control
CSCTL0 = CSKEY; // unlock clock system registers
CSCTL1 = DCORSEL|DCOFSEL_4; // Set DCO to 16MHz
CSCTL2 = SELA__LFXTCLK|SELS__DCOCLK|SELM__DCOCLK; // ACLK = XT1, MCLK = DCO
CSCTL3 = DIVA__1|DIVM__1|DIVS__16; // set clock dividers
// Startup the LFXT
PJSEL0 |= BIT4|BIT5; // assign pins to oscillator
CSCTL4 &= ~LFXTOFF; // LFXT On
// Wait for oscillator to start
do {
CSCTL5 &= ~LFXTOFFG; // clear fault flag
SFRIFG1 &= ~OFIFG;
} while(SFRIFG1&OFIFG);
CSCTL0_L = 0; // lock clock system registers
P3OUT &= ~0x10; // disable transmitter
P2SEL1 |= 0x60; // assign TXD and RXD pins to module
P2SEL0 &= ~0x60;
UCA1CTLW0 |= UCSWRST;
UCA1CTLW0 = UCSWRST|UCSSEL__SMCLK; // SMCLK (nominal 1MHz)
UCA1BRW = 6; // this is always 6 for 9600bps
UCA1MCTLW = 0x2081; // default value for now
UCA1CTLW0 &= ~UCSWRST; // start UART
DMACTL0 = DMA0TSEL__UCA1TXIFG;
DMA0CTL = DMADT_0|DMASRCINCR_3|DMADSTBYTE|DMASRCBYTE;
DMA0DA_L = (int)&UCA1TXBUF;
DMA0SA_L = (int)message+1;
DMA0SZ = strlen(message)-1; // count of bytes to transfer
UCA1IE |= UCTXCPTIE;
__eint();
while(1)
{
__delay_cycles(32000000L);
LED2_ON;
P3OUT |= 0x10; // Enable RS-485 transmitter
DMA0CTL |= DMAEN; // enable DMAC
UCA1TXBUF = message[0]; // transmit first byte of packet
}
}
__attribute__((wakeup, interrupt(USCI_A1_VECTOR))) void rxISR(void)
{
switch(UCA1IV)
{
case USCI_UART_UCTXCPTIFG:
P3OUT &= ~0x10; // disable RS485 transmitter
LED2_OFF;
break;
}
}
