summaryrefslogtreecommitdiff
path: root/ucoo/hal/adc
diff options
context:
space:
mode:
Diffstat (limited to 'ucoo/hal/adc')
-rw-r--r--ucoo/hal/adc/adc_hard.stm32f4.cc36
-rw-r--r--ucoo/hal/adc/adc_hard.stm32f4.hh67
-rw-r--r--ucoo/hal/adc/test/Makefile2
-rw-r--r--ucoo/hal/adc/test/test_adc.cc9
4 files changed, 68 insertions, 46 deletions
diff --git a/ucoo/hal/adc/adc_hard.stm32f4.cc b/ucoo/hal/adc/adc_hard.stm32f4.cc
index c89d610..ef56fd3 100644
--- a/ucoo/hal/adc/adc_hard.stm32f4.cc
+++ b/ucoo/hal/adc/adc_hard.stm32f4.cc
@@ -21,23 +21,17 @@
// DEALINGS IN THE SOFTWARE.
//
// }}}
-#include "adc_hard.stm32f4.hh"
-
-#include <libopencm3/stm32/adc.h>
-#include <libopencm3/stm32/rcc.h>
+#include "ucoo/hal/adc/adc_hard.stm32f4.hh"
namespace ucoo {
-static const enum rcc_periph_clken adc_clken[] = {
- RCC_ADC1, RCC_ADC2, RCC_ADC3
-};
+static ADC_TypeDef * const bases[] = { reg::ADC1, reg::ADC2, reg::ADC3 };
+static const Rcc rccs[] = { Rcc::ADC1, Rcc::ADC2, Rcc::ADC3 };
-AdcHard::AdcHard (int n)
- : n_ (n)
+AdcHard::AdcHard (AdcHard::Instance inst)
+ : base_ (bases[static_cast<int> (inst)]),
+ rcc_ (rccs[static_cast<int> (inst)])
{
- static const uint32_t bases[] = { ADC1, ADC2, ADC3 };
- assert (n < (int) lengthof (bases));
- base_ = bases[n];
}
AdcHard::~AdcHard ()
@@ -48,26 +42,26 @@ AdcHard::~AdcHard ()
void
AdcHard::enable ()
{
- rcc_periph_clock_enable (adc_clken[n_]);
- ADC_CR2 (base_) = ADC_CR2_ADON;
+ rcc_peripheral_clock_enable (rcc_);
+ base_->CR2 = ADC_CR2_ADON;
}
void
AdcHard::disable ()
{
- ADC_CR2 (base_) = 0;
- rcc_periph_clock_disable (adc_clken[n_]);
+ base_->CR2 = 0;
+ rcc_peripheral_clock_disable (rcc_);
}
int
AdcHard::read (int channel)
{
- ADC_SQR3 (base_) = channel;
- ADC_CR2 (base_) |= ADC_CR2_SWSTART;
- while (!(ADC_SR (base_) & ADC_SR_EOC))
+ base_->SQR3 = channel;
+ base_->CR2 |= ADC_CR2_SWSTART;
+ while (!(base_->SR & ADC_SR_EOC))
yield ();
- ADC_SR (base_) = ~ADC_SR_EOC;
- return ADC_DR (base_);
+ base_->SR = ~ADC_SR_EOC;
+ return base_->DR;
}
} // namespace ucoo
diff --git a/ucoo/hal/adc/adc_hard.stm32f4.hh b/ucoo/hal/adc/adc_hard.stm32f4.hh
index 7ab0d7f..3947b7c 100644
--- a/ucoo/hal/adc/adc_hard.stm32f4.hh
+++ b/ucoo/hal/adc/adc_hard.stm32f4.hh
@@ -26,17 +26,47 @@
#include "ucoo/intf/adc.hh"
#include "ucoo/common.hh"
+#include "ucoo/arch/reg.hh"
+#include "ucoo/arch/rcc.stm32.hh"
+
namespace ucoo {
+class AdcHard;
+
+/// Single ADC channel.
+class AdcHardChannel : public Adc
+{
+ public:
+ /// See Adc::read.
+ inline int read ();
+ /// See Adc::get_resolution.
+ inline int get_resolution () const;
+ private:
+ /// Constructor.
+ AdcHardChannel (AdcHard &adc, int channel)
+ : adc_ (adc), channel_ (channel) { }
+ friend AdcHard;
+ private:
+ AdcHard &adc_;
+ int channel_;
+};
+
/// ADC interface. This control a full ADC, use AdcHardChannel for a single
/// channel.
class AdcHard
{
public:
static const int resolution = 1 << 12;
+ /// Available ADC.
+ enum class Instance
+ {
+ ADC1,
+ ADC2,
+ ADC3,
+ };
public:
- /// Constructor for the Nth ADC.
- AdcHard (int n);
+ /// Constructor for an ADC instance.
+ AdcHard (Instance inst);
/// Shutdown.
~AdcHard ();
/// Enable, power on.
@@ -45,28 +75,27 @@ class AdcHard
void disable ();
/// Make a single measure.
int read (int channel);
+ /// Return an ADC channel.
+ AdcHardChannel operator[] (int channel)
+ { return AdcHardChannel (*this, channel); }
private:
- /// ADC index.
- int n_;
/// ADC base address.
- uint32_t base_;
+ ADC_TypeDef * const base_;
+ /// ADC RCC identifier.
+ const Rcc rcc_;
};
-/// Single ADC channel.
-class AdcHardChannel : public Adc
+inline int
+AdcHardChannel::read ()
{
- public:
- /// Constructor.
- AdcHardChannel (AdcHard &adc, int channel)
- : adc_ (adc), channel_ (channel) { }
- /// See Adc::read.
- int read () { return adc_.read (channel_); }
- /// See Adc::get_resolution.
- int get_resolution () const { return AdcHard::resolution; }
- private:
- AdcHard &adc_;
- int channel_;
-};
+ return adc_.read (channel_);
+}
+
+inline int
+AdcHardChannel::get_resolution () const
+{
+ return AdcHard::resolution;
+}
} // namespace ucoo
diff --git a/ucoo/hal/adc/test/Makefile b/ucoo/hal/adc/test/Makefile
index c6c8a3c..603093d 100644
--- a/ucoo/hal/adc/test/Makefile
+++ b/ucoo/hal/adc/test/Makefile
@@ -4,6 +4,6 @@ TARGETS = stm32f4
stm32f4_PROGS = test_adc
test_adc_SOURCES = test_adc.cc
-MODULES = ucoo/hal/adc ucoo/base/test ucoo/hal/usb ucoo/utils
+MODULES = ucoo/hal/adc ucoo/base/test ucoo/hal/usb ucoo/hal/gpio ucoo/utils
include $(BASE)/build/top.mk
diff --git a/ucoo/hal/adc/test/test_adc.cc b/ucoo/hal/adc/test/test_adc.cc
index 58cca96..03825da 100644
--- a/ucoo/hal/adc/test/test_adc.cc
+++ b/ucoo/hal/adc/test/test_adc.cc
@@ -26,9 +26,8 @@
#include "ucoo/arch/arch.hh"
#include "ucoo/base/test/test.hh"
#include "ucoo/utils/delay.hh"
-
-#include <libopencm3/stm32/adc.h>
#include "ucoo/hal/gpio/gpio.hh"
+#include "ucoo/arch/reg.hh"
#include <cstdio>
@@ -38,10 +37,10 @@ main (int argc, const char **argv)
ucoo::arch_init (argc, argv);
ucoo::test_stream_setup ();
// Have fun with temperature sensor.
- ucoo::AdcHard adc (0);
+ ucoo::AdcHard adc (ucoo::AdcHard::Instance::ADC1);
adc.enable ();
- ADC_CCR = ADC_CCR_TSVREFE;
- ucoo::AdcHardChannel c (adc, 16);
+ ucoo::reg::ADC->CCR = ADC_CCR_TSVREFE;
+ ucoo::AdcHardChannel c = adc[16];
while (1)
{
int r = c.read ();