oswald/metawatch/mw_adc.c
2021-02-14 18:03:13 +01:00

101 lines
2.6 KiB
C

#include <msp430.h>
#include <msp430xgeneric.h>
#include <stdint.h>
#include "mw_main.h"
#define HARDWARE_CFG_INPUT_CHANNEL ( ADC12INCH_13 )
#define BATTERY_SENSE_INPUT_CHANNEL ( ADC12INCH_15 )
#define LIGHT_SENSE_INPUT_CHANNEL ( ADC12INCH_1 )
#define ENABLE_ADC() { ADC12CTL0 |= ADC12ON; ADC12CTL0 |= ADC12ENC + ADC12SC; }
#define DISABLE_ADC() { ADC12CTL0 &= ~ADC12ENC; ADC12CTL0 &= ~ADC12ON; }
#define CLEAR_START_ADDR() { ADC12CTL1 &= 0x0FFF; }
const double CONVERSION_FACTOR_BATTERY = ((24300.0+38300.0)*2.5*1000.0)/(4095.0*24300.0);
#define BATTERY_FULL_LEVEL (4140)
#define BATTERY_CRITICAL_LEVEL (3300)
#define BATTERY_LEVEL_RANGE (BATTERY_FULL_LEVEL - BATTERY_CRITICAL_LEVEL)
/*! conversion factor */
const double CONVERSION_FACTOR = 2.5*10000.0/4096.0;
void mw_init_adc(void)
{
REFCTL0 = REFMSTR | REFTCOFF;
LIGHT_SENSE_INIT();
BATTERY_SENSE_INIT();
HARDWARE_CFG_SENSE_INIT();
/* allow conditional request for modosc */
UCSCTL8 |= MODOSCREQEN;
/* select ADC12SC bit as sample and hold source (00)
* and use pulse mode
* use modosc / 8 because frequency must be 0.45 MHz to 2.7 MHz (0.625 MHz)
*/
ADC12CTL1 = ADC12CSTARTADD_0 + ADC12SHP + ADC12SSEL_0 + ADC12DIV_7;
/* 12 bit resolution, only use reference when doing a conversion */
ADC12CTL2 = ADC12TCOFF + ADC12RES_2 + ADC12REFBURST;
/* setup input channels */
ADC12MCTL0 = HARDWARE_CFG_INPUT_CHANNEL + ADC12EOS;
ADC12MCTL1 = BATTERY_SENSE_INPUT_CHANNEL + ADC12EOS;
ADC12MCTL2 = LIGHT_SENSE_INPUT_CHANNEL + ADC12EOS;
}
unsigned int mw_get_battery_adc_val(void)
{
BATTERY_SENSE_ENABLE();
/* low_bat_en assertion to bat_sense valid is ~100 ns */
/* Start battery sense conversion */
CLEAR_START_ADDR();
ADC12CTL1 |= ADC12CSTARTADD_1;
ENABLE_ADC();
/* WaitForAdcBusy(); */
while (ADC12CTL1 & ADC12BUSY)
nop();
/* Convert the ADC count for the battery input into a voltage
* ADC12MEM1: Counts Battery Voltage in ADC counts
* Result: Battery voltage in millivolts */
BATTERY_SENSE_DISABLE();
return (unsigned int)(CONVERSION_FACTOR_BATTERY * (double)ADC12MEM1);
}
uint8_t mw_get_battery_percentage_from_val(unsigned int BattVal)
{
if (BattVal > BATTERY_FULL_LEVEL)
BattVal = BATTERY_FULL_LEVEL;
if (BattVal < BATTERY_CRITICAL_LEVEL)
BattVal = 0;
else
BattVal -= BATTERY_CRITICAL_LEVEL;
BattVal = (BattVal > 0) ? (BattVal * 10 / (BATTERY_LEVEL_RANGE / 10)) : 0;
return (unsigned char)BattVal;
}
uint16_t mw_get_amblight_adc_val(void)
{
LIGHT_SENSE_ENABLE();
CLEAR_START_ADDR();
ADC12CTL1 |= ADC12CSTARTADD_2;
ENABLE_ADC();
/* WaitForAdcBusy(); */
while (ADC12CTL1 & ADC12BUSY)
nop();
LIGHT_SENSE_DISABLE();
return ADC12MEM2;
}