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.

[参考译文] MSPM0L2228:MSPM0L2228 LPM 退出问题

Guru**** 2885250 points

Other Parts Discussed in Thread: MSPM0L2228

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1640398/mspm0l2228-mspm0l2228-lpm-exit-issue

器件型号: MSPM0L2228

我开发了基于 MSPM0L2228 的燃气流量计、并实现了 LPM 模式。 完成任务后、我们进入 LPM。 每当有中断、我们计划退出 LPM。 我们可以看到、带中断的 OUT 进入和 LPM 退出工作正常。 但在 LPM 退出后、主循环不执行。  我有 UART 上拉,I2C 接口启用和禁用,但仍然面临的问题,没有线索如何解决它.

void LOW_POWER_MODE_ENABLE (void){
 // print_string (unsigned char *)“\r\nLOW POWER MODE“、
 //        strlen(“\r\nLOW POWER MODE“)、DEBUG_COM);
 LOW_POWER_MODE = true;
 adc_disable();
 CAP_TEMPERATURE_COUNT = 0;

 DL_UART_DISABLE (BLE_UART_INST);
 DL_UART_DISABLE (NBIOT_UART_INST);
 DL_UART_DISABLE (CONSOLE_UART_INST);
 DL_I2C_disableController (I2C_INST);
 DL_SYSCTL_setPowerPolicyRUN2SLEEP2();
 __ WFI ();
}

void LOW_POWER_MODE_DISABLE (void){
 if (LOW_POWER_MODE){
  DL_SYSCTL_setPowerPolicyRUN0SLEEP0 ();
  DL_UART_ENABLE (BLE_UART_INST);
  DL_UART_ENABLE (NBIOT_UART_INST);
  DL_UART_ENABLE (CONSOLE_UART_INST);
  DL_I2C_enableController (I2C_INST);

  LOW_POWER_MODE = false;
  print_string (unsigned char *)“\r\nLOW POWER MODE EXIT“、
         strlen(“\r\nLOW POWER MODE EXIT“)、DEBUG_COM);
 }
}

ti_msp_dl_config.h ti_msp_dl_config.c  

此致

Nandish  

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

    您好、Nandish、

    您能展示主循环器件的代码吗? 我想知道您使用的主环路器件逻辑。 请注意、如果您希望 M0 在唤醒后不会返回 LPM、我们建议您在主代码中添加以下 API

    DL_SYSCTL_disableSleepOnExit();
    此致、  
    Janz Bai
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    int main(void){

     SYSCFG_DL_init();
     SYSCFG_DL_RTC_A_init();

     NVIC_ClearPendingIRQ(CONSOLE_UART_INST_INT_IRQN);
     NVIC_EnableIRQ(CONSOLE_UART_INST_INT_IRQN);

     NVIC_ClearPendingIRQ(NBIOT_UART_INST_INT_IRQN);
     NVIC_EnableIRQ(NBIOT_UART_INST_INT_IRQN);

     NVIC_ClearPendingIRQ(BLE_UART_INST_INT_IRQN);
     NVIC_EnableIRQ(BLE_UART_INST_INT_IRQN);

     NVIC_ClearPendingIRQ(EXT_IN_GPIOA_INT_IIDX);
     NVIC_EnableIRQ(EXT_IN_GPIOA_INT_IIDX);

     NVIC_ClearPendingIRQ(EXT_IN_GPIOB_INT_IIDX);
     NVIC_EnableIRQ(EXT_IN_GPIOB_INT_IIDX);

     NVIC_ClearPendingIRQ(EXT_IN_GPIOC_INT_IIDX);
     NVIC_EnableIRQ(EXT_IN_GPIOC_INT_IIDX);

     DL_RTC_A_enableClockControl(RTC_A);
     NVIC_EnableIRQ(RTC_A_INT_IRQn);

     NVIC_ClearPendingIRQ(I2C_INST_INT_IRQN);
     NVIC_EnableIRQ(I2C_INST_INT_IRQN);

     NVIC_EnableIRQ(SUPPLY_SOH ADC_INST_INT_IRQN);
     DL_ADC12_startConversion(SUPPLY_SOH ADC_INST);

     DL_GPIO_setPins(EXT_OUT_EEPROM_LOAD_SW_PORT、
             EXT_OUT_EEPROM_LOAD_SW_PIN); // EEPROM_LOAD_SW 引脚启用

     memset(print_data、 '\0'256);
     sprint f((char *) print_data、
         “\r\n/****Capital InnoTech 燃气表***** /\nFIRMWARE版本 %s“
         “\n 完成时间 %s“
         device_firmware_version、build_time);

     print_string(unsigned char *) print_data、 strlen(char *) print_data)、
            DEBUG_COM);
     memset(print_data、 '\0'256);
     sprintf((char *) print_data、 “\r\n/****MCU 已重新启动且原因为 %d****\n“
         DL_SYSCTL_getResetCause();
     print_string(unsigned char *) print_data、 strlen(char *) print_data)、
            DEBUG_COM);
     memset(print_data、 '\0'256);

     rio_flash_time_read();

     lcd_backlight_off; /**<最初关闭 LCD 背光*/

     rio_flash_read(&tamp_data、 gNextRecords Address_Tamperflag
             sizeof(tamp_data));
     print_tamp_data(&tamp_data);

     rio_flash_read(&rio_default_app_config_data、 gNextRecords Address_App
             sizeof(Rio_default_app_config_data);
     PRINT_RIO_DEFAULT_APP_CONFIG_DATA(&RIO_DEFAULT_APP_CONFIG_DATA);
     while (1){   
     print_string(unsigned char *)“\r\nmainloop“
             strlen(“\r\n 主循环“)
             DEBUG_COM);  DELAY_CYCLES (32000000);}
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Nandish、

    在您分享的过程中、您在 API low_power_mode_enable 中调用了“WFI ()“、但我 在主循环中找不到您调用 low_power_mode_enable 的位置。 “WFI ()“用于让 MCU 进入低功耗模式。 CPU 将在 WFI () 处停止并等待中断唤醒。 当中断发生时、MCU 完成对中断的处理后、MCU 将继续运行以下代码“WFI ()“。 这是进入和存在 LPM 的逻辑。 请 先添加 DL_SYSCTL_disableSleepOnExit (),然后检查您的主循环逻辑。  

    BR、

    Janz Bai

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

    你(们)好  

    uint8_t sl_count = 0
    int main(void){

     SYSCFG_DL_init();
     SYSCFG_DL_RTC_A_init();

     NVIC_ClearPendingIRQ(CONSOLE_UART_INST_INT_IRQN);
     NVIC_EnableIRQ(CONSOLE_UART_INST_INT_IRQN);

     NVIC_ClearPendingIRQ(NBIOT_UART_INST_INT_IRQN);
     NVIC_EnableIRQ(NBIOT_UART_INST_INT_IRQN);

     NVIC_ClearPendingIRQ(BLE_UART_INST_INT_IRQN);
     NVIC_EnableIRQ(BLE_UART_INST_INT_IRQN);

     NVIC_ClearPendingIRQ(EXT_IN_GPIOA_INT_IIDX);
     NVIC_EnableIRQ(EXT_IN_GPIOA_INT_IIDX);

     NVIC_ClearPendingIRQ(EXT_IN_GPIOB_INT_IIDX);
     NVIC_EnableIRQ(EXT_IN_GPIOB_INT_IIDX);

     NVIC_ClearPendingIRQ(EXT_IN_GPIOC_INT_IIDX);
     NVIC_EnableIRQ(EXT_IN_GPIOC_INT_IIDX);

     DL_RTC_A_enableClockControl(RTC_A);
     NVIC_EnableIRQ(RTC_A_INT_IRQn);

     NVIC_ClearPendingIRQ(I2C_INST_INT_IRQN);
     NVIC_EnableIRQ(I2C_INST_INT_IRQN);

     NVIC_EnableIRQ(SUPPLY_SOH ADC_INST_INT_IRQN);
     DL_ADC12_startConversion(SUPPLY_SOH ADC_INST);

     DL_GPIO_setPins(EXT_OUT_EEPROM_LOAD_SW_PORT、
             EXT_OUT_EEPROM_LOAD_SW_PIN); // EEPROM_LOAD_SW 引脚启用

     memset(print_data、 '\0'256);
     sprint f((char *) print_data、
         “\r\n/****米***** /\nFIRMWARE版本 %s“
         “\n 完成时间 %s“
         device_firmware_version、build_time);

     print_string(unsigned char *) print_data、 strlen(char *) print_data)、
            DEBUG_COM);
     memset(print_data、 '\0'256);
     sprintf((char *) print_data、 “\r\n/****MCU 已重新启动且原因为 %d****\n“
         DL_SYSCTL_getResetCause();
     print_string(unsigned char *) print_data、 strlen(char *) print_data)、
            DEBUG_COM);
     memset(print_data、 '\0'256);

     DL_SYSCTL_disableSleepOnExit();
     while (1){
      SL_COUNT++;

      print_string(unsigned char *)“\r\n 主循环“strlen(“\r\n 主循环“)
             DEBUG_COM);

      if (!LOW_POWER_MODE)
       screen_change() /**<处理屏幕更改*/

      if (sl_count >= 10){
       sl_COUNT = 0
       LOW_POWER_MODE_ENABLE(); /**<启用低功耗模式*/
      }
      delay_cycles(32000000);
     }
    }  
    //这是我退出 LPM 的中断   
    if (pending_interrupt_ext_inb == EXT_IN_touch_2_IIDX){
      low_power_mode_disable()
      print_string(unsigned char *)“\r\n/****interrupt***/“
             strlen(“\r\n/**interrupt***/“)、debug_com);
      DL_GPIO_clearInterruptStatus(GPIOB、EXT_IN_Touch_2_PIN);
     }   
    我添加了 sleepon_exit、但仍然没有仅主循环中断  
    此致
    Nandish  
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Janz、

    我已经尝试了很多种调试方法、但我没有看到在我的工程中使用 WFI 之后执行的代码。 在初始开发过程中、我们遇到了类似的问题、当时我们观察到启用 UART 导致了 LPM 退出问题、后来我得到了在 UART 引脚上启用上拉的指令、它当时有效、但现在我们正处于最终开发阶段、再次面临该问题  

    BR、

    Nandish  

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

    您好、Nandish、

    根据您当前的共享代码、CPU 将在此处停止以等待中断

    然后、在中断发生且 CPU 完成处理后、CPU 将在“while (1) 循环“中继续运行。 等待下一个中断

    我不知道您在哪里添加以下代码

    您说中断可以正常进入并正常退出、只是主循环无法正常运行。 那么、您是否曾尝试过在调试模式下、看看从 LPM 退出后 CPU 将停止的位置? 我的意思是、您可以在从 LPM 唤醒后应运行的代码行设置一个断点、并在调试模式下查看它是否可以运行这个点、如果不可以、CPU 的运行位置。  

    您是否设置了高频率的中断? 例如、设置计时器中断或 RTC 中断、其高频将永远触发中断。 这将导致 CPU 没有时间处理主循环代码。

    我认为、如果您可以逐步简化代码、然后逐步添加函数、进行测试、确认可能的原因、我认为这也是一种更好的方法

    BR。

    Janz Bai

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

    尊敬的 Janz:

     

    __ WFI ();    
    print_string(unsigned char *)“\r\nLOWPOWER MODE“、  
            strlen(“\r\nLOWPOWER MODE“)、DEBUG_COM); 尝试使用断点调试代码、中断后没有发现断点命中。  
    注意:我们可以在公共论坛上发布我们的产品代码。 我为我们的运行提供了完整的代码逻辑。
    此致
    Nandish  
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Janz:  

    调试后、我们发现我们的代码滞留在 RUN2SLeep2 函数、   DL_SYSCTL_setMCLKSource(SYSOSC、LFCLK、(boolTRUE);  和时钟验证中  

      while ((DL_SYSCTL_getClockStatus()& SYSCTL_CLKSTATUS_CURMCLKSEL_MASK)!=
          DL_SYSCTL_CLK_STATUS_MCLK_SOURCE_LFCLK){
        ;
      }
    它没有从这里出来。

    void DL_SYSCTL_switchMCLKfromtoLFCLK(bool disableSYSOSC)
      if (disableSYSOSC == false){
        //如果保持启用状态、则将 SYSOSC 设置回基础频率
        DL_SYSCTL_setSYSOSCFreq(DL_SYSCTL_SYSOSC_FREQ_BASE);
        SysCtl->SOCLOCK.SYSOSCCFG &=~SysCtl_SYSOSCCFG_DISABLE_ENABLE;
      } 其他 {
        SysCtl->SOCLOCK.SYSOSCCFG |= SYSCTL_SYSOSCCFG_DISABLE_ENABLE;
      }
      SysCtl->SOCLOCK.MCLKCFG || SYSCTL_MCLKCFG.USELFCLK_IN;

      //验证 LFCLK -> MCLK
      while ((DL_SYSCTL_getClockStatus()& SYSCTL_CLKSTATUS_CURMCLKSEL_MASK)!=
          DL_SYSCTL_CLK_STATUS_MCLK_SOURCE_LFCLK){
        ;
      }
    }
    _static_inline void DL_SYSCTL_setPowerPolicyRUN2SLEEP2(void)
      DL_SYSCTL_setMCLKSource(SYSOSC、LFCLK、(bool) true);
      SCB->SCR &=~(SCB_SCR_SLEEPDEEP_MSK);
    }  
    此致
    Nandish