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.

[参考译文] MSPM0G3507:MSPM0G3507 -在80MHz 时 UART0 TX DMA 丢失随机字节

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1420292/mspm0g3507-mspm0g3507---uart0-tx-dma-missing-random-bytes-at-80mhz

器件型号:MSPM0G3507
主题中讨论的其他器件:MSPM0G3106

工具与软件:

你(们)好  

我将 MSPM0G3106/MSPM0G3507用于以以下配置运行的 UART DMA 通信。  

波特率- 2mbps  

CPU 时钟- 80MHz  

MCLK - 80MHz  

ULPCLK - 40MHz (根据 TRM 可能达到的最大值)  

 所使用的 UART0 (电源域0)、指40MHz (最大值) 的 ULPCLK 作为其运行的 BUSCLK。 DMA 用于 RX 和 TX  、触发条件设置为向/从 RX/TX FIFO 传输。 DMA (电源域1)。  


问题说明:  

我们是一个运行时间为1ms 的 TX 任务,它一次最多创建130字节的数据包,这将成为 DMA 推送到 UART TX FIFO 的源缓冲区。  在启用内部环回的情况下、我们观察到传输的数据包中缺少随机的1或2个字节。 我们已验证数据包结构、直到为 UART DMA 事务指定了缓冲区、因此问题必须由 UART/DMA 层本身引起。  

观察结果:

1、相同的代码将 MCLK 和 CPU 时钟设置为40MHz ,同时 ULPCLK 也设置为40MHz ,似乎不会造成问题。  

2.在 launchpad 上, 与使用 UART3 (PD1)代替 UART0(PD0)进行的测试相同,该测试使用 MCLK 80MHz 进行 UART3 (PD1)-此设置也会处理字节的缺失问题。  


对于使用 UART0 DMA 与 ULPCLK -40MHz、MCLK -80MHz、CPU 时钟-80MHz 以获得稳定性、是否有任何建议?  



请查找发现问题时使用的配置的代码片段 :

时钟配置(SYS PLL):


static const DL_SYSCTL_SYSPLLConfig gSYSPLLConfig = {
    .inputFreq              = DL_SYSCTL_SYSPLL_INPUT_FREQ_16_32_MHZ,
    .rDivClk2x              = 0,
    .rDivClk1               = 0,
    .rDivClk0               = 0,
    .enableCLK2x            = DL_SYSCTL_SYSPLL_CLK2X_DISABLE,
    .enableCLK1             = DL_SYSCTL_SYSPLL_CLK1_ENABLE,
    .enableCLK0             = DL_SYSCTL_SYSPLL_CLK0_ENABLE,
    .sysPLLMCLK             = DL_SYSCTL_SYSPLL_MCLK_CLK0,
    .sysPLLRef              = DL_SYSCTL_SYSPLL_REF_SYSOSC,
    .qDiv                   = 9,
    .pDiv                   = DL_SYSCTL_SYSPLL_PDIV_2
};


    DL_SYSCTL_setSYSOSCFreq(DL_SYSCTL_SYSOSC_FREQ_BASE);
    DL_SYSCTL_configSYSPLL((DL_SYSCTL_SYSPLLConfig *) &gSYSPLLConfig);
    DL_SYSCTL_setMCLKSource(SYSOSC, HSCLK, DL_SYSCTL_HSCLK_SOURCE_SYSPLL);
    DL_SYSCTL_setULPCLKDivider(DL_SYSCTL_ULPCLK_DIV_2);
    //Low Power Mode is configured to be SLEEP0
    DL_SYSCTL_setBORThreshold(DL_SYSCTL_BOR_THRESHOLD_LEVEL_0);
    DL_SYSCTL_setFlashWaitState(DL_SYSCTL_FLASH_WAIT_STATE_2);

UART0和 DMA 配置:

DL_UART_Main_setOversampling(UART_INST, DL_UART_OVERSAMPLING_RATE_16X);

DL_UART_Main_setBaudRateDivisor(UART_INST, UART_IBRD_40_MHZ_2000000_BAUD, UART_FBRD_40_MHZ_2000000_BAUD);

DL_UART_Main_enableDMAReceiveEvent(UART_INST, DL_UART_DMA_INTERRUPT_RX);
DL_UART_Main_enableDMATransmitEvent(UART_INST);

    /* Configure FIFOs */
    DL_UART_Main_enableFIFOs(UART_INST);
    DL_UART_Main_setRXFIFOThreshold(UART_INST, DL_UART_RX_FIFO_LEVEL_ONE_ENTRY);
    DL_UART_Main_setTXFIFOThreshold(UART_INST, DL_UART_TX_FIFO_LEVEL_ONE_ENTRY);


/* Configuration for UART 0 Peripheral  */
static const DL_UART_Main_ClockConfig gUART_ClockConfig = {
    .clockSel    = DL_UART_MAIN_CLOCK_BUSCLK,
    .divideRatio = DL_UART_MAIN_CLOCK_DIVIDE_RATIO_1
};

static const DL_UART_Main_Config gUART_Config = {
    .mode        = DL_UART_MAIN_MODE_NORMAL,
    .direction   = DL_UART_MAIN_DIRECTION_TX_RX,
    .flowControl = DL_UART_MAIN_FLOW_CONTROL_NONE,
    .parity      = DL_UART_MAIN_PARITY_NONE,
    .wordLength  = DL_UART_MAIN_WORD_LENGTH_8_BITS,
    .stopBits    = DL_UART_MAIN_STOP_BITS_ONE
};




/*configuration for DMA TX channel - Channel 1*/
static const DL_DMA_Config gDMA_CH1Config = {
    .transferMode   = DL_DMA_SINGLE_TRANSFER_MODE,
    .extendedMode   = DL_DMA_NORMAL_MODE,
    .destIncrement  = DL_DMA_ADDR_UNCHANGED,
    .srcIncrement   = DL_DMA_ADDR_INCREMENT,
    .destWidth      = DL_DMA_WIDTH_BYTE,
    .srcWidth       = DL_DMA_WIDTH_BYTE,
    .trigger        = UART_INST_DMA_TRIGGER_1,
    .triggerType    = DL_DMA_TRIGGER_TYPE_EXTERNAL,
};


/*configuration for DMA RX channel - Channel 0*/
static const DL_DMA_Config gDMA_CH0Config = {
    .transferMode   = DL_DMA_FULL_CH_REPEAT_SINGLE_TRANSFER_MODE,
    .extendedMode   = DL_DMA_NORMAL_MODE,
    .destIncrement  = DL_DMA_ADDR_INCREMENT,
    .srcIncrement   = DL_DMA_ADDR_UNCHANGED,
    .destWidth      = DL_DMA_WIDTH_BYTE,
    .srcWidth       = DL_DMA_WIDTH_BYTE,
    .trigger        = UART_INST_DMA_TRIGGER_0,
    .triggerType    = DL_DMA_TRIGGER_TYPE_EXTERNAL,
};


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

    尊敬的 Jayakrishnan Menon:

    我们已经将这确定为勘误表、我们将在下次勘误表更新中介绍这一勘误表、我们计划很快将其提供。 以下是详细信息。

    DMA_ERR_01

    DMA 模块

    对应

    正常工作

    位置

    当通过时钟资源同时访问外设寄存器时、DMA 或 CPU 可能丢失操作

    该设计的链接

    DMA 和 CPU 都来自 MCLK。 当 MCLK 以高于 ULPCLK 的频率运行时、在同时访问来自 ULPCLK (包括所有 PD0外设)的外设寄存器时、DMA 或 CPU 可能会丢失操作。 访问的外设或寄存器不必相同。 注意:ADC 是 PD0外设、而 DMA 或 CPU 访问 ADC 的 SVT_MEMRES 或 SVT_FIFODATA 没有限制。 示例:假设 DMA 访问 UART0寄存器、例如 DMA 向 TXDATA 写入数据、如果 CPU 在 DMA 操作期间也访问 PD0外设、例如 CPU 从 TIMG0 CTR 读取数据、则 DMA 或 CPU 可能会丢失数据。

    解决方法

    当 MCLK 以高于 ULPCLK 的频率运行时、CPU 和 DMA 不应同时访问 PD0外设。
    此致、
    Luke
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Luke:  

    感谢您的响应。  是否会在将来的芯片修订版本中解决此问题?   


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

    尊敬的 Jayakrishnan:

    目前、对于此器件(MSPM0G350x)、近期没有修订计划。 对于未来的器件、它可能会被修复。

    此致、
    Luke

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

    尊敬的 Luke:  

    同样的勘误表是否适用于 MSPM0G3106?  

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

    尊敬的 Jayakrishnan:

    同样的勘误表也适用。

    此致、
    Luke

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

    尊敬的 Luke:  

    如果我将 UART0 (PD0)更改为 UART3 (PD1)、则 UART3的 BUSCLK 指的 是 MCLK 而不是 ULPCLK。  

    因此、 如果 MCLK、CPUCLK 为80MHz 并使用 UART3 (PD1)、那么我将看不到从 DMA 到 UART3 TX 缺少的字节。   

    使用的其他 PD0外设包括 TIMG0 (用于周期性性能捕获)、WWDT0、FLASHCTL。   

    参考上述勘误表、是否可以在硬件中将 UART0更改为 UART3 (考虑到列出的其他 PD0外设)。  是否还有其他需要考虑的因素?  

    谢谢、此致  
    Jayakrishnan  

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

    尊敬的 Jayakrishnan:

    您可能在其他电源域中激活其他外设、问题是 DMA 和 CPU 访问时 PD0中的同一外设 当 MCLK > ULPCLK 时。

    在 PD1电源域中切换到 UART3是一种可接受的权变措施。

    此致、
    Luke

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

    尊敬的 Luke:  

    实际上、我们还尝试了保留 UART0并 将 TIMG0 (PD0)更改为 TIMG6 (PD1)。  此处的情形仍然类似于使用 ULPCLK 的 UART0、MCLK > ULPCLK。 通过此设置、我们还没有看到 DMA 到 UART0 TX 缺少数据包的问题。   
    根据勘误表说明-   示例:假设 DMA 访问 UART0寄存器、例如 DMA 向 TXDATA 写入数据、如果 CPU 在 DMA 操作期间也访问 PD0外设、例如 CPU 从 TIMG0 CTR 读取数据、则 DMA 或 CPU 可能会丢失数据。


    考虑到未来在使用 PD0外设的同一系统上运行范围、以下2个选项中的哪一个可能是更好的可接受的权变措施。  
    1.将 UART0更改为 UART3  

    2.将 TIMG0更改为 TIMG6  
     

    谢谢、此致
    Jayakrishnan

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

    尊敬的 Jayakrishnan:

    抱歉、我之前发布的文章、该勘误表适用于同一电源域上的不同外设。

    如果您将计时器转换为 PD1、那么您可以在 DMA 处理 PD0 UART 的情况下通过 CPU 访问它。 您还可以着手并设置 DMA 来处理所有 PD0外设(或 PD1)、从而保证 CPU 和 DMA 不会同时访问 PD0外设。

    我个人将由 DMA 处理通信数据、因为在不同应用中通常会对您接收到的数据进行一些处理、这将允许 CPU 在您进行有效通信的同时继续处理数据。

    此致、
    Luke

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

    尊敬的 Luke:  

    1."如果您将计时器转换为 PD1、则可以在 DMA 处理 PD0 UART 的情况下通过 CPU 访问计时器。 您还可以通过设置 DMA 来处理所有 PD0外设(或 PD1)、从而保证 CPU 和 DMA 不会同时访问 PD0外设。"

    所以在这种情况下,当 UART0与 DMA 一起使用,与 TIMG0一起使用时 , CPU 对 TIMG0的读取是导致错误的原因,所以这是像如果我们阻止 CPU 读取 TIMG0 ,替换为 PD1 TIMG6 ,那么我们是好的使用 DMA 与任何 PD0外设包括 UART0 ?  "只有 CPU 对 PD0外设的读取导致了冲突或者 CPU 写入是否有任何影响?"   

    这可能是一个工作中没有错误,但如果将来有 PD0 CPU 访问可能会出现潜在问题?


    2."我个人会让 DMA 处理通信数据、因为在不同应用中对您接收的数据进行一些处理是很常见的、这允许 CPU 在您进行有效通信的同时继续处理数据。"

    考虑到我们将带有 DMA 的 UART3用于主通信通道、那么我们可以访问任何其他 PD0外设、而不依赖于勘误表对吧?  


    谢谢、此致
    Jayakrishnan  

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

    尊敬的 Luke:  

    您能否确认、如果只有 CPU 在 MCLK > ULPCLK 时对 PD0外设进行读取访问、则 会出现错误情况、或者是否同时对 PD0外设进行并行 CPU 写入/CPU 读取访问而会导致问题。  

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

    尊敬的 Jayakrishnan:

    我来检查勘误表是否也会影响外设上的写入。

    此致、
    Luke