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.

[参考译文] MSP-EXP430FR5994:带有 DMA 的 UART 环回示例接收

Guru**** 2524460 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1109165/msp-exp430fr5994-uart-loopback-example-receive-with-dma

器件型号:MSP-EXP430FR5994

我正在尝试使用 DMA 通道进行仅接收的 UART 环回示例。 DMA 中断不会触发。 这是为什么?

/* --COPYRIGHT--,BSD
 * Copyright (c) 2017, Texas Instruments Incorporated
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * *  Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * *  Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * *  Neither the name of Texas Instruments Incorporated nor the names of
 *    its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * --/COPYRIGHT--*/
//******************************************************************************
//!  EUSCI_A1 External Loopback test using EUSCI_A_UART_init API
//!
//!  Description: This demo connects TX to RX of the MSP430 UART
//!  The example code shows proper initialization of registers
//!  and interrupts to receive and transmit data.
//!
//!  ACLK = BRCLK = 32.768kHz, MCLK = SMCLK = DCO = ~1MHz
//!
//!
//!      Tested on MSP430FR5969
//!             -----------------
//!       RST -|     P2.0/UCA1TXD|----|
//!            |                 |    |
//!            |                 |    |
//!            |     P2.1/UCA1RXD|----|
//!            |                 |
//!
//! This example uses the following peripherals and I/O signals.  You must
//! review these and change as needed for your own board:
//! - UART peripheral
//! - GPIO Port peripheral (for UART pins)
//! - UCA1TXD
//! - UCA1RXD
//!
//! This example uses the following interrupt handlers.  To use this example
//! in your own application you must add these interrupt handlers to your
//! vector table.
//! - USCI_A1_VECTOR.
//******************************************************************************
#include "LP_bspFuncs_BQUart.h"


#define BQUART_DMA_RX_TRIGGER         DMA1TSEL__UCA1RXIFG
#define TOTALBOARDS       2               //all boards in stack, including base device
#define MAXBYTES 8*(TOTALBOARDS-1)

extern void configure_pins_BQUart(void);


uint16_t dma_value[MAXBYTES] = {0};

uint16_t i;
uint8_t RXData = 0, TXData = 54;
uint8_t check = 0;

void init_clock(void);

void DMA_Init(){
    __data20_write_long((uintptr_t)&DMA1SA, (uintptr_t)&BQUART_RXBUF);
    __data20_write_long((uintptr_t)&DMA1DA, (uintptr_t) dma_value);

    DMA3CTL &= ~DMAEN;
    DMACTL0 |= BQUART_DMA_RX_TRIGGER;
    DMACTL4 |= DMARMWDIS;

    //Single transfer; increment destination address; source address unchanged;
    //byte to byte transfer source to DMA; byte to byte transfer destination to DMA;
    //rising edge DMA trigger; DMA enable

    DMA3CTL |= DMADT_0|DMADSTINCR_3|DMASRCINCR_0|DMASRCBYTE__BYTE|DMADSTBYTE__BYTE|DMA_TRIGGER_RISINGEDGE|DMAEN;

}

void main(void)
{
    uint32_t u32ClockFrequencyCheck = 0u;
    // stop watchdog
    WDT_A_hold(WDT_A_BASE);

    init_clock();

    u32ClockFrequencyCheck = CS_getMCLK();
    u32ClockFrequencyCheck = CS_getSMCLK();

    configure_pins_BQUart();


    BQUART_REG  &= ~BQUART_TX_PIN;
    __delay_cycles(44000);          //Transmit 2.5ms low
    BQUART_REG  = BQUART_TX_PIN;
    __delay_cycles(56000);

    // Configure UART pins
    //Set P2.0 and P2.1 as Secondary Module Function Input.
    /*

    * Select Port 2d
    * Set Pin 0, 1 to input Secondary Module Function, (UCA1TXD/UCA1SIMO, UCA1RXD/UCA1SOMI).
    */
    GPIO_setAsPeripheralModuleFunctionInputPin(
        BQUART_TX_PORT,
        BQUART_TX_PIN + BQUART_RX_PIN,
        BQUART_SELECT_FUNCTION
    );

    /*
     * Disable the GPIO power-on default high-impedance mode to activate
     * previously configured port settings
     */



    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, &param))
    {
           return;
    }


    BQUART_enable(BQUART);


    __enable_interrupt();
    while (1)
    {
        TXData = TXData+1;                      // Increment TX data
        // Load data onto buffer
        DMA3SZ = 1;
        DMA3CTL |= DMAEN;
        DMA3CTL |= DMAIE;
        while (!(BQUART_IFG & UCTXIFG));
        BQUART_TXBUF = TXData;

        while(check != 1);
        check = 0;

    }
}

#pragma vector=DMA_VECTOR
__interrupt void dmaIsrHandler(void)
{
    switch(__even_in_range(DMAIV, DMAIV_DMA3IFG))
    {
    case DMAIV_DMA1IFG:
        DMA3CTL &= ~DMAIE;
        RXData = *dma_value;
        if(!(RXData == TXData))                   // Check value
              {
                while(1);
              }
         check =1;

        // Exit low power mode on wake-up
        __bic_SR_register_on_exit(LPM4_bits);
        break;
    case DMAIV_DMA0IFG:
        break;

    case DMAIV_DMA2IFG:
        break;

    case DMAIV_DMA3IFG:
            break;

    case DMAIV_DMA4IFG:
        break;

    case DMAIV_DMA5IFG:
        break;

    default: break;
    }
}

void init_clock(void){
    // LFXT Setup
    //Set PJ.4 and PJ.5 as Primary Module Function Input.
    /*

    * Select Port J
    * Set Pin 4, 5 to input Primary Module Function, LFXT.
    */
    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);


    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_turnOnHFXT(CS_HFXT_DRIVE_16MHZ_24MHZ);


}

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    DMACTL0不是 DMA3的触发器设置所在的位置。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我已将所有 DMAxCtl 字段更改为 DMA1Ctl。 仍然没有接收数据。 等待互联网在中断后恢复、无法发布代码。 感谢您的回答  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Priya、

    您能否附上代码、因为 UART 环回示例应开箱即用、否则必须更改/意外编辑。

    这将使 David、JD 和我更需要了解。

    谢谢、
    Chris

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    当然、这里是 UART 环回示例、修改后使用 DMA 进行接收、与上面附加的代码相同、DMA 设置已更正。

    /* --COPYRIGHT--,BSD
     * Copyright (c) 2017, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     * --/COPYRIGHT--*/
    //******************************************************************************
    //!  EUSCI_A1 External Loopback test using EUSCI_A_UART_init API
    //!
    //!  Description: This demo connects TX to RX of the MSP430 UART
    //!  The example code shows proper initialization of registers
    //!  and interrupts to receive and transmit data.
    //!
    //!  ACLK = BRCLK = 32.768kHz, MCLK = SMCLK = DCO = ~1MHz
    //!
    //!
    //!      Tested on MSP430FR5969
    //!             -----------------
    //!       RST -|     P2.0/UCA1TXD|----|
    //!            |                 |    |
    //!            |                 |    |
    //!            |     P2.1/UCA1RXD|----|
    //!            |                 |
    //!
    //! This example uses the following peripherals and I/O signals.  You must
    //! review these and change as needed for your own board:
    //! - UART peripheral
    //! - GPIO Port peripheral (for UART pins)
    //! - UCA1TXD
    //! - UCA1RXD
    //!
    //! This example uses the following interrupt handlers.  To use this example
    //! in your own application you must add these interrupt handlers to your
    //! vector table.
    //! - USCI_A1_VECTOR.
    //******************************************************************************
    #include "LP_bspFuncs_BQUart.h"
    
    
    #define BQUART_DMA_RX_TRIGGER         DMA1TSEL__UCA1RXIFG
    #define TOTALBOARDS       2               //all boards in stack, including base device
    #define MAXBYTES 8*(TOTALBOARDS-1)
    
    uint16_t dma_value[MAXBYTES] = {0};
    
    uint16_t i;
    uint8_t RXData = 0, TXData = 54;
    uint8_t check = 0;
    
    extern void configure_pins_BQUart(void);
    void init_clock(void);
    
    void DMA_Init(){
        __data20_write_long((uintptr_t)&DMA1SA, (uintptr_t)&BQUART_RXBUF);
        __data20_write_long((uintptr_t)&DMA1DA, (uintptr_t) dma_value);
    
        DMA1CTL &= ~DMAEN;
        DMACTL0 |= BQUART_DMA_RX_TRIGGER;
        DMACTL4 |= DMARMWDIS;
    
        //Single transfer; increment destination address; source address unchanged;
        //byte to byte transfer source to DMA; byte to byte transfer destination to DMA;
        //rising edge DMA trigger; DMA enable
    
        DMA1CTL |= DMADT_0|DMADSTINCR_3|DMASRCINCR_0|DMASRCBYTE__BYTE|DMADSTBYTE__BYTE|DMA_TRIGGER_RISINGEDGE|DMAEN;
    
    }
    
    void main(void)
    {
        uint32_t u32ClockFrequencyCheck = 0u;
        // stop watchdog
        WDT_A_hold(WDT_A_BASE);
    
        init_clock();
    
        u32ClockFrequencyCheck = CS_getMCLK();
        u32ClockFrequencyCheck = CS_getSMCLK();
    
        configure_pins_BQUart();
        DMA_Init();
    
    
        BQUART_REG  &= ~BQUART_TX_PIN;
        __delay_cycles(44000);          //Transmit 2.5ms low
        BQUART_REG  = BQUART_TX_PIN;
        __delay_cycles(56000);
    
        // Configure UART pins
        //Set P2.0 and P2.1 as Secondary Module Function Input.
        /*
    
        * Select Port 2d
        * Set Pin 0, 1 to input Secondary Module Function, (UCA1TXD/UCA1SIMO, UCA1RXD/UCA1SOMI).
        */
        GPIO_setAsPeripheralModuleFunctionInputPin(
            BQUART_TX_PORT,
            BQUART_TX_PIN + BQUART_RX_PIN,
            BQUART_SELECT_FUNCTION
        );
    
        /*
         * Disable the GPIO power-on default high-impedance mode to activate
         * previously configured port settings
         */
    
    
    
        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, &param))
        {
               return;
        }
    
    
        BQUART_enable(BQUART);
    
    
        __enable_interrupt();
        while (1)
        {
            TXData = TXData+1;                      // Increment TX data
            // Load data onto buffer
            DMA1SZ = 1;
            DMA1CTL |= DMAEN;
            DMA1CTL |= DMAIE;
            while (!(BQUART_IFG & UCTXIFG));
            BQUART_TXBUF = TXData;
    
            while(check != 1);
            check = 0;
    
        }
    }
    
    #pragma vector=DMA_VECTOR
    __interrupt void dmaIsrHandler(void)
    {
        switch(__even_in_range(DMAIV, DMAIV_DMA1IFG))
        {
        case DMAIV_DMA1IFG:
            DMA1CTL &= ~DMAIE;
            RXData = dma_value[0];
            if(!(RXData == TXData))                   // Check value
                  {
                    while(1);
                  }
             check =1;
    
            // Exit low power mode on wake-up
            __bic_SR_register_on_exit(LPM4_bits);
            break;
        case DMAIV_DMA0IFG:
            break;
    
        case DMAIV_DMA2IFG:
            break;
    
        case DMAIV_DMA3IFG:
                break;
    
        case DMAIV_DMA4IFG:
            break;
    
        case DMAIV_DMA5IFG:
            break;
    
        default: break;
        }
    }
    
    void init_clock(void){
        // LFXT Setup
        //Set PJ.4 and PJ.5 as Primary Module Function Input.
        /*
    
        * Select Port J
        * Set Pin 4, 5 to input Primary Module Function, LFXT.
        */
        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);
    
    
        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_turnOnHFXT(CS_HFXT_DRIVE_16MHZ_24MHZ);
    
    
    }
    

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    好的、感谢 Priya、DMA 中断是否仍然不会触发?  此外、您能否调试项目(通过 XDS/JTAG 等进行单步调试)以查看在视在(NO)触发之前和期间/之后立即发生了什么?  谢谢、Chris

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我很困惑。  此问题已标记为已解决、因为该示例按预期工作。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Priya、

    这也是我的期望(已解决)、但出于某种原因、您仍然认为您仍有一些悬而未决的问题。  如果情况不是这样、我们可以关闭此操作并锁定线程、以便为将来的讨论创建新的线程、从而避免混淆。

    非常感谢您的回复。

    Chris