Added ADC to RP2040

This commit is contained in:
curuvar
2022-07-07 07:10:58 -04:00
committed by Alan Carvalho de Assis
parent 7307b8b6d5
commit aa6ec6518c
17 changed files with 1137 additions and 6 deletions
+3 -1
View File
@@ -26,10 +26,12 @@
*.sym
*.wsp
*.ddc
*.dds
*~
.depend
/.config
/.config.old
/.config.*
/.config-*
/.config\ *
/.cproject
/.gdbinit
+4
View File
@@ -70,6 +70,10 @@ ifeq ($(CONFIG_WS2812),y)
CHIP_CSRCS += rp2040_ws2812.c
endif
ifeq ($(CONFIG_ADC),y)
CHIP_CSRCS += rp2040_adc.c
endif
ifeq ($(CONFIG_RP2040_FLASH_BOOT),y)
ifneq ($(PICO_SDK_PATH),)
include chip/boot2/Make.defs
+120
View File
@@ -0,0 +1,120 @@
/****************************************************************************
* arch/arm/src/rp2040/hardware/rp2040_adc.h
*
* Generated from rp2040.svd originally provided by
* Raspberry Pi (Trading) Ltd.
*
* Copyright 2020 (c) 2020 Raspberry Pi (Trading) Ltd.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
#ifndef __ARCH_ARM_SRC_RP2040_HARDWARE_RP2040_ADC_H
#define __ARCH_ARM_SRC_RP2040_HARDWARE_RP2040_ADC_H
/****************************************************************************
* Included Files
****************************************************************************/
#include "hardware/rp2040_memorymap.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Register offsets *********************************************************/
#define RP2040_ADC_CS_OFFSET 0x000000 /* ADC Control and Status register */
#define RP2040_ADC_RESULT_OFFSET 0x000004 /* ADC Results register */
#define RP2040_ADC_FCS_OFFSET 0x000008 /* ADC FIFO Control and Status register */
#define RP2040_ADC_FIFO_OFFSET 0x00000c /* ADC Result FIFO */
#define RP2040_ADC_DIV_OFFSET 0x000010 /* ADC Clock Divider register */
#define RP2040_ADC_INTR_OFFSET 0x000014 /* ADC Raw Interrupts register */
#define RP2040_ADC_INTE_OFFSET 0x000018 /* ADC Interrupt Enable register */
#define RP2040_ADC_INTF_OFFSET 0x00001c /* ADC Interrupt Force register */
#define RP2040_ADC_INTS_OFFSET 0x000020 /* ADC Interrupt Status register */
/* Register definitions *****************************************************/
#define RP2040_ADC_CS (RP2040_ADC_BASE + RP2040_ADC_CS_OFFSET)
#define RP2040_ADC_RESULT (RP2040_ADC_BASE + RP2040_ADC_RESULT_OFFSET)
#define RP2040_ADC_FCS (RP2040_ADC_BASE + RP2040_ADC_FCS_OFFSET)
#define RP2040_ADC_FIFO (RP2040_ADC_BASE + RP2040_ADC_FIFO_OFFSET)
#define RP2040_ADC_DIV (RP2040_ADC_BASE + RP2040_ADC_DIV_OFFSET)
#define RP2040_ADC_INTR (RP2040_ADC_BASE + RP2040_ADC_INTR_OFFSET)
#define RP2040_ADC_INTE (RP2040_ADC_BASE + RP2040_ADC_INTE_OFFSET)
#define RP2040_ADC_INTF (RP2040_ADC_BASE + RP2040_ADC_INTF_OFFSET)
#define RP2040_ADC_INTS (RP2040_ADC_BASE + RP2040_ADC_INTS_OFFSET)
/* Register bit definitions *************************************************/
#define RP2040_ADC_CS_RROBIN_SHIFT (16)
#define RP2040_ADC_CS_RROBIN_MASK (0x001fl << RPC2040_ADC_CS_RROBIN_SHIFT)
#define RP2040_ADC_CS_AINSEL_SHIFT (12)
#define RP2040_ADC_CS_AINSEL_MASK (0x0007l << RPC2040_ADC_CS_AINSEL_SHIFT)
#define RP2040_ADC_CS_ERR_STICKY (1 << 10)
#define RP2040_ADC_CS_ERR (1 << 9)
#define RP2040_ADC_CS_READY (1 << 8)
#define RP2040_ADC_CS_START_MANY (1 << 3)
#define RP2040_ADC_CS_START_ONCE (1 << 2)
#define RP2040_ADC_CS_TS_ENA (1 << 1)
#define RP2040_ADC_CS_EN (1 << 0)
#define RP2040_ADC_RESULT_VAL_MASK (0x00000fffl)
#define RP2040_ADC_FCS_THRESH_SHIFT (24)
#define RP2040_ADC_FCS_THRESH_MASK (0x000fl << RP2040_ADC_FCS_THRESH_SHIFT)
#define RP2040_ADC_FCS_LEVEL_SHIFT (16)
#define RP2040_ADC_FCS_LEVEL_MASK (0x000fl << RP2040_ADC_FCS_LEVEL_SHIFT)
#define RP2040_ADC_FCS_OVER (1 << 11)
#define RP2040_ADC_FCS_UNDER (1 << 10)
#define RP2040_ADC_FCS_FULL (1 << 9)
#define RP2040_ADC_FCS_EMPTY (1 << 8)
#define RP2040_ADC_FCS_DREQ_EN (1 << 3)
#define RP2040_ADC_FCS_ERR (1 << 2)
#define RP2040_ADC_FCS_SHIFT (1 << 1)
#define RP2040_ADC_FCS_EN (1 << 0)
#define RP2040_ADC_FIFO_ERR (1 << 15)
#define RP2040_ADC_FIFO_VAL_MASK (0x0fffl)
#define RP2040_ADC_DIV_INT_SHIFT (8)
#define RP2040_ADC_DIV_INT_MASK (0x0fffl << RP2040_ADC_DIV_INT_SHIFT)
#define RP2040_ADC_DIV_FRAC_SHIFT (0)
#define RP2040_ADC_DIV_FRAC_MASK (0x00ffl << RP2040_ADC_DIV_FRAC_MASK)
#define RP2040_ADC_INTR_FIFO (1 << 0) /* Raw interrupt status */
#define RP2040_ADC_INTE_FIFO (1 << 0) /* Set to pass interrupts */
#define RP2040_ADC_INTF_FIFO (1 << 0) /* Write 1 to force the interrupt. */
#define RP2040_ADC_INTS_FIFO (1 << 0) /* Masked interrupt status */
#endif /* __ARCH_ARM_SRC_RP2040_HARDWARE_RP2040_ADC_H */
File diff suppressed because it is too large Load Diff
+108
View File
@@ -0,0 +1,108 @@
/****************************************************************************
* arch/arm/src/rp2040/rp2040_adc.h
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Note:
* The ADC driver upper-half returns signed values of up to 32-bits to
* the user and expects the high-order bits in any result to be
* significant. So, while the RP2040 hardware returns an unsigned value
* in the low-order 12 bits of the result register, we shift this
* value to the high-order bits.
*
* The result is that to convert a 32-bit value returned from the ADC
* driver, you should use V = ADC_AVDD * value / (2^31) where ADC_AVDD
* is the analogue reference voltage supplied to the RP2040 chip. If
* 8 or 16 bit values are returned the divisor would be (2^15) or (2^7)
* respectively.
*
* Also, if the conversion error bit was set for a particular sample,
* the return value will be negated. Any negative return value should
* be treated as erroneous.
****************************************************************************/
#ifndef __ARCH_ARM_SRC_RP2040_RP2040_ADC_H
#define __ARCH_ARM_SRC_RP2040_RP2040_ADC_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <debug.h>
#include <stdbool.h>
#ifndef __ASSEMBLY__
#if defined(__cplusplus)
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
#ifdef CONFIG_RP2040_ADC
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
#ifdef CONFIG_ADC
/****************************************************************************
* Name: rp2040_adc_setup
*
* Description:
* Initialize and register the ADC driver.
*
* Input Parameters:
* path - Path to the ws2812 device (e.g. "/dev/adc0")
* read_adc0 - This device reads ADC0
* read_adc1 - This device reads ADC1
* read_adc2 - This device reads ADC3
* read_adc3 - This device reads ADC4
* read_temp - This device reads the chip temperature.
*
* Returned Value:
* OK on success or an ERROR on failure
****************************************************************************/
int rp2040_adc_setup(FAR const char *path,
bool read_adc0,
bool read_adc1,
bool read_adc2,
bool read_adc3,
bool read_temp);
#else /* CONFIG_ADC */
/* ### TODO ### Add programmatic access function. */
#endif /* CONFIG_ADC */
#endif /* CONFIG_RP2040_ADC */
#undef EXTERN
#if defined(__cplusplus)
}
#endif
#endif /* __ASSEMBLY__ */
#endif /* __ARCH_ARM_SRC_RP2040_RP2040_ADC_H */
+1 -1
View File
@@ -92,4 +92,4 @@ int rp2040_ws2812_release(FAR void * driver);
#endif
#endif /* __ASSEMBLY__ */
#endif /* __ARCH_ARM_SRC_RP2040_RP2040_I2C_H */
#endif /* __ARCH_ARM_SRC_RP2040_RP2040_WS2812_H */
+3
View File
@@ -3510,6 +3510,9 @@ endif
if ARCH_CHIP_STM32
source "boards/arm/stm32/common/Kconfig"
endif
if ARCH_CHIP_RP2040
source "boards/arm/rp2040/common/Kconfig"
endif
endif
config BOARD_CRASHDUMP
@@ -14,6 +14,7 @@ Currently only the following devices are supported.
- SPI
- DMAC
- PWM
- ADC
- USB device
- MSC, CDC/ACM serial and these composite device are supported.
- CDC/ACM serial device can be used for the console.
@@ -74,6 +74,10 @@
#define HAS_WHITE false
#endif /* CONFIG_WS2812_HAS_WHITE */
#if defined(CONFIG_ADC) && defined(CONFIG_RP2040_ADC)
#include "rp2040_adc.h"
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
@@ -462,5 +466,46 @@ int rp2040_bringup(void)
HAS_WHITE);
#endif
#if defined(CONFIG_ADC) && defined(CONFIG_RP2040_ADC)
# ifdef CONFIG_RPC2040_ADC_CHANNEL0
# define ADC_0 true
# else
# define ADC_0 false
# endif
# ifdef CONFIG_RPC2040_ADC_CHANNEL1
# define ADC_1 true
# else
# define ADC_1 false
# endif
# ifdef CONFIG_RPC2040_ADC_CHANNEL2
# define ADC_2 true
# else
# define ADC_2 false
# endif
# ifdef CONFIG_RPC2040_ADC_CHANNEL3
# define ADC_3 true
# else
# define ADC_3 false
# endif
# ifdef CONFIG_RPC2040_ADC_TEMPERATURE
# define ADC_TEMP true
# else
# define ADC_TEMP false
# endif
ret = rp2040_adc_setup("/dev/adc0", ADC_0, ADC_1, ADC_2, ADC_3, ADC_TEMP);
if (ret != OK)
{
syslog(LOG_ERR, "Failed to initialize ADC Driver: %d\n", ret);
return ret;
}
#endif /* defined(CONFIG_ADC) && defined(CONFIG_RP2040_ADC) */
return ret;
}
@@ -13,6 +13,7 @@ Currently only the following devices are supported.
- SPI
- DMAC
- PWM
- ADC
- USB device
- MSC, CDC/ACM serial and these composite device are supported.
- CDC/ACM serial device can be used for the console.
@@ -74,6 +74,10 @@
#define HAS_WHITE false
#endif /* CONFIG_WS2812_HAS_WHITE */
#if defined(CONFIG_ADC) && defined(CONFIG_RP2040_ADC)
#include "rp2040_adc.h"
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
@@ -462,5 +466,46 @@ int rp2040_bringup(void)
HAS_WHITE);
#endif
#if defined(CONFIG_ADC) && defined(CONFIG_RP2040_ADC)
# ifdef CONFIG_RPC2040_ADC_CHANNEL0
# define ADC_0 true
# else
# define ADC_0 false
# endif
# ifdef CONFIG_RPC2040_ADC_CHANNEL1
# define ADC_1 true
# else
# define ADC_1 false
# endif
# ifdef CONFIG_RPC2040_ADC_CHANNEL2
# define ADC_2 true
# else
# define ADC_2 false
# endif
# ifdef CONFIG_RPC2040_ADC_CHANNEL3
# define ADC_3 true
# else
# define ADC_3 false
# endif
# ifdef CONFIG_RPC2040_ADC_TEMPERATURE
# define ADC_TEMP true
# else
# define ADC_TEMP false
# endif
ret = rp2040_adc_setup("/dev/adc0", ADC_0, ADC_1, ADC_2, ADC_3, ADC_TEMP);
if (ret != OK)
{
syslog(LOG_ERR, "Failed to initialize ADC Driver: %d\n", ret);
return ret;
}
#endif /* defined(CONFIG_ADC) && defined(CONFIG_RP2040_ADC) */
return ret;
}
+54
View File
@@ -0,0 +1,54 @@
#
# For a description of the syntax of this configuration file,
# see the file kconfig-language.txt in the NuttX tools repository.
#
if ARCH_BOARD_RASPBERRYPI_PICO
config RP2040_ADC
bool "Enable ADC Support"
default n
---help---
If y, the RP2040 ADC code will be built. For ADC device driver
support you must also select "Analog-to-Digital Conversion"
under the "Device Driver/Analog Device Support" menu.
If the ADC device driver is not built, basic functions
to programatically access the ADC ports will be added.
if RP2040_ADC && ADC
config RPC2040_ADC_CHANNEL0
bool "Read ADC channel 0"
default n
---help---
If y, then ADC0 will be read.
config RPC2040_ADC_CHANNEL1
bool "Read ADC channel 1"
default n
---help---
If y, then ADC1 will be read.
config RPC2040_ADC_CHANNEL2
bool "Read ADC channel 2"
default n
---help---
If y, then ADC2 will be read.
config RPC2040_ADC_CHANNEL3
bool "Read ADC channel 3"
default n
---help---
If y, then ADC3 will be read.
config RPC2040_ADC_TEMPERATURE
bool "Read ADC chip temperature channel"
default n
---help---
If y, then the ADC chip temperature
will be read.
endif
endif
@@ -17,6 +17,7 @@ Currently only the following devices are supported.
- SPI
- DMAC
- PWM
- ADC
- USB device
- MSC, CDC/ACM serial and these composite device are supported.
- CDC/ACM serial device can be used for the console.
@@ -38,6 +38,10 @@
#include "rp2040_pwmdev.h"
#endif
#if defined(CONFIG_ADC) && defined(CONFIG_RP2040_ADC)
#include "rp2040_adc.h"
#endif
#if defined(CONFIG_RP2040_BOARD_HAS_WS2812) && defined(CONFIG_WS2812)
#include "rp2040_ws2812.h"
#endif
@@ -408,6 +412,49 @@ int rp2040_bringup(void)
# endif
#endif
/* Initialize ADC */
#if defined(CONFIG_ADC) && defined(CONFIG_RP2040_ADC)
# ifdef CONFIG_RPC2040_ADC_CHANNEL0
# define ADC_0 true
# else
# define ADC_0 false
# endif
# ifdef CONFIG_RPC2040_ADC_CHANNEL1
# define ADC_1 true
# else
# define ADC_1 false
# endif
# ifdef CONFIG_RPC2040_ADC_CHANNEL2
# define ADC_2 true
# else
# define ADC_2 false
# endif
# ifdef CONFIG_RPC2040_ADC_CHANNEL3
# define ADC_3 true
# else
# define ADC_3 false
# endif
# ifdef CONFIG_RPC2040_ADC_TEMPERATURE
# define ADC_TEMP true
# else
# define ADC_TEMP false
# endif
ret = rp2040_adc_setup("/dev/adc0", ADC_0, ADC_1, ADC_2, ADC_3, ADC_TEMP);
if (ret != OK)
{
syslog(LOG_ERR, "Failed to initialize ADC Driver: %d\n", ret);
return ret;
}
#endif /* defined(CONFIG_ADC) && defined(CONFIG_RP2040_ADC) */
/* Initialize board neo-pixel */
#if defined(CONFIG_RP2040_BOARD_HAS_WS2812) && defined(CONFIG_WS2812)
@@ -14,6 +14,7 @@ Currently only the following devices are supported.
- SPI
- DMAC
- PWM
- ADC
- USB device
- MSC, CDC/ACM serial and these composite device are supported.
- CDC/ACM serial device can be used for the console.
@@ -64,6 +64,10 @@
#include "rp2040_pwmdev.h"
#endif
#if defined(CONFIG_ADC) && defined(CONFIG_RP2040_ADC)
#include "rp2040_adc.h"
#endif
#if defined(CONFIG_RP2040_BOARD_HAS_WS2812) && defined(CONFIG_WS2812)
#include "rp2040_ws2812.h"
#endif
@@ -487,6 +491,49 @@ int rp2040_bringup(void)
}
#endif
/* Initialize ADC */
#if defined(CONFIG_ADC) && defined(CONFIG_RP2040_ADC)
# ifdef CONFIG_RPC2040_ADC_CHANNEL0
# define ADC_0 true
# else
# define ADC_0 false
# endif
# ifdef CONFIG_RPC2040_ADC_CHANNEL1
# define ADC_1 true
# else
# define ADC_1 false
# endif
# ifdef CONFIG_RPC2040_ADC_CHANNEL2
# define ADC_2 true
# else
# define ADC_2 false
# endif
# ifdef CONFIG_RPC2040_ADC_CHANNEL3
# define ADC_3 true
# else
# define ADC_3 false
# endif
# ifdef CONFIG_RPC2040_ADC_TEMPERATURE
# define ADC_TEMP true
# else
# define ADC_TEMP false
# endif
ret = rp2040_adc_setup("/dev/adc0", ADC_0, ADC_1, ADC_2, ADC_3, ADC_TEMP);
if (ret != OK)
{
syslog(LOG_ERR, "Failed to initialize ADC Driver: %d\n", ret);
return ret;
}
#endif /* defined(CONFIG_ADC) && defined(CONFIG_RP2040_ADC) */
/* Initialize board neo-pixel */
#if defined(CONFIG_RP2040_BOARD_HAS_WS2812) && defined(CONFIG_WS2812)
+4 -4
View File
@@ -148,14 +148,14 @@ static int adc_open(FAR struct file *filep)
/* Finally, Enable the ADC RX interrupt */
dev->ad_ops->ao_rxint(dev, true);
/* Save the new open count on success */
dev->ad_ocount = tmp;
}
leave_critical_section(flags);
}
/* Save the new open count on success */
dev->ad_ocount = tmp;
}
nxsem_post(&dev->ad_closesem);