nrf52: add PWM support

This commit is contained in:
raiden00pl
2020-09-13 12:29:19 +02:00
committed by Alan Carvalho de Assis
parent 493b0bf074
commit a2b00fd348
6 changed files with 1208 additions and 0 deletions
+1
View File
@@ -212,6 +212,7 @@ config ARCH_CHIP_NRF52
#select ARCH_HAVE_MPU
#select ARM_HAVE_MPU_UNIFIED
select ARCH_HAVE_FPU
select ARCH_HAVE_PWM_MULTICHAN
---help---
Nordic NRF52 architectures (ARM Cortex-M4).
+177
View File
@@ -101,6 +101,10 @@ config NRF52_TIMER
bool
default n
config NRF52_PWM
bool
default n
config NRF52_RTC
bool
default n
@@ -219,6 +223,27 @@ config NRF52_TIMER4
select NRF52_TIMER
default n
config NRF52_PWM0
bool "PWM0"
select NRF52_PWM
default n
config NRF52_PWM1
bool "PWM1"
select NRF52_PWM
default n
config NRF52_PWM2
bool "PWM2"
select NRF52_PWM
default n
config NRF52_PWM3
bool "PWM3"
depends on NRF52_HAVE_PWM3
select NRF52_PWM
default n
config NRF52_PPI
bool "PPI"
default n
@@ -358,3 +383,155 @@ config NRF52_PROGMEM
menu "GPIO Interrupt Configuration"
endmenu # GPIO Interrupt Configuration
menu "PWM configuration"
config NRF52_PWM_MULTICHAN
bool "PWM Multiple Output Channels"
default n
if NRF52_PWM_MULTICHAN
if NRF52_PWM0
config NRF52_PWM0_CH0
bool "PWM0 Channel 0 Output"
default n
---help---
Enables channel 0 output.
config NRF52_PWM0_CH1
bool "PWM0 Channel 1 Output"
default n
---help---
Enables channel 1 output.
config NRF52_PWM0_CH2
bool "PWM0 Channel 2 Output"
default n
---help---
Enables channel 2 output.
config NRF52_PWM0_CH3
bool "PWM0 Channel 3 Output"
default n
---help---
Enables channel 3 output.
endif # NRF52_PWM0
if NRF52_PWM1
config NRF52_PWM1_CH0
bool "PWM1 Channel 0 Output"
default n
---help---
Enables channel 0 output.
config NRF52_PWM1_CH1
bool "PWM1 Channel 1 Output"
default n
---help---
Enables channel 1 output.
config NRF52_PWM1_CH2
bool "PWM1 Channel 2 Output"
default n
---help---
Enables channel 2 output.
config NRF52_PWM1_CH3
bool "PWM1 Channel 3 Output"
default n
---help---
Enables channel 3 output.
endif # NRF52_PWM1
if NRF52_PWM2
config NRF52_PWM2_CH0
bool "PWM2 Channel 0 Output"
default n
---help---
Enables channel 0 output.
config NRF52_PWM2_CH1
bool "PWM2 Channel 1 Output"
default n
---help---
Enables channel 1 output.
config NRF52_PWM2_CH2
bool "PWM2 Channel 2 Output"
default n
---help---
Enables channel 2 output.
config NRF52_PWM2_CH3
bool "PWM2 Channel 3 Output"
default n
---help---
Enables channel 3 output.
endif # NRF52_PWM2
if NRF52_PWM3
config NRF52_PWM3_CH0
bool "PWM3 Channel 0 Output"
default n
---help---
Enables channel 0 output.
config NRF52_PWM3_CH1
bool "PWM3 Channel 1 Output"
default n
---help---
Enables channel 1 output.
config NRF52_PWM3_CH2
bool "PWM3 Channel 2 Output"
default n
---help---
Enables channel 2 output.
config NRF52_PWM3_CH3
bool "PWM3 Channel 3 Output"
default n
---help---
Enables channel 3 output.
endif # NRF52_PWM3
endif # !NRF52_PWM_MULTICHAN
if !NRF52_PWM_MULTICHAN
config NRF52_PWM0_CHANNEL
int "PWM0 Output Channel"
depends on NRF52_PWM0
default 0
range 0 3
config NRF52_PWM1_CHANNEL
int "PWM1 Output Channel"
depends on NRF52_PWM1
default 0
range 0 3
config NRF52_PWM2_CHANNEL
int "PWM2 Output Channel"
depends on NRF52_PWM2
default 0
range 0 3
config NRF52_PWM3_CHANNEL
int "PWM3 Output Channel"
depends on NRF52_PWM3
default 0
range 0 3
endif # !NRF52_PWM_MULTICHAN
endmenu # PWM configuration
+4
View File
@@ -147,3 +147,7 @@ endif
ifeq ($(CONFIG_NRF52_RTC),y)
CHIP_CSRCS += nrf52_rtc.c
endif
ifeq ($(CONFIG_NRF52_PWM),y)
CHIP_CSRCS += nrf52_pwm.c
endif
+176
View File
@@ -0,0 +1,176 @@
/****************************************************************************
* arch/arm/src/nrf52/hardware/nrf52_pwm.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.
*
****************************************************************************/
#ifndef __ARCH_ARM_SRC_NRF52_HARDWARE_NRF52_PWM_H
#define __ARCH_ARM_SRC_NRF52_HARDWARE_NRF52_PWM_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include "hardware/nrf52_memorymap.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Configuration ************************************************************/
/* Register offsets *********************************************************/
#define NRF52_PWM_TASKS_STOP_OFFSET 0x0004 /* Stop PWM */
#define NRF52_PWM_TASKS_SEQSTART0_OFFSET 0x0008 /* Sequence 0 start */
#define NRF52_PWM_TASKS_SEQSTART1_OFFSET 0x000c /* Sequence 1 start */
#define NRF52_PWM_TASKS_NEXTSTEP_OFFSET 0x0010 /* Steps by one value in the current sequence */
#define NRF52_PWM_EVENTS_STOPPED_OFFSET 0x0104 /* STOP event */
#define NRF52_PWM_EVENTS_SEQSTARTED0_OFFSET 0x0108 /* Sequence 0 started event */
#define NRF52_PWM_EVENTS_SEQSTARTED1_OFFSET 0x010c /* Sequence 1 started event */
#define NRF52_PWM_EVENTS_SEQEND0_OFFSET 0x0110 /* Sequence 0 end event */
#define NRF52_PWM_EVENTS_SEQEND1_OFFSET 0x0114 /* Sequence 1 end event */
#define NRF52_PWM_EVENTS_PWMPERIODEN_OFFSET 0x0118 /* PWM period end event */
#define NRF52_PWM_EVENTS_LOOPSDONE_OFFSET 0x011c /* Loop done event */
#define NRF52_PWM_SHORTS_OFFSET 0x0200 /* Shourtcut register */
#define NRF52_PWM_INTEN_OFFSET 0x0300 /* Enable or disable interrupt */
#define NRF52_PWM_INTENSET_OFFSET 0x0304 /* Enable interrupt */
#define NRF52_PWM_INTENCLR_OFFSET 0x0308 /* Disable interrupt */
#define NRF52_PWM_ENABLE_OFFSET 0x0500 /* PWM enable */
#define NRF52_PWM_MODE_OFFSET 0x0504 /* Wave counter mode */
#define NRF52_PWM_COUNTERTOP_OFFSET 0x0508 /* Counter max value */
#define NRF52_PWM_PRESCALER_OFFSET 0x050c /* Prescaler configuration */
#define NRF52_PWM_DECODER_OFFSET 0x0510 /* Configuration of the decoder */
#define NRF52_PWM_LOOP_OFFSET 0x0514 /* Amount of playback of a loop */
#define NRF52_PWM_SEQ0PTR_OFFSET 0x0520 /* Sequence 0 beginning address */
#define NRF52_PWM_SEQ0CNT_OFFSET 0x0524 /* Sequence 0 length */
#define NRF52_PWM_SEQ0REFRESH_OFFSET 0x0528 /* Sequence 0 additional periods */
#define NRF52_PWM_SEQ0ENDDELAY_OFFSET 0x052c /* Time added after sequence 0 */
#define NRF52_PWM_SEQ1PTR_OFFSET 0x0540 /* Sequence 1 beginning address */
#define NRF52_PWM_SEQ1CNT_OFFSET 0x0544 /* Sequence 1 length */
#define NRF52_PWM_SEQ1REFRESH_OFFSET 0x0548 /* Sequence 0 additional periods */
#define NRF52_PWM_SEQ1ENDDELAY_OFFSET 0x054c /* Time added after sequence 1 */
#define NRF52_PWM_PSEL0_OFFSET 0x0560 /* Output pin select for PWM chan 0 */
#define NRF52_PWM_PSEL1_OFFSET 0x0564 /* Output pin select for PWM chan 1 */
#define NRF52_PWM_PSEL2_OFFSET 0x0568 /* Output pin select for PWM chan 2 */
#define NRF52_PWM_PSEL3_OFFSET 0x056c /* Output pin select for PWM chan 3 */
/* Register Bitfield Definitions ********************************************/
/* TASKS_STOP Register */
#define PWM_TASKS_STOP (1 << 0) /* Bit 0: Stop PWM */
/* TASKS_SEQSTART[n] Register */
#define PWM_TASKS_SEQSTART (1 << 0) /* Bit 0: Start sequence */
/* TASKS_NEXTSTEP Register */
#define PWM_TASKS_NEXTSTEP (1 << 0) /* Bit 0: Next step */
/* SHORTS Register */
#define PWM_SHORTS_SEQEND0_STOP (1 << 0) /* Bit 0: Shortcut between event SEQEND[0] and task STOP */
#define PWM_SHORTS_SEQEND1_STOP (1 << 1) /* Bit 1: Shortcut between event SEQEND[1] and task STOP */
#define PWM_SHORTS_LOOPSDONE_SEQSTART0 (1 << 2) /* Bit 2: Shortcut between event LOOPSDONE and task SEQSTART[0] */
#define PWM_SHORTS_LOOPSDONE_SEQSTART1 (1 << 3) /* Bit 3: Shortcut between event LOOPSDONE and task SEQSTART[1] */
#define PWM_SHORTS_LOOPSDONE_STOP (1 << 4) /* Bit 4: Shortcut between event LOOPSDONE and task STOP */
/* INTEN/INTENSET/INTENCLR Register */
#define PWM_INT_STOPPED (1 << 0) /* Bit 0: Interrupt for event STOPPED */
#define PWM_INT_SEQSTARTED0 (1 << 1) /* Bit 1: Interrupt for event SEQSTARTED0 */
#define PWM_INT_SEQSTARTED1 (1 << 2) /* Bit 2: Interrupt for event SEQSTARTED2 */
#define PWM_INT_SEQEND0 (1 << 3) /* Bit 3: Interrupt for event SEQEND0 */
#define PWM_INT_SEQEND1 (1 << 4) /* Bit 4: Interrupt for event SEQEND1 */
#define PWM_INT_PWMPERIODEND (1 << 5) /* Bit 5: Interrupt for event PWMPERIODEND */
#define PWM_INT_LOOPSDONE (1 << 6) /* Bit 6: Interrupt for event LOOPSDONE */
/* ENABLE Register */
#define PWM_ENABLE_ENABLE (1 << 0) /* Bit 0: Enable PWM module */
#define PWM_ENABLE_DISABLE (0 << 0) /* Bit 0: Disable PWM module */
/* MODE Register */
#define PWM_MODE_UP (0 << 0) /* Bit 0: Up counter, edge-aligned PWM */
#define PWM_MODE_UPDOWN (1 << 0) /* Bit 0: Up and down counter, center-aligned PWM */
/* COUNTERTOP Register */
#define PWM_COUNTERTOP_MASK (0x7fff)
/* PRESCALER Register */
#define PWM_PRESCALER_SHIFT (0)
#define PWM_PRESCALER_MASK (7 << PWM_PRESCALER_SHIFT)
# define PWM_PRESCALER_16MHZ (0 << PWM_PRESCALER_SHIFT)
# define PWM_PRESCALER_8MHZ (1 << PWM_PRESCALER_SHIFT)
# define PWM_PRESCALER_4MHZ (2 << PWM_PRESCALER_SHIFT)
# define PWM_PRESCALER_2MHZ (3 << PWM_PRESCALER_SHIFT)
# define PWM_PRESCALER_1MHZ (4 << PWM_PRESCALER_SHIFT)
# define PWM_PRESCALER_500KHZ (5 << PWM_PRESCALER_SHIFT)
# define PWM_PRESCALER_250KHZ (6 << PWM_PRESCALER_SHIFT)
# define PWM_PRESCALER_125KHZ (7 << PWM_PRESCALER_SHIFT)
/* DECODER Register */
#define PWM_DECODER_LOAD_SHIFT (0) /* Bits 0-1: How a sequence is read from RAM */
#define PWM_DECODER_LOAD_MASK (3 << PWM_DECODER_LOAD_SHIFT)
# define PWM_DECODER_LOAD_COMMON (0 << PWM_DECODER_LOAD_SHIFT)
# define PWM_DECODER_LOAD_GROUPED (1 << PWM_DECODER_LOAD_SHIFT)
# define PWM_DECODER_LOAD_INDIVIDUAL (2 << PWM_DECODER_LOAD_SHIFT)
# define PWM_DECODER_LOAD_WAVEFORM (3 << PWM_DECODER_LOAD_SHIFT)
#define PWM_DECODER_MODE_REFRESH (8 << 0) /* Bit 8: */
#define PWM_DECODER_MODE_NEXTSTEP (8 << 1) /* Bit 8: */
/* LOOP Register */
#define PWM_LOOP_MASK (0xffff)
/* SEQ[n]CNT Register */
#define PWM_SEQCNT_MASK (0x7fff)
/* SEQ[n]REFRESH Register */
#define PWM_SEQREFRESH_MASK (0xffffff)
/* SEQ[n]ENDDELAY Register */
#define PWM_SEQENDDELAY_MASK (0xffffff)
/* PSEL[x] Register */
#define PWM_PSEL_PIN_SHIFT (0) /* Bits 0-4: OUT pin number */
#define PWM_PSEL_PIN_MASK (0x1f << PWM_PSELSDA_PIN_SHIFT)
#define PWM_PSEL_PORT_SHIFT (5) /* Bit 5: PUT port number */
#define PWM_PSEL_PORT_MASK (0x1 << PWM_PSELSDA_PORT_SHIFT)
#define PWM_PSEL_CONNECTED (1 << 31) /* Bit 31: Connection */
#define PWM_PSEL_RESET (0xffffffff)
/* Decoder data */
#define PWM_DECODER_COMPARE_SHIFT (0)
#define PWM_DECODER_COMPARE_MASK (0x7fff)
#define PWM_DECODER_POL_RISING (0 << 15)
#define PWM_DECODER_POL_FALLING (1 << 15)
#endif /* __ARCH_ARM_SRC_NRF52_HARDWARE_NRF52_PWM_H */
File diff suppressed because it is too large Load Diff
+131
View File
@@ -0,0 +1,131 @@
/****************************************************************************
* arch/arm/src/nrf52/nrf52_pwm.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.
*
****************************************************************************/
#ifndef __ARCH_ARM_SRC_NRF52_NRF52_PWM_H
#define __ARCH_ARM_SRC_NRF52_NRF52_PWM_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/timers/pwm.h>
#include "chip.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Configuration ************************************************************/
/* Enable the specified PWM channel if multichannel PWM is disabled */
#ifndef CONFIG_NRF52_PWM_MULTICHAN
# ifdef CONFIG_NRF52_PWM0
# if !defined(CONFIG_NRF52_PWM0_CHANNEL)
# error "CONFIG_NRF52_PWM0_CHANNEL must be provided"
# elif CONFIG_NRF52_PWM0_CHANNEL == 0
# define CONFIG_NRF52_PWM0_CH0 1
# elif CONFIG_NRF52_PWM0_CHANNEL == 1
# define CONFIG_NRF52_PWM0_CH1 1
# elif CONFIG_NRF52_PWM0_CHANNEL == 2
# define CONFIG_NRF52_PWM0_CH2 1
# elif CONFIG_NRF52_PWM0_CHANNEL == 3
# define CONFIG_NRF52_PWM0_CH3 1
# else
# error "Unsupported value of CONFIG_NRF52_PWM0_CHANNEL"
# endif
# endif
# ifdef CONFIG_NRF52_PWM1
# if !defined(CONFIG_NRF52_PWM1_CHANNEL)
# error "CONFIG_NRF52_PWM1_CHANNEL must be provided"
# elif CONFIG_NRF52_PWM1_CHANNEL == 0
# define CONFIG_NRF52_PWM1_CH0 1
# elif CONFIG_NRF52_PWM1_CHANNEL == 1
# define CONFIG_NRF52_PWM1_CH1 1
# elif CONFIG_NRF52_PWM1_CHANNEL == 2
# define CONFIG_NRF52_PWM1_CH2 1
# elif CONFIG_NRF52_PWM1_CHANNEL == 3
# define CONFIG_NRF52_PWM1_CH3 1
# else
# error "Unsupported value of CONFIG_NRF52_PWM1_CHANNEL"
# endif
# endif
# ifdef CONFIG_NRF52_PWM2
# if !defined(CONFIG_NRF52_PWM2_CHANNEL)
# error "CONFIG_NRF52_PWM2_CHANNEL must be provided"
# elif CONFIG_NRF52_PWM2_CHANNEL == 0
# define CONFIG_NRF52_PWM2_CH0 1
# elif CONFIG_NRF52_PWM2_CHANNEL == 1
# define CONFIG_NRF52_PWM2_CH1 1
# elif CONFIG_NRF52_PWM2_CHANNEL == 2
# define CONFIG_NRF52_PWM2_CH2 1
# elif CONFIG_NRF52_PWM2_CHANNEL == 3
# define CONFIG_NRF52_PWM2_CH3 1
# else
# error "Unsupported value of CONFIG_NRF52_PWM2_CHANNEL"
# endif
# endif
# ifdef CONFIG_NRF52_PWM3
# if !defined(CONFIG_NRF52_PWM3_CHANNEL)
# error "CONFIG_NRF52_PWM3_CHANNEL must be provided"
# elif CONFIG_NRF52_PWM3_CHANNEL == 0
# define CONFIG_NRF52_PWM3_CH0 1
# elif CONFIG_NRF52_PWM3_CHANNEL == 1
# define CONFIG_NRF52_PWM3_CH1 1
# elif CONFIG_NRF52_PWM3_CHANNEL == 2
# define CONFIG_NRF52_PWM3_CH2 1
# elif CONFIG_NRF52_PWM3_CHANNEL == 3
# define CONFIG_NRF52_PWM3_CH3 1
# else
# error "Unsupported value of CONFIG_NRF52_PWM3_CHANNEL"
# endif
# endif
#endif
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: nrf52_pwminitialize
*
* Description:
* Initialize one timer for use with the upper_level PWM driver.
*
* Input Parameters:
* pwm - A number identifying the pwm instance.
*
* Returned Value:
* On success, a pointer to the NRF52 lower half PWM driver is returned.
* NULL is returned on any failure.
*
****************************************************************************/
FAR struct pwm_lowerhalf_s *nrf52_pwminitialize(int pwm);
#endif /* __ARCH_ARM_SRC_NRF52_NRF52_PWM_H */