mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
cpu/rpx0xx: add minimal ADC support
Signed-off-by: Dylan Laduranty <dylan.laduranty@mesotic.com>
This commit is contained in:
parent
9c5e508d2f
commit
aaecb5419e
@ -1,5 +1,6 @@
|
||||
CPU := rpx0xx
|
||||
|
||||
# Put defined MCU peripherals here (in alphabetical order)
|
||||
FEATURES_PROVIDED += periph_adc
|
||||
FEATURES_PROVIDED += periph_timer
|
||||
FEATURES_PROVIDED += periph_uart
|
||||
|
@ -78,6 +78,21 @@ static const timer_conf_t timer_config[] = {
|
||||
|
||||
#define TIMER_NUMOF ARRAY_SIZE(timer_config)
|
||||
|
||||
/**
|
||||
* @name ADC configuration
|
||||
*
|
||||
* The configuration consists simply of a list of channels that should be used
|
||||
* @{
|
||||
*/
|
||||
static const adc_conf_t adc_config[] = {
|
||||
{ .pin = GPIO_PIN(0, 26), .chan = 0},
|
||||
{ .pin = GPIO_PIN(0, 27), .chan = 1},
|
||||
{ .pin = GPIO_PIN(0, 28), .chan = 2},
|
||||
};
|
||||
|
||||
#define ADC_NUMOF ARRAY_SIZE(adc_config)
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -390,6 +390,14 @@ typedef struct {
|
||||
} gpio_io_ctrl_t;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief ADC channel configuration data
|
||||
*/
|
||||
typedef struct {
|
||||
gpio_t pin; /**< Pin connected to the channel */
|
||||
uint8_t chan; /**< CPU ADC channel connected to the pin */
|
||||
} adc_conf_t;
|
||||
|
||||
/**
|
||||
* @brief Configuration details for an UART interface needed by the RPX0XX peripheral
|
||||
*/
|
||||
|
97
cpu/rpx0xx/periph/adc.c
Normal file
97
cpu/rpx0xx/periph/adc.c
Normal file
@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Mesotic SAS
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup cpu_rpx0xx
|
||||
* @ingroup drivers_periph_adc
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Low-level ADC driver implementation
|
||||
*
|
||||
* @author Dylan Laduranty <dylan.laduranty@mesotic.com>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include "cpu.h"
|
||||
#include "mutex.h"
|
||||
#include "periph/adc.h"
|
||||
#include "periph_conf.h"
|
||||
|
||||
/**
|
||||
* @brief Lock to prevent concurrency issues when used from different threads
|
||||
*/
|
||||
static mutex_t lock;
|
||||
|
||||
static inline void _prep(void)
|
||||
{
|
||||
mutex_lock(&lock);
|
||||
}
|
||||
|
||||
static inline void _done(void)
|
||||
{
|
||||
mutex_unlock(&lock);
|
||||
}
|
||||
|
||||
static void _disable_digital_func(gpio_t pin)
|
||||
{
|
||||
|
||||
const gpio_pad_ctrl_t disable_digital_pad = {
|
||||
.input_enable = 0,
|
||||
.output_disable = 1,
|
||||
};
|
||||
|
||||
gpio_set_pad_config(pin, disable_digital_pad);
|
||||
}
|
||||
|
||||
int adc_init(adc_t line)
|
||||
{
|
||||
if (line >= ADC_NUMOF) {
|
||||
return -ENODEV;
|
||||
}
|
||||
/* Lock mutex for exclusive access */
|
||||
_prep();
|
||||
/* Reset ADC peripheral */
|
||||
periph_reset(RESETS_RESET_adc_Msk);
|
||||
periph_reset_done(RESETS_RESET_adc_Msk);
|
||||
|
||||
/* Enable ADC peripheral and its clock */
|
||||
io_reg_atomic_set(&ADC->CS, 1 << ADC_CS_EN_Pos);
|
||||
/* Disable associated GPIO functionality as requested by datasheet */
|
||||
_disable_digital_func(adc_config[line].pin);
|
||||
/* Unlock mutex */
|
||||
_done();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t adc_sample(adc_t line, adc_res_t res)
|
||||
{
|
||||
int val = 0;
|
||||
|
||||
/* rpx0xx MCU only supports 12 bits resolution */
|
||||
if (res != ADC_RES_12BIT) {
|
||||
return -EINVAL;
|
||||
}
|
||||
/* Lock mutex for exclusive access */
|
||||
_prep();
|
||||
/* Select the channel */
|
||||
io_reg_write_dont_corrupt(&ADC->CS, adc_config[line].chan << ADC_CS_AINSEL_Pos,
|
||||
ADC_CS_AINSEL_Msk);
|
||||
/* Wait for ADC to be ready */
|
||||
while (!(ADC->CS & ADC_CS_READY_Msk)) {}
|
||||
/* Trigger one-shot sample */
|
||||
io_reg_atomic_set(&ADC->CS, 1 << ADC_CS_START_ONCE_Pos);
|
||||
/* Wait for completion */
|
||||
while (!(ADC->CS & ADC_CS_READY_Msk)) {}
|
||||
/* Get the result */
|
||||
val = ADC->RESULT & ADC_RESULT_RESULT_Msk;
|
||||
/* Unlock mutex */
|
||||
_done();
|
||||
return val;
|
||||
}
|
Loading…
Reference in New Issue
Block a user