Other Parts Discussed in Thread: BQ79616, BQ79600EVM,
I have the UART loopback example working at 1Mbps baud rate with no problems. I used a 4MHz SMCLK for the UART clock. These results are using an eternal clock on the MSP430 EVM.
When interfaced with the BQ79600EVM and the a custom BQ79616, the uart receive interrupt is firing soon after I try a single device read command. I can see the UCOE flag is set. Is there anything wrong in the setup/use of the UART driver?
I have setup a 100 bit delay for the BQ79600 chip to respond so the MSP430 has time to switch from uart transmit to uart receive. Is there an ideal number for the MSP430 for this to happen?
I am using the external clock in this setup.
#define BQUART EUSCI_A1_BASE #define BQUART_DISABLE EUSCI_A_UART_disable #define BQUART_CLOCKSOURCE EUSCI_A_UART_CLOCKSOURCE_SMCLK #define BQUART_PARITY EUSCI_A_UART_NO_PARITY #define BQUART_BITORDER EUSCI_A_UART_LSB_FIRST #define BQUART_STOPBIT EUSCI_A_UART_ONE_STOP_BIT #define BQUART_MODE EUSCI_A_UART_MODE #define BQUART_OVERSAMPLING EUSCI_A_UART_LOW_FREQUENCY_BAUDRATE_GENERATION #define BQUART_INIT EUSCI_A_UART_init #define BQUART_initParam EUSCI_A_UART_initParam #define BQUART_enable EUSCI_A_UART_enable #define BQUART_disable EUSCI_A_UART_disable #define BQUART_REG P2OUT #define BQUART_TX_PORT GPIO_PORT_P2 #define BQUART_RX_PORT GPIO_PORT_P2 #define BQUART_RX_PIN GPIO_PIN6 #define BQUART_TX_PIN GPIO_PIN5 #define BQUART_SELECT_FUNCTION GPIO_SECONDARY_MODULE_FUNCTION #define BQUART_enableInterrupt EUSCI_A_UART_enableInterrupt #define BQUART_RX_INT EUSCI_A_UART_RECEIVE_INTERRUPT #define BQUART_clearInterrupt EUSCI_A_UART_clearInterrupt #define BQUART_TXBUF UCA1TXBUF #define BQUART_RXBUF UCA1RXBUF #define BQUART_ISR USCI_A1_ISR #define BQUART_VECTOR USCI_A1_VECTOR #define BQUART_IFG UCA1IFG #define BQUART_IV UCA1IV #define BQUART_BUSY (UCA1STATW&UCBUSY) void Clock_Init() { #ifdef EXT_CLK GPIO_setAsPeripheralModuleFunctionInputPin( GPIO_PORT_PJ, GPIO_PIN4 + GPIO_PIN5, GPIO_PRIMARY_MODULE_FUNCTION ); // Set PJ.6 and PJ.7 as Primary Module Function Input, HFXT. GPIO_setAsPeripheralModuleFunctionInputPin( GPIO_PORT_PJ, GPIO_PIN6 + GPIO_PIN7, GPIO_PRIMARY_MODULE_FUNCTION ); // Check if one FRAM waitstate is needed for 5962, 5994 device as well! FRAMCtl_A_configureWaitStateControl(FRAMCTL_A_ACCESS_TIME_CYCLES_1); uint32_t u32ClockFrequencyCheck = 0u; // JA - Enable lxft & HXFT CS_setExternalClockSource(32768, 16000000); CS_initClockSignal(CS_SMCLK, CS_HFXTCLK_SELECT, CS_CLOCK_DIVIDER_4); CS_initClockSignal(CS_MCLK, CS_HFXTCLK_SELECT, CS_CLOCK_DIVIDER_1); //Set ACLK=LFXT CS_initClockSignal(CS_ACLK, CS_LFXTCLK_SELECT, CS_CLOCK_DIVIDER_1); //Set the appropriate drive values for each oscillator for the launchpad vs. actual schematic. CS_turnOnLFXT(CS_LFXT_DRIVE_3); // CS_turnOnLFXT(CS_LFXT_DRIVE_0); CS_turnOnHFXT(CS_HFXT_DRIVE_16MHZ_24MHZ); // JA - SMCLK appears to be running extremely slowly when sourced from HFXT // JA - Check SMCLK, MCLK clock frequencies u32ClockFrequencyCheck = CS_getMCLK(); u32ClockFrequencyCheck = CS_getSMCLK(); #endif #ifdef DCO_CLK // Configure one FRAM waitstate as required by the device datasheet for MCLK // operation beyond 8MHz _before_ configuring the clock system. FRCTL0 = FRCTLPW | NWAITS_1; // Clock System Setup CSCTL0_H = CSKEY_H; // Unlock CS registers CSCTL1 = DCOFSEL_0; // Set DCO to 1MHz // Set SMCLK = MCLK = DCO, ACLK = VLOCLK CSCTL2 = SELA__VLOCLK | SELS__DCOCLK | SELM__DCOCLK; // Per Device Errata set divider to 4 before changing frequency to // prevent out of spec operation from overshoot transient CSCTL3 = DIVA__4 | DIVS__4 | DIVM__4; // Set all corresponding clk sources to divide by 4 for errata CSCTL1 = DCOFSEL_4 | DCORSEL; // Set DCO to 16MHz // Delay by ~10us to let DCO settle. 60 cycles = 20 cycles buffer + (10us / (1/4MHz)) __delay_cycles(60); CSCTL3 = DIVA__1 | DIVS__4 | DIVM__1; // SMCLK=2Mhz MCLK=16MHz CSCTL0_H = 0; // Lock CS registers #endif } void UART_Init(void){ GPIO_setAsPeripheralModuleFunctionInputPin( BQUART_TX_PORT, BQUART_TX_PIN + BQUART_RX_PIN, BQUART_SELECT_FUNCTION ); BQUART_initParam param = {0}; param.clockPrescalar = 4, param.firstModReg = 0, param.secondModReg = 0, param.selectClockSource = BQUART_CLOCKSOURCE; param.parity = BQUART_PARITY; param.msborLsbFirst = BQUART_BITORDER; param.numberofStopBits = BQUART_STOPBIT; param.uartMode = BQUART_MODE; param.overSampling = BQUART_OVERSAMPLING; if(STATUS_FAIL == BQUART_INIT(BQUART, ¶m)) { return; } BQUART_enable(BQUART); BQUART_clearInterrupt(BQUART, BQUART_RX_INT); BQUART_enableInterrupt(BQUART, BQUART_RX_INT); } void uartSend(int length, uint8_t * data){ uint8_t i; for (i = 0; i < length; i++){ while (!(UCA1IFG & UCTXIFG)); BQUART_TXBUF = data[i]; } } void uartReceive(BYTE * data, BYTE length){ while (length > 0){ while (BQUART_BUSY); *data = BQUART_RXBUF; data++; length--; } } //****************************************************************************** // SPI_B1 Interrupt ************************************************************ //****************************************************************************** #pragma vector=BQUART_VECTOR /******************************************************************************* USCI_B1_ISR ****************************************************************** ******************************************************************************* * Function: B1 Interrupt Routine ********************************************************************************/ __interrupt void BQUART_ISR(void) { switch(__even_in_range(BQUART_IV, USCI_UART_UCTXCPTIFG)) { case USCI_NONE: break; case USCI_UART_UCRXIFG: BQUART_IFG &= ~UCRXIFG; __bic_SR_register_on_exit(LPM0_bits); // Exit LPM0 on reti break; case USCI_UART_UCTXIFG: break; case USCI_UART_UCSTTIFG: break; case USCI_UART_UCTXCPTIFG: break; default: break; } } #endif