diff --git a/include/msp430fr5969lp/driver/adc.h b/include/msp430fr5969lp/driver/adc.h
new file mode 100644
index 0000000000000000000000000000000000000000..d93aed43b45c351ec0c97371ba00f346b4c4a758
--- /dev/null
+++ b/include/msp430fr5969lp/driver/adc.h
@@ -0,0 +1,17 @@
+#ifndef ADC_H
+#define ADC_H
+
+class ADC {
+	private:
+		ADC(ADC const &copy);
+
+	public:
+		ADC() {}
+
+		float getTemp();
+		float getVCC();
+};
+
+extern ADC adc;
+
+#endif
diff --git a/src/arch/msp430fr5969lp/Makefile.inc b/src/arch/msp430fr5969lp/Makefile.inc
index 6d2ae6a0d4e909ec5cf56a657c835ce89cba43d7..8d3647d31e8592d49fbdd1e5520e6ad9253480ca 100644
--- a/src/arch/msp430fr5969lp/Makefile.inc
+++ b/src/arch/msp430fr5969lp/Makefile.inc
@@ -11,6 +11,7 @@ CXX = /opt/msp430/ti/gcc/bin/msp430-elf-g++
 OBJCOPY = /opt/msp430/ti/gcc/bin/msp430-elf-objcopy
 
 TARGETS += src/arch/msp430fr5969lp/arch.cc
+TARGETS += src/arch/msp430fr5969lp/driver/adc.cc
 TARGETS += src/arch/msp430fr5969lp/driver/gpio.cc
 TARGETS += src/arch/msp430fr5969lp/driver/stdout.cc
 TARGETS += src/arch/msp430fr5969lp/driver/uptime.cc
diff --git a/src/arch/msp430fr5969lp/driver/adc.cc b/src/arch/msp430fr5969lp/driver/adc.cc
new file mode 100644
index 0000000000000000000000000000000000000000..5a044a6986b72ab00ac0e3f028a8f5845d7acc3f
--- /dev/null
+++ b/src/arch/msp430fr5969lp/driver/adc.cc
@@ -0,0 +1,71 @@
+#include "driver/adc.h"
+#include <msp430.h>
+
+#define CALADC12_12V_30C  *((unsigned int *)0x1A1A)
+#define CALADC12_12V_85C  *((unsigned int *)0x1A1C)
+
+float ADC::getTemp()
+{
+	float ret;
+
+	while(REFCTL0 & REFGENBUSY);
+
+	REFCTL0 = REFVSEL_0 | REFON;
+	ADC12CTL0 &= ~ADC12ENC;
+	ADC12CTL0 = ADC12SHT0_8 | ADC12ON;
+	ADC12CTL1 = ADC12SHP;
+	ADC12CTL3 = ADC12TCMAP;
+	ADC12MCTL0 = ADC12VRSEL_1 | ADC12INCH_30;
+	while(!(REFCTL0 & REFGENRDY));
+
+	ADC12CTL0 |= ADC12ENC;
+	ADC12CTL0 |= ADC12SC;
+	while (ADC12CTL1 & ADC12BUSY);
+
+	ret = (float)((long)ADC12MEM0 - CALADC12_12V_30C) * (85 - 30) /
+		(CALADC12_12V_85C - CALADC12_12V_30C) + 30.0f;
+
+	// Disable ADC
+	ADC12CTL0 &= ~ADC12ENC; // disable any conversion to allow ADC configuration
+	ADC12CTL0 &= ~ADC12ON; // Turn off ADC
+
+	// Disable internal 2V reference
+	while(REFCTL0 & REFGENBUSY);
+	REFCTL0 &= ~REFON;
+
+	return ret;
+}
+
+float ADC::getVCC()
+{
+	float ret;
+
+	while(REFCTL0 & REFGENBUSY);
+
+	REFCTL0 = REFVSEL_1 | REFON;
+	ADC12CTL0 &= ~ADC12ENC;
+	ADC12CTL0 = ADC12SHT0_8 | ADC12ON;
+	ADC12CTL1 = ADC12SHP;
+	ADC12CTL3 = ADC12BATMAP;
+	ADC12MCTL0 = ADC12VRSEL_1 | ADC12INCH_31;
+	while(!(REFCTL0 & REFGENRDY));
+
+	ADC12CTL0 |= ADC12ENC;
+	ADC12CTL0 |= ADC12SC;
+	while (ADC12CTL1 & ADC12BUSY);
+
+	ret = (float)ADC12MEM0 / 4096 * 2 * 2;
+	return ret;
+
+	// Disable ADC
+	ADC12CTL0 &= ~ADC12ENC; // disable any conversion to allow ADC configuration
+	ADC12CTL0 &= ~ADC12ON; // Turn off ADC
+
+	// Disable internal 2V reference
+	while(REFCTL0 & REFGENBUSY);
+	REFCTL0 &= ~REFON;
+
+	return ret;
+}
+
+ADC adc;