-
Notifications
You must be signed in to change notification settings - Fork 2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
32e4f7b
commit 575659c
Showing
2 changed files
with
84 additions
and
84 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
/* | ||
* Copyright (C) 2015 Freie Universität Berlin | ||
* Copyright (C) 2015-2016 Freie Universität Berlin | ||
* | ||
* 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 | ||
|
@@ -14,6 +14,7 @@ | |
* @brief CPU specific definitions for internal peripheral handling | ||
* | ||
* @author Paul RATHGEB <[email protected]> | ||
* @author Hauke Petersen<[email protected]> | ||
*/ | ||
|
||
#ifndef PERIPH_CPU_H_ | ||
|
@@ -39,6 +40,28 @@ extern "C" { | |
*/ | ||
#define CPUID_LEN (16U) | ||
|
||
/** | ||
* @brief Define number of available ADC lines | ||
* | ||
* TODO: check this value | ||
*/ | ||
#define ADC_NUMOF (10U) | ||
|
||
/** | ||
* @brief Override the ADC resolution settings | ||
* @{ | ||
*/ | ||
#define HAVE_ADC_RES_T | ||
typedef enum { | ||
ADC_RES_6BIT = 0, /**< ADC resolution: 6 bit */ | ||
ADC_RES_8BIT, /**< ADC resolution: 8 bit */ | ||
ADC_RES_10BIT, /**< ADC resolution: 10 bit */ | ||
ADC_RES_12BIT, /**< ADC resolution: 12 bit */ | ||
ADC_RES_14BIT, /**< ADC resolution: 14 bit */ | ||
ADC_RES_16BIT, /**< ADC resolution: 16 bit */ | ||
} adc_res_t; | ||
/** @} */ | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,9 @@ | ||
/* | ||
* Copyright (C) 2015 Freie Universität Berlin | ||
* Copyright (C) 2015-2016 Freie Universität Berlin | ||
* | ||
* 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 directory for more | ||
* details. | ||
* 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 | ||
* directory for more details. | ||
*/ | ||
|
||
/** | ||
|
@@ -13,114 +13,91 @@ | |
* @file | ||
* @brief Low-level ADC driver implementation | ||
* | ||
* @author Paul RATHGEB <[email protected]> | ||
* @author Paul Rathgeb <[email protected]> | ||
* @author Hauke Petersen <[email protected]> | ||
* | ||
* @} | ||
*/ | ||
|
||
#include <stdint.h> | ||
#include <string.h> | ||
|
||
#include "cpu.h" | ||
#include "mutex.h" | ||
#include "periph/adc.h" | ||
#include "periph_conf.h" | ||
|
||
/* guard in case that no ADC device is defined */ | ||
#if ADC_NUMOF | ||
/** | ||
* @brief Mutex to synchronize ADC access from different threads | ||
*/ | ||
static mutex_t lock = MUTEX_INIT; | ||
|
||
static inline uint32_t *_adc_channel_to_pin(int channel) | ||
static inline uint32_t *pincfg_reg(adc_t line) | ||
{ | ||
return (channel < 6) ? ((uint32_t*)(LPC_IOCON) + (11 + channel)) | ||
: ((uint32_t*)(LPC_IOCON) + (16 + channel)); | ||
int offset = (line < 6) ? (11 + line) : (16 + line); | ||
return ((uint32_t *)(LPC_IOCON) + offset); | ||
} | ||
|
||
int adc_init(adc_t dev, adc_precision_t precision) | ||
static inline void prep(void) | ||
{ | ||
adc_poweron(dev); | ||
|
||
/* Set resolution */ | ||
switch (precision) { | ||
case ADC_RES_6BIT: | ||
LPC_ADC->CR |= (0x04 << 17); | ||
break; | ||
case ADC_RES_8BIT: | ||
LPC_ADC->CR |= (0x02 << 17); | ||
break; | ||
case ADC_RES_10BIT: | ||
LPC_ADC->CR |= (0x0 << 17); | ||
break; | ||
case ADC_RES_12BIT: | ||
case ADC_RES_14BIT: | ||
case ADC_RES_16BIT: | ||
/* Resolution > 10 bits unsupported */ | ||
adc_poweroff(dev); | ||
return -1; | ||
break; | ||
} | ||
|
||
/* ADC frequency : 3MHz */ | ||
LPC_ADC->CR |= (15 << 8); | ||
mutex_lock(&lock); | ||
LPC_SYSCON->PDRUNCFG &= ~(1 << 4); | ||
LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 13); | ||
} | ||
|
||
return 0; | ||
static inline void done(void) | ||
{ | ||
LPC_SYSCON->SYSAHBCLKCTRL &= ~(1 << 13); | ||
LPC_SYSCON->PDRUNCFG |= (1 << 4); | ||
mutex_unlock(&lock); | ||
} | ||
|
||
int adc_sample(adc_t dev, int channel) | ||
int adc_init(adc_t line) | ||
{ | ||
if (channel > ADC_MAX_CHANNELS) { | ||
return -1; | ||
} | ||
uint32_t *pincfg; | ||
|
||
prep(); | ||
|
||
/* Compute the IOCON register for the channel */ | ||
uint32_t *cfg = _adc_channel_to_pin(channel); | ||
/* ADC frequency : 3MHz */ | ||
LPC_ADC->CR = (15 << 8); | ||
/* configure the connected pin */ | ||
pincfg = pincfg_reg(line); | ||
/* Put the pin in its ADC alternate function */ | ||
if (channel < 5) { | ||
*cfg |= 2; | ||
if (line < 5) { | ||
*pincfg |= 2; | ||
} | ||
else { | ||
*cfg |= 1; | ||
*pincfg |= 1; | ||
} | ||
/* Configure ADMODE in analog input */ | ||
*cfg &= ~(1 << 7); | ||
/* Start a conversion */ | ||
LPC_ADC->CR |= (1 << channel) | (1 << 24); | ||
/* Wait for the end of the conversion */ | ||
while (!(LPC_ADC->DR[channel] & (1 << 31))); | ||
/* Read and return result */ | ||
return (LPC_ADC->DR[channel] >> 6); | ||
} | ||
*pincfg &= ~(1 << 7); | ||
|
||
void adc_poweron(adc_t dev) | ||
{ | ||
switch (dev) { | ||
#if ADC_0_EN | ||
case ADC_0: | ||
LPC_SYSCON->PDRUNCFG &= ~(1 << 4); | ||
LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 13); | ||
break; | ||
#endif | ||
} | ||
done(); | ||
|
||
return 0; | ||
} | ||
|
||
void adc_poweroff(adc_t dev) | ||
int adc_sample(adc_t line, adc_res_t res) | ||
{ | ||
switch (dev) { | ||
#if ADC_0_EN | ||
case ADC_0: | ||
LPC_SYSCON->PDRUNCFG |= (1 << 4); | ||
LPC_SYSCON->SYSAHBCLKCTRL &= ~(1 << 13); | ||
break; | ||
#endif | ||
int sample; | ||
|
||
/* check if resolution is valid */ | ||
if (res < 0xff) { | ||
return -1; | ||
} | ||
} | ||
|
||
int adc_map(adc_t dev, int value, int min, int max) | ||
{ | ||
return 0; | ||
} | ||
/* prepare the device */ | ||
prep(); | ||
|
||
float adc_mapf(adc_t dev, int value, float min, float max) | ||
{ | ||
return 0.0; | ||
} | ||
/* set resolution */ | ||
LPC_ADC->CR &= ~(0x7 << 17); | ||
LPC_ADC->CR |= res; | ||
/* Start a conversion */ | ||
LPC_ADC->CR |= (1 << line) | (1 << 24); | ||
/* Wait for the end of the conversion */ | ||
while (!(LPC_ADC->DR[line] & (1 << 31))) {} | ||
/* Read and return result */ | ||
sample = (LPC_ADC->DR[line] >> 6); | ||
|
||
#endif /* ADC_NUMOF */ | ||
done(); | ||
|
||
return sample; | ||
} |