1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

cpu/cc2538: enhance periph ADC

Adapt the periph ADC implementation to use vendor defines where
    ever possible. Remove duplicate or obsolete defines and adapt
    board configuration as required.
This commit is contained in:
smlng 2018-08-06 21:44:00 +02:00
parent 11f1955ad4
commit d40cfab95a
10 changed files with 40 additions and 82 deletions

View File

@ -118,7 +118,7 @@ static const spi_conf_t spi_config[] = {
* @name ADC configuration
* @{
*/
#define SOC_ADC_ADCCON_REF SOC_ADC_ADCCON_REF_AVDD5
#define SOC_ADC_ADCCON3_EREF SOC_ADC_ADCCON3_EREF_AVDD5
static const adc_conf_t adc_config[] = {
GPIO_PIN(0, 6), /**< GPIO_PA6 = ADC_ALS_PIN */

View File

@ -71,7 +71,7 @@ static const timer_conf_t timer_config[] = {
* @name ADC configuration
* @{
*/
#define SOC_ADC_ADCCON_REF SOC_ADC_ADCCON_REF_AVDD5
#define SOC_ADC_ADCCON3_EREF SOC_ADC_ADCCON3_EREF_AVDD5
static const adc_conf_t adc_config[] = {
GPIO_PIN(1, 0), /**< GPIO_PB0 = GPIO0_PIN */

View File

@ -69,7 +69,7 @@ static const timer_conf_t timer_config[] = {
* @name ADC configuration
* @{
*/
#define SOC_ADC_ADCCON_REF SOC_ADC_ADCCON_REF_AVDD5
#define SOC_ADC_ADCCON3_EREF SOC_ADC_ADCCON3_EREF_AVDD5
static const adc_conf_t adc_config[] = {
GPIO_PIN(0, 2), /**< GPIO_PA2 = AD4_PIN */

View File

@ -73,7 +73,7 @@ static const spi_conf_t spi_config[] = {
* @name ADC configuration
* @{
*/
#define SOC_ADC_ADCCON_REF SOC_ADC_ADCCON_REF_AVDD5
#define SOC_ADC_ADCCON3_EREF SOC_ADC_ADCCON3_EREF_AVDD5
static const adc_conf_t adc_config[] = {
GPIO_PIN(0, 6), /**< GPIO_PA6 = ADC2_PIN */

View File

@ -73,7 +73,7 @@ static const spi_conf_t spi_config[] = {
* @name ADC configuration
* @{
*/
#define SOC_ADC_ADCCON_REF SOC_ADC_ADCCON_REF_AVDD5
#define SOC_ADC_ADCCON3_EREF SOC_ADC_ADCCON3_EREF_AVDD5
static const adc_conf_t adc_config[] = {
GPIO_PIN(0, 5), /**< GPIO_PA5 = ADC1_PIN */

View File

@ -75,7 +75,7 @@ static const spi_conf_t spi_config[] = {
* @name ADC configuration
* @{
*/
#define SOC_ADC_ADCCON_REF SOC_ADC_ADCCON_REF_AVDD5
#define SOC_ADC_ADCCON3_EREF SOC_ADC_ADCCON3_EREF_AVDD5
static const adc_conf_t adc_config[] = {
GPIO_PIN(0, 5), /**< GPIO_PA5 = ADC1_PIN */

View File

@ -675,14 +675,6 @@ typedef volatile uint32_t cc2538_reg_t; /**< Least-significant 32 bits of the IE
#define SMWDTHROSC_STCV2 ( *(cc2538_reg_t*)0x400d5064 ) /**< Sleep Timer Capture value byte 2 */
#define SMWDTHROSC_STCV3 ( *(cc2538_reg_t*)0x400d5068 ) /**< Sleep Timer Capture value byte 3 */
#define ANA_REGS_IVCTRL ( *(cc2538_reg_t*)0x400d6004 ) /**< Analog control register */
#define SOC_ADC_ADCCON1 ( *(cc2538_reg_t*)0x400d7000 ) /**< ADC Control Register 1 */
#define SOC_ADC_ADCCON2 ( *(cc2538_reg_t*)0x400d7004 ) /**< ADC Control Register 2 */
#define SOC_ADC_ADCCON3 ( *(cc2538_reg_t*)0x400d7008 ) /**< ADC Control Register 3 */
#define SOC_ADC_ADCL ( *(cc2538_reg_t*)0x400d700c ) /**< Least-significant part of ADC conversion result. */
#define SOC_ADC_ADCH ( *(cc2538_reg_t*)0x400d7010 ) /**< Most-significant part of ADC conversion result. */
#define SOC_ADC_RNDL ( *(cc2538_reg_t*)0x400d7014 ) /**< Random-number-generator data; low byte. */
#define SOC_ADC_RNDH ( *(cc2538_reg_t*)0x400d7018 ) /**< Random-number-generator data; high byte. */
#define SOC_ADC_CMPCTL ( *(cc2538_reg_t*)0x400d7024 ) /**< Analog comparator control and status register. */
#define GPIO_A_DATA ( *(cc2538_reg_t*)0x400d9000 ) /**< GPIO_A Data Register */
#define GPIO_A_DIR ( *(cc2538_reg_t*)0x400d9400 ) /**< GPIO_A data direction register */
#define GPIO_A_IS ( *(cc2538_reg_t*)0x400d9404 ) /**< GPIO_A Interrupt Sense register */

View File

@ -1,5 +1,6 @@
/*
* Copyright (C) 2014 Loci Controls Inc.
* 2018 HAW Hamburg
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
@ -15,6 +16,7 @@
* @brief CC2538 SOC ADC interface
*
* @author Ian Martin <ian@locicontrols.com>
* @author Sebastian Meiling <s@mlng.net>
*/
#ifndef CC2538_SOC_ADC_H
@ -30,34 +32,17 @@ extern "C" {
* @brief SOC ADC component registers
*/
typedef struct {
/**
* @brief ADC control register
*/
union {
cc2538_reg_t ADCCON1; /**< ADC Control Register 1 */
struct {
cc2538_reg_t RESERVED2 : 2; /**< Reserved bits */
cc2538_reg_t RCTRL : 2; /**< Random number generator control */
cc2538_reg_t STSEL : 2; /**< Start select */
cc2538_reg_t ST : 1; /**< Start conversion */
cc2538_reg_t EOC : 1; /**< End of conversion */
cc2538_reg_t RESERVED1 : 24; /**< Reserved bits */
} ADCCON1bits;
} cc2538_adc_adccon1;
cc2538_reg_t ADCCON2; /**< ADC Control Register 2 */
cc2538_reg_t ADCCON3; /**< ADC Control Register 3 */
cc2538_reg_t ADCL; /**< Least-significant part of ADC conversion result. */
cc2538_reg_t ADCH; /**< Most-significant part of ADC conversion result. */
cc2538_reg_t RNDL; /**< Random-number-generator data; low byte. */
cc2538_reg_t RNDH; /**< Random-number-generator data; high byte. */
cc2538_reg_t RESERVED[2]; /**< Reserved bytes */
cc2538_reg_t CMPCTL; /**< Analog comparator control and status register. */
cc2538_reg_t ADCCON1; /**< ADC Control Register 1 */
cc2538_reg_t ADCCON2; /**< ADC Control Register 2 */
cc2538_reg_t ADCCON3; /**< ADC Control Register 3 */
cc2538_reg_t ADCL; /**< Least-significant part of ADC conversion result. */
cc2538_reg_t ADCH; /**< Most-significant part of ADC conversion result. */
cc2538_reg_t RNDL; /**< Random-number-generator data; low byte. */
cc2538_reg_t RNDH; /**< Random-number-generator data; high byte. */
cc2538_reg_t RESERVED[2]; /**< Reserved bytes */
cc2538_reg_t CMPCTL; /**< Analog comparator control and status register. */
} cc2538_soc_adc_t;
#define SOC_ADC ( (cc2538_soc_adc_t*)0x400d7000 ) /**< One and only instance of the SOC ADC component */
#ifdef __cplusplus
} /* end extern "C" */
#endif

View File

@ -24,6 +24,8 @@
#include <stdint.h>
#include <stdio.h>
#include "vendor/hw_soc_adc.h"
#include "cpu.h"
#include "vendor/hw_ssi.h"
@ -264,36 +266,13 @@ typedef enum {
typedef gpio_t adc_conf_t;
/**
* @name SOC_ADC_ADCCON3 register bit masks
* @name SOC_ADC_ADCCON3_EREF registers field values
* @{
*/
#define SOC_ADC_ADCCON3_EREF (0x000000C0) /**< Reference voltage for extra */
#define SOC_ADC_ADCCON3_EDIV (0x00000030) /**< Decimation rate for extra */
#define SOC_ADC_ADCCON3_ECH (0x0000000F) /**< Single channel select */
/** @} */
/**
* @name SOC_ADC_ADCCONx registers field values
* @{
*/
#define SOC_ADC_ADCCON_REF_INT (0 << 6) /**< Internal reference */
#define SOC_ADC_ADCCON_REF_EXT (1 << 6) /**< External reference on AIN7 pin */
#define SOC_ADC_ADCCON_REF_AVDD5 (2 << 6) /**< AVDD5 pin */
#define SOC_ADC_ADCCON_REF_DIFF (3 << 6) /**< External reference on AIN6-AIN7 differential input */
#define SOC_ADC_ADCCON_CH_GND (0xC) /**< GND */
/** @} */
/**
* @brief Mask to check end-of-conversion (EOC) bit
*/
#define SOC_ADC_ADCCON1_EOC_MASK (0x80)
/**
* @name Masks for ADC raw data
* @{
*/
#define SOC_ADC_ADCL_MASK (0x000000FC)
#define SOC_ADC_ADCH_MASK (0x000000FF)
#define SOC_ADC_ADCCON3_EREF_INT (0 << SOC_ADC_ADCCON3_EREF_S) /**< Internal reference */
#define SOC_ADC_ADCCON3_EREF_EXT (1 << SOC_ADC_ADCCON3_EREF_S) /**< External reference on AIN7 pin */
#define SOC_ADC_ADCCON3_EREF_AVDD5 (2 << SOC_ADC_ADCCON3_EREF_S) /**< AVDD5 pin */
#define SOC_ADC_ADCCON3_EREF_DIFF (3 << SOC_ADC_ADCCON3_EREF_S) /**< External reference on AIN6-AIN7 differential input */
/** @} */
/**

View File

@ -20,6 +20,9 @@
* @}
*/
#include "vendor/hw_memmap.h"
#include "vendor/hw_soc_adc.h"
#include "board.h"
#include "cpu.h"
#include "periph_conf.h"
@ -29,6 +32,8 @@
#define ENABLE_DEBUG (0)
#include "debug.h"
static cc2538_soc_adc_t *soc_adc = (cc2538_soc_adc_t *)SOC_ADC_BASE;
int adc_init(adc_t line)
{
if (line >= ADC_NUMOF) {
@ -36,11 +41,10 @@ int adc_init(adc_t line)
return -1;
}
cc2538_soc_adc_t *adca = SOC_ADC;
/* stop random number generator, and set STSEL = 1 */
adca->cc2538_adc_adccon1.ADCCON1 = 0x3c;
soc_adc->ADCCON1 = (SOC_ADC_ADCCON1_STSEL_M | SOC_ADC_ADCCON1_RCTRL_M);
/* disable any DMA, continous ADC settings */
adca->ADCCON2 = 0x0;
soc_adc->ADCCON2 = 0x0;
/* configure ADC GPIO as analog input */
gpio_init(adc_config[line], GPIO_IN_ANALOG);
@ -83,25 +87,23 @@ int adc_sample(adc_t line, adc_res_t res)
*/
rshift--;
cc2538_soc_adc_t *adca = SOC_ADC;
/* configure adc line with parameters and trigger a single conversion*/
uint32_t reg = (adca->ADCCON3) & ~(SOC_ADC_ADCCON3_EREF |
SOC_ADC_ADCCON3_EDIV |
SOC_ADC_ADCCON3_ECH);
adca->ADCCON3 = reg | res | SOC_ADC_ADCCON_REF |
(adc_config[line] & GPIO_PIN_MASK);
uint32_t reg = (soc_adc->ADCCON3) & ~(SOC_ADC_ADCCON3_EREF_M |
SOC_ADC_ADCCON3_EDIV_M |
SOC_ADC_ADCCON3_ECH_M);
soc_adc->ADCCON3 = reg | res | SOC_ADC_ADCCON3_EREF |
(adc_config[line] & GPIO_PIN_MASK);
DEBUG("ADCCON1: %"PRIu32" ADCCON2: %"PRIu32" ADCCON3: %"PRIu32"\n",
adca->cc2538_adc_adccon1.ADCCON1, adca->ADCCON2, adca->ADCCON3);
soc_adc->ADCCON1, soc_adc->ADCCON2, soc_adc->ADCCON3);
/* Poll/wait until end of conversion */
while ((adca->cc2538_adc_adccon1.ADCCON1 &
SOC_ADC_ADCCON1_EOC_MASK) == 0) {}
while ((soc_adc->ADCCON1 & SOC_ADC_ADCCON1_EOC_M) == 0) {}
/* Read result after conversion completed,
* reading SOC_ADC_ADCH last will clear SOC_ADC_ADCCON1.EOC */
int16_t sample = adca->ADCL & SOC_ADC_ADCL_MASK;
sample |= (adca->ADCH & SOC_ADC_ADCH_MASK) << 8;
int16_t sample = soc_adc->ADCL & SOC_ADC_ADCL_ADC_M;
sample |= (soc_adc->ADCH & SOC_ADC_ADCH_ADC_M) << 8;
/* sample right shifted depending on resolution */
sample = sample >> rshift;
DEBUG("adc_sample: raw value %"PRIi16"\n", sample);