1 #ifdef SLI_SI91X_MCU_ENABLE_IPMU_APIS
2 /******************************************************************************
3 * @file ipmu_apis.c
4 *******************************************************************************
5 * # License
6 * <b>Copyright 2024 Silicon Laboratories Inc. www.silabs.com</b>
7 *******************************************************************************
8 *
9 * SPDX-License-Identifier: Zlib
10 *
11 * The licensor of this software is Silicon Laboratories Inc.
12 *
13 * This software is provided 'as-is', without any express or implied
14 * warranty. In no event will the authors be held liable for any damages
15 * arising from the use of this software.
16 *
17 * Permission is granted to anyone to use this software for any purpose,
18 * including commercial applications, and to alter it and redistribute it
19 * freely, subject to the following restrictions:
20 *
21 * 1. The origin of this software must not be misrepresented; you must not
22 * claim that you wrote the original software. If you use this software
23 * in a product, an acknowledgment in the product documentation would be
24 * appreciated but is not required.
25 * 2. Altered source versions must be plainly marked as such, and must not be
26 * misrepresented as being the original software.
27 * 3. This notice may not be removed or altered from any source distribution.
28 *
29 ******************************************************************************/
30 #ifdef SLI_SI91X_MCU_INTERFACE
31 #include <stdint.h>
32 #include "rsi_ipmu.h"
33 #include "rsi_system_config.h"
34 #define IPMU_DOTC_PROG
35 #define IPMU_CALIB_DATA
36 typedef uint16_t uint16;
37 typedef uint32_t uint32;
38 typedef int32_t int32;
39 typedef uint8_t uint8;
40 #define cmemcpy memcpy
41 #endif
42 #ifndef SLI_SI91X_MCU_INTERFACE
43 #include "data_types.h"
44 #include "defines.h"
45 #include "pm.h"
46 #include "soc_intf.h"
47 #include "lib_intf.h"
48 #include "gpio.h"
49 #include "timer.h"
50 #include "semaphore.h"
51 #include "error_code.h"
52 #include "common_intf.h"
53 #include "sleep_state.h"
54 #include "pll.h"
55 #include "pmu.h"
56 #include "misc_config.h"
57 #include "intr.h"
58 #include "bb_rf_prog_intf.h"
59 #include "bb_rf_prog.h"
60 #include "wlan_coex_intf.h"
61 #include "dev_ps.h"
62 #include "common_lmac.h"
63 #include "dbg.h"
64 #include "soft_timer.h"
65 #include "bb_rf_prog.h"
66 #include "dma.h"
67 #include "dynamic_clock.h"
68 #include "structures.h"
69 #include "ps.h"
70 #include "spi.h"
71 #include "hwrng.h"
72 #include "fmc.h"
73 #ifdef CHIP_9118
74 #include "pwr_ctrl.h"
75 #endif
76 #include "rsi_global_non_rom.h"
77 #include "obe_low_pwr.h"
78 #include "common_ram.h"
79 #include "bb_rf_prog_ram.h"
80 #include "soc_address_map.h"
81 #include "ipmu_defines.h"
82 #include "no_host_intf.h" /* BT_DEV_MODE */
83 #include "bt/bt.h"
84 #include "bt/bt_common.h"
85 #include "wakefi.h"
86 #include "cortex_m4.h"
87 #include "bb_rf_calib.h"
88 #include "wrappers_common.h"
89 #endif
90 void program_ipmu_data(const uint32_t *src);
91 #ifndef BT_LE_ONLY_MODE
92 #ifdef SLI_SI91X_MCU_INTERFACE
93 void ipmu_init_mcu(void);
94 #else
95 void ipmu_init_mcu(void) __attribute__((section(".common_non_tcm_code")));
96 #endif
97 void set_scdc(uint32 Deepsleep);
ipmu_init_mcu(void)98 void ipmu_init_mcu(void)
99 {
100 #ifdef IPMU_DOTC_PROG
101 program_ipmu_data(ipmu_common_config); //IPMU1
102 program_ipmu_data(pmu_common_config); //PMU1
103 #ifndef SLI_SI91X_MCU_INTERFACE
104 if (HF_RC_CLK_MODE == 0) {
105 program_ipmu_data(m20rc_osc_trim_efuse); //M20RC_EFUSE
106 } else if (HF_RC_CLK_MODE == 1) {
107 program_ipmu_data(m32rc_osc_trim_efuse); //M32RC_EFUSE
108 }
109 program_ipmu_data(dblr_32m_trim_efuse); //DBLR_EFUSE
110 program_ipmu_data(m20ro_osc_trim_efuse); //M20RO_EFUSE
111 program_ipmu_data(ro_32khz_trim_efuse); //RO32K_EFUSE
112 if (RC_CLK_MODE == 0) {
113 program_ipmu_data(rc_16khz_trim_efuse); //RC16K_EFUSE
114 } else if (RC_CLK_MODE == 1) {
115 program_ipmu_data(rc_32khz_trim_efuse); //RC32K_EFUSE
116 } else if (RC_CLK_MODE == 2) {
117 program_ipmu_data(rc_64khz_trim_efuse); //RC64K_EFUSE
118 }
119 #endif
120 #ifdef SLI_SI91X_MCU_INTERFACE
121 if (HF_RC_CLK_MODE == 0) {
122 /* program the trim value for 20Mhz RC oscillator */
123 RSI_IPMU_M20rcOsc_TrimEfuse(); //M20RC_EFUSE
124 } else if (HF_RC_CLK_MODE == 1) {
125 /* program the trim value for 32Mhz RC oscillator */
126 RSI_IPMU_M32rc_OscTrimEfuse(); //M32RC_EFUSE
127 }
128 /* program the trim value for RC 32MHz doubler */
129 RSI_IPMU_DBLR32M_TrimEfuse(); //DBLR_EFUSE
130 /* program the trim value for 20MHz RC oscillator */
131 RSI_IPMU_M20roOsc_TrimEfuse(); //M20RO_EFUSE
132 /* program the trim value for 32KHZ RO oscillator */
133 RSI_IPMU_RO32khz_TrimEfuse(); //RO32K_EFUSE
134 if (RC_CLK_MODE == 0) {
135 /* program the trim value for 16KHz RC oscillator */
136 RSI_IPMU_RC16khz_TrimEfuse(); //RC16K_EFUSE
137 } else if (RC_CLK_MODE == 1) {
138 /* program the trim value for 32KHz RC oscillator */
139 RSI_IPMU_RC32khz_TrimEfuse(); //RC32K_EFUSE
140 } else if (RC_CLK_MODE == 2) {
141 /* program the trim value for 64KHz RC oscillator */
142 RSI_IPMU_RC64khz_TrimEfuse(); //RC64K_EFUSE
143 }
144 #endif
145 program_ipmu_data(vbatt_status_trim_efuse); //VBATT_MON_EFUSE
146 #ifndef SLI_SI91X_MCU_INTERFACE
147 program_ipmu_data(ro_ts_efuse); //RO_TS_EFUSE
148 program_ipmu_data(vbg_tsbjt_efuse); //VBG_TS_EFUSE
149 program_ipmu_data(auxadc_off_diff_efuse); //AUXADC_DIFFOFF_EFUSE
150 program_ipmu_data(auxadc_gain_diff_efuse); //AUXADC_DIFFGAIN_EFUSE
151 program_ipmu_data(auxadc_off_se_efuse); //AUXADC_SEOFF_EFUSE
152 program_ipmu_data(auxadc_gain_se_efuse); //AUXADC_SEGAIN_EFUSE
153 #endif
154 program_ipmu_data(bg_trim_efuse); //bg_trim_efuse
155 program_ipmu_data(blackout_trim_efuse); //blackout_trim_efuse
156 program_ipmu_data(poc_bias_efuse); //poc_bias_efuse
157 program_ipmu_data(buck_trim_efuse);
158 program_ipmu_data(ldosoc_trim_efuse);
159 program_ipmu_data(dpwm_freq_trim_efuse);
160 program_ipmu_data(delvbe_tsbjt_efuse);
161 program_ipmu_data(xtal1_bias_efuse);
162 #ifdef SLI_SI91X_MCU_INTERFACE
163 program_ipmu_data(xtal2_bias_efuse);
164 #endif
165 #ifdef V1P20_IPMU_CHANGES
166 //http://192.168.1.215:8090/display/RS9116/Release+V1.19+Porting+Guide
167 //Retention-LDO Configuration
168 program_ipmu_data(retn_ldo_lpmode); //RETN1
169 program_ipmu_data(retnLP_volt_trim_efuse); //RETNLP_TRIM_EFUSE
170 #ifdef SCDC_EXTCAP_MODE
171 program_ipmu_data(lp_scdc_extcapmode); //SCDC1
172 #endif
173 #endif
174 #endif
175 }
176 #endif
177
178 #ifdef IPMU_CALIB_DATA
179 /**
180 * @brief This function reads, modifies & writes to the iPMU registers based on different PMU SPI register type
181 * @param void
182 * @return void
183 */
update_ipmu_data(uint32_t reg_addr,uint32_t reg_type,uint32_t data,uint32_t mask)184 void update_ipmu_data(uint32_t reg_addr, uint32_t reg_type, uint32_t data, uint32_t mask)
185 {
186 uint32_t value = 0;
187
188 if (reg_type == ULP_SPI) {
189 value = PMU_DIRECT_ACCESS(reg_addr);
190 } else if (reg_type == PMU_SPI) {
191 value = PMU_SPI_DIRECT_ACCESS(reg_addr);
192 } else if (reg_type == DIRECT) {
193 value = *(volatile uint32_t *)(reg_addr);
194 }
195 value &= ~mask;
196 value |= data;
197 if (reg_type == ULP_SPI) {
198 PMU_DIRECT_ACCESS(reg_addr) = value;
199 } else if (reg_type == PMU_SPI) {
200 PMU_SPI_DIRECT_ACCESS(reg_addr) = value;
201 } else if (reg_type == DIRECT) {
202 *(volatile uint32_t *)(reg_addr) = value;
203 }
204 }
205 uint16 scdc_active;
206 uint16 scdc_sleep;
207 /**
208 * @brief This function prepares the data from the ipmu calib structure content and writes to each specific register
209 * @param void
210 * @return void
211 */
212 void update_ipmu_calib_data(const efuse_ipmu_t *ipmu_calib_data) __attribute__((section(".common_tcm_code")));
update_ipmu_calib_data(const efuse_ipmu_t * ipmu_calib_data)213 void update_ipmu_calib_data(const efuse_ipmu_t *ipmu_calib_data)
214 {
215 uint32_t data;
216 uint32_t mask;
217 uint32 calibratedtrim_scdc;
218 uint32 calibratedtrim;
219 #ifndef SLI_SI91X_MCU_INTERFACE
220 common_info_ext_t *glbl_common_info_ext_p = (common_info_ext_t *)glbl_common_info.reserved_ptr;
221 #endif
222 //ROW 4,5,6
223 #ifdef SLI_SI91X_MCU_INTERFACE
224 data = (ipmu_calib_data->trim_0p5na1 << 18);
225 mask = MASK_BITS(1, 18);
226 #else
227 data = (0 << 18) | (ipmu_calib_data->resbank_trim << 10);
228 mask = MASK_BITS(1, 18) | MASK_BITS(2, 10);
229 #endif
230 update_ipmu_data(iPMU_SPARE_REG1_OFFSET, ULP_SPI, data, mask);
231
232 //ROW 5
233 data = (ipmu_calib_data->bg_r_ptat_vdd_ulp << 19);
234 mask = MASK_BITS(3, 19);
235 if (ipmu_calib_data->set_vref1p3 == 0) {
236 data |= (2 << 10) | (2 << 7);
237 } else {
238 data |= (uint32_t)(ipmu_calib_data->scdc_dcdc_trim << 10) | (ipmu_calib_data->scdc_hpldo_trim << 7);
239 }
240 mask |= MASK_BITS(3, 10) | MASK_BITS(3, 7);
241 update_ipmu_data(BG_SCDC_PROG_REG_1_OFFSET, ULP_SPI, data, mask);
242
243 scdc_active = (uint16)data;
244
245 calibratedtrim = ((data >> 7) & 7);
246 calibratedtrim_scdc = ((data >> 10) & 7);
247 #ifdef DEEPSLEEP_SCDC_0P95
248 if (calibratedtrim_scdc < 4) {
249 calibratedtrim_scdc = calibratedtrim_scdc + 2;
250 } else if (calibratedtrim_scdc == 4) {
251 calibratedtrim_scdc = calibratedtrim_scdc + 1;
252 }
253 if (calibratedtrim == 0) {
254 calibratedtrim = calibratedtrim + 3;
255 } else if (calibratedtrim == 1) {
256 calibratedtrim = calibratedtrim + 1;
257 } else if ((calibratedtrim == 2) || (calibratedtrim == 3)) {
258 calibratedtrim = calibratedtrim + 2;
259 } else if (calibratedtrim == 4) {
260 calibratedtrim = calibratedtrim + 1;
261 }
262 #else
263 if (calibratedtrim_scdc < 5) {
264 calibratedtrim_scdc = calibratedtrim_scdc + 1;
265 }
266 if (calibratedtrim == 0) {
267 calibratedtrim = calibratedtrim + 2;
268 } else if (calibratedtrim == 1) {
269 calibratedtrim = calibratedtrim - 1;
270 } else if ((calibratedtrim == 2) || (calibratedtrim == 3) || (calibratedtrim == 4)) {
271 calibratedtrim = calibratedtrim + 1;
272 }
273 #endif
274 scdc_sleep = (uint16)((calibratedtrim << 7) | (calibratedtrim_scdc << 10));
275 //ROW 2
276 data = ipmu_calib_data->bg_r_vdd_ulp;
277 mask = MASK_BITS(5, 0);
278 update_ipmu_data(BG_BLACKOUT_REG_OFFSET, ULP_SPI, data, mask);
279
280 //ROW 7,17
281 update_ipmu_data(ULPCLKS_MRC_CLK_REG_OFFSET, ULP_SPI, (ipmu_calib_data->trim_sel << 14), MASK_BITS(7, 14));
282
283 //ROW 9
284 update_ipmu_data(ULPCLKS_DOUBLER_XTAL_REG_OFFSET, ULP_SPI, (ipmu_calib_data->del_2x_sel << 15), MASK_BITS(6, 15));
285
286 //ROW 10
287 update_ipmu_data(ULPCLKS_32KRO_CLK_REG_OFFSET,
288 ULP_SPI,
289 (ipmu_calib_data->ro_32khz_00_trim << 16),
290 MASK_BITS(5, 16)); //rahul
291
292 //ROW 11
293 if (RC_CLK_MODE == 0) {
294 data = (ipmu_calib_data->fine_trim_16k << 14);
295 } else if (RC_CLK_MODE == 1) {
296 data = (ipmu_calib_data->fine_trim_32k << 14);
297 } else if (RC_CLK_MODE == 2) {
298 data = (ipmu_calib_data->fine_trim_64k << 14);
299 }
300 mask = MASK_BITS(7, 14);
301 update_ipmu_data(ULPCLKS_32KRC_CLK_REG_OFFSET, ULP_SPI, data, mask);
302
303 //ROW 12
304 if (XTAL_SEL == 1) {
305 data = ipmu_calib_data->xtal1_trim_32k << 13;
306 } else if (XTAL_SEL == 2) {
307 data = ipmu_calib_data->xtal2_trim_32k << 13;
308 }
309 update_ipmu_data(ULPCLKS_32KXTAL_CLK_REG_OFFSET, ULP_SPI, data, MASK_BITS(4, 13));
310
311 //ROW 13
312 update_ipmu_data(ULPCLKS_HF_RO_CLK_REG_OFFSET, ULP_SPI, (ipmu_calib_data->trim_ring_osc << 14), MASK_BITS(7, 14));
313
314 //ROW 16
315 data = (ipmu_calib_data->f2_nominal);
316 mask = MASK_BITS(10, 0);
317 update_ipmu_data((TEMP_SENSOR_BASE_ADDRESS + TS_NOMINAL_SETTINGS_OFFSET), DIRECT, data, mask);
318
319 //ROW 18
320 data = *(volatile uint32_t *)(ULP_TASS_MISC_CONFIG_REG + 0x34);
321 //! For AUX_LDO register access, need to enable ulp_aux_clock
322 *(volatile uint32_t *)(ULP_TASS_MISC_CONFIG_REG + 0x34) = 0x1;
323 update_ipmu_data((AUX_BASE_ADDR + 0x210), DIRECT, ipmu_calib_data->ldo_ctrl, MASK_BITS(4, 0));
324 //! restore the reg
325 *(volatile uint32_t *)(ULP_TASS_MISC_CONFIG_REG + 0x34) = data;
326
327 //ROW 34
328 if (ipmu_calib_data->set_vref1p3 == 0) {
329 data = (0xC << 17);
330 } else {
331 data = (ipmu_calib_data->set_vref1p3 << 17);
332 }
333 mask = MASK_BITS(4, 17);
334 update_ipmu_data(PMU_1P3_CTRL_REG_OFFSET, PMU_SPI, data, mask);
335
336 //ROW 38
337 data = ipmu_calib_data->trim_r1_resistorladder;
338 mask = MASK_BITS(4, 0);
339 update_ipmu_data(SPARE_REG_3_OFFSET, PMU_SPI, data, mask);
340
341 //ROW 48
342 data = (ipmu_calib_data->dpwm_freq_trim) << 13;
343 mask = MASK_BITS(4, 13);
344 update_ipmu_data(PMU_ADC_REG_OFFSET, PMU_SPI, data, mask);
345
346 #ifdef V1P20_IPMU_CHANGES
347 if (ipmu_calib_data->set_vref1p3 == 0) {
348 data = (0x2 << 18);
349 } else {
350 data = ((ipmu_calib_data->retn_ldo_lptrim) << 18);
351 }
352 mask = MASK_BITS(3, 18);
353 update_ipmu_data(BG_LDO_REG_OFFSET, ULP_SPI, data, mask);
354 #endif
355 #ifndef SLI_SI91X_MCU_INTERFACE
356 glbl_common_info_ext_p->eeprom_calib_values.vbatt_status_trim_efuse = ipmu_calib_data->vbatt_status_1;
357 #endif
358 }
359 /**
360 * @brief This API is used to reduce or increase the SCDC voltage by 1 value
361 * @param Deepsleep : provide '1' before going to sleep.(i.e.Reduce the SCDC voltage by one value)
362 * provide '0' after wake up.(i.e.Set the SCDC voltage to the actual value)
363 * @return void
364 */
set_scdc(uint32 Deepsleep)365 void set_scdc(uint32 Deepsleep)
366 {
367 uint32 mask;
368
369 mask = MASK_BITS(3, 10) | MASK_BITS(3, 7);
370 update_ipmu_data(BG_SCDC_PROG_REG_1_OFFSET, ULP_SPI, Deepsleep ? scdc_sleep : scdc_active, mask);
371 }
372 /**
373 * @brief This function checks for magic byte in efuse/flash, copies the content if valid data present and calls to update the ipmu registers
374 * @param void
375 * @return void
376 */
init_ipmu_calib_data(uint32_t m4_present)377 uint32_t init_ipmu_calib_data(uint32_t m4_present)
378 {
379 (void)m4_present;
380 efuse_ipmu_t ipmu_calib_data;
381 efuse_ipmu_t *ipmu_calib_data_p;
382 #ifndef SLI_SI91X_MCU_INTERFACE
383 common_info_ext_t *glbl_common_info_ext_p;
384 #endif
385 ipmu_calib_data_p = &ipmu_calib_data;
386 #ifndef SLI_SI91X_MCU_INTERFACE
387 common_info_t *glbl_common_info_p = &glbl_common_info;
388 glbl_common_info_ext_p = (common_info_ext_t *)glbl_common_info_p->reserved_ptr;
389
390 if ((*(uint8 *)(MANF_DATA_BASE_ADDR + BASE_OFFSET_BB_RF_IN_FLASH)) != MAGIC_WORD) {
391 //NO CALIB DATA. Return
392 return 1;
393 }
394 #endif
395 if (*(uint8 *)(MANF_DATA_BASE_ADDR + IPMU_VALUES_OFFSET) == 0x00) {
396 // NO CALIB DATA. Return
397 return 1;
398 }
399 if (*(uint8 *)(MANF_DATA_BASE_ADDR + IPMU_VALUES_OFFSET) == 0xFF) {
400 // NO CALIB DATA. Return
401 return 1;
402 }
403 memcpy(ipmu_calib_data_p, (efuse_ipmu_t *)(MANF_DATA_BASE_ADDR + IPMU_VALUES_OFFSET), sizeof(efuse_ipmu_t));
404 #ifndef SLI_SI91X_MCU_INTERFACE
405 glbl_common_info_ext_p->auxadc_offset_single = ipmu_calib_data_p->auxadc_offset_single;
406 glbl_common_info_ext_p->vbg_tsbjt_efuse = ipmu_calib_data_p->vbg_tsbjt_efuse;
407 glbl_common_info_ext_p->str_bjt_temp_sense_off = ipmu_calib_data_p->str_bjt_temp_sense_off;
408 if (m4_present == 0) {
409 #endif
410 //Dummy read
411 PMU_SPI_DIRECT_ACCESS(PMU_PFM_REG_OFFSET);
412
413 update_ipmu_calib_data(ipmu_calib_data_p);
414 #ifdef SLI_SI91X_MCU_INTERFACE
415 RSI_IPMU_UpdateIpmuCalibData_efuse(ipmu_calib_data_p);
416 #endif
417 //Dummy read
418 PMU_SPI_DIRECT_ACCESS(PMU_PFM_REG_OFFSET);
419 #ifndef SLI_SI91X_MCU_INTERFACE
420 }
421 #endif
422 #ifndef SLI_SI91X_MCU_INTERFACE
423 //ROW 38
424 update_ipmu_data((NWP_AHB_ADDR + 0x604), DIRECT, (ipmu_calib_data_p->scale_soc_ldo_vref << 31), MASK_BITS(1, 31));
425 #endif
426 return 0;
427 }
428 #endif
429 #ifdef IPMU_DOTC_PROG
430 #ifdef SLI_SI91X_MCU_INTERFACE
431 void program_ipmu_data(const uint32_t *src);
432 #else
433 void program_ipmu_data(const uint32_t *src) __attribute__((section(".common_non_tcm_code")));
434 #endif
program_ipmu_data(const uint32_t * src)435 void program_ipmu_data(const uint32_t *src)
436 {
437 uint32_t write_data;
438 uint32_t num_of_reg;
439 uint32_t mask = 0;
440 uint32_t read_data;
441 uint32_t addr;
442 uint32_t ls_shift;
443 uint32_t ms_shift;
444 uint32_t mask_bits;
445 uint32_t inx = 0;
446 num_of_reg = src[inx];
447 inx++;
448
449 //Dummy Read
450 PMU_SPI_DIRECT_ACCESS(PMU_PFM_REG_OFFSET);
451
452 while (num_of_reg--) {
453 addr = src[inx];
454 //! 32bit Write data [31:27] ms shift and [26:22] ls shift and [21:0] data
455 write_data = src[inx + 1];
456 //! extracting bit positions in which the data should be updated
457 ls_shift = (write_data >> LS_SHIFT) & 0x1F;
458 ms_shift = (write_data >> MS_SHIFT) & 0x1F;
459 //! Extracting 21-bit data from the structure
460 write_data = write_data & IPMU_DATAMASK;
461 read_data = *(uint32_t *)addr;
462 //! no of bits be updated
463 mask_bits = ms_shift - ls_shift + 1;
464 //! creating mask for the no of bits to be updated
465 while (mask_bits--) {
466 mask |= BIT(mask_bits);
467 }
468 //! resetting the bits in the read_data to update the data and writing the data to it
469 read_data &= ~(mask << ls_shift);
470 read_data |= (write_data & mask) << ls_shift;
471 *(uint32_t *)addr = read_data;
472 inx += 2;
473 mask = 0;
474 }
475 }
476 #endif
477 #ifdef SLI_SI91X_MCU_INTERFACE
478 void shut_down_non_wireless_mode_pds(void);
479 #else
480 // Power Domain Controls
481 void shut_down_non_wireless_mode_pds(void) __attribute__((section(".common_non_tcm_code")));
482 #endif
shut_down_non_wireless_mode_pds(void)483 void shut_down_non_wireless_mode_pds(void)
484 {
485 uint32_t reg_val = 0;
486 // WuRX
487 PMU_DIRECT_ACCESS(iPMU_SPARE_REG2_OFFSET) &= ~(wurx_lvl_shift_en);
488 PMU_DIRECT_ACCESS(iPMU_SPARE_REG2_OFFSET) &= ~(wurx_pg_en_1);
489
490 PMU_DIRECT_ACCESS(ULPCLKS_REF_CLK_REG_OFFSET) &= ~pass_clk_40m_buffer_enable;
491
492 #ifndef IPMU_DOTC_PROG
493 PMU_DIRECT_ACCESS(0x125) |= (BIT(2)); //! Added by Nagaraj
494 PMU_DIRECT_ACCESS(0x127) &= ~((BIT(3)) | BIT(4)); //! Added by Nagaraj
495 #else
496 program_ipmu_data(ana_perif_ptat_common_config2);
497 program_ipmu_data(ipmu_bod_clks_common_config2);
498 #endif
499
500 reg_val = (PMU_DIRECT_ACCESS(POWERGATE_REG_READ_OFFSET) >> 5);
501 reg_val &= ~(cmp_npss_pg_enb | ulp_ang_clks_pg_enb | wurx_corr_pg_enb | wurx_pg_enb | auxadc_pg_enb | auxdac_pg_enb);
502 PMU_DIRECT_ACCESS(POWERGATE_REG_WRITE_OFFSET) = reg_val;
503 #ifndef SLI_SI91X_MCU_INTERFACE
504 // MHz RC
505 PMU_DIRECT_ACCESS(ULPCLKS_MRC_CLK_REG_OFFSET) &= ~rc_mhz_en;
506 MCU_FSM_DIRECT_ACCESS(MCU_FSM_CLK_ENS_AND_FIRST_BOOTUP) &= ~mcu_ulp_mhz_rc_clk_en;
507 #endif
508 #if 0
509 reg_val = (PMU_DIRECT_ACCESS(POWERGATE_REG_READ_OFFSET) >> 5);
510 reg_val &= ~(wurx_corr_pg_enb | wurx_pg_enb);
511 PMU_DIRECT_ACCESS(POWERGATE_REG_WRITE_OFFSET) = reg_val;
512
513 // BG-PMU_SPI
514 reg_val = (PMU_DIRECT_ACCESS(POWERGATE_REG_READ_OFFSET) >> 5);
515 reg_val &= ~(ulp_ang_pwrsupply_pg_enb | wurx_pg_enb);
516 PMU_DIRECT_ACCESS(POWERGATE_REG_WRITE_OFFSET) = reg_val;
517
518 // Button-Wakeup
519 PMU_DIRECT_ACCESS(BOD_TEST_PG_VBATT_STATUS_REG_OFFSET) &= ~bod_pwrgate_en_n_ulp_button_calib;
520
521 // Clk Calibration
522 PMU_DIRECT_ACCESS(ULPCLKS_TRIM_SEL_REG_OFFSET) &= ~calib_powergate_en;
523
524 // Adaptive Calibration
525 PMU_DIRECT_ACCESS(ULPCLKS_ADAPTIVE_REG_OFFSET) &= ~adapt_powergate_en;
526
527 // High Freq RO
528 PMU_DIRECT_ACCESS(ULPCLKS_HF_RO_CLK_REG_OFFSET) &= ~ro_hf_en;
529 MCU_FSM_DIRECT_ACCESS(MCU_FSM_CLK_ENS_AND_FIRST_BOOTUP) &= ~mcu_ulp_20mhz_ring_osc_clk_en;
530 ULP_DIRECT_ACCESS(NWP_FSM_FIRST_BOOTUP) &= ~nwp_ulp_20mhz_ring_osc_clk_en;
531
532 // 32KHz XTAL
533 PMU_DIRECT_ACCESS(ULPCLKS_32KXTAL_CLK_REG_OFFSET) &= ~xtal_32khz_en;
534 MCU_FSM_DIRECT_ACCESS(MCU_FSM_CLK_ENS_AND_FIRST_BOOTUP) &= ~mcu_ulp_32khz_xtal_clk_en;
535 ULP_DIRECT_ACCESS(NWP_FSM_FIRST_BOOTUP) &= ~nwp_ulp_32khz_xtal_clk_en;
536
537 // 32MHz Doubler
538 PMU_DIRECT_ACCESS(ULPCLKS_DOUBLER_XTAL_REG_OFFSET) &= ~doubler_en;
539 MCU_FSM_DIRECT_ACCESS(MCU_FSM_CLK_ENS_AND_FIRST_BOOTUP) &= ~mcu_ulp_doubler_clk_en;
540 ULP_DIRECT_ACCESS(NWP_FSM_FIRST_BOOTUP) &= ~nwp_ulp_doubler_clk_en;
541
542 // MHz RC
543 PMU_DIRECT_ACCESS(ULPCLKS_MRC_CLK_REG_OFFSET) &= ~rc_mhz_en;
544 MCU_FSM_DIRECT_ACCESS(MCU_FSM_CLK_ENS_AND_FIRST_BOOTUP) &= ~mcu_ulp_mhz_rc_clk_en;
545 ULP_DIRECT_ACCESS(NWP_FSM_FIRST_BOOTUP) &= ~nwp_ulp_mhz_rc_clk_en;
546
547 // Tempsense_RO
548 TS_ENABLE_AND_TEMPERATURE_DONE &= ~temp_sens_en;
549
550 // Tempsense_BJT
551 //TEMP_SENSOR_BJT &= ~BIT(0);
552
553 // Aux-ADC/Aux-DAC
554 reg_val = (PMU_DIRECT_ACCESS(POWERGATE_REG_READ_OFFSET) >> 5);
555 reg_val &= ~(auxadc_pg_enb | auxdac_pg_enb);
556 PMU_DIRECT_ACCESS(POWERGATE_REG_WRITE_OFFSET) = reg_val;
557 #endif
558 }
559 #ifdef SLI_SI91X_MCU_INTERFACE
560 void ipmu_init(void);
561 #else
562 void ipmu_init(void) __attribute__((section(".common_non_tcm_code")));
563 #endif
ipmu_init(void)564 void ipmu_init(void)
565 {
566 #ifndef SLI_SI91X_MCU_INTERFACE
567 //http://192.168.1.215:8090/display/IPMU40GF/Registers+Summary
568 uint32_t ipmu_calb_data_invalid = 1;
569 #endif
570 #ifndef IPMU_DOTC_PROG
571 uint32_t pmu_1p3_ctrl_data;
572 #endif
573 uint32_t pmu_1p2_ctrl_word;
574 uint32_t bypass_curr_ctrl_data;
575 const retention_boot_status_word_t *retention_reg = (const retention_boot_status_word_t *)MCURET_BOOTSTATUS;
576
577 //! If M4 present and host interface with M4(M4 master) case, total IPMU and MCU FSM registers has to be initialised in M4.
578 //! Always NWP FSM registers has to be programmed here.
579 //! In WiSE MCU BLE only mode IPMU programming will be done in MCU
580
581 #ifndef SLI_SI91X_MCU_INTERFACE
582 #ifndef BT_LE_ONLY_MODE
583 if (!retention_reg->m4_present) {
584 ipmu_init_mcu();
585 }
586 #endif
587 #ifdef IPMU_CALIB_DATA
588 //! Read calib data from efuse/flash and update to iPMU registers
589 ipmu_calb_data_invalid = init_ipmu_calib_data(retention_reg->m4_present);
590 #endif
591 #else
592 ipmu_init_mcu();
593 //! Read calib data from efuse/flash and update to iPMU registers
594 init_ipmu_calib_data(retention_reg->m4_present);
595 #endif
596
597 #ifndef DISABLE_M4SS_SWITCH_OFF
598 #ifndef SLI_SI91X_MCU_INTERFACE
599 if (!retention_reg->m4_present)
600 #endif
601 {
602 #ifdef SLI_SI91X_MCU_INTERFACE
603 MCU_PMU_LDO_CTRL_CLEAR_REG_1 =
604 #else
605 MCU_PMU_LDO_CTRL_CLEAR =
606 #endif
607 (mcu_soc_ldo_lvl | mcu_dcdc_lvl); //Dynamic control of LDO-SoC and VOUTBCK o/p volt from NWP
608 MCU_FSM_PMU_CTRL |= standby_dc1p3; //Dynamic control of PFM Mode from NWP
609 MCU_FSM_DIRECT_ACCESS(MCU_FSM_PMU_STATUS_REG_OFFSET) |= (scdcdc_lp_mode_en);
610 MCU_FSM_DIRECT_ACCESS(MCU_FSM_PMU_STATUS_REG_OFFSET) |= (bgpmu_sleep_en);
611
612 #ifdef IPMU_DOTC_PROG
613 #ifndef IPMU_POWER_ENHANCEMENT
614 //This is commented sothat retention ldo trim value BG_LDO_REG_OFFSET[20:18] is not over written
615 program_ipmu_data(retn_ldo_lpmode);
616 #endif
617 #else
618 PMU_DIRECT_ACCESS(0x129) |= (BIT(15) | BIT(16)); //! Added by Nagaraj
619 PMU_DIRECT_ACCESS(0x140) |= (BIT(15) | BIT(18) | BIT(19)); //! Added by Nagaraj
620 #endif
621
622 #ifdef IPMU_DOTC_PROG
623 #if 0
624 program_ipmu_data(lp_scdc_extcapmode);
625 #endif
626 #else
627 PMU_DIRECT_ACCESS(BG_SCDC_PROG_REG_2_OFFSET);
628 PMU_DIRECT_ACCESS(SCDC_CTRL_REG_0_OFFSET) = 0x3e002f;
629 PMU_DIRECT_ACCESS(BG_SCDC_PROG_REG_2_OFFSET) = 0x200020;
630 PMU_DIRECT_ACCESS(BG_LDO_REG_OFFSET) = 0x58000;
631 #endif
632
633 PMU_DIRECT_ACCESS(SELECT_BG_CLK_OFFSET) |= BIT(1); //! BG-PMU Clock configured to MCU_FSM_SLEEP_CLK
634 #ifndef SLI_SI91X_MCU_INTERFACE
635 shut_down_non_wireless_mode_pds();
636 #endif
637 #ifdef SLI_SI91X_MCU_INTERFACE
638 MCUAON_GEN_CTRLS_REG &= ~NPSS_SUPPLY_0P9_BIT; //Dynamic switching of NPSS/iPMU supply during sleep
639 MCUAON_GEN_CTRLS_REG |= ENABLE_PDO_BIT; //Dynamic control of PADs PDO during sleep
640 #else
641 MCUAON_GEN_CTRLS_REG &= ~NPSS_SUPPLY_0P9; //Dynamic switching of NPSS/iPMU supply during sleep
642 MCUAON_GEN_CTRLS_REG |= ENABLE_PDO; //Dynamic control of PADs PDO during sleep
643 #endif
644 #ifndef IPMU_DOTC_PROG
645 PMU_SPI_DIRECT_ACCESS(PMU_LDO_REG_OFFSET) &= ~LDOSOC_DEFAULT_MODE_EN; //LDO-SoC o/p Volt is configurable from NPSS
646 PMU_SPI_DIRECT_ACCESS(PMU_PWRTRAIN_REG_OFFSET) |= BYPASS_LDORF_CTRL; //LDO-FLASH is configurable from NPSS
647
648 if (ipmu_calb_data_invalid) {
649 PMU_SPI_DIRECT_ACCESS(0x1DA) = 0x2818;
650 PMU_SPI_DIRECT_ACCESS(0x1DD) = 0x26249A;
651 PMU_SPI_DIRECT_ACCESS(0x1D0) = 0x132241;
652 PMU_SPI_DIRECT_ACCESS(0x1D2) = 0xE80D7;
653 PMU_SPI_DIRECT_ACCESS(0x1D3) = 0x872B;
654 }
655
656 // Setting VOUTBCK to 1.35V (Finally Done from Calibration Data in EFUSE)
657 pmu_1p3_ctrl_data = PMU_SPI_DIRECT_ACCESS(PMU_1P3_CTRL_REG_OFFSET);
658 pmu_1p3_ctrl_data &= ~(0xF << 17);
659 PMU_SPI_DIRECT_ACCESS(PMU_1P3_CTRL_REG_OFFSET) = (pmu_1p3_ctrl_data | (0xA << 17));
660 ////////////////////////////////////////////////////////////
661 #endif
662
663 // Setting VOUTBCK_LOW to 1.25V based on the data obtained from Calibration Data
664 bypass_curr_ctrl_data = PMU_SPI_DIRECT_ACCESS(PMU_1P3_CTRL_REG_OFFSET);
665 pmu_1p2_ctrl_word = ((bypass_curr_ctrl_data >> 17) & 0xF) - 2;
666 bypass_curr_ctrl_data = PMU_SPI_DIRECT_ACCESS(BYPASS_CURR_CTRL_REG_OFFSET);
667 bypass_curr_ctrl_data &= (uint32_t)(~(0xF << 5));
668 PMU_SPI_DIRECT_ACCESS(BYPASS_CURR_CTRL_REG_OFFSET) = (bypass_curr_ctrl_data | (pmu_1p2_ctrl_word << 5));
669
670 PMU_DIRECT_ACCESS(BG_SLEEP_TIMER_REG_OFFSET) |= BIT(19); //bgs_active_timer_sel
671 //http://192.168.1.215:8090/display/RS9116/MCU+AON+Registers#MCUAONRegisters-MCUAON_SHELF_MODE
672 MCUAON_SHELF_MODE |= (7 << 19); //Programmable delay for resetting Chip
673 }
674 #endif
675
676 #ifndef SLI_SI91X_MCU_INTERFACE
677
678 #ifdef BGPMU_SAMPLING_EN
679 ULP_DIRECT_ACCESS(NWP_PMU_CTRLS) |= (scdcdc_lp_mode_en);
680 ULP_DIRECT_ACCESS(NWP_PMU_CTRLS) |= (bgpmu_sleep_en); //Disabling Brownout Detection. enable once issue is fixed.
681 #endif
682 #ifdef DCDC_STANDBY_MODE_EN
683 ULP_DIRECT_ACCESS(NWP_PMU_CTRLS) |= standby_dc1p3;
684 #endif
685
686 //BIT(16) is added for smooth reset of bandgap in 1.4REV Silicon
687 ULP_DIRECT_ACCESS(NWPAON_POR_CTRL_BITS) |= (poc_cntrl_reg_0 | BIT(16));
688
689 //! RC MHz disable from NWP
690 ULP_DIRECT_ACCESS(NWP_FSM_FIRST_BOOTUP) &= ~nwp_ulp_mhz_rc_clk_en;
691
692 TASS_FSM_CTRL_BYPASS &= ~ta_pmu_shut_down_bypass;
693 TASS_FSM_CTRL_BYPASS &= ~ta_pmu_shut_down_bypass_cntrl;
694
695 TASS_FSM_CTRL_BYPASS |= ta_buck_boost_enable_bypass;
696 #endif
697 }
698 #ifdef SLI_SI91X_MCU_INTERFACE
699 void configure_uulp_gpio_to_1p8v(void);
700 #else
701 void configure_uulp_gpio_to_1p8v(void) __attribute__((section(".common_non_tcm_code")));
702 #endif
configure_uulp_gpio_to_1p8v(void)703 void configure_uulp_gpio_to_1p8v(void)
704 {
705 //! UULP GPIO to operate at 1.8v
706 //http://192.168.1.215:8090/display/IPMU40GF/Registers+Summary
707 PMU_DIRECT_ACCESS(iPMU_SPARE_REG1_OFFSET); //Dummy read
708 PMU_DIRECT_ACCESS(iPMU_SPARE_REG1_OFFSET) |= BIT(13);
709 }
710
711 #ifdef SLI_SI91X_MCU_INTERFACE
712 void configure_ipmu_mode(uint32_t mode);
713 #else
714 void configure_ipmu_mode(uint32_t mode) __attribute__((section(".common_non_tcm_code")));
715 #endif
configure_ipmu_mode(uint32_t mode)716 void configure_ipmu_mode(uint32_t mode)
717 {
718 if (mode) {
719 //program_ipmu_data(hpldo_volt_trim_efuse); //HPLDO_TRIM_EFUSE
720 program_ipmu_data(hpldo_tran); //SCDC3
721 program_ipmu_data(buck_fast_transient_duty_1p8); //SCDC3
722 program_ipmu_data(LDOFLASH_BYPASS); //keeping ldoflash in bypass mode in 1p8V supply mode;
723 } else {
724 //program_ipmu_data(scdc_volt_trim_efuse); //SCDC_TRIM_EFUSE
725 program_ipmu_data(ipmu_scdc_enable); //EXT CAP Mode
726 program_ipmu_data(lp_scdc_extcapmode); //EXT CAP Mode
727 }
728 }
729 #ifndef SLI_SI91X_MCU_INTERFACE
730 void disable_ipmu_write_access() __attribute__((section(".common_non_tcm_code")));
disable_ipmu_write_access()731 void disable_ipmu_write_access()
732 {
733 PMU_DIRECT_ACCESS(SELECT_BG_CLK_OFFSET);
734 PMU_DIRECT_ACCESS(SELECT_BG_CLK_OFFSET) &=
735 ~(latch_transparent_lf | latch_transparent_hf | latch_top_spi); //! Added by Nagaraj
736 PMU_DIRECT_ACCESS(SELECT_BG_CLK_OFFSET);
737 }
738 // temp sensor
adc_read_data_func()739 uint16 adc_read_data_func()
740 {
741 uint16 adc_data;
742 uint32_t dummy_read;
743 uint32_t adc_data_avg;
744 //uint16 fifo_data[16][32];
745 uint32_t inxx2 = 0;
746
747 adc_data_avg = 0;
748
749 for (dummy_read = 0; dummy_read < 32; dummy_read++) {
750 while ((*(volatile uint32_t *)(0x24043830)) & BIT(2))
751 ;
752 adc_data = ((*(volatile uint32_t *)(0x24043814)) & 0xFFF);
753 adc_data = BIT(11) ^ adc_data;
754 if (dummy_read > 15) {
755 adc_data_avg += adc_data;
756 }
757 //fifo_data[inxx2][dummy_read] = adc_data;
758 }
759 adc_data_avg /= 16;
760 inxx2 = (inxx2 + 1) & 15;
761 return adc_data_avg;
762 }
763
764 uint32_t adccalibDone;
765 #define ULP_SPI_MEM_MAP(REG_ADR) (*((uint32_t volatile *)(PMU_SPI_BASE_ADDR + (0xa000 + (REG_ADR * 4)))))
766 #define AUX_LDO *(volatile uint32_t *)(0x24043a10)
calibrate_adc()767 void calibrate_adc()
768 {
769 uint32_t auxadcCalibValueLoad = 0, auxadcCalibValue = 0;
770
771 if (adccalibDone == 0) {
772 ULP_SPI_MEM_MAP(0x110) |= BIT(11);
773 ULP_SPI_MEM_MAP(0x110) |= (BIT(12) | BIT(13) | BIT(8) | BIT(7) | BIT(6));
774 while (*(volatile uint32_t *)(0x24050000 + 0x02) & BIT(8))
775 ;
776 while (!(ULP_SPI_MEM_MAP(0x1C1) & BIT(0)))
777 ;
778 while ((ULP_SPI_MEM_MAP(0x1C1) & BIT(0)))
779 ;
780 usleep(20);
781 auxadcCalibValue = ULP_SPI_MEM_MAP(0x112);
782 usleep(20);
783 auxadcCalibValueLoad |= BIT(0) | BIT(7);
784 auxadcCalibValueLoad |= (auxadcCalibValue & 0x1F) << 2;
785 auxadcCalibValueLoad |= (((auxadcCalibValue >> 6) & 0x1F) << 8);
786 auxadcCalibValueLoad |= (((auxadcCalibValue >> 11) & 0x1F) << 13);
787 adccalibDone = 1;
788 }
789 ULP_SPI_MEM_MAP(0x111) = (auxadcCalibValueLoad);
790
791 while (*(volatile uint32_t *)(0x24050000 + 0x02) & BIT(8))
792 ;
793
794 /* read calibrated p and n values */
795 //calibrated_value = ULP_SPI_MEM_MAP(0x112);
796 }
797
get_ipmu_temperature(common_info_t * glbl_common_info_p)798 void get_ipmu_temperature(common_info_t *glbl_common_info_p)
799 {
800 int32 adc_off;
801 int32 Vbg;
802 int32 Voffset;
803 uint32_t pmu_reg;
804 int32 irf_temperature;
805 int32 adc_bjt;
806 int32 adc_bg;
807 // int32 dbg_adc_bjt[32];
808 // int32 dbg_adc_bg[32];
809 // int16 temp[32];
810 uint8 inxx = 0;
811 common_info_ext_t *glbl_common_info_ext_p = (common_info_ext_t *)glbl_common_info_p->reserved_ptr;
812
813 if ((glbl_common_info_p->host_if == CORTEX_M4) || (!glbl_common_info_ext_p->chip_version_1p4_or_more)) {
814 irf_temperature = 70;
815 goto end_temp_measurement;
816 }
817 get_m4ss_access();
818 *(volatile uint32_t *)(0x2405a000 + (0x142 * 4)); //dummy read
819
820 //reg_val1 = PMU_DIRECT_ACCESS(BG_SCDC_PROG_REG_1_OFFSET);
821
822 //PMU_DIRECT_ACCESS(BG_SCDC_PROG_REG_1_OFFSET) = reg_val1 | BIT(4);
823
824 *(volatile uint32_t *)(0x2405a000 + (0x143 * 4)) = 0;
825 *(volatile uint32_t *)(0x2405a000 + (0x142 * 4)) = 0x1F910;
826
827 ULPSS_PWRCTRL_SET_REG = ulpss_ext_pwrgate_en_n_ulp_AUX;
828
829 ULP_DYN_CLK_CTRL_DISABLE |= BIT(11) | BIT(12) | BIT(13);
830 ULP_MISC_SOFT_SET_REG &= 0xfff8001f;
831 ULP_MISC_SOFT_SET_REG |= 0x0007ffe0;
832 ULP_AUXADC_CLK_GEN_REG = 0x1;
833 AUX_LDO = 0x7b;
834
835 *(volatile uint32_t *)(0x2404380C) = 40;
836
837 // wait for 50us
838 usleep(100);
839
840 //*(uint32_t*)(0x2404C000 + 9 *(0x10))=(7<<2);//FIXME DELETE
841
842 pmu_reg = ~0x1E & (*(volatile uint32_t *)(0x2405a000 + (0x129 * 4)));
843 *(volatile uint32_t *)(0x2405a000 + (0x129 * 4)) = pmu_reg | (8 << 1);
844 *(volatile uint32_t *)(0x24043a18) = 0x2e005;
845
846 while (*(volatile uint32_t *)(0x24050000 + 0x02) & BIT(8))
847 ;
848
849 *(volatile uint32_t *)(0x24043800 + 0x24) &= ~BIT(4);
850 *((volatile uint32_t *)(0x24043800 + (512 + 8))) = 0x00000C15; //OPAMP2 Channel21
851 *((volatile uint32_t *)(0x24043800 + (78 * 4))) = 0x00000000;
852 *((volatile uint32_t *)(0x24043800 + (94 * 4))) = 0x00000001;
853 *((volatile uint32_t *)(0x24043800 + (119 * 4))) = 0x00000001;
854 *((volatile uint32_t *)(0x24043800 + (1 * 4))) = 0x8000C05;
855
856 usleep(400);
857 calibrate_adc();
858
859 adc_bg = adc_read_data_func();
860
861 *((volatile uint32_t *)(0x24043800 + (1 * 4))) = 0x0;
862 *((volatile uint32_t *)(0x24043800 + (512 + 8))) = 0x15;
863 ////////////TS BJT /////////////////////////
864
865 TS_SLOPE_SET |= BIT(28);
866 VAD_BBP_ID |= BIT(16);
867 //To control ADC channel
868 ADC_CHANNEL = 0x002e0000;
869 //For ADC channel contro
870 ADC_CHANNEL_CNTRL = 0x00000000;
871 //Internal DMA disable and channel enable
872 DMA = 0x00000001;
873
874 //Enbale temperature sensor
875 TEM = 0x00000001;
876
877 //BJT TEMP TEST MUX
878 *(volatile uint32_t *)(0x2405a000 + (0x143 * 4)) = 0x3C0010;
879 *(volatile uint32_t *)(0x2405a000 + (0x140 * 4)) = 0x220;
880 while (*(volatile uint32_t *)(0x24050000 + 0x02) & BIT(8))
881 ;
882
883 *(volatile uint32_t *)(0x2404380C) = 20;
884 *(volatile uint32_t *)(0x24043800 + 0x24) &= ~BIT(4);
885 *((volatile uint32_t *)(0x24043800 + (512 + 8))) = 0x00000C17;
886 *((volatile uint32_t *)(0x24043800 + (1 * 4))) = 0x8000C05;
887
888 adc_bjt = adc_read_data_func();
889
890 ADC_CHANNEL = 0x00000000;
891 ADC_CHANNEL;
892 /* turn off adc */
893 *((volatile uint32_t *)(0x24043800 + (512 + 8))) &= ~((BIT(10) | BIT(11)));
894 *((volatile uint32_t *)(0x24043800 + (1 * 4))) &= ~BIT(0);
895 //PMU_DIRECT_ACCESS(BG_SCDC_PROG_REG_1_OFFSET) = reg_val1;
896
897 adc_off = glbl_common_info_ext_p->auxadc_offset_single;
898 Vbg = glbl_common_info_ext_p->vbg_tsbjt_efuse;
899 Voffset = 961 - glbl_common_info_ext_p->str_bjt_temp_sense_off;
900
901 //dbg_adc_bg[inxx] = adc_bg;
902 //dbg_adc_bjt[inxx] = adc_bjt;
903 irf_temperature = -268 + (310 * (((Vbg * (adc_bjt - adc_off)) / (adc_bg - adc_off)) + Voffset) / 1000) + 40;
904
905 //temp[inxx] = irf_temperature -40;
906 if ((irf_temperature > 100) || (irf_temperature < 50)) {
907 //while(1);
908 }
909 if (inxx == 7)
910 while (1)
911 ;
912 inxx = (inxx + 1) & 31;
913 release_m4ss_access();
914 end_temp_measurement:
915 glbl_common_info_ext_p->chip_temperature = irf_temperature;
916 }
917 #endif
918
919 #endif
920