cpu/lpc11u34: fixed ADC driver

- fixed selection of resolution
- fixed result masking
- fixed channel selection (and optimized it)
- fixed clock prescaler calculation
This commit is contained in:
Hauke Petersen 2017-04-25 15:29:54 +02:00
parent da4f2f6e6e
commit ae3f0193b8
2 changed files with 25 additions and 19 deletions

View File

@ -44,10 +44,8 @@ extern "C" {
/** /**
* @brief Define number of available ADC lines * @brief Define number of available ADC lines
*
* TODO: check this value
*/ */
#define ADC_NUMOF (10U) #define ADC_NUMOF (8U)
/** /**
* @brief Override the default GPIO type * @brief Override the default GPIO type
@ -95,12 +93,12 @@ typedef enum {
*/ */
#define HAVE_ADC_RES_T #define HAVE_ADC_RES_T
typedef enum { typedef enum {
ADC_RES_6BIT = 0, /**< ADC resolution: 6 bit */ ADC_RES_6BIT = (0x4 << 17), /**< ADC resolution: 6 bit */
ADC_RES_8BIT, /**< ADC resolution: 8 bit */ ADC_RES_8BIT = (0x2 << 17), /**< ADC resolution: 8 bit */
ADC_RES_10BIT, /**< ADC resolution: 10 bit */ ADC_RES_10BIT = (0x0 << 17), /**< ADC resolution: 10 bit */
ADC_RES_12BIT, /**< ADC resolution: 12 bit */ ADC_RES_12BIT = 1, /**< ADC resolution: 12 bit, no supported */
ADC_RES_14BIT, /**< ADC resolution: 14 bit */ ADC_RES_14BIT = 2, /**< ADC resolution: 14 bit, no supported */
ADC_RES_16BIT, /**< ADC resolution: 16 bit */ ADC_RES_16BIT = 3, /**< ADC resolution: 16 bit, no supported */
} adc_res_t; } adc_res_t;
/** @} */ /** @} */
#endif /* ndef DOXYGEN */ #endif /* ndef DOXYGEN */

View File

@ -24,8 +24,19 @@
#include "cpu.h" #include "cpu.h"
#include "mutex.h" #include "mutex.h"
#include "assert.h"
#include "periph/adc.h" #include "periph/adc.h"
#define START_CMD (0x1 << 24)
#define DONE_BIT (0x1 << 31)
#define RES_MASK (0xf << 17)
#define SAMPLE_SHIFT (6)
#define SAMPLE_MASK (0x3ff)
/* we chose an ADC clock smaller or equal than but close to 4.5MHz (as proposed
* in the reference manual) */
#define CLK_DIV (((CLOCK_CORECLOCK / 45000000) & 0xff) << 8)
/** /**
* @brief Mutex to synchronize ADC access from different threads * @brief Mutex to synchronize ADC access from different threads
*/ */
@ -57,8 +68,6 @@ int adc_init(adc_t line)
prep(); prep();
/* ADC frequency : 3MHz */
LPC_ADC->CR = (15 << 8);
/* configure the connected pin */ /* configure the connected pin */
pincfg = pincfg_reg(line); pincfg = pincfg_reg(line);
/* Put the pin in its ADC alternate function */ /* Put the pin in its ADC alternate function */
@ -80,23 +89,22 @@ int adc_sample(adc_t line, adc_res_t res)
{ {
int sample; int sample;
assert(line < ADC_NUMOF);
/* check if resolution is valid */ /* check if resolution is valid */
if (res < 0xff) { if (res & ~(RES_MASK)) {
return -1; return -1;
} }
/* prepare the device */ /* prepare the device */
prep(); prep();
/* set resolution */ /* start conversion */
LPC_ADC->CR &= ~(0x7 << 17); LPC_ADC->CR = ((1 << line) | CLK_DIV | res | START_CMD);
LPC_ADC->CR |= res;
/* Start a conversion */
LPC_ADC->CR |= (1 << line) | (1 << 24);
/* Wait for the end of the conversion */ /* Wait for the end of the conversion */
while (!(LPC_ADC->DR[line] & (1 << 31))) {} while (!(LPC_ADC->DR[line] & DONE_BIT)) {}
/* Read and return result */ /* Read and return result */
sample = (LPC_ADC->DR[line] >> 6); sample = ((LPC_ADC->DR[line] >> SAMPLE_SHIFT) & SAMPLE_MASK);
done(); done();