stm32f0/f3: adc: extract beginnings of common v2 periph

The f0, f30x and l0 have a very similar "v2" adc peripheral.
Start extracting out some of the common code, and fix the glaring bug in
adc_power_down that was affecting them both.

This is not intended to be a fully comprehensive extraction, just the first
easy steps.
This commit is contained in:
Karl Palsson 2015-10-16 22:37:54 +00:00
parent 0758deb04d
commit a89cd86454
8 changed files with 175 additions and 63 deletions

View File

@ -0,0 +1,54 @@
/** @addtogroup adc_defines
@author @htmlonly &copy; @endhtmlonly 2015 Karl Palsson <karlp@tweak.net.au>
*/
/*
* This file is part of the libopencm3 project.
*
* Copyright (C) 2015 Karl Palsson <karlp@tweak.net.au>
*
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
/**@{*/
/* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY, BUT ONLY VIA ADC.H
The order of header inclusion is important. adc.h includes the device
specific memorymap.h header before including this header file.*/
/** @cond */
#ifdef LIBOPENCM3_ADC_H
/** @endcond */
#ifndef LIBOPENCM3_ADC_COMMON_V2_H
#define LIBOPENCM3_ADC_COMMON_V2_H
/* --- Function prototypes ------------------------------------------------- */
BEGIN_DECLS
void adc_power_on_async(uint32_t adc);
void adc_power_on(uint32_t adc);
bool adc_is_power_on(uint32_t adc);
void adc_power_off_async(uint32_t adc);
void adc_power_off(uint32_t adc);
bool adc_is_power_off(uint32_t adc);
END_DECLS
#endif
#endif /* LIBOPENCM3_ADC_H */
/**@}*/

View File

@ -33,6 +33,8 @@
#ifndef LIBOPENCM3_ADC_H
#define LIBOPENCM3_ADC_H
#include <libopencm3/stm32/common/adc_common_v2.h>
/*****************************************************************************/
/* Module definitions */
/*****************************************************************************/
@ -305,8 +307,6 @@ void adc_enable_eoc_interrupt(uint32_t adc);
void adc_disable_eoc_interrupt(uint32_t adc);
/* Basic configuration */
void adc_power_off(uint32_t adc);
void adc_power_on(uint32_t adc);
void adc_set_clk_source(uint32_t adc, uint32_t source);
void adc_set_regular_sequence(uint32_t adc, uint8_t length, uint8_t channel[]);
void adc_set_sample_time_on_all_channels(uint32_t adc, uint8_t time);

View File

@ -34,6 +34,8 @@
#ifndef LIBOPENCM3_ADC_H
#define LIBOPENCM3_ADC_H
#include <libopencm3/stm32/common/adc_common_v2.h>
#define ADC1 ADC1_BASE
#define ADC2 ADC2_BASE
#define ADC3 ADC3_BASE
@ -863,8 +865,6 @@
BEGIN_DECLS
void adc_power_on(uint32_t adc);
void adc_power_off(uint32_t adc);
void adc_enable_analog_watchdog_regular(uint32_t adc);
void adc_disable_analog_watchdog_regular(uint32_t adc);
void adc_enable_analog_watchdog_injected(uint32_t adc);

View File

@ -0,0 +1,115 @@
/** @addtogroup adc_file
@author @htmlonly &copy; @endhtmlonly
2015 Karl Palsson <karlp@tweak.net.au>
This library supports one style of the Analog to Digital Conversion System in
the STM32 series of ARM Cortex Microcontrollers by ST Microelectronics.
The style of ADC Peripheral supported by this code is found in the F0, L0 and
F30x series devices (at the time of writing)
LGPL License Terms @ref lgpl_license
*/
/*
* This file is part of the libopencm3 project.
*
* Copyright (C) 2015 Karl Palsson <karlp@tweak.net.au>
*
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
/**@{*/
#include <libopencm3/stm32/adc.h>
/**
* Turn on the ADC (async)
* @sa adc_wait_power_on
* @param adc ADC Block register address base @ref adc_reg_base
*/
void adc_power_on_async(uint32_t adc)
{
ADC_CR(adc) |= ADC_CR_ADEN;
}
/**
* Is the ADC powered up and ready?
* @sa adc_power_on_async
* @param adc ADC Block register address base @ref adc_reg_base
* @return true if adc is ready for use
*/
bool adc_is_power_on(uint32_t adc)
{
return (ADC_ISR(adc) & ADC_ISR_ADRDY);
}
/**
* Turn on the ADC
* @sa adc_power_on_async
* @param adc ADC Block register address base @ref adc_reg_base
*/
void adc_power_on(uint32_t adc)
{
adc_power_on_async(adc);
while (!adc_is_power_on(adc));
}
/**
* Turn off the ADC (async)
* This will actually block if it needs to turn off a currently running
* conversion, as per ref man. (Handles injected on hardware that supports
* injected conversions.
* @sa adc_wait_power_off
* @param adc ADC Block register address base @ref adc_reg_base
*/
void adc_power_off_async(uint32_t adc)
{
uint32_t checks = ADC_CR_ADSTART;
uint32_t stops = ADC_CR_ADSTP;
#if defined (ADC_CR_JADSTART)
checks |= ADC_CR_JADSTART;
stops |= ADC_CR_JADSTP;
#endif
if (ADC_CR(adc) & checks) {
ADC_CR(adc) |= stops;
while (ADC_CR(adc) & checks);
}
ADC_CR(adc) |= ADC_CR_ADDIS;
}
/**
* Is the ADC powered down?
* @sa adc_power_off_async
* @param adc ADC Block register address base @ref adc_reg_base
*/
bool adc_is_power_off(uint32_t adc)
{
return (!(ADC_CR(adc) & ADC_CR_ADEN));
}
/**
* Turn off the ADC
* This will actually block if it needs to turn off a currently running
* conversion, as per ref man.
* @sa adc_power_off_async
* @param adc ADC Block register address base @ref adc_reg_base
*/
void adc_power_off(uint32_t adc)
{
adc_power_off_async(adc);
while (!adc_is_power_off(adc));
}

View File

@ -43,6 +43,7 @@ OBJS += gpio_common_all.o gpio_common_f0234.o crc_common_all.o \
dma_common_l1f013.o exti_common_all.o spi_common_all.o \
spi_common_f03.o flash_common_f01.o dac_common_all.o \
timer_common_all.o rcc_common_all.o
OBJS += adc_common_v2.o
OBJS += crs_common_all.o
OBJS += usb.o usb_control.o usb_standard.o

View File

@ -461,34 +461,6 @@ void adc_disable_eoc_interrupt(uint32_t adc)
*
*@{*/
/*---------------------------------------------------------------------------*/
/** @brief ADC Power Off
*
* Turn off the ADC to reduce power consumption to a few microamps.
*
* @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base)
*/
void adc_power_off(uint32_t adc)
{
ADC_CR(adc) &= ~ADC_CR_ADEN;
}
/*---------------------------------------------------------------------------*/
/** @brief ADC Power On
*
* If the ADC is in power-down mode then it is powered up. The application
* needs to wait a time of about 3 microseconds for stabilization before using
* the ADC. If the ADC is already on this function call will have no effect.
*
* @param[in] adc Unsigned int32. ADC base address (@ref adc_reg_base)
*/
void adc_power_on(uint32_t adc)
{
ADC_CR(adc) |= ADC_CR_ADEN;
}
/*---------------------------------------------------------------------------*/
/** @brief ADC Set Clock Prescale
*

View File

@ -43,6 +43,7 @@ OBJS += gpio_common_all.o gpio_common_f0234.o \
iwdg_common_all.o spi_common_all.o dma_common_l1f013.o\
timer_common_all.o timer_common_f234.o flash_common_f234.o \
flash.o exti_common_all.o rcc_common_all.o spi_common_f03.o
OBJS += adc_common_v2.o
OBJS += usb.o usb_control.o usb_standard.o
OBJS += st_usbfs_core.o st_usbfs_v1.o

View File

@ -88,20 +88,6 @@
/**@{*/
/*---------------------------------------------------------------------------*/
/** @brief ADC Off
*
* Turn off the ADC to reduce power consumption to a few microamps.
*
* @param[in] adc Unsigned int32. ADC block register address base @ref
* adc_reg_base
*/
void adc_power_off(uint32_t adc)
{
ADC_CR(adc) &= ~ADC_CR_ADEN;
}
/*---------------------------------------------------------------------------*/
/** @brief ADC Enable Analog Watchdog for Regular Conversions
*
@ -905,23 +891,6 @@ void adc_set_injected_offset(uint32_t adc, uint8_t reg, uint32_t offset)
}
}
/*---------------------------------------------------------------------------*/
/** @brief ADC Power On
*
* If the ADC is in power-down mode then it is powered up. The application
* needs to wait a time of about 3 microseconds for stabilization before using
* the ADC. If the ADC is already on this function call will have no effect.
*
* @param[in] adc Unsigned int32. ADC block register address base @ref
* adc_reg_base
*/
void adc_power_on(uint32_t adc)
{
ADC_CR(adc) |= ADC_CR_ADEN;
}
/*---------------------------------------------------------------------------*/
/** @brief ADC Set Clock Prescale
*