ocode_init.c 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. /*
  2. * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include <stdint.h>
  7. #include "soc/soc.h"
  8. #include "soc/rtc.h"
  9. #include "soc/regi2c_dig_reg.h"
  10. #include "soc/regi2c_lp_bias.h"
  11. #include "hal/efuse_hal.h"
  12. #include "hal/efuse_ll.h"
  13. #include "regi2c_ctrl.h"
  14. #include "esp_hw_log.h"
  15. static const char *TAG = "ocode_init";
  16. static void set_ocode_by_efuse(int ocode_scheme_ver)
  17. {
  18. assert(ocode_scheme_ver == 1);
  19. unsigned int ocode = efuse_ll_get_ocode();
  20. //set ext_ocode
  21. REGI2C_WRITE_MASK(I2C_ULP, I2C_ULP_EXT_CODE, ocode);
  22. REGI2C_WRITE_MASK(I2C_ULP, I2C_ULP_IR_FORCE_CODE, 1);
  23. }
  24. static void calibrate_ocode(void)
  25. {
  26. /*
  27. Bandgap output voltage is not precise when calibrate o-code by hardware sometimes, so need software o-code calibration (must turn off PLL).
  28. Method:
  29. 1. read current cpu config, save in old_config;
  30. 2. switch cpu to xtal because PLL will be closed when o-code calibration;
  31. 3. begin o-code calibration;
  32. 4. wait o-code calibration done flag(odone_flag & bg_odone_flag) or timeout;
  33. 5. set cpu to old-config.
  34. */
  35. soc_rtc_slow_clk_src_t slow_clk_src = rtc_clk_slow_src_get();
  36. rtc_cal_sel_t cal_clk = RTC_CAL_RTC_MUX;
  37. if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_OSC_SLOW) {
  38. cal_clk = RTC_CAL_32K_OSC_SLOW;
  39. } else if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) {
  40. cal_clk = RTC_CAL_32K_XTAL;
  41. }
  42. uint64_t max_delay_time_us = 10000;
  43. uint32_t slow_clk_period = rtc_clk_cal(cal_clk, 100);
  44. uint64_t max_delay_cycle = rtc_time_us_to_slowclk(max_delay_time_us, slow_clk_period);
  45. uint64_t cycle0 = rtc_time_get();
  46. uint64_t timeout_cycle = cycle0 + max_delay_cycle;
  47. uint64_t cycle1 = 0;
  48. rtc_cpu_freq_config_t old_config;
  49. rtc_clk_cpu_freq_get_config(&old_config);
  50. rtc_clk_cpu_freq_set_xtal();
  51. REGI2C_WRITE_MASK(I2C_ULP, I2C_ULP_IR_RESETB, 0);
  52. REGI2C_WRITE_MASK(I2C_ULP, I2C_ULP_IR_RESETB, 1);
  53. bool odone_flag = 0;
  54. bool bg_odone_flag = 0;
  55. while (1) {
  56. odone_flag = REGI2C_READ_MASK(I2C_ULP, I2C_ULP_O_DONE_FLAG);
  57. bg_odone_flag = REGI2C_READ_MASK(I2C_ULP, I2C_ULP_BG_O_DONE_FLAG);
  58. cycle1 = rtc_time_get();
  59. if (odone_flag && bg_odone_flag) {
  60. break;
  61. }
  62. if (cycle1 >= timeout_cycle) {
  63. ESP_HW_LOGW(TAG, "o_code calibration fail\n");
  64. break;
  65. }
  66. }
  67. rtc_clk_cpu_freq_set_config(&old_config);
  68. }
  69. void esp_ocode_calib_init(void)
  70. {
  71. if (efuse_hal_blk_version() >= 1) {
  72. set_ocode_by_efuse(1);
  73. } else {
  74. calibrate_ocode();
  75. }
  76. }