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.

[参考译文] RM57L843:HET1 DMA

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1638000/rm57l843-het1-dma

部件号: RM57L843

您好:

我正在使用如下所示的 HET IDE 代码:

l00 CNT{next=l01、reqnum=0、request=GENREQ、reg=a、max=5}; 
L01 ECMP{next=L02、hr_lr=high、en_pin_action=on、COND_addr=L03、pin=27、action=PULSEHI、reg=A、data=0、hr_data=0};
L02 MOV32{REMOTE=L01、type=IMTOREG&REM、reg=none、data=0、hr_data=0};
L03 BR{next=L00、COND_addr=L00、event=NOCOND};

我尝试g_test_tx_buf使用 HET + HTU 传输存储在中的数据:

uint32_t g_test_tx_buf[2048]; 

设置功能:

void Transmit_Engine_Setup (uint32_t * sourceAddr、uint32_t targetIdx、uint32_t len) 

htuREG1->GC = 0x00010000;
for (volatile int i=0;i<3000;i++);

htuREG1->CPENA = 0x00;
htuREG1->MPCS = 0x00000005;

htuDCP1[0].IFADCR =(uint32_t) sourceAddr;
htuDCP1[0].IHADDRCT =(1U << 23)|(1U << 18)| targetIdx;
htuDCP1[0].ITCOUNT = 0x00010000 + len;

hetREG1->GCR = 0x00010001;
hetREG1->REQENS =(1U << 0);

htuREG1->CPENA = 0x01;
}

函数调用:

Transmit_Engine_Setup (g_test_tx_buf、HTU_DCP0_TARGET、2048); 

根据 TRM(SPNU562A、第 1168 页)、IFTCOUNT中的字段ITCOUNT为 8 位、因此每帧最大传输计数为 255。

由于这一限制、似乎无法在单个操作中传输 2048 个字。

我的问题是:

  1. 是否有一种使用 HTU 传输大于 255 个字的缓冲区的推荐方法?
  2. 是否应该通过将传输拆分成多个 HTU 帧来处理?
  3. 是否有任何硬件支持的机制(例如自动重新加载,链接或循环模式)可以有效处理更大的传输?

请提供任何指导。

谢谢你。

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

    尊敬的 Jung:

    在第一阶段、我建议您参阅以下有关内部 AI 工具的回答;如果您还有其他问题、我将再次帮助您解决这些问题。

    处理 RM57L843 上的大型 HTU 传输

    您是正确的、该 IFTCOUNT 字段限制为 8 位(每帧最多 255 次传输)。 以下是传输 2048 个字的建议方法:

    1.具有控制数据包链接的多帧传输

    HTU 支持 控制数据包链接 这是为此目的设计的硬件机制。

    实施:
    #define MAX_FRAME_SIZE 255
    #define TOTAL_WORDS 2048
    #define NUM_FRAMES ((TOTAL_WORDS + MAX_FRAME_SIZE - 1) / MAX_FRAME_SIZE) // = 9 frames
    
    void Transmit_Engine_Setup(uint32_t* sourceAddr, uint32_t targetIdx, uint32_t len)
    {
        uint32_t remaining = len;
        uint32_t offset = 0;
        uint32_t frameIdx = 0;
        
        // Disable HTU
        htuREG1->GC = 0x00010000;
        for(volatile int i=0; i<3000; i++);
        htuREG1->CPENA = 0x00;
        htuREG1->MPCS = 0x00000005;
        
        // Setup control packets with chaining
        while(remaining > 0)
        {
            uint32_t frameSize = (remaining > MAX_FRAME_SIZE) ? MAX_FRAME_SIZE : remaining;
            
            htuDCP1[frameIdx].IFADDRA = (uint32_t)(sourceAddr + offset);
            htuDCP1[frameIdx].IHADDRCT = (1U << 23) | (1U << 18) | targetIdx;
            htuDCP1[frameIdx].ITCOUNT = (0x00010000) | frameSize;
            
            // Setup chaining: point to next control packet
            if(remaining > MAX_FRAME_SIZE)
            {
                // Enable chaining (bit 20) and set next CP address
                htuDCP1[frameIdx].IHADDRCT |= (1U << 20); // TMBA bit
                htuDCP1[frameIdx].ITCOUNT |= ((frameIdx + 1) << 24); // Next CP index
            }
            
            offset += frameSize;
            remaining -= frameSize;
            frameIdx++;
        }
        
        // Enable HET and HTU
        hetREG1->GCR = 0x00010001;
        hetREG1->REQENS = (1U << 0);
        htuREG1->CPENA = 0x01;
    }

    2.中断驱动的方法

    如果您更喜欢更多控制、请使用 HTU 中断来触发下一次传输:

    volatile uint32_t g_current_offset = 0;
    volatile uint32_t g_remaining_words = 0;
    volatile uint32_t* g_source_ptr = NULL;
    
    void Transmit_Engine_Setup(uint32_t* sourceAddr, uint32_t targetIdx, uint32_t len)
    {
        g_source_ptr = sourceAddr;
        g_current_offset = 0;
        g_remaining_words = len;
        
        htuREG1->GC = 0x00010000;
        for(volatile int i=0; i<3000; i++);
        htuREG1->CPENA = 0x00;
        htuREG1->MPCS = 0x00000005;
        
        // Enable HTU interrupts
        htuREG1->INTENAS = 0x01; // Enable interrupt for CP0
        
        // Start first frame
        Start_Next_Frame(targetIdx);
        
        hetREG1->GCR = 0x00010001;
        hetREG1->REQENS = (1U << 0);
        htuREG1->CPENA = 0x01;
    }
    
    void Start_Next_Frame(uint32_t targetIdx)
    {
        uint32_t frameSize = (g_remaining_words > MAX_FRAME_SIZE) ? 
                             MAX_FRAME_SIZE : g_remaining_words;
        
        htuDCP1[0].IFADDRA = (uint32_t)(g_source_ptr + g_current_offset);
        htuDCP1[0].IHADDRCT = (1U << 23) | (1U << 18) | targetIdx;
        htuDCP1[0].ITCOUNT = 0x00010000 | frameSize;
    }
    
    #pragma INTERRUPT(htuInterrupt, IRQ)
    void htuInterrupt(void)
    {
        // Check if transfer complete
        if(htuREG1->INTFLG & 0x01)
        {
            htuREG1->INTFLG = 0x01; // Clear flag
            
            g_current_offset += MAX_FRAME_SIZE;
            g_remaining_words -= MAX_FRAME_SIZE;
            
            if(g_remaining_words > 0)
            {
                Start_Next_Frame(HTU_DCP0_TARGET);
            }
            else
            {
                // Transfer complete
                htuREG1->CPENA = 0x00;
            }
        }
    }

    3、关键点

    • TMBA 位 (IHADDRCT 中的位 20):启用控制数据包链接
    • NXTCP 字段 (ITCOUNT 中的位 31-24):指定下一个控制数据包索引
    • 最多 16 个控制数据包 每个 HTU 实例可用
    • 对于 2048 个字:需要 9 个帧 (8×255 + 1×8)

    建议

    应用 方法 1(控制数据包链接) 因为它受硬件支持且效率最高。 HTU 将自动处理所有链接的数据包、而无需 CPU 干预。

    --
    此致、
    Jagadish。

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

    感谢您的答复。 我想再问一个关于方法 1 的问题。

    SPN215C 数据表第 182 页(第 7.6.7.2 节“触发器连接“)中、每个模块似乎都通过 8 行连接。 是否可以有 16 个连接?

    谢谢你。