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:UART 接收 DMA 值回绕

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1110656/msp-exp430fr5994-uart-receive-dma-value-wrap-around

器件型号:MSP-EXP430FR5994

我已将 BQ UART 设置为使用 DMA 触发器进行接收。  

我将 dma_value 设置为 uint16_t、因为测量数据大小是 uint16_t 但是、初始化数据是 uint8_t  

BQInitTest 显示了正确的初始化字节序列。

但我在 dma_value 中看到的内容如图片 dmaValue 所示。 我不了解 dmaValue 中的字节顺序。 如逻辑分析仪中所示、BQ 对初始化的响应是正确的。 我已经附加了 DMA 设置和 DMA ISR uartSend 的代码。uartReceive 也已连接、但问题发生在这之前。

extern uint16_t bq79600Addr;

extern BYTE autoaddr_response_frame[(1+6)*TOTALBOARDS];
extern uint16_t response_frame[(8)*TOTALBOARDS];

uint8_t uartRxLen;
uint16_t dma_value[(8)*TOTALBOARDS] = {0};
uint8_t startMeasure = 0;
uint8_t bqAddr = 0;

void DMA_Init(){
    __data20_write_long((uintptr_t)&BQUART_DMASA, (uintptr_t)&BQUART_RXBUF);
    __data20_write_long((uintptr_t)&BQUART_DMADA, (uintptr_t) dma_value);

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

    //Repeated 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

    BQUART_DMACTL |= DMADT_4|DMADSTINCR_3|DMASRCINCR_0|DMASRCBYTE__BYTE|DMADSTBYTE__BYTE|DMA_TRIGGER_RISINGEDGE|DMAEN;

}


int ReadFrameReq(BYTE bID, uint16_t wAddr, BYTE bByteToReturn, BYTE bWriteType, BYTE rxLen) {
    bReturn = bByteToReturn - 1;

    uartRxLen = rxLen;

    //PN setting a flag to identify when BQ79600 address is being read
    if (wAddr == 0x2001)
        bqAddr = 1;
    if (wAddr != 0x2001)
        bqAddr = 0;

    if (bReturn > 127)
        return 0;

    return WriteFrame(bID, wAddr, &bReturn, 1, bWriteType);
}

void uartSend(int length, uint8_t * data){
    uint8_t i;

    BQUART_DMASZ = uartRxLen;
    BQUART_DMACTL |= DMAEN;
    BQUART_DMACTL |= DMAIE;


    for (i = 0; i < length; i++){
        while (!(BQUART_IFG & UCTXIFG));
        BQUART_TXBUF = data[i];
    }


}

void uartReceive(void){
uint8_t i;
uint8_t aaResp[7*TOTALBOARDS];

    if (startMeasure == 1){
        memcpy(response_frame, dma_value, uartRxLen);
    }

    if (bqAddr == 1){
        for (i = 0; i < 4; i++){
           aaResp[2*i] = (uint8_t) dma_value[i] & 0x00ff;
           aaResp[2*i+1] = (uint8_t) ((dma_value[i] & 0xff00) >> 8);

        }

        memcpy(autoaddr_response_frame, aaResp, uartRxLen+1);
        bq79600Addr = autoaddr_response_frame[4];
        startMeasure = 1;
    }


}

#pragma vector=DMA_VECTOR
__interrupt void dmaIsrHandler(void)
{
    switch(__even_in_range(DMAIV,  BQUART_DMAIV_IFG))
    {
    case BQUART_DMAIV_IFG:
        BQUART_DMACTL &= ~DMAIE;

        uartReceive();

        // 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;
    }
}

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

    从讨论中不清楚您的投诉是什么。 但我看到您告诉 DMA 控制器从源读取一个字节并将一个字节写入目标。 目的恰好是一个 INT 数组。 如果您希望 DMA 控制器知道它是一个整数组并相应地增加其地址、则您将被错误地误认为是正确的。

    DMA 控制器可以读取一个字节并写入一个字、如果需要、将字的上半部分清零。 也许这正是您所期望的。 如果是、则需要告知 DMA 控制器。

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

    extern uint16_t bq79600Addr;
    
    extern BYTE autoaddr_response_frame[(1+6)*TOTALBOARDS];
    extern uint16_t response_frame[(8)*TOTALBOARDS];
    
    uint8_t uartRxLen;
    uint16_t dma_value[(8)*TOTALBOARDS] = {0};
    uint8_t startMeasure = 0;
    uint8_t bqAddr = 0;
    
    void DMA_Init(){
        __data20_write_long((uintptr_t)&BQUART_DMASA, (uintptr_t)&BQUART_RXBUF);
        __data20_write_long((uintptr_t)&BQUART_DMADA, (uintptr_t) dma_value);
    
        BQUART_DMACTL &= ~DMAEN;
        DMACTL0 |= BQUART_DMA_RX_TRIGGER;
        DMACTL4 |= DMARMWDIS;
    
        //Repeated 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
    
        BQUART_DMACTL |= DMADT_4|DMADSTINCR_3|DMASRCINCR_0|DMASRCBYTE__WORD|DMADSTBYTE__WORD|DMA_TRIGGER_RISINGEDGE|DMAEN;
    
    }
    
    void uartSend(int length, uint8_t * data){
        uint8_t i;
    
        BQUART_DMASZ = uartRxLen;
        BQUART_DMACTL |= DMAEN;
        BQUART_DMACTL |= DMAIE;
    
    
        for (i = 0; i < length; i++){
            while (!(BQUART_IFG & UCTXIFG));
            BQUART_TXBUF = data[i];
        }
    
    
    }
    
    void uartReceive(void){
    uint8_t i;
    
        if (startMeasure == 1){
            memcpy(response_frame, dma_value, uartRxLen);
        }
    
        if (bqAddr == 1){
            for (i = 0; i < uartRxLen; i++){
                autoaddr_response_frame[i] = (uint8_t) dma_value[i];
            }
            bq79600Addr = autoaddr_response_frame[4];
            startMeasure = 1;
        }
    
    
    }
    
    #pragma vector=DMA_VECTOR
    __interrupt void dmaIsrHandler(void)
    {
        switch(__even_in_range(DMAIV,  BQUART_DMAIV_IFG))
        {
        case BQUART_DMAIV_IFG:
            BQUART_DMACTL &= ~DMAIE;
    
            uartReceive();
    
            // 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;
        }
    }

    将字传输到字节会有所帮助。 但是、我不理解 DMA_VALUE 中的字节顺序。

    在 dma_value 中、我希望在索引0-5中看到索引1-6中的字节。 索引0中的字节应该位于索引6中、因为它是 CRC 的一部分。

    当 dma_value 复制到 autodr_Response_FRAME 时、字节0不会被复制 corretty。 出于某种原因、0x55变为0x9C。 其余副本正常。

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

    由于 您在启用 DMA 之前没有清除 RXIFG、因此在 RXBUF 中悬挂一个字节非常容易。 因此、当您启用 DMA 时、您会立即触发。 这会将前一帧的最后一个字节放入当前帧的第一个字节中。