This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP430FR5969: MSP430FR5969 - UART with DMA initialization

Part Number: MSP430FR5969

Hello,

We have an application in one of our products where we use UART with DMA to communicate with a Radio chip from Telit. Since this is a low powered application it is required to put the chip to sleep mode ,disable UART and switch the Rx,Tx pins to input mode. On hourly wakeup we enable the UART again , transmit some data and put the chip to sleep again.

 

At initialization we first initialize the UART and then initialize the DMA. When putting the chip in sleep or wakeup we do not enable/disable the DMA peripheral again. Is it OK if we don’t do that? If yes then how does the DMA module stay in sync with UART?

Below are code snippet for the peripheral initialization in the firmware on power up and other scenarios.

Microcontroller : MSP430FR5969

UART A1 used with DMA channels 0 and 1.

 

 

  1. Function below called on power up for UART and DMA initialization

 

void Init_ZigBee_Interface(void)

{

       PM5CTL0 &= ~LOCKLPM5;

       EUSCI_A_UART_initParam param = {0};

       param.selectClockSource = EUSCI_A_UART_CLOCKSOURCE_SMCLK;

       param.clockPrescalar = 8;

       param.firstModReg = 0; //not valid when overSampling is

       param.secondModReg = 0xD6;

       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_LOW_FREQUENCY_BAUDRATE_GENERATION;

 

       EUSCI_A_UART_init(EUSCI_A1_BASE, &param);

 

       EUSCI_A_UART_enable(EUSCI_A1_BASE);

 

       //DMA Rx

       Param param1 = {0};

       param1.channelSelect = DMA_CHANNEL_0;

       param1.transferModeSelect = DMA_TRANSFER_REPEATED_SINGLE;

       param1.transferSize = M_SERIAL_BUFFER_LEN;

       param1.triggerSourceSelect = DMA_TRIGGERSOURCE_16;

       param1.transferUnitSelect = DMA_SIZE_SRCBYTE_DSTBYTE;

       param1.triggerTypeSelect = DMA_TRIGGER_RISINGEDGE;

 

       DMA_init(&param1);

       //DMA_disableTransferDuringReadModifyWrite();

       DMA_enableRoundRobinPriority();

 

       DMA_setSrcAddress(DMA_CHANNEL_0,

                    (uint32_t)&(UCA1RXBUF),

                    DMA_DIRECTION_UNCHANGED);

 

       DMA_setDstAddress(DMA_CHANNEL_0,

                    (uint32_t)&(zigBee_DMA_RxBuf.buffer[0]),

                    DMA_DIRECTION_INCREMENT);

 

       DMA_enableTransfers(DMA_CHANNEL_0);

       DMA_enableInterrupt(DMA_CHANNEL_0);

 

       //DMA Tx

       param1.channelSelect = DMA_CHANNEL_1;

       param1.transferModeSelect = DMA_TRANSFER_BURSTBLOCK;

       param1.transferSize = 1;

       param1.triggerSourceSelect = DMA_TRIGGERSOURCE_17;

       param1.transferUnitSelect = DMA_SIZE_SRCBYTE_DSTBYTE;

       param1.triggerTypeSelect = DMA_TRIGGER_HIGH;

 

       DMA_init(&param1);

       DMA_enableRoundRobinPriority();

 

       DMA_setSrcAddress(DMA_CHANNEL_1,

                    (uint32_t)&(mZhData.SerialBuffer.TxBuf[1]),     //transmission buffer

                    DMA_DIRECTION_INCREMENT);

 

       DMA_setDstAddress(DMA_CHANNEL_1,

                    (uint32_t)&UCA1TXBUF,                           //receive buffer

                    DMA_DIRECTION_UNCHANGED);

 

       DMA_enableInterrupt(DMA_CHANNEL_1);

 

}

2. Code snippet below called in an infinite loop to put the Telit module to sleep or wakeup the Telit module from sleep

/**check to put the zigbee module to sleep mode*/

   if(mZhData.StateMachine.bSleeping)

   {

       EUSCI_A_UART_disable(EUSCI_A1_BASE);

       if(!ZB_PwrCycFlg)

       {

           GPIO_setOutputHighOnPin(GPIO_PORT_P4,GPIO_PIN0);       /**CTS High*/

       }

       /**putting TXD, RXD of ZE61 in tristate*/

       GPIO_setAsInputPin(GPIO_PORT_P2,GPIO_PIN6);

       GPIO_setAsInputPin(GPIO_PORT_P2,GPIO_PIN5);

       LPM_Flag |= LPM_WIRELESS;

   }

 

/**check to wake up the zigbee module*/

   else

   {

       /**Setting UART Function RXD for Port 2, Pin 1*/

       GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P2, GPIO_PIN6, GPIO_SECONDARY_MODULE_FUNCTION); /**TXD of ZE61*/

       /**Setting UART Function TXD for Port 2, Pin 0*/

       GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P2, GPIO_PIN5, GPIO_SECONDARY_MODULE_FUNCTION); /**RXD of ZE61*/

       GPIO_setOutputLowOnPin(GPIO_PORT_P4,GPIO_PIN0);            //CTS Low

       EUSCI_A_UART_enable(EUSCI_A1_BASE);

   }

3. Code snippet below called in escalation mode to change the baud rate runtime

/*!

* @fn void coSetZigBeeUart9600(void)

* @brief this function is called to switch the ZigBee UART at 9600 baudrate

* @return None

*/

void coSetZigBeeUart9600()

{

#ifdef ZIGBEEHANDLER_FPI_H_DEBUG

       printf("\r\nbaud9600\r\n");

#endif

       EUSCI_A_UART_initParam param = {0};

       param.selectClockSource = EUSCI_A_UART_CLOCKSOURCE_SMCLK;

       //1Mhz 9600

       param.clockPrescalar = 6;

       param.firstModReg = 8;

       param.secondModReg = 0x20;

       //1Mhz 38400

       //     param.clockPrescalar = 1;

       //     param.firstModReg = 10;

       //     param.secondModReg = 0x00;

 

       //     param.clockPrescalar = 26;

       //     param.firstModReg = 0;

       //     param.secondModReg = 0xB6;

       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;

 

       EUSCI_A_UART_init(EUSCI_A1_BASE, &param);

 

//     if(!flg_FW_UpgradeUart)

             EUSCI_A_UART_enable(EUSCI_A1_BASE);

 

       DMA_clearInterrupt(DMA_CHANNEL_0);

       DMA_enableInterrupt(DMA_CHANNEL_0);

 

       //     EUSCI_A_UART_clearInterrupt(EUSCI_A1_BASE,

       //                  EUSCI_A_UART_RECEIVE_INTERRUPT);

       //

       //     /* Enable USCI_A0 RX interrupt*/

       //     EUSCI_A_UART_enableInterrupt(EUSCI_A1_BASE,

       //                  EUSCI_A_UART_RECEIVE_INTERRUPT); // Enable interrupt

}

 

/*!

* @fn void coSetZigBeeUart115200(void)

* @brief this function is called to switch the ZigBee UART at 115200 baudrate

* @return None

*/

void coSetZigBeeUart115200()

{

#ifdef ZIGBEEHANDLER_FPI_H_DEBUG

       printf("\r\nbaud115200\r\n");

#endif

       EUSCI_A_UART_initParam param1 = {0};

       param1.selectClockSource = EUSCI_A_UART_CLOCKSOURCE_SMCLK;

       param1.clockPrescalar = 8;

       param1.firstModReg = 0;

       param1.secondModReg = 0xD6;

       //     param.clockPrescalar = 2;

       //     param.firstModReg = 2; //not valid when overSampling is

       //     param.secondModReg = 0xBB;

       param1.parity = EUSCI_A_UART_NO_PARITY;

       param1.msborLsbFirst = EUSCI_A_UART_LSB_FIRST;

       param1.numberofStopBits = EUSCI_A_UART_ONE_STOP_BIT;

       param1.uartMode = EUSCI_A_UART_MODE;

       param1.overSampling = EUSCI_A_UART_LOW_FREQUENCY_BAUDRATE_GENERATION;

       //     param.overSampling = EUSCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION;

 

       EUSCI_A_UART_init(EUSCI_A1_BASE, &param1);

 

//     if(!flg_FW_UpgradeUart)

             EUSCI_A_UART_enable(EUSCI_A1_BASE);

 

       DMA_clearInterrupt(DMA_CHANNEL_0);

       DMA_enableInterrupt(DMA_CHANNEL_0);

 

       //     EUSCI_A_UART_clearInterrupt(EUSCI_A1_BASE,

       //                  EUSCI_A_UART_RECEIVE_INTERRUPT);

       //

       //     /* Enable USCI_A0 RX interrupt*/

       //     EUSCI_A_UART_enableInterrupt(EUSCI_A1_BASE,

       //                  EUSCI_A_UART_RECEIVE_INTERRUPT); // Enable interrupt

}

 

Regards,

Raman

  • Hi Ramandeep,

    I don't see anything wrong with leaving the DMA enabled when you switch the UART pins to input and go to a LPM. The mechanism that keeps the DMA in sync with the UART module is the state of the UCA1RXIFG and the UCA1TXIFG. As long as these bits are not interrupted during this process the DMA will stay in sync with the UART module.

    Best regards,
    Caleb Overbay

**Attention** This is a public forum