• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 HPMicro
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #include "hpm_pcfg_drv.h"
9 #include "hpm_soc_feature.h"
10 
11 #define PCFG_CURRENT_MEASUREMENT_STEP (50U)
12 #define HPM_PMU_DRV_RETRY_COUNT (5000U)
13 
pcfg_ldo1p1_set_voltage(PCFG_Type * ptr,uint16_t mv)14 hpm_stat_t pcfg_ldo1p1_set_voltage(PCFG_Type *ptr, uint16_t mv)
15 {
16     if ((mv < PCFG_SOC_LDO1P1_MIN_VOLTAGE_IN_MV)
17             || (mv > PCFG_SOC_LDO1P1_MAX_VOLTAGE_IN_MV)) {
18         return status_pcfg_ldo_out_of_range;
19     }
20     ptr->LDO1P1 = (ptr->LDO1P1 & ~PCFG_LDO1P1_VOLT_MASK) | PCFG_LDO1P1_VOLT_SET(mv);
21     return status_success;
22 }
23 
pcfg_ldo2p5_set_voltage(PCFG_Type * ptr,uint16_t mv)24 hpm_stat_t pcfg_ldo2p5_set_voltage(PCFG_Type *ptr, uint16_t mv)
25 {
26     uint32_t retry = 0;
27     if ((mv < PCFG_SOC_LDO2P5_MIN_VOLTAGE_IN_MV)
28             || (mv > PCFG_SOC_LDO2P5_MAX_VOLTAGE_IN_MV)) {
29         return status_pcfg_ldo_out_of_range;
30     }
31     ptr->LDO2P5 &= ~PCFG_LDO2P5_ENABLE_MASK;
32     ptr->LDO2P5 = PCFG_LDO2P5_ENABLE_MASK | PCFG_LDO2P5_VOLT_SET(mv);
33 
34     while (!PCFG_LDO2P5_READY_GET(ptr->LDO2P5)) {
35         if (retry > HPM_PMU_DRV_RETRY_COUNT) {
36             break;
37         }
38         retry++;
39     }
40     if (retry > HPM_PMU_DRV_RETRY_COUNT) {
41         return status_timeout;
42     }
43 
44     return status_success;
45 }
46 
pcfg_dcdc_get_current_level(PCFG_Type * ptr)47 uint16_t pcfg_dcdc_get_current_level(PCFG_Type *ptr)
48 {
49     uint32_t retry = 0;
50     while (!pcfg_dcdc_is_measure_current_valid(ptr)) {
51         if (retry > HPM_PMU_DRV_RETRY_COUNT) {
52             break;
53         }
54         retry++;
55     }
56     if (retry > HPM_PMU_DRV_RETRY_COUNT) {
57         return 0;
58     }
59 
60     return PCFG_DCDC_CURRENT_LEVEL_GET(ptr->DCDC_CURRENT) * PCFG_CURRENT_MEASUREMENT_STEP;
61 }
62 
pcfg_dcdc_set_voltage(PCFG_Type * ptr,uint16_t mv)63 hpm_stat_t pcfg_dcdc_set_voltage(PCFG_Type *ptr, uint16_t mv)
64 {
65     hpm_stat_t stat = status_success;
66     if ((mv < PCFG_SOC_DCDC_MIN_VOLTAGE_IN_MV) || (mv > PCFG_SOC_DCDC_MAX_VOLTAGE_IN_MV)) {
67         return status_invalid_argument;
68     }
69     ptr->DCDC_MODE = (ptr->DCDC_MODE & ~PCFG_DCDC_MODE_VOLT_MASK) | PCFG_DCDC_MODE_VOLT_SET(mv);
70     return stat;
71 }
72 
73 #define PCFG_RC24M_FREQ (24000000UL)
pcfg_irc24m_config_track(PCFG_Type * ptr,pcfg_irc24m_config_t * config)74 void pcfg_irc24m_config_track(PCFG_Type *ptr, pcfg_irc24m_config_t *config)
75 {
76     uint32_t calculated_freq;
77     uint16_t mul = 1;
78     uint16_t div = 1;
79 
80     if (!(config->freq_in_hz < PCFG_RC24M_FREQ)) {
81         /* calculate div */
82         div = PCFG_RC24M_FREQ / config->freq_in_hz;
83     }
84     calculated_freq = PCFG_RC24M_FREQ / div;
85     while (calculated_freq < config->freq_in_hz) {
86         calculated_freq *= (mul++);
87     }
88     ptr->TRACK_TARGET = PCFG_TRACK_TARGET_PRE_DIV_SET(div - 1)
89         | PCFG_TRACK_TARGET_TARGET_SET(mul - 1);
90     ptr->RC24M_TRACK = PCFG_RC24M_TRACK_SEL24M_SET(config->reference)
91         | PCFG_RC24M_TRACK_RETURN_SET(config->return_to_default_on_xtal_loss)
92         | PCFG_RC24M_TRACK_TRACK_SET(config->free_run);
93 }
94 
pcfg_dcdc_set_lpmode_voltage(PCFG_Type * ptr,uint16_t mv)95 hpm_stat_t pcfg_dcdc_set_lpmode_voltage(PCFG_Type *ptr, uint16_t mv)
96 {
97     hpm_stat_t stat = status_success;
98     if ((mv < PCFG_SOC_DCDC_MIN_VOLTAGE_IN_MV) || (mv > PCFG_SOC_DCDC_MAX_VOLTAGE_IN_MV)) {
99         return status_invalid_argument;
100     }
101     ptr->DCDC_LPMODE = (ptr->DCDC_LPMODE & ~PCFG_DCDC_LPMODE_STBY_VOLT_MASK) | PCFG_DCDC_LPMODE_STBY_VOLT_SET(mv);
102     return stat;
103 }
104