mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
Merge pull request #9722 from smlng/pr/cc2538/adc
cpu/cc2538: enhance periph ADC
This commit is contained in:
commit
dc6eb82406
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
|
@ -21,22 +21,31 @@
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "vendor/hw_memmap.h"
|
||||
#include "vendor/hw_soc_adc.h"
|
||||
|
||||
#include "cpu.h"
|
||||
#include "periph/hwrng.h"
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
static cc2538_soc_adc_t *soc_adc = (cc2538_soc_adc_t *)SOC_ADC_BASE;
|
||||
|
||||
void hwrng_init(void)
|
||||
{
|
||||
uint16_t seed = 0;
|
||||
int i;
|
||||
|
||||
/* Make sure the RNG is on */
|
||||
SOC_ADC->cc2538_adc_adccon1.ADCCON1bits.RCTRL = 0;
|
||||
uint32_t reg32 = soc_adc->ADCCON1 & ~(SOC_ADC_ADCCON1_RCTRL_M);
|
||||
soc_adc->ADCCON1 = reg32;
|
||||
|
||||
/* Enable clock for the RF Core */
|
||||
SYS_CTRL_RCGCRFC = 1;
|
||||
|
||||
/* Wait for the clock ungating to take effect */
|
||||
while (SYS_CTRL_RCGCRFC != 1);
|
||||
while (SYS_CTRL_RCGCRFC != 1) {}
|
||||
|
||||
/* Infinite RX - FRMCTRL0[3:2] = 10. This will mess with radio operation */
|
||||
RFCORE_XREG_FRMCTRL0 = 0x00000008;
|
||||
@ -63,8 +72,8 @@ void hwrng_init(void)
|
||||
}
|
||||
|
||||
/* Seed the high byte first: */
|
||||
SOC_ADC_RNDL = (seed >> 8) & 0xff;
|
||||
SOC_ADC_RNDL = seed & 0xff;
|
||||
soc_adc->RNDH = (seed >> 8) & 0xff;
|
||||
soc_adc->RNDL = seed & 0xff;
|
||||
|
||||
/* Turn RF off: */
|
||||
RFCORE_SFR_RFST = ISRFOFF;
|
||||
@ -72,16 +81,16 @@ void hwrng_init(void)
|
||||
|
||||
void hwrng_read(void *buf, unsigned int num)
|
||||
{
|
||||
unsigned count;
|
||||
uint8_t *b = (uint8_t *)buf;
|
||||
|
||||
for (count = 0; count < num; ) {
|
||||
for (unsigned count = 0; count < num; count++) {
|
||||
/* Clock the RNG LSFR once: */
|
||||
SOC_ADC->cc2538_adc_adccon1.ADCCON1bits.RCTRL = 1;
|
||||
|
||||
soc_adc->ADCCON1 = soc_adc->ADCCON1 | (1UL << SOC_ADC_ADCCON1_RCTRL_S);
|
||||
/* Read up to 2 bytes of hwrng data: */
|
||||
b[count++] = SOC_ADC_RNDL;
|
||||
if (count >= num) break;
|
||||
b[count++] = SOC_ADC_RNDH;
|
||||
b[count] = soc_adc->RNDL;
|
||||
count++;
|
||||
if (count < num) {
|
||||
b[count] = soc_adc->RNDH;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user