EFR32 Mighty Gecko 1 Software Documentation  efr32mg1-doc-5.1.2
util_supply.c
Go to the documentation of this file.
1 /***************************************************************************/
16 #include <stdio.h>
17 
18 #include "em_device.h"
19 #include "em_cmu.h"
20 #include "em_gpio.h"
21 #include "em_emu.h"
22 #include "em_adc.h"
23 #include "em_cmu.h"
24 #include "em_prs.h"
25 
26 #include "thunderboard/board.h"
27 #include "thunderboard/util.h"
28 #include "thunderboard/si7021.h"
29 
30 /***************************************************************************/
37 /***************************************************************************/
41 static float measureSupplyVoltage ( unsigned int avg );
42 static float measureSupplyIR ( uint8_t loadSetting );
43 
44 float UTIL_supplyVoltage;
45 float UTIL_supplyIR;
46 uint8_t UTIL_supplyType;
52 /***************************************************************************/
57 /***************************************************************************/
64 static void adcInit( void )
65 {
66 
69 
72 
73  /* Only configure the ADC if it is not already running */
74  if( ADC0 ->CTRL == _ADC_CTRL_RESETVALUE ) {
75 
76  init.timebase = ADC_TimebaseCalc( 0 );
77  init.prescale = ADC_PrescaleCalc( 1000000, 0 );
78  ADC_Init( ADC0, &init );
79  }
80 
81  initSingle.acqTime = adcAcqTime16;
82  initSingle.reference = adcRef5VDIFF;
83  initSingle.posSel = adcPosSelAVDD;
84  initSingle.negSel = adcNegSelVSS;
85  initSingle.prsEnable = true;
86  initSingle.prsSel = adcPRSSELCh4;
87 
88  ADC_InitSingle( ADC0, &initSingle );
89 
90  return;
91 
92 }
93 
94 /***************************************************************************/
101 static void adcDeInit( void )
102 {
103 
104  PRS_SourceAsyncSignalSet( 4, 0, 0 );
105  CMU->CTRL &= ~_CMU_CTRL_CLKOUTSEL1_MASK;
106 
107  return;
108 
109 }
110 
111 /***************************************************************************/
118 static uint16_t getAdcSample( void )
119 {
120 
122  while( !( ADC_IntGet( ADC0 ) & ADC_IF_SINGLE ) )
123  ;
124 
125  return ADC_DataSingleGet( ADC0 );
126 
127 }
128 
129 /***************************************************************************/
139 static float measureSupplyVoltage( unsigned int avg )
140 {
141 
142  uint16_t adcData;
143  float supplyVoltage;
144  int i;
145 
146  adcInit();
147 
148  supplyVoltage = 0;
149 
150  for( i = 0; i < avg; i++ ) {
151  adcData = getAdcSample();
152  supplyVoltage += (float) adcData * 5.0 / 4095.0;
153  }
154 
155  adcDeInit();
156 
157  supplyVoltage = supplyVoltage / (float) avg;
158 
159  return supplyVoltage;
160 
161 }
162 
163 /***************************************************************************/
175 static float measureSupplyIR( uint8_t loadSetting )
176 {
177 
178  float supplyVoltage;
179  float supplyVoltageLoad;
180  float i, r;
181 
182  uint8_t cmd;
183  uint8_t data;
184 
185  UTIL_delay( 250 );
186  supplyVoltage = measureSupplyVoltage( 16 );
187 
188  /* Enable heater in Si7021 - 9.81 mA */
190  data = loadSetting;
191  SI7021_cmdWrite( &cmd, 1, &data, 1 );
192 
194  data = 0x04;
195  SI7021_cmdWrite( &cmd, 1, &data, 1 );
196 
197  /* Wait for battery voltage to settle */
198  UTIL_delay( 250 );
199  supplyVoltageLoad = measureSupplyVoltage( 16 );
200 
201  /* Turn off heater */
203  data = 0x00;
204  SI7021_cmdWrite( &cmd, 1, &data, 1 );
205 
206  i = 0.006074 * loadSetting + 0.00309;
207  r = ( supplyVoltage - supplyVoltageLoad ) / i;
208 
209  printf( " sv = %.3f svl = %.3f i = %.3f r = %.3f\r\n",
210  supplyVoltage, supplyVoltageLoad, i, r );
211 
212  return r;
213 
214 }
215 
216 /***************************************************************************/
224 void UTIL_supplyProbe( void )
225 {
226 
227  SI7021_init();
228 
229  uint8_t type;
230  float r, v;
231 
233 
234  /* Try to measure using 9.18 mA first */
235  v = measureSupplyVoltage( 16 );
236  r = measureSupplyIR( 0x00 );
237  if( r > 5.0 ) {
239  }
240  else if( ( v < 3.20 ) || ( r > 0.5 ) ) {
241  type = UTIL_SUPPLY_TYPE_AAA;
242  }
243  else {
244  type = UTIL_SUPPLY_TYPE_USB;
245  }
246 
247  UTIL_supplyVoltage = v;
248  UTIL_supplyIR = r;
249  UTIL_supplyType = type;
250 
251  SI7021_deInit();
252 
253  return;
254 
255 }
256 
257 /***************************************************************************/
273 void UTIL_supplyGetCharacteristics( uint8_t *type, float *voltage, float *ir )
274 {
275 
276  *type = UTIL_supplyType;
277  *voltage = UTIL_supplyVoltage;
278  *ir = UTIL_supplyIR;
279 
280  return;
281 
282 }
283 
284 /***************************************************************************/
291 uint8_t UTIL_supplyGetType( void )
292 {
293 
294  return UTIL_supplyType;
295 
296 }
297 
298 /***************************************************************************/
305 bool UTIL_isLowPower( void )
306 {
307 
308  bool lp;
309 
310  if( ( UTIL_supplyType != UTIL_SUPPLY_TYPE_CR2032 ) && ( UTIL_supplyType != UTIL_SUPPLY_TYPE_UNKNOWN ) ) {
311  lp = false;
312  }
313  else {
314  lp = true;
315  }
316 
317  return lp;
318 
319 }
320 
Driver for the Si7021 I2C Humidity and Temperature Sensor.
Clock management unit (CMU) API.
ADC_PosSel_TypeDef posSel
Definition: em_adc.h:1014
uint8_t UTIL_supplyGetType(void)
Returns the type of the power supply.
Definition: util_supply.c:291
bool UTIL_isLowPower(void)
Checks if the current power supply has low power capability.
Definition: util_supply.c:305
static void adcInit(void)
Initializes the A/D converter.
Definition: util_supply.c:64
uint8_t timebase
Definition: em_adc.h:819
void UTIL_delay(uint32_t ms)
Delays number of msTick Systicks (1 ms)
Definition: util.c:97
ADC_AcqTime_TypeDef acqTime
Definition: em_adc.h:993
#define ADC_INITSINGLE_DEFAULT
Definition: em_adc.h:1062
ADC_NegSel_TypeDef negSel
Definition: em_adc.h:1020
CMSIS Cortex-M Peripheral Access Layer for Silicon Laboratories microcontroller devices.
#define ADC_INIT_DEFAULT
Definition: em_adc.h:855
__STATIC_INLINE uint32_t ADC_DataSingleGet(ADC_TypeDef *adc)
Get single conversion result.
Definition: em_adc.h:1096
static void adcDeInit(void)
De-initializes the A/D converter.
Definition: util_supply.c:101
ADC_PRSSEL_TypeDef prsSel
Definition: em_adc.h:990
#define UTIL_SUPPLY_TYPE_AAA
Definition: util.h:36
#define ADC0
static uint16_t getAdcSample(void)
Initiates an A/D conversion and reads the sample when done.
Definition: util_supply.c:118
void ADC_Init(ADC_TypeDef *adc, const ADC_Init_TypeDef *init)
Initialize ADC.
Definition: em_adc.c:371
static float measureSupplyVoltage(unsigned int avg)
Measures the supply voltage by averaging multiple readings.
Definition: util_supply.c:139
General Purpose IO (GPIO) peripheral API.
#define UTIL_SUPPLY_TYPE_USB
Definition: util.h:34
#define _ADC_CTRL_RESETVALUE
Definition: efr32mg1p_adc.h:85
uint8_t ADC_TimebaseCalc(uint32_t hfperFreq)
Calculate timebase value in order to get a timebase providing at least 1us.
Definition: em_adc.c:1118
uint32_t SI7021_cmdWrite(uint8_t *cmd, size_t cmdLen, uint8_t *data, size_t dataLen)
Sends a command and data to the chip over the I2C bus.
Definition: si7021.c:247
Utility Functions for the Thunderboard Sense.
void CMU_ClockEnable(CMU_Clock_TypeDef clock, bool enable)
Enable/disable a clock.
Definition: em_cmu.c:1453
#define _CMU_CTRL_CLKOUTSEL1_MASK
uint8_t prescale
Definition: em_adc.h:822
void ADC_InitSingle(ADC_TypeDef *adc, const ADC_InitSingle_TypeDef *init)
Initialize single ADC sample conversion.
Definition: em_adc.c:854
#define UTIL_SUPPLY_TYPE_UNKNOWN
Definition: util.h:33
void UTIL_supplyGetCharacteristics(uint8_t *type, float *voltage, float *ir)
Retrieves the supply characteristic variables.
Definition: util_supply.c:273
#define UTIL_SUPPLY_TYPE_CR2032
Definition: util.h:37
#define SI7021_CMD_WRITE_HEATER_CTRL
Definition: si7021.h:80
Energy management unit (EMU) peripheral API.
uint32_t SI7021_init(void)
Initializes the Si7021 chip.
Definition: si7021.c:41
uint8_t ADC_PrescaleCalc(uint32_t adcFreq, uint32_t hfperFreq)
Calculate prescaler value used to determine ADC clock.
Definition: em_adc.c:1025
__STATIC_INLINE void ADC_Start(ADC_TypeDef *adc, ADC_Start_TypeDef cmd)
Start scan sequence and/or single conversion.
Definition: em_adc.h:1318
Analog to Digital Converter (ADC) peripheral API.
ADC_Ref_TypeDef reference
Definition: em_adc.h:999
#define SI7021_CMD_WRITE_USER_REG1
Definition: si7021.h:78
void UTIL_supplyProbe(void)
Probes the connected supply and determines its type. The results are stored in global variables...
Definition: util_supply.c:224
#define CMU
static float measureSupplyIR(uint8_t loadSetting)
Measures the unladed and loaded supply voltage and calculates the intermal resistance of the connecte...
Definition: util_supply.c:175
#define ADC_IF_SINGLE
void PRS_SourceAsyncSignalSet(unsigned int ch, uint32_t source, uint32_t signal)
Set source and asynchronous signal to be used for a channel.
Definition: em_prs.c:115
__STATIC_INLINE uint32_t ADC_IntGet(ADC_TypeDef *adc)
Get pending ADC interrupt flags.
Definition: em_adc.h:1253
BOARD module header file.
Peripheral Reflex System (PRS) peripheral API.
void SI7021_deInit(void)
De-initializes the Si7021 chip. Disables the sensor power domain, this also disables other sensors...
Definition: si7021.c:74