Part Number: MSP430FR2476
Other Parts Discussed in Thread: MSP430F2132, ,
Hello,
I'm working on moving a software item from an MSP430F2132 to an MSP430FR2476 and my UARTs don't appear to be working. When I write data to UCA0TXBUF it doesn't show up coming out of the pin with my logic analyzer. Data being sent to the RX pin isn't triggering the interrupt, either, though the TX interrupt does get triggered.
I'm using msp430fr267x_euscia0_uart_1.c as a guide (https://dev.ti.com/tirex/explore/node?node=AKTwCkgQg9Z0vk0pj8kphQ__IOGqZri__LATEST) after starting with the OutOfBox_LP-MSP430FR2476 example code.
Here's the initialization function with my updates:
UART_TX_PORT = GPIO_PORT_P2
UART_RX_PORT = GPIO_PORT_P2
UART_TX_PIN = GPIO_PIN6
UART_RX_PIN = GPIO_PIN5
//Stop watchdog timer WDT_A_hold(WDT_A_BASE);
void UART_Init (void) {
// Initialize UART-related variables
txComplete = false;
remainingCurrentCmdTxLenBytes = 0;
commandBytesTxed = 0;
commandBytesRxed = 0;
// Setup circular buffer for incoming data bytes
byteIndexWr = 0;
byteIndexRd = 0;
// Adapted from EUSCI_init in LP-MSP430FR2476_Software_Examples/Firmware/Source/OutOfBox_LP-MSP430FR2476/main.c
// Configure UCA0TXD and UCA0RXD
GPIO_setAsPeripheralModuleFunctionOutputPin(UART_TX_PORT, UART_TX_PIN, UART_SELECT_FUNCTION);
GPIO_setAsPeripheralModuleFunctionInputPin(UART_RX_PORT, UART_RX_PIN, UART_SELECT_FUNCTION);
// Configure eUSCI UART @115200 baud, 8M
// software-dl.ti.com/.../index.html
EUSCI_A_UART_initParam param = {0};
param.selectClockSource = EUSCI_A_UART_CLOCKSOURCE_SMCLK;
param.clockPrescalar = 4;
param.firstModReg = 5;
param.secondModReg = 85;
param.parity = EUSCI_A_UART_NO_PARITY;
param.msborLsbFirst = EUSCI_A_UART_LSB_FIRST;
param.numberofStopBits = EUSCI_A_UART_ONE_STOP_BIT;
param.uartMode = EUSCI_A_UART_MODE;
param.overSampling = EUSCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION;
if(STATUS_FAIL == EUSCI_A_UART_init(EUSCI_A0_BASE, ¶m))
{
return;
}
EUSCI_A_UART_enable(EUSCI_A0_BASE);
// Enable UART interrupts
EUSCI_A_UART_enableInterrupt( EUSCI_A0_BASE,
EUSCI_A_UART_TRANSMIT_INTERRUPT | /* Transmit interrupt enabled */
EUSCI_A_UART_RECEIVE_INTERRUPT ); /* Receive interrupt enabled */
}
// Disable global interrupts
__bic_SR_register(GIE);
// Disable and clear all pending interrupts
SFRIE1 = ( WDTIE__DISABLE | /* Watchdog timer interrupts disabled */
OFIE__DISABLE | /* Oscillator fault interrupts disabled */
VMAIE__DISABLE | /* Vacant memory access interrupts disabled */
NMIIE__DISABLE | /* NMI pin interrupts disabled */
JMBINIE__DISABLE | /* JTAG mailbox input interrupts disabled */
JMBOUTIE__DISABLE ); /* JTAG mailbox output interrupts disabled */
SFRIFG1 = ( WDTIFG_0 | /* Watchdog timer no interrupt pending */
OFIFG_0 | /* Oscillator fault no interrupt pending */
VMAIFG_0 | /* Vacant memory access no interrupt pending */
NMIIFG_0 | /* NMI pin no interrupt pending */
JMBINIFG_0 | /* JTAG mailbox input no interrupt pending */
JMBOUTIFG_0 ); /* JTAG mailbox output no interrupt pending */
// Enable global interrupts
__bis_SR_register(GIE);
As stated in the above comment, I got the values for the clockPrescalar, firstModReg, and secondModReg from the calculator here (http://software-dl.ti.com/msp430/msp430_public_sw/mcu/msp430/MSP430BaudRateConverter/index.html) using EUSCI, a clock of 8MHz (which I checked with a logic analyzer), and 11520bps. They also appear to match the values in the User's Guide, slau445i Table 22-5:
BRCLK Baud Rate UCOS16 UCBRx UCBRFx UCBRSx
8000000 115200 1 4 5 0x55
When comparing what these functions do to the uart_01 example, the only thing I see missing is this line:
SYSCFG3|=USCIA0RMP;
Which I don't think would be necessary for my pin assigments...
Here is my interrupt code:
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=EUSCI_A0_VECTOR
__interrupt void EUSCI_A0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(EUSCI_A0_VECTOR))) EUSCI_A0_ISR (void)
#else
#error Compiler not supported!
#endif
{
switch (__even_in_range(UCA0IV, UCIV__UCTXCPTIFG)) {
case UCIV__UCRXIFG: { /* Interrupt Source: Receive buffer full; Interrupt
Flag: UCRXIFG; Interrupt Priority: Highest */
// Detected RX interrupt so store new byte in circular buffer
byteBuffer[byteIndexWr] = UCA0RXBUF;
byteIndexWr += 1;
byteIndexWr &= 0x07;
break;
}
case UCIV__UCTXIFG: { /* Interrupt Source: Transmit buffer empty;
Interrupt Flag: UCTXIFG */
// Send next byte if message not fully transmitted
if (commandBytesTxed <= remainingCurrentCmdTxLenBytes) {
// Place next byte in TX buffer
UCA0TXBUF = currentCmdTx[commandBytesTxed++];
}
else {
// Set TX complete flag
txComplete = true;
// Clear TX interrupt
UCA1IFG &= ~UCTXIFG_1;
}
break;
}
default:
break;
}
}
Please let me know if anything stands out right away or if you have some ideas I can try, thanks!