From b47f63cc93b71bf0305932a1eb0c3697cffd44c0 Mon Sep 17 00:00:00 2001 From: raiden00pl Date: Sat, 4 Jan 2020 11:10:56 +0100 Subject: [PATCH 1/5] arch/arm/src/nrf52: add GPIOTE and SAADC registers definitions --- arch/arm/src/nrf52/hardware/nrf52_gpiote.h | 99 +++++++++ arch/arm/src/nrf52/hardware/nrf52_saadc.h | 221 +++++++++++++++++++++ 2 files changed, 320 insertions(+) create mode 100644 arch/arm/src/nrf52/hardware/nrf52_gpiote.h create mode 100644 arch/arm/src/nrf52/hardware/nrf52_saadc.h diff --git a/arch/arm/src/nrf52/hardware/nrf52_gpiote.h b/arch/arm/src/nrf52/hardware/nrf52_gpiote.h new file mode 100644 index 0000000000000..1530294ded518 --- /dev/null +++ b/arch/arm/src/nrf52/hardware/nrf52_gpiote.h @@ -0,0 +1,99 @@ +/************************************************************************************************ + * arch/arm/src/nrf52/hardware/nrf52_gpiote.h + * + * Copyright (C) 2019 Gregory Nutt. All rights reserved. + * Author: Mateusz Szafoni + * + * 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 NuttX 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 OWNER 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_NRF52_HARDWARE_NRF52_GPIOTE_H +#define __ARCH_ARM_SRC_NRF52_HARDWARE_NRF52_GPIOTE_H + +/************************************************************************************************ + * Included Files + ************************************************************************************************/ + +#include +#include "hardware/nrf52_memorymap.h" + +/************************************************************************************************ + * Pre-processor Definitions + ************************************************************************************************/ + +/* Register offsets for GPIOTE ******************************************************************/ + +#define NRF52_GPIOTE_TASKS_OUT_OFFSET(x) (0x0000 + (0x04 * x)) /* TASKS_OUT[x] */ +#define NRF52_GPIOTE_TASKS_SET_OFFSET(x) (0x0030 + (0x04 * x)) /* TASKS_SET[x] */ +#define NRF52_GPIOTE_TASKS_CLR_OFFSET(x) (0x0060 + (0x04 * x)) /* TASKS_CLR[x] */ +#define NRF52_GPIOTE_EVENTS_IN_OFFSET(x) (0x0100 + (0x04 * x)) /* EVENTS_IN[x] */ +#define NRF52_GPIOTE_EVENTS_PORT_OFFSET 0x017c /* EVENTS_PORT */ +#define NRF52_GPIOTE_INTENSET_OFFSET 0x0304 /* INTENSET */ +#define NRF52_GPIOTE_INTENCLR_OFFSET 0x0308 /* INTENCLR */ +#define NRF52_GPIOTE_CONFIG_OFFSET(x) (0x0510 + (0x04 * x)) /* CONFIG[x] */ + +/* Register addresses for GPIOTE ****************************************************************/ + +#define NRF52_GPIOTE_TASKS_OUT(x) (NRF52_GPIOTE_BASE + NRF52_GPIOTE_TASKS_OUT_OFFSET(x)) +#define NRF52_GPIOTE_TASKS_SET(x) (NRF52_GPIOTE_BASE + NRF52_GPIOTE_TASKS_SET_OFFSET(x)) +#define NRF52_GPIOTE_TASKS_CLR(x) (NRF52_GPIOTE_BASE + NRF52_GPIOTE_TASKS_CLR_OFFSET(x)) +#define NRF52_GPIOTE_EVENTS_IN(x) (NRF52_GPIOTE_BASE + NRF52_GPIOTE_EVENTS_IN_OFFSET(x)) +#define NRF52_GPIOTE_EVENTS_PORT (NRF52_GPIOTE_BASE + NRF52_GPIOTE_EVENTS_PORT_OFFSET) +#define NRF52_GPIOTE_INTENSET (NRF52_GPIOTE_BASE + NRF52_GPIOTE_INTENSET_OFFSET) +#define NRF52_GPIOTE_INTENCLR (NRF52_GPIOTE_BASE + NRF52_GPIOTE_INTENCLR_OFFSET) +#define NRF52_GPIOTE_CONFIG(x) (NRF52_GPIOTE_BASE + NRF52_GPIOTE_CONFIG_OFFSET(x)) + +/* Register offsets for GPIOTE ******************************************************************/ + +/* INTENSET/INTENCLR Register */ + +#define GPIOTE_INT_IN_SHIFT 0 /* Bits 0-7: Enable interrupt for event IN[i] */ +#define GPIOTE_INT_IN_MASK (0xff << GPIOTE_INT_IN_SHIFT) +# define GPIOTE_INT_IN(i) ((1 << (i + GPIOTE_INT_IN_SHIFT)) & GPIOTE_INT_IN_MASK) +#define GPIOTE_INT_PORT 31 /* Bit 31: Enable interrupt for event PORT */ + +/* CONFIG Register */ + +#define GPIOTE_CONFIG_MODE_SHIFT 0 /* Bits 0-1: Mode */ +#define GPIOTE_CONFIG_MODE_MASK (0x3 << GPIOTE_CONFIG_MODE_SHIFT) +# define GPIOTE_CONFIG_MODE_DIS (0x0 << GPIOTE_CONFIG_MODE_SHIFT) /* 0: Disabled */ +# define GPIOTE_CONFIG_MODE_EV (0x0 << GPIOTE_CONFIG_MODE_SHIFT) /* 1: Event */ +# define GPIOTE_CONFIG_MODE_TS (0x0 << GPIOTE_CONFIG_MODE_SHIFT) /* 2: Task */ +#define GPIOTE_CONFIG_PSEL_SHIFT (8) /* Bits 8-12: GPIO number */ +#define GPIOTE_CONFIG_PSEL_MASK (0x1f << GPIOTE_CONFIG_PSEL_SHIFT) +#define GPIOTE_CONFIG_PORT_SHIFT (13) /* Bit 13: GPIO port */ +#define GPIOTE_CONFIG_POL_SHIFT (16) /* Bits 16-17: Polarity */ +#define GPIOTE_CONFIG_POL_MASK (0x3 << GPIOTE_CONFIG_POL_SHIFT) +# define GPIOTE_CONFIG_POL_NONE (0x0 << GPIOTE_CONFIG_POL_SHIFT) /* 0: None */ +# define GPIOTE_CONFIG_POL_LTH (0x1 << GPIOTE_CONFIG_POL_SHIFT) /* 1: LoToHi */ +# define GPIOTE_CONFIG_POL_HTL (0x2 << GPIOTE_CONFIG_POL_SHIFT) /* 2: HiToLo */ +# define GPIOTE_CONFIG_POL_TG (0x3 << GPIOTE_CONFIG_POL_SHIFT) /* 3: Toggle */ +#define GPIOTE_CONFIG_OUTINIT (20) /* Bit 20: Initial value */ + +#endif /* __ARCH_ARM_SRC_NRF52_HARDWARE_NRF52_GPIOTE_H */ diff --git a/arch/arm/src/nrf52/hardware/nrf52_saadc.h b/arch/arm/src/nrf52/hardware/nrf52_saadc.h new file mode 100644 index 0000000000000..68babacbb0f6d --- /dev/null +++ b/arch/arm/src/nrf52/hardware/nrf52_saadc.h @@ -0,0 +1,221 @@ +/************************************************************************************************ + * arch/arm/src/nrf52/hardware/nrf52_saadc.h + * + * Copyright (C) 2019 Gregory Nutt. All rights reserved. + * Author: Mateusz Szafoni + * + * 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 NuttX 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 OWNER 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_NRF52_HARDWARE_NRF52_SAADC_H +#define __ARCH_ARM_SRC_NRF52_HARDWARE_NRF52_SAADC_H + +/************************************************************************************************ + * Included Files + ************************************************************************************************/ + +#include +#include "hardware/nrf52_memorymap.h" + +/************************************************************************************************ + * Pre-processor Definitions + ************************************************************************************************/ + +/* Register offsets for SAADC *******************************************************************/ + +#define NRF52_SAADC_TASKS_START 0x0000 /* Start the SAADCM */ +#define NRF52_SAADC_TASKS_SAMPLE 0x0004 /* Takes one SAADC sample */ +#define NRF52_SAADC_TASKS_STOP 0x0008 /* Stop the SAADC */ +#define NRF52_SAADC_TASKS_CALEOFFSET 0x000c /* Starts offset auto-calibration */ +#define NRF52_SAADC_EVENTS_STARTED 0x0100 /* The SAADC has started */ +#define NRF52_SAADC_EVENTS_END 0x0104 /* The SAADC has filled up the result buffer */ +#define NRF52_SAADC_EVENTS_DONE 0x0108 /* A conversio ntask has been completed */ +#define NRF52_SAADC_EVENTS_RESULTDONE 0x010c /* Result ready for transfer to RAM */ +#define NRF52_SAADC_EVENTS_CALDONE 0x0110 /* Calibration is complete */ +#define NRF52_SAADC_EVENTS_STOPPED 0x0110 /* The SAADC has stopped */ +#define NRF52_SAADC_EVENTS_CHLIMH(x) (0x118 + (x + 0x8)) /* Limit high event for channel x */ +#define NRF52_SAADC_EVENTS_CHLIML(x) (0x11c + (x + 0x8)) /* Limit low event for channel x */ +#define NRF52_SAADC_INTEN 0x0300 /* Enable or disable interrupt */ +#define NRF52_SAADC_INTENSET 0x0304 /* Enable interrupt */ +#define NRF52_SAADC_INTENCLR 0x0308 /* Disable interrupt */ +#define NRF52_SAADC_STATUS 0x0400 /* Status */ +#define NRF52_SAADC_ENABLE 0x0500 /* Enable or disable SAADC */ +#define NRF52_SAADC_CHPSELP(x) (0x510 + (x + 0x10)) /* Input positive pin for CH[x] */ +#define NRF52_SAADC_CHPSELN(x) (0x514 + (x + 0x10)) /* Input negative pin for CH[x] */ +#define NRF52_SAADC_CHCONFIG(x) (0x518 + (x + 0x10)) /* Input configuration for CH[x] */ +#define NRF52_SAADC_CHLIMIT(x) (0x51c + (x + 0x10)) /* High/low limits for event monitoring of a CH[x] */ +#define NRF52_SAADC_RESOLUTION 0x05f0 /* Resolution configuration */ +#define NRF52_SAADC_OVERSAMPLE 0x05f4 /* Oversampling configuration */ +#define NRF52_SAADC_SAMPLERATE 0x05f8 /* Controls normal or continous sample rate */ +#define NRF52_SAADC_PTR 0x062c /* Data pointer */ +#define NRF52_SAADC_MAXCNT 0x0630 /* Maximum number of 16-bit samples */ +#define NRF52_SAADC_AMOUNT 0x0634 /* Number of 16-bit samples written to buffer */ + +/* Register Bitfield Definitions for SAADC ******************************************************/ + +/* INTEN/INTENSET/INTENCLR Register */ + +#define SAADC_INT_STARTED (1 << 0) /* Bit 0: Interrupt for event STARTED */ +#define SAADC_INT_END (1 << 1) /* Bit 1: Interrupt for event END */ +#define SAADC_INT_DONE (1 << 2) /* Bit 2: Interrupt for event DONE */ +#define SAADC_INT_RESULTDONE (1 << 3) /* Bit 3: Interrupt for event RESULTDONE */ +#define SAADC_INT_CALDONE (1 << 4) /* Bit 4: Interrupt for event CALIBRATEDONE */ +#define SAADC_INT_STOPPED (1 << 5) /* Bit 5: Interrupt for event STOPPED */ +#define SAADC_INT_CHXLIMH(x) (1 << (x + 0x6)) /* Bit (x+6): Interrupt for event CHxLIMITH */ +#define SAADC_INT_CHXLIML(x) (1 << (x + 0x7)) /* Bit (x+7): Interrupt for event CHxLIMITL */ + +/* STATUS Register */ + +#define SAADC_STATUS_READY (0) /* Bit 0: SAADC is ready */ +#define SAADC_STATUS_BUSY (1 << 0) /* Bit 0: SAADC is busy */ + +/* ENABLE Register */ + +#define SAADC_ENABLE_DIS (0) /* Bit 0: Disable SAADC */ +#define SAADC_ENABLE_EN (1 << 0) /* Bit 0: Enable SAADC */ + +/* CH[n] PSELP Register */ + +#define SAADC_CHPSELP_SHIFT (0) /* Bits 0-4: Intput positive pin selection for CH[x] */ +#define SAADC_CHPSELP_MASK (0xf << SAADC_CHPSELP_SHIFT) +# define SAADC_CHPSELP_NC (0x0 << SAADC_CHPSELP_SHIFT) +# define SAADC_CHPSELP_IN0 (0x1 << SAADC_CHPSELP_SHIFT) +# define SAADC_CHPSELP_IN1 (0x2 << SAADC_CHPSELP_SHIFT) +# define SAADC_CHPSELP_IN2 (0x3 << SAADC_CHPSELP_SHIFT) +# define SAADC_CHPSELP_IN3 (0x4 << SAADC_CHPSELP_SHIFT) +# define SAADC_CHPSELP_IN4 (0x5 << SAADC_CHPSELP_SHIFT) +# define SAADC_CHPSELP_IN5 (0x6 << SAADC_CHPSELP_SHIFT) +# define SAADC_CHPSELP_IN6 (0x7 << SAADC_CHPSELP_SHIFT) +# define SAADC_CHPSELP_IN7 (0x8 << SAADC_CHPSELP_SHIFT) +# define SAADC_CHPSELP_VDD (0x9 << SAADC_CHPSELP_SHIFT) +# define SAADC_CHPSELP_VDDHDIV5 (0xd << SAADC_CHPSELP_SHIFT) + +/* CH[n] PSELN Register */ + +#define SAADC_CHPSELN_SHIFT (0) /* Bits 0-4: Intput negative pin selection for CH[x] */ +#define SAADC_CHPSELN_MASK (0xf << SAADC_CHPSELN_SHIFT) +# define SAADC_CHPSELN_NC (0x0 << SAADC_CHPSELN_SHIFT) +# define SAADC_CHPSELN_IN0 (0x1 << SAADC_CHPSELN_SHIFT) +# define SAADC_CHPSELN_IN1 (0x2 << SAADC_CHPSELN_SHIFT) +# define SAADC_CHPSELN_IN2 (0x3 << SAADC_CHPSELN_SHIFT) +# define SAADC_CHPSELN_IN3 (0x4 << SAADC_CHPSELN_SHIFT) +# define SAADC_CHPSELN_IN4 (0x5 << SAADC_CHPSELN_SHIFT) +# define SAADC_CHPSELN_IN5 (0x6 << SAADC_CHPSELN_SHIFT) +# define SAADC_CHPSELN_IN6 (0x7 << SAADC_CHPSELN_SHIFT) +# define SAADC_CHPSELN_IN7 (0x8 << SAADC_CHPSELN_SHIFT) +# define SAADC_CHPSELN_VDD (0x9 << SAADC_CHPSELN_SHIFT) +# define SAADC_CHPSELN_VDDHDIV5 (0xd << SAADC_CHPSELN_SHIFT) + +/* CH[n] CONFIG Register */ + +#define SAADC_CONFIG_RESP_SHIFT (0) /* Bits 0-2: Positive channel resistor control */ +#define SAADC_CONFIG_RESP_MASK (0x3 << SAADC_CONFIG_RESP_SHIFT) +# define SAADC_CONFIG_RESN_NONE (0x0 << SAADC_CONFIG_RESP_SHIFT) +# define SAADC_CONFIG_RESN_PD (0x1 << SAADC_CONFIG_RESP_SHIFT) +# define SAADC_CONFIG_RESN_PU (0x2 << SAADC_CONFIG_RESP_SHIFT) +# define SAADC_CONFIG_RESN_VDD1P2 (0x3 << SAADC_CONFIG_RESP_SHIFT) +#define SAADC_CONFIG_RESN_SHIFT (4) /* Bits 4-5: Negative channel resistor control */ +#define SAADC_CONFIG_RESN_MASK (0x3 << SAADC_CONFIG_RESN_SHIFT) +# define SAADC_CONFIG_RESN_NONE (0x0 << SAADC_CONFIG_RESN_SHIFT) +# define SAADC_CONFIG_RESN_PD (0x1 << SAADC_CONFIG_RESN_SHIFT) +# define SAADC_CONFIG_RESN_PU (0x2 << SAADC_CONFIG_RESN_SHIFT) +# define SAADC_CONFIG_RESN_VDD1D2 (0x3 << SAADC_CONFIG_RESN_SHIFT) +#define SAADC_CONFIG_GAIN_SHIFT (8) /* Bits 8-10: Gain control */ +#define SAADC_CONFIG_GAIN_MASK (0x7 << SAADC_CONFIG_GAIN_SHIFT) +# define SAADC_CONFIG_GAIN_1P6 (0x0 << SAADC_CONFIG_GAIN_SHIFT) +# define SAADC_CONFIG_GAIN_1P5 (0x1 << SAADC_CONFIG_GAIN_SHIFT) +# define SAADC_CONFIG_GAIN_1P4 (0x2 << SAADC_CONFIG_GAIN_SHIFT) +# define SAADC_CONFIG_GAIN_1P3 (0x3 << SAADC_CONFIG_GAIN_SHIFT) +# define SAADC_CONFIG_GAIN_1P2 (0x4 << SAADC_CONFIG_GAIN_SHIFT) +# define SAADC_CONFIG_GAIN_1 (0x5 << SAADC_CONFIG_GAIN_SHIFT) +# define SAADC_CONFIG_GAIN_2 (0x6 << SAADC_CONFIG_GAIN_SHIFT) +# define SAADC_CONFIG_GAIN_4 (0x7 << SAADC_CONFIG_GAIN_SHIFT) +#define SAADC_REFSEL_INTERNAL (0 << 12) /* Bit 12: Internal reference (0.6V) */ +#define SAADC_REFSEL_VDD1P4 (1 << 12) /* Bit 12: VDD/4 as reference */ +#define SAADC_CONFIG_TACQ_SHIFT (16) /* Bits 16-18: Acquisition time */ +#define SAADC_CONFIG_TACQ_MASK (0x7 << SAADC_CONFIG_TACQ_SHIFT) +# define SAADC_CONFIG_TACQ_3US (0x0 << SAADC_CONFIG_TACQ_SHIFT) +# define SAADC_CONFIG_TACQ_5US (0x1 << SAADC_CONFIG_TACQ_SHIFT) +# define SAADC_CONFIG_TACQ_10US (0x2 << SAADC_CONFIG_TACQ_SHIFT) +# define SAADC_CONFIG_TACQ_15US (0x3 << SAADC_CONFIG_TACQ_SHIFT) +# define SAADC_CONFIG_TACQ_20US (0x4 << SAADC_CONFIG_TACQ_SHIFT) +# define SAADC_CONFIG_TACQ_40US (0x5 << SAADC_CONFIG_TACQ_SHIFT) +#define SAADC_CONFIG_MODE_SE (0 << 20) /* Bit 20: Single-ended */ +#define SAADC_CONFIG_MODE_DIFF (1 << 20) /* Bit 20: Differential */ +#define SAADC_CONFIG_BURS_DIS (0 << 24) /* Bit 24: Burst mode is disabled */ +#define SAADC_CONFIG_BURS_EN (1 << 24) /* Bit 24: Burst mode is enabled */ + +/* CH[n] LIMIT Register */ + +#define SAADC_CHLIMIT_LOW_SHIFT (0) /* Bits 0-15: Low level limit */ +#define SAADC_CHLIMIT_LOW_MASK (0xffff << SAADC_CHLIMIT_LOW_SHIFT) +#define SAADC_CHLIMIT_HIGH_SHIFT (16) /* Bits 0-15: High level limit */ +#define SAADC_CHLIMIT_HIGH_MASK (0xffff << SAADC_CHLIMIT_HIGH_SHIFT) + +/* RESOLUTION Register */ + +#define SAADC_RESOLUTION_SHIFT (0) /* Bits 0-2: SAADC resolution */ +#define SAADC_RESOLUTION_MASK (0xf << SAADC_RESOLUTION_SHIFT) +# define SAADC_RESOLUTION_8BIT (0x0 << SAADC_RESOLUTION_SHIFT) +# define SAADC_RESOLUTION_10BIT (0x1 << SAADC_RESOLUTION_SHIFT) +# define SAADC_RESOLUTION_12BIT (0x2 << SAADC_RESOLUTION_SHIFT) +# define SAADC_RESOLUTION_14BIT (0x3 << SAADC_RESOLUTION_SHIFT) + +/* OVERSAMPLE Register */ + +#define SAADC_OVERSAMPLE_SHIFT (0) /* Bit 0-3: Oversample control */ +#define SAADC_OVERSAMPLE_MASK (0xf << SAADC_OVERSAMPLE_SHIFT) +# define SAADC_OVERSAMPLE_NONE (0x0 << SAADC_OVERSAMPLE_SHIFT) +# define SAADC_OVERSAMPLE_2X (0x1 << SAADC_OVERSAMPLE_SHIFT) +# define SAADC_OVERSAMPLE_4X (0x2 << SAADC_OVERSAMPLE_SHIFT) +# define SAADC_OVERSAMPLE_8X (0x3 << SAADC_OVERSAMPLE_SHIFT) +# define SAADC_OVERSAMPLE_16X (0x4 << SAADC_OVERSAMPLE_SHIFT) +# define SAADC_OVERSAMPLE_32X (0x5 << SAADC_OVERSAMPLE_SHIFT) +# define SAADC_OVERSAMPLE_64X (0x6 << SAADC_OVERSAMPLE_SHIFT) +# define SAADC_OVERSAMPLE_128X (0x7 << SAADC_OVERSAMPLE_SHIFT) +# define SAADC_OVERSAMPLE_256X (0x8 << SAADC_OVERSAMPLE_SHIFT) + +/* SAMPLERATE Register */ + +#define SAADC_SAMPLERATE_CC_SHIFT (0) /* Bits 0-10: Capture and compare value */ +#define SAADC_SAMPLERATE_CC_MASK (0x7ff << SAADC_SAMPLERATE_CC_SHIFT) +#define SAADC_SAMPLERATE_MODE_TASK (0 << 12) /* Bit 12: Rate is controlled from SAMPLE task */ +#define SAADC_SAMPLERATE_MODE_TIMERS (1 << 12) /* Bit 12: Rate is controlled from local timer */ + +/* MAXCNT Register */ + +#define SAADC_MAXCNT_SHIFT (0) /* Bits 0-14: Maximum of 16-bit samples written to output buffer */ +#define SAADC_MAXCNT_MASK (0x7fff) + +/* AMOUNT Register */ + +#define SAADC_AMOUNT_SHIFT (0) /* Bits 0-14: Number of 16-bit samples written to output buffer */ +#define SAADC_AMOUNT_MASK (0x7fff) + +#endif /* __ARCH_ARM_SRC_NRF52_HARDWARE_NRF52_SAADC_H */ From db760c855a0d56af09059b0a4a8f216fc23bc109 Mon Sep 17 00:00:00 2001 From: raiden00pl Date: Sat, 4 Jan 2020 11:12:38 +0100 Subject: [PATCH 2/5] arch/arm/src/nrf52: update some registers definitions --- arch/arm/src/nrf52/hardware/nrf52_gpio.h | 2 ++ arch/arm/src/nrf52/hardware/nrf52_spi.h | 8 ++++++-- arch/arm/src/nrf52/hardware/nrf52_twi.h | 4 +++- arch/arm/src/nrf52/hardware/nrf52_uarte.h | 4 ++++ 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/arch/arm/src/nrf52/hardware/nrf52_gpio.h b/arch/arm/src/nrf52/hardware/nrf52_gpio.h index 3fb29bc00d3ac..118e2f9d54bd5 100644 --- a/arch/arm/src/nrf52/hardware/nrf52_gpio.h +++ b/arch/arm/src/nrf52/hardware/nrf52_gpio.h @@ -89,6 +89,8 @@ /* Register bit definitions *********************************************************/ +#define NRF52_GPIO_CNF_DIR (1 << 0) /* Bit 0: Pin direction */ +#define NRF52_GPIO_CNF_INPUT (1 << 1) /* Bit 1: Input buffer disconnect */ #define NRF52_GPIO_CNF_PULL_SHIFT (2) #define NRF52_GPIO_CNF_PULL_MASK (0x3 << NRF52_GPIO_CNF_PULL_SHIFT) # define NRF52_GPIO_CNF_PULL_DISABLED (0 << NRF52_GPIO_CNF_PULL_SHIFT) diff --git a/arch/arm/src/nrf52/hardware/nrf52_spi.h b/arch/arm/src/nrf52/hardware/nrf52_spi.h index 7f56d9836710b..cdb53ded58b07 100644 --- a/arch/arm/src/nrf52/hardware/nrf52_spi.h +++ b/arch/arm/src/nrf52/hardware/nrf52_spi.h @@ -160,13 +160,13 @@ /* STALLLSTAT Register */ -#define SPIM_STALLSTAT_TX (1 << 0) /* Bit 0: Stall status for EasyDMA RAM reads */ +#define SPIM_STALLSTAT_RX (1 << 0) /* Bit 0: Stall status for EasyDMA RAM reads */ #define SPIM_STALLSTAT_TX (1 << 1) /* Bit 1: Stall status for EasyDMA RAM writes */ /* ENABLE Register */ #define SPIM_ENABLE_DIS (0) /* Disable SPIM */ -#define SPIM_ENABLE_EN (0xf << 0) /* Enable SPIM */ +#define SPIM_ENABLE_EN (0x7 << 0) /* Enable SPIM */ /* PSELSCK Register */ @@ -175,6 +175,7 @@ #define SPIM_PSELSCK_PORT_SHIFT (5) /* Bit 5: SCK port number */ #define SPIM_PSELSCK_PORT_MASK (0x1 << SPIM_PSELSCK_PORT_SHIFT) #define SPIM_PSELSCK_CONNECTED (1 << 31) /* Bit 31: Connection */ +#define SPIM_PSELSCK_RESET (0xffffffff) /* PSELMOSI Register */ @@ -183,6 +184,7 @@ #define SPIM_PSELMOSI_PORT_SHIFT (5) /* Bit 5: MOSI port number */ #define SPIM_PSELMOSI_PORT_MASK (0x1 << SPIM_PSELMOSI_PORT_SHIFT) #define SPIM_PSELMOSI_CONNECTED (1 << 31) /* Bit 31: Connection */ +#define SPIM_PSELMOSI_RESET (0xffffffff) /* PSELMISO Register */ @@ -191,6 +193,7 @@ #define SPIM_PSELMISO_PORT_SHIFT (5) /* Bit 5: MISO port number */ #define SPIM_PSELMISO_PORT_MASK (0x1 << SPIM_PSELMISO_PORT_SHIFT) #define SPIM_PSELMISO_CONNECTED (1 << 31) /* Bit 31: Connection */ +#define SPIM_PSELMISO_RESET (0xffffffff) /* PSELCSN Register */ @@ -199,6 +202,7 @@ #define SPIM_PSELCSN_PORT_SHIFT (5) /* Bit 5: CSN port number */ #define SPIM_PSELCSN_PORT_MASK (0x1 << SPIM_PSELCSN_PORT_SHIFT) #define SPIM_PSELCSN_CONNECTED (1 << 31) /* Bit 31: Connection */ +#define SPIM_PSELCSN_RESET (0xffffffff) /* FREQUENCY Register */ diff --git a/arch/arm/src/nrf52/hardware/nrf52_twi.h b/arch/arm/src/nrf52/hardware/nrf52_twi.h index c27e9b91408a4..4643f837d0d3c 100644 --- a/arch/arm/src/nrf52/hardware/nrf52_twi.h +++ b/arch/arm/src/nrf52/hardware/nrf52_twi.h @@ -145,7 +145,7 @@ /* ENABLE Register */ #define TWIM_ENABLE_DIS (0) /* Disable TWIM */ -#define TWIM_ENABLE_EN (0xf << 0) /* Disable TWIM */ +#define TWIM_ENABLE_EN (0x6 << 0) /* Disable TWIM */ /* PSELSCL Register */ @@ -154,6 +154,7 @@ #define TWIM_PSELSCL_PORT_SHIFT (5) /* Bit 5: SCL port number */ #define TWIM_PSELSCL_PORT_MASK (0x1 << TWIM_PSELSCL_PORT_SHIFT) #define TWIM_PSELSCL_CONNECTED (1 << 31) /* Bit 31: Connection */ +#define TWIM_PSELSCL_RESET (0xffffffff) /* PSELSDA Register */ @@ -162,6 +163,7 @@ #define TWIM_PSELSDA_PORT_SHIFT (5) /* Bit 5: SDA port number */ #define TWIM_PSELSDA_PORT_MASK (0x1 << TWIM_PSELSDA_PORT_SHIFT) #define TWIM_PSELSDA_CONNECTED (1 << 31) /* Bit 31: Connection */ +#define TWIM_PSELSDA_RESET (0xffffffff) /* FREQUENCY Register */ diff --git a/arch/arm/src/nrf52/hardware/nrf52_uarte.h b/arch/arm/src/nrf52/hardware/nrf52_uarte.h index cb9c3c258a79e..dafc8b13aefa8 100644 --- a/arch/arm/src/nrf52/hardware/nrf52_uarte.h +++ b/arch/arm/src/nrf52/hardware/nrf52_uarte.h @@ -242,6 +242,7 @@ #define UART_PSELRTS_PORT_SHIFT (5) /* Bit 5: Port number */ #define UART_PSELRTS_PORT_MASK (0x1 << UART_PSELRTS_PORT_SHIFT) #define UART_PSELRTS_CONNECT (1 << 31) /* Bit 31: Connection */ +#define UART_PSELRTS_RESET (0xffffffff) /* PSELTXD Register */ @@ -250,6 +251,7 @@ #define UART_PSELTXD_PORT_SHIFT (5) /* Bit 5: Port number */ #define UART_PSELTXD_PORT_MASK (0x1 << UART_PSELTXD_PORT_SHIFT) #define UART_PSELTXD_CONNECT (1 << 31) /* Bit 31: Connection */ +#define UART_PSELTXD_RESET (0xffffffff) /* PSELCTS Register */ @@ -258,6 +260,7 @@ #define UART_PSELCTS_PORT_SHIFT (5) /* Bit 5: Port number */ #define UART_PSELCTS_PORT_MASK (0x1 << UART_PSELCTS_PORT_SHIFT) #define UART_PSELCTS_CONNECT (1 << 31) /* Bit 31: Connection */ +#define UART_PSELCTS_RESET (0xffffffff) /* PSELRXD Register */ @@ -266,6 +269,7 @@ #define UART_PSELRXD_PORT_SHIFT (5) /* Bit 5: Port number */ #define UART_PSELRXD_PORT_MASK (0x1 << UART_PSELRXD_PORT_SHIFT) #define UART_PSELRXD_CONNECT (1 << 31) /* Bit 31: Connection */ +#define UART_PSELRXD_RESET (0xffffffff) /* ENABLE Register */ From de81606c2515259ba121488054a0e53f75fd8724 Mon Sep 17 00:00:00 2001 From: raiden00pl Date: Sat, 4 Jan 2020 11:13:39 +0100 Subject: [PATCH 3/5] arch/arm/src/nrf52: add basic I2C support --- arch/arm/src/nrf52/nrf52_i2c.c | 644 +++++++++++++++++++++++++++++++++ arch/arm/src/nrf52/nrf52_i2c.h | 92 +++++ 2 files changed, 736 insertions(+) create mode 100644 arch/arm/src/nrf52/nrf52_i2c.c create mode 100644 arch/arm/src/nrf52/nrf52_i2c.h diff --git a/arch/arm/src/nrf52/nrf52_i2c.c b/arch/arm/src/nrf52/nrf52_i2c.c new file mode 100644 index 0000000000000..258917ab20ccd --- /dev/null +++ b/arch/arm/src/nrf52/nrf52_i2c.c @@ -0,0 +1,644 @@ +/**************************************************************************** + * arch/arm/src/nrf52/nrf52_i2c.c + * + * Copyright (C) 2020 Gregory Nutt. All rights reserved. + * Author: Mateusz Szafoni + * + * 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 NuttX 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 OWNER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include "up_arch.h" + +#include "nrf52_gpio.h" +#include "nrf52_i2c.h" + +#include "hardware/nrf52_twi.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef CONFIG_I2C_POLLED +# error I2C irq not supported yet +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* I2C Device Private Data */ + +struct nrf52_i2c_priv_s +{ + const struct i2c_ops_s *ops; /* Standard I2C operations */ + uint32_t base; /* TWI base address */ + uint32_t scl_pin; /* SCL pin configuration */ + uint32_t sda_pin; /* SDA pin configuration */ + int refs; /* Reference count */ +#ifndef CONFIG_I2C_POLLED + uint32_t irq; /* TWI interrupt */ +#endif + uint8_t msgc; /* Message count */ + struct i2c_msg_s *msgv; /* Message list */ + uint8_t *ptr; /* Current message buffer */ + uint32_t freq; /* Current I2C frequency */ + int dcnt; /* Current message length */ + uint16_t flags; /* Current message flags */ + uint16_t addr; /* Current I2C address*/ + sem_t sem_excl; /* Mutual exclusion semaphore */ +#ifndef CONFIG_I2C_POLLED + sem_t sem_isr; /* Interrupt wait semaphore */ +#endif +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static inline void nrf52_i2c_putreg(FAR struct nrf52_i2c_priv_s *priv, + uint32_t offset, + uint32_t value); +static inline uint32_t nrf52_i2c_getreg(FAR struct nrf52_i2c_priv_s *priv, + uint32_t offset); +static int nrf52_i2c_transfer(FAR struct i2c_master_s *dev, + FAR struct i2c_msg_s *msgs, + int count); +#ifdef CONFIG_I2C_RESET +static int nrf52_i2c_reset(FAR struct i2c_master_s *dev); +#endif +#ifndef CONFIG_I2C_POLLED +static int nrf52_i2c_isr(int irq, void *context, FAR void *arg); +#endif +static int nrf52_i2c_deinit(FAR struct nrf52_i2c_priv_s *priv); +static int nrf52_i2c_init(FAR struct nrf52_i2c_priv_s *priv); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* I2C operations */ + +static const struct i2c_ops_s g_nrf52_i2c_ops = +{ + .transfer = nrf52_i2c_transfer +#ifdef CONFIG_I2C_RESET + , .reset = nrf52_i2c_reset +#endif +}; + +/* I2C0 (TWI0) device */ + +#ifdef CONFIG_NRF52_I2C0_MASTER + +static struct nrf52_i2c_priv_s g_nrf52_i2c0_priv = +{ + .ops = &g_nrf52_i2c_ops, + .base = NRF52_TWIM0_BASE, + .scl_pin = BOARD_I2C0_SCL_PIN, + .sda_pin = BOARD_I2C0_SDA_PIN, + .refs = 0, +#ifndef CONFIG_I2C_POLLED + .irq = NRF52_IRQ_SPI_TWI_0, +#endif + .msgc = 0, + .msgv = NULL, + .ptr = NULL, + .freq = 0, + .dcnt = 0, + .flags = 0, + .addr = 0, +}; +#endif + +/* I2C1 (TWI1) device */ + +#ifdef CONFIG_NRF52_I2C1_MASTER +static struct nrf52_i2c_priv_s g_nrf52_i2c1_priv = +{ + .ops = &g_nrf52_i2c_ops, + .base = NRF52_TWIM0_BASE, + .scl_pin = BOARD_I2C1_SCL_PIN, + .sda_pin = BOARD_I2C1_SDA_PIN, + .refs = 0, +#ifndef CONFIG_I2C_POLLED + .irq = NRF52_IRQ_SPI_TWI_1, +#endif + .msgc = 0, + .msgv = NULL, + .ptr = NULL, + .freq = 0, + .dcnt = 0, + .flags = 0, + .addr = 0, +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nrf52_i2c_putreg + * + * Description: + * Put a 32-bit register value by offset + * + ****************************************************************************/ + +static inline void nrf52_i2c_putreg(FAR struct nrf52_i2c_priv_s *priv, + uint32_t offset, + uint32_t value) +{ + putreg32(value, priv->base + offset); +} + +/**************************************************************************** + * Name: nrf52_i2c_getreg + * + * Description: + * Get a 32-bit register value by offset + * + ****************************************************************************/ + +static inline uint32_t nrf52_i2c_getreg(FAR struct nrf52_i2c_priv_s *priv, + uint32_t offset) +{ + return getreg32(priv->base + offset); +} + +/**************************************************************************** + * Name: nrf52_i2c_transfer + * + * Description: + * Generic I2C transfer function + * + ****************************************************************************/ + +static int nrf52_i2c_transfer(FAR struct i2c_master_s *dev, + FAR struct i2c_msg_s *msgs, + int count) +{ + FAR struct nrf52_i2c_priv_s *priv = (FAR struct nrf52_i2c_priv_s *)dev; + uint32_t regval = 0; + int ret = OK; + + /* Reset ptr and dcnt */ + + priv->dcnt = 0; + priv->ptr = NULL; + + priv->msgv = msgs; + priv->msgc = count; + + /* Do we need change I2C bus freqency ? */ + + if (priv->msgv->frequency != priv->freq) + { + /* Get TWI frequency */ + + switch (priv->msgv->frequency) + { + case 100000: + { + regval = TWIM_FREQUENCY_100KBPS; + break; + } + + case 250000: + { + regval = TWIM_FREQUENCY_250KBPS; + break; + } + + case 400000: + { + regval = TWIM_FREQUENCY_400KBPS; + break; + } + + default: + { + ret = -EINVAL; + goto errout; + } + } + + /* Write TWI frequency */ + + nrf52_i2c_putreg(priv, NRF52_TWIM_FREQUENCY_OFFSET, regval); + + /* Save the new I2C frequency */ + + priv->freq = priv->msgv->frequency; + } + + /* I2C transfer */ + + do + { + /* Get current message data */ + + priv->ptr = priv->msgv->buffer; + priv->dcnt = priv->msgv->length; + priv->flags = priv->msgv->flags; + priv->addr = priv->msgv->addr; + + /* Write TWI address */ + + regval = priv->addr; + nrf52_i2c_putreg(priv, NRF52_TWIM_ADDRESS_OFFSET, regval); + + if ((priv->flags & I2C_M_READ) == 0) + { + /* Write TXD data pointer */ + + regval = (uint32_t)priv->ptr; + nrf52_i2c_putreg(priv, NRF52_TWIM_TXDPTR_OFFSET, regval); + + /* Write number of bytes in TXD buffer */ + + regval = priv->dcnt; + nrf52_i2c_putreg(priv, NRF52_TWIM_TXMAXCNT_OFFSET, regval); + + /* Start TX sequence */ + + nrf52_i2c_putreg(priv, NRF52_TWIM_TASKS_STARTTX_OFFSET, 1); + + /* Wait for last TX event */ + +#ifdef CONFIG_I2C_POLLED + while (nrf52_i2c_getreg(priv, + NRF52_TWIM_EVENTS_LASTTX_OFFSET) != 1); +#endif + + /* TWIM stop */ + + nrf52_i2c_putreg(priv, NRF52_TWIM_TASKS_STOP_OFFSET, 1); + + /* Wait for stop event */ + +#ifdef CONFIG_I2C_POLLED + while (nrf52_i2c_getreg(priv, + NRF52_TWIM_EVENTS_STOPPED_OFFSET) != 1); +#endif + } + else + { + /* Write RXD data pointer */ + + regval = (uint32_t)priv->ptr; + nrf52_i2c_putreg(priv, NRF52_TWIM_RXDPTR_OFFSET, regval); + + /* Write number of bytes in RXD buffer */ + + regval = priv->dcnt; + nrf52_i2c_putreg(priv, NRF52_TWIM_RXDMAXCNT_OFFSET, regval); + + /* Start RX sequence */ + + nrf52_i2c_putreg(priv, NRF52_TWIM_TASKS_STARTRX_OFFSET, 1); + + /* Wait for last RX done */ + +#ifdef CONFIG_I2C_POLLED + while (nrf52_i2c_getreg(priv, + NRF52_TWIM_EVENTS_LASTRX_OFFSET) != 1); +#endif + /* Stop TWIM */ + + nrf52_i2c_putreg(priv, NRF52_TWIM_TASKS_STOP_OFFSET, 1); + + /* Wait for stop event */ + +#ifdef CONFIG_I2C_POLLED + while (nrf52_i2c_getreg(priv, + NRF52_TWIM_EVENTS_STOPPED_OFFSET) != 1); +#endif + } + + /* Next message */ + + priv->msgc -= 1; + priv->msgv += 1; + } + while (priv->msgc > 0); + +errout: + return ret; +} + +/**************************************************************************** + * Name: nrf52_i2c_reset + * + * Description: + * Perform an I2C bus reset in an attempt to break loose stuck I2C devices. + * + * Input Parameters: + * dev - Device-specific state data + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_I2C_RESET +static int nrf52_i2c_reset(FAR struct i2c_master_s *dev) +{ +#error not implemented +} +#endif + +/**************************************************************************** + * Name: nrf52_i2c_isr + * + * Description: + * Common I2C interrupt service routine + * + ****************************************************************************/ + +#ifndef CONFIG_I2C_POLLED +static int nrf52_i2c_isr(int irq, void *context, FAR void *arg) +{ +#error not implemented +} +#endif + +/**************************************************************************** + * Name: nrf52_i2c_init + * + * Description: + * Setup the I2C hardware, ready for operation with defaults + * + ****************************************************************************/ + +static int nrf52_i2c_init(FAR struct nrf52_i2c_priv_s *priv) +{ + uint32_t regval = 0; + int pin = 0; + int port = 0; + + /* Configure SCL and SDA pins */ + + nrf52_gpio_config(priv->scl_pin); + nrf52_gpio_config(priv->sda_pin); + + /* Select SCL pin */ + + pin = (priv->scl_pin & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + port = (priv->scl_pin & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + + regval = (pin << TWIM_PSELSCL_PIN_SHIFT); + regval |= (port << TWIM_PSELSCL_PORT_SHIFT); + nrf52_i2c_putreg(priv, NRF52_TWIM_PSELSCL_OFFSET, regval); + + /* Select SDA pin */ + + pin = (priv->sda_pin & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + port = (priv->sda_pin & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + + regval = (pin << TWIM_PSELSDA_PIN_SHIFT); + regval |= (port << TWIM_PSELSDA_PORT_SHIFT); + nrf52_i2c_putreg(priv, NRF52_TWIM_PSELSDA_OFFSET, regval); + + /* Enable TWI interface */ + + nrf52_i2c_putreg(priv, NRF52_TWIS_ENABLE_OFFSET, TWIM_ENABLE_EN); + +#ifndef CONFIG_I2C_POLLED + /* Attach error and event interrupts to the ISRs */ + + irq_attach(priv->irq, nrf52_i2c_isr, priv); + up_enable_irq(priv->irq); +#endif + + return OK; +} + +/**************************************************************************** + * Name: nrf52_i2c_sem_init + * + * Description: + * Initialize semaphores + * + ****************************************************************************/ + +static int nrf52_i2c_sem_init(FAR struct nrf52_i2c_priv_s *priv) +{ + /* Initialize semaphores */ + + nxsem_init(&priv->sem_excl, 0, 1); + +#ifndef CONFIG_I2C_POLLED + /* This semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + + nxsem_init(&priv->sem_isr, 0, 0); + nxsem_setprotocol(&priv->sem_isr, SEM_PRIO_NONE); +#endif + + return OK; +} + +/**************************************************************************** + * Name: nrf52_i2c_sem_destroy + * + * Description: + * Destroy semaphores. + * + ****************************************************************************/ + +static int nrf52_i2c_sem_destroy(FAR struct nrf52_i2c_priv_s *priv) +{ + /* Release unused resources */ + + nxsem_destroy(&priv->sem_excl); +#ifndef CONFIG_I2C_POLLED + nxsem_destroy(&priv->sem_isr); +#endif + + return OK; +} + +/**************************************************************************** + * Name: nrf52_i2c_deinit + * + * Description: + * Shutdown the I2C hardware + * + ****************************************************************************/ + +static int nrf52_i2c_deinit(FAR struct nrf52_i2c_priv_s *priv) +{ + /* Enable TWI interface */ + + nrf52_i2c_putreg(priv, TWIM_ENABLE_DIS, NRF52_TWIS_ENABLE_OFFSET); + + /* Unconfigure GPIO pins */ + + nrf52_gpio_unconfig(priv->scl_pin); + nrf52_gpio_unconfig(priv->sda_pin); + + /* Deatach TWI from GPIO */ + + nrf52_i2c_putreg(priv, NRF52_TWIM_PSELSCL_OFFSET, TWIM_PSELSCL_RESET); + nrf52_i2c_putreg(priv, NRF52_TWIM_PSELSDA_OFFSET, TWIM_PSELSDA_RESET); + + /* Disable and detach interrupts */ + +#ifndef CONFIG_I2C_POLLED + up_disable_irq(priv->irq); + irq_detach(priv->irq); +#endif + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nrf52_i2cbus_initialize + * + * Description: + * Initialize one I2C bus + * + ****************************************************************************/ + +FAR struct i2c_master_s *nrf52_i2cbus_initialize(int port) +{ + FAR struct nrf52_i2c_priv_s *priv = NULL; + irqstate_t flags; + + /* Get interface */ + + switch (port) + { +#ifdef CONFIG_NRF52_I2C0_MASTER + case 0: + { + priv = (FAR struct nrf52_i2c_priv_s *)&g_nrf52_i2c0_priv; + break; + } +#endif + +#ifdef CONFIG_NRF52_I2C1_MASTER + case 1: + { + priv = (FAR struct nrf52_i2c_priv_s *)&g_nrf52_i2c1_priv; + break; + } +#endif + + default: + { + return NULL; + } + } + + /* Initialize private data for the first time, increment reference count, + * power-up hardware and configure GPIOs. + */ + + flags = enter_critical_section(); + + if (priv->refs++ == 0) + { + /* Initialize sempaphores */ + + nrf52_i2c_sem_init(priv); + + /* Initialize I2C */ + + nrf52_i2c_init(priv); + } + + leave_critical_section(flags); + + return (struct i2c_master_s *)priv; +} + +/**************************************************************************** + * Name: nrf52_i2cbus_uninitialize + * + * Description: + * Uninitialize an I2C bus + * + ****************************************************************************/ + +int nrf52_i2cbus_uninitialize(FAR struct i2c_master_s *dev) +{ + FAR struct nrf52_i2c_priv_s *priv = (struct nrf52_i2c_priv_s *)dev; + irqstate_t flags; + + DEBUGASSERT(dev); + + /* Decrement reference count and check for underflow */ + + if (priv->refs == 0) + { + return ERROR; + } + + flags = enter_critical_section(); + + if (--priv->refs) + { + leave_critical_section(flags); + return OK; + } + + leave_critical_section(flags); + + /* Disable power and other HW resource (GPIO's) */ + + nrf52_i2c_deinit(priv); + + /* Release semaphores */ + + nrf52_i2c_sem_destroy(priv); + + return OK; +} diff --git a/arch/arm/src/nrf52/nrf52_i2c.h b/arch/arm/src/nrf52/nrf52_i2c.h new file mode 100644 index 0000000000000..9e39e7b773eab --- /dev/null +++ b/arch/arm/src/nrf52/nrf52_i2c.h @@ -0,0 +1,92 @@ +/**************************************************************************** + * arch/arm/src/nrf52/nrf52_i2c.h + * + * Copyright (C) 2019 Gregory Nutt. All rights reserved. + * Author: Mateusz Szafoni + * + * 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 NuttX 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 OWNER 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_NRF52_NRF52_I2C_H +#define __ARCH_ARM_SRC_NRF52_NRF52_I2C_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "chip.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: nrf52_i2cbus_initialize + * + * Description: + * Initialize the selected I2C port. And return a unique instance of struct + * struct i2c_master_s. This function may be called to obtain multiple + * instances of the interface, each of which may be set up with a + * different frequency and slave address. + * + * Input Parameters: + * Port number (for hardware that has multiple TWI interfaces) + * + * Returned Value: + * Valid I2C device structure reference on success; a NULL on failure + * + ****************************************************************************/ + +FAR struct i2c_master_s *nrf52_i2cbus_initialize(int port); + +/**************************************************************************** + * Name: nrf52_i2cbus_uninitialize + * + * Description: + * De-initialize the selected I2C port, and power down the device. + * + * Input Parameters: + * Device structure as returned by the nrf52_i2cbus_initialize() + * + * Returned Value: + * OK on success, ERROR when internal reference count mismatch or dev + * points to invalid hardware device. + * + ****************************************************************************/ + +int nrf52_i2cbus_uninitialize(FAR struct i2c_master_s *dev); + +#endif /* __ARCH_ARM_SRC_NRF52_NRF52_I2C_H */ From 3d527a80e0f25fff3980c39784f80faa75310b35 Mon Sep 17 00:00:00 2001 From: raiden00pl Date: Sat, 4 Jan 2020 11:21:30 +0100 Subject: [PATCH 4/5] arch/arm/src/nrf52: add function to unconfigure GPIO --- arch/arm/src/nrf52/nrf52_gpio.c | 30 ++++++++++++++++++++++++++++++ arch/arm/src/nrf52/nrf52_gpio.h | 10 ++++++++++ arch/arm/src/nrf52/nrf52_lowputc.c | 12 +++++++++++- arch/arm/src/nrf52/nrf52_lowputc.h | 2 +- arch/arm/src/nrf52/nrf52_serial.c | 4 +--- 5 files changed, 53 insertions(+), 5 deletions(-) diff --git a/arch/arm/src/nrf52/nrf52_gpio.c b/arch/arm/src/nrf52/nrf52_gpio.c index 70c788488df6e..c5f29d030415c 100644 --- a/arch/arm/src/nrf52/nrf52_gpio.c +++ b/arch/arm/src/nrf52/nrf52_gpio.c @@ -228,6 +228,36 @@ int nrf52_gpio_config(nrf52_pinset_t cfgset) return OK; } +/**************************************************************************** + * Name: nrf52_gpio_unconfig + * + * Description: + * Unconfigure a GPIO pin based on bit-encoded description of the pin. + * + ****************************************************************************/ + +int nrf52_gpio_unconfig(nrf52_pinset_t cfgset) +{ + unsigned int pin; + unsigned int port; + uint32_t offset; + + /* Get port and pin number */ + + port = (cfgset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + pin = (cfgset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + + /* Get address offset */ + + offset = nrf52_gpio_regget(port, NRF52_GPIO_PIN_CNF_OFFSET(pin)); + + /* Configure as input and disconnect input buffer */ + + putreg32(NRF52_GPIO_CNF_INPUT, offset); + + return OK; +} + /**************************************************************************** * Name: nrf52_gpio_write * diff --git a/arch/arm/src/nrf52/nrf52_gpio.h b/arch/arm/src/nrf52/nrf52_gpio.h index 55f6580ecd8e9..612d0af7de0e8 100644 --- a/arch/arm/src/nrf52/nrf52_gpio.h +++ b/arch/arm/src/nrf52/nrf52_gpio.h @@ -225,6 +225,16 @@ void nrf52_gpio_irqinitialize(void); int nrf52_gpio_config(nrf52_pinset_t cfgset); +/************************************************************************************ + * Name: nrf52_gpio_unconfig + * + * Description: + * Unconfigure a GPIO pin based on bit-encoded description of the pin. + * + ************************************************************************************/ + +int nrf52_gpio_unconfig(nrf52_pinset_t cfgset); + /************************************************************************************ * Name: nrf52_gpio_interrupt * diff --git a/arch/arm/src/nrf52/nrf52_lowputc.c b/arch/arm/src/nrf52/nrf52_lowputc.c index ca44bcb04c2be..8988862ba80a5 100644 --- a/arch/arm/src/nrf52/nrf52_lowputc.c +++ b/arch/arm/src/nrf52/nrf52_lowputc.c @@ -216,7 +216,7 @@ void nrf52_usart_configure(uintptr_t base, const struct uart_config_s *config) ****************************************************************************/ #ifdef HAVE_UART_DEVICE -void nrf52_usart_disable(uintptr_t base) +void nrf52_usart_disable(uintptr_t base, const struct uart_config_s *config) { /* Disable interrupts */ @@ -228,6 +228,16 @@ void nrf52_usart_disable(uintptr_t base) putreg32(0xffffffff, base + NRF52_UART_PSELTXD_OFFSET); putreg32(0xffffffff, base + NRF52_UART_PSELRXD_OFFSET); + + /* Unconfigure GPIO */ + + nrf52_gpio_unconfig(config->rxpin); + nrf52_gpio_unconfig(config->txpin); + + /* Deatach TWI from GPIO */ + + putreg32(UART_PSELTXD_RESET, base + NRF52_UART_PSELTXD_OFFSET); + putreg32(UART_PSELRXD_RESET, base + NRF52_UART_PSELRXD_OFFSET); } #endif diff --git a/arch/arm/src/nrf52/nrf52_lowputc.h b/arch/arm/src/nrf52/nrf52_lowputc.h index 75034125fa08a..af020aac74182 100644 --- a/arch/arm/src/nrf52/nrf52_lowputc.h +++ b/arch/arm/src/nrf52/nrf52_lowputc.h @@ -109,7 +109,7 @@ void nrf52_usart_configure(uintptr_t base, FAR const struct uart_config_s *confi ************************************************************************************/ #ifdef HAVE_UART_DEVICE -void nrf52_usart_disable(uintptr_t base); +void nrf52_usart_disable(uintptr_t base, FAR const struct uart_config_s *config); #endif #endif /* __ARCH_ARM_SRC_NRF52_NRF52_LOWPUTC_H */ diff --git a/arch/arm/src/nrf52/nrf52_serial.c b/arch/arm/src/nrf52/nrf52_serial.c index f4a269bd679eb..70c8e7644d2a1 100644 --- a/arch/arm/src/nrf52/nrf52_serial.c +++ b/arch/arm/src/nrf52/nrf52_serial.c @@ -319,13 +319,11 @@ static void nrf52_shutdown(struct uart_dev_s *dev) { struct nrf52_dev_s *priv = (struct nrf52_dev_s *)dev->priv; - /* TODO: release uart pins */ - /* Disable interrupts */ /* Reset hardware and disable Rx and Tx */ - nrf52_usart_disable(priv->uartbase); + nrf52_usart_disable(priv->uartbase, &priv->config); } /**************************************************************************** From 82caa0c66af53427a87d475d86fe1e6bcce8cc56 Mon Sep 17 00:00:00 2001 From: raiden00pl Date: Sat, 4 Jan 2020 13:27:09 +0100 Subject: [PATCH 5/5] arch/arm/src/nrf52/nrf52_lowputc: add missing FAR --- arch/arm/src/nrf52/nrf52_lowputc.c | 9 ++++++--- arch/arm/src/nrf52/nrf52_lowputc.h | 6 ++++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/arch/arm/src/nrf52/nrf52_lowputc.c b/arch/arm/src/nrf52/nrf52_lowputc.c index 8988862ba80a5..68f7600798c2f 100644 --- a/arch/arm/src/nrf52/nrf52_lowputc.c +++ b/arch/arm/src/nrf52/nrf52_lowputc.c @@ -114,7 +114,8 @@ static const struct uart_config_s g_console_config = ****************************************************************************/ #ifdef HAVE_UART_DEVICE -static void nrf52_setbaud(uintptr_t base, const struct uart_config_s *config) +static void nrf52_setbaud(uintptr_t base, + FAR const struct uart_config_s *config) { uint32_t br = 0; @@ -163,7 +164,8 @@ void nrf52_lowsetup(void) ****************************************************************************/ #ifdef HAVE_UART_DEVICE -void nrf52_usart_configure(uintptr_t base, const struct uart_config_s *config) +void nrf52_usart_configure(uintptr_t base, + FAR const struct uart_config_s *config) { uint32_t pin = 0; uint32_t port = 0; @@ -216,7 +218,8 @@ void nrf52_usart_configure(uintptr_t base, const struct uart_config_s *config) ****************************************************************************/ #ifdef HAVE_UART_DEVICE -void nrf52_usart_disable(uintptr_t base, const struct uart_config_s *config) +void nrf52_usart_disable(uintptr_t base, + FAR const struct uart_config_s *config) { /* Disable interrupts */ diff --git a/arch/arm/src/nrf52/nrf52_lowputc.h b/arch/arm/src/nrf52/nrf52_lowputc.h index af020aac74182..aac31d9f99a06 100644 --- a/arch/arm/src/nrf52/nrf52_lowputc.h +++ b/arch/arm/src/nrf52/nrf52_lowputc.h @@ -96,7 +96,8 @@ void nrf52_lowsetup(void); ************************************************************************************/ #ifdef HAVE_UART_DEVICE -void nrf52_usart_configure(uintptr_t base, FAR const struct uart_config_s *config); +void nrf52_usart_configure(uintptr_t base, + FAR const struct uart_config_s *config); #endif /************************************************************************************ @@ -109,7 +110,8 @@ void nrf52_usart_configure(uintptr_t base, FAR const struct uart_config_s *confi ************************************************************************************/ #ifdef HAVE_UART_DEVICE -void nrf52_usart_disable(uintptr_t base, FAR const struct uart_config_s *config); +void nrf52_usart_disable(uintptr_t base, + FAR const struct uart_config_s *config); #endif #endif /* __ARCH_ARM_SRC_NRF52_NRF52_LOWPUTC_H */