arch/nrf53: add PWM support

This commit is contained in:
raiden00pl 2023-03-13 12:39:14 +01:00 committed by Petro Karashchenko
parent c2abd16dd7
commit 93ac27ff63
5 changed files with 960 additions and 0 deletions

View File

@ -280,6 +280,7 @@ config ARCH_CHIP_NRF52
config ARCH_CHIP_NRF53
bool "Nordic NRF53"
select ARCH_CORTEXM33
select ARCH_HAVE_PWM_MULTICHAN
depends on EXPERIMENTAL
---help---
Nordic NRF53 architectures (ARM dual Cortex-M33).

View File

@ -21,6 +21,8 @@ config NRF53_APPCORE
bool
default n
select ARM_HAVE_DSP
select ARCH_HAVE_FPU
select NRF53_HAVE_PWM
config NRF53_NETCORE
bool
@ -66,6 +68,12 @@ config NRF53_ENABLE_APPROTECT
bool "NRF53 enable APPROTECT"
default n
# Peripheral support
config NRF53_HAVE_PWM
bool
default n
# Peripheral Selection
config NRF53_IPC
@ -80,6 +88,10 @@ config NRF53_TIMER
bool
default n
config NRF53_PWM
bool
default n
menu "NRF53 Peripheral Selection"
config NRF53_UART0
@ -108,6 +120,20 @@ config NRF53_TIMER1
config NRF53_TIMER2
bool "TIMER2"
select NRF53_TIMER
config NRF53_PWM0
bool "PWM0"
select NRF53_PWM
default n
config NRF53_PWM1
bool "PWM1"
select NRF53_PWM
default n
config NRF53_PWM2
bool "PWM2"
select NRF53_PWM
default n
endmenu # NRF53 Peripheral Selection
@ -188,6 +214,124 @@ endchoice
endmenu # System Timer
menu "PWM configuration"
config NRF53_PWM_MULTICHAN
bool "PWM Multiple Output Channels"
default n
if NRF53_PWM_MULTICHAN
if NRF53_PWM0
config NRF53_PWM0_CH0
bool "PWM0 Channel 0 Output"
default n
---help---
Enables channel 0 output.
config NRF53_PWM0_CH1
bool "PWM0 Channel 1 Output"
default n
---help---
Enables channel 1 output.
config NRF53_PWM0_CH2
bool "PWM0 Channel 2 Output"
default n
---help---
Enables channel 2 output.
config NRF53_PWM0_CH3
bool "PWM0 Channel 3 Output"
default n
---help---
Enables channel 3 output.
endif # NRF53_PWM0
if NRF53_PWM1
config NRF53_PWM1_CH0
bool "PWM1 Channel 0 Output"
default n
---help---
Enables channel 0 output.
config NRF53_PWM1_CH1
bool "PWM1 Channel 1 Output"
default n
---help---
Enables channel 1 output.
config NRF53_PWM1_CH2
bool "PWM1 Channel 2 Output"
default n
---help---
Enables channel 2 output.
config NRF53_PWM1_CH3
bool "PWM1 Channel 3 Output"
default n
---help---
Enables channel 3 output.
endif # NRF53_PWM1
if NRF53_PWM2
config NRF53_PWM2_CH0
bool "PWM2 Channel 0 Output"
default n
---help---
Enables channel 0 output.
config NRF53_PWM2_CH1
bool "PWM2 Channel 1 Output"
default n
---help---
Enables channel 1 output.
config NRF53_PWM2_CH2
bool "PWM2 Channel 2 Output"
default n
---help---
Enables channel 2 output.
config NRF53_PWM2_CH3
bool "PWM2 Channel 3 Output"
default n
---help---
Enables channel 3 output.
endif # NRF53_PWM2
endif # !NRF53_PWM_MULTICHAN
if !NRF53_PWM_MULTICHAN
config NRF53_PWM0_CHANNEL
int "PWM0 Output Channel"
depends on NRF53_PWM0
default 0
range 0 3
config NRF53_PWM1_CHANNEL
int "PWM1 Output Channel"
depends on NRF53_PWM1
default 0
range 0 3
config NRF53_PWM2_CHANNEL
int "PWM2 Output Channel"
depends on NRF53_PWM2
default 0
range 0 3
endif # !NRF53_PWM_MULTICHAN
endmenu # PWM configuration
menuconfig NRF53_SOFTDEVICE_CONTROLLER
bool "SoftDevice Controller"
depends on ALLOW_BSDNORDIC_COMPONENTS

View File

@ -58,6 +58,10 @@ CHIP_CSRCS += nrf53_tim_lowerhalf.c
endif
endif
ifeq ($(CONFIG_NRF53_PWM),y)
CHIP_CSRCS += nrf53_pwm.c
endif
ifeq ($(CONFIG_PM),y)
CHIP_CSRCS += nrf53_pminitialize.c
endif

View File

@ -0,0 +1,696 @@
/****************************************************************************
* arch/arm/src/nrf53/nrf53_pwm.c
*
* 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.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <assert.h>
#include <debug.h>
#include <errno.h>
#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>
#include <arch/board/board.h>
#include "arm_internal.h"
#include "nrf53_gpio.h"
#include "nrf53_pwm.h"
#include "hardware/nrf53_pwm.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Default PWM polarity */
#define PWM_POLARITY_DEFAULT (PWM_DECODER_POL_FALLING)
/* Sequence 0 length */
#define PWM_SEQ0_LEN (4)
/****************************************************************************
* Private Types
****************************************************************************/
struct nrf53_pwm_s
{
const struct pwm_ops_s *ops; /* PWM operations */
uint32_t base; /* Base address of PWM register */
uint32_t frequency; /* Current frequency setting */
uint32_t cntrtop; /* Counter top */
uint32_t ch0_pin; /* Channel 1 pin */
uint32_t ch1_pin; /* Channel 2 pin */
uint32_t ch2_pin; /* Channel 3 pin */
uint32_t ch3_pin; /* Channel 4 pin */
/* Sequence 0 */
uint16_t seq0[PWM_SEQ0_LEN];
};
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/* PWM Register access */
static inline void nrf53_pwm_putreg(struct nrf53_pwm_s *priv,
uint32_t offset,
uint32_t value);
static inline uint32_t nrf53_pwm_getreg(struct nrf53_pwm_s *priv,
uint32_t offset);
/* PWM helpers */
static int nrf53_pwm_configure(struct nrf53_pwm_s *priv);
static int nrf53_pwm_duty(struct nrf53_pwm_s *priv, uint8_t chan,
ub16_t duty);
static int nrf53_pwm_freq(struct nrf53_pwm_s *priv, uint32_t freq);
/* PWM driver methods */
static int nrf53_pwm_setup(struct pwm_lowerhalf_s *dev);
static int nrf53_pwm_shutdown(struct pwm_lowerhalf_s *dev);
#ifdef CONFIG_PWM_PULSECOUNT
static int nrf53_pwm_start(struct pwm_lowerhalf_s *dev,
const struct pwm_info_s *info,
void *handle);
#else
static int nrf53_pwm_start(struct pwm_lowerhalf_s *dev,
const struct pwm_info_s *info);
#endif
static int nrf53_pwm_stop(struct pwm_lowerhalf_s *dev);
static int nrf53_pwm_ioctl(struct pwm_lowerhalf_s *dev,
int cmd, unsigned long arg);
/****************************************************************************
* Private Data
****************************************************************************/
/* This is the list of lower half PWM driver methods used by the upper half
* driver.
*/
static const struct pwm_ops_s g_nrf53_pwmops =
{
.setup = nrf53_pwm_setup,
.shutdown = nrf53_pwm_shutdown,
.start = nrf53_pwm_start,
.stop = nrf53_pwm_stop,
.ioctl = nrf53_pwm_ioctl,
};
#ifdef CONFIG_NRF53_PWM0
/* PWM 0 */
struct nrf53_pwm_s g_nrf53_pwm0 =
{
.ops = &g_nrf53_pwmops,
.base = NRF53_PWM0_BASE,
#ifdef CONFIG_NRF53_PWM0_CH0
.ch0_pin = NRF53_PWM0_CH0_PIN,
#endif
#ifdef CONFIG_NRF53_PWM0_CH1
.ch1_pin = NRF53_PWM0_CH1_PIN,
#endif
#ifdef CONFIG_NRF53_PWM0_CH2
.ch2_pin = NRF53_PWM0_CH2_PIN,
#endif
#ifdef CONFIG_NRF53_PWM0_CH3
.ch3_pin = NRF53_PWM0_CH3_PIN,
#endif
};
#endif
#ifdef CONFIG_NRF53_PWM1
/* PWM 1 */
struct nrf53_pwm_s g_nrf53_pwm1 =
{
.ops = &g_nrf53_pwmops,
.base = NRF53_PWM1_BASE,
#ifdef CONFIG_NRF53_PWM1_CH0
.ch0_pin = NRF53_PWM1_CH0_PIN,
#endif
#ifdef CONFIG_NRF53_PWM1_CH1
.ch1_pin = NRF53_PWM1_CH1_PIN,
#endif
#ifdef CONFIG_NRF53_PWM1_CH2
.ch2_pin = NRF53_PWM1_CH2_PIN,
#endif
#ifdef CONFIG_NRF53_PWM1_CH3
.ch3_pin = NRF53_PWM1_CH3_PIN,
#endif
};
#endif
#ifdef CONFIG_NRF53_PWM2
/* PWM 2 */
struct nrf53_pwm_s g_nrf53_pwm2 =
{
.ops = &g_nrf53_pwmops,
.base = NRF53_PWM2_BASE,
#ifdef CONFIG_NRF53_PWM2_CH0
.ch0_pin = NRF53_PWM2_CH0_PIN,
#endif
#ifdef CONFIG_NRF53_PWM2_CH1
.ch1_pin = NRF53_PWM2_CH1_PIN,
#endif
#ifdef CONFIG_NRF53_PWM2_CH2
.ch2_pin = NRF53_PWM2_CH2_PIN,
#endif
#ifdef CONFIG_NRF53_PWM2_CH3
.ch3_pin = NRF53_PWM2_CH3_PIN,
#endif
};
#endif
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: nrf53_pwm_putreg
*
* Description:
* Put a 32-bit register value by offset
*
****************************************************************************/
static inline void nrf53_pwm_putreg(struct nrf53_pwm_s *priv,
uint32_t offset,
uint32_t value)
{
putreg32(value, priv->base + offset);
}
/****************************************************************************
* Name: nrf53_pwm_getreg
*
* Description:
* Get a 32-bit register value by offset
*
****************************************************************************/
static inline uint32_t nrf53_pwm_getreg(struct nrf53_pwm_s *priv,
uint32_t offset)
{
return getreg32(priv->base + offset);
}
/****************************************************************************
* Name: nrf53_pwm_configure
*
* Description:
* Configure PWM
*
****************************************************************************/
static int nrf53_pwm_configure(struct nrf53_pwm_s *priv)
{
uint32_t regval = 0;
int ret = OK;
DEBUGASSERT(priv);
/* Configure PWM mode */
nrf53_pwm_putreg(priv, NRF53_PWM_MODE_OFFSET, PWM_MODE_UP);
/* Configure decoder */
regval = PWM_DECODER_LOAD_INDIVIDUAL | PWM_DECODER_MODE_REFRESH;
nrf53_pwm_putreg(priv, NRF53_PWM_DECODER_OFFSET, regval);
/* Configure sequence 0 */
regval = (uint32_t)priv->seq0;
nrf53_pwm_putreg(priv, NRF53_PWM_SEQ0PTR_OFFSET, regval);
regval = PWM_SEQ0_LEN;
nrf53_pwm_putreg(priv, NRF53_PWM_SEQ0CNT_OFFSET, regval);
regval = 0;
nrf53_pwm_putreg(priv, NRF53_PWM_SEQ0REFRESH_OFFSET, regval);
return ret;
}
/****************************************************************************
* Name: nrf53_pwm_duty
*
* Description:
* Configure PWM duty
*
****************************************************************************/
static int nrf53_pwm_duty(struct nrf53_pwm_s *priv, uint8_t chan,
ub16_t duty)
{
uint16_t compare = 0;
DEBUGASSERT(priv);
pwminfo("PWM channel: %d duty: %" PRId32 "\n", chan, duty);
/* Get compare
*
* duty cycle = compare / reload (fractional value)
*/
compare = b16toi(duty * priv->cntrtop + b16HALF);
/* Configure channel sequence */
priv->seq0[chan] = PWM_POLARITY_DEFAULT | compare;
pwminfo("seq0[%d]: %d %d\n", chan, compare, priv->seq0[chan]);
return OK;
}
/****************************************************************************
* Name: nrf53_pwm_freq
*
* Description:
* Configure PWM frequency
*
****************************************************************************/
static int nrf53_pwm_freq(struct nrf53_pwm_s *priv, uint32_t freq)
{
uint32_t regval = 0;
uint32_t pwm_clk = 0;
uint32_t top = 0;
uint32_t prescaler = 0;
uint64_t tmp = 0;
int ret = OK;
DEBUGASSERT(priv);
/* Get best prescaler */
tmp = PWM_COUNTERTOP_MASK * freq;
if (tmp >= 16000000)
{
pwm_clk = 16000000;
prescaler = PWM_PRESCALER_16MHZ;
}
else if (tmp >= 8000000)
{
pwm_clk = 8000000;
prescaler = PWM_PRESCALER_8MHZ;
}
else if (tmp >= 4000000)
{
pwm_clk = 4000000;
prescaler = PWM_PRESCALER_4MHZ;
}
else if (tmp >= 2000000)
{
pwm_clk = 2000000;
prescaler = PWM_PRESCALER_2MHZ;
}
else if (tmp >= 1000000)
{
pwm_clk = 1000000;
prescaler = PWM_PRESCALER_1MHZ;
}
else if (tmp >= 500000)
{
pwm_clk = 500000;
prescaler = PWM_PRESCALER_500KHZ;
}
else if (tmp >= 250000)
{
pwm_clk = 250000;
prescaler = PWM_PRESCALER_250KHZ;
}
else
{
pwm_clk = 125000;
prescaler = PWM_PRESCALER_125KHZ;
}
/* Configure prescaler */
nrf53_pwm_putreg(priv, NRF53_PWM_PRESCALER_OFFSET, prescaler);
/* Get counter max */
top = pwm_clk / freq;
if (top < 2)
{
top = 1;
}
else if (top > PWM_COUNTERTOP_MASK)
{
top = PWM_COUNTERTOP_MASK;
}
else
{
top = top - 1;
}
/* Configure counter max */
regval = top;
nrf53_pwm_putreg(priv, NRF53_PWM_COUNTERTOP_OFFSET, regval);
priv->cntrtop = top;
pwminfo("PWM frequency: %" PRId32 " pwm_clk: %" PRId32
" pwm_prescaler: %" PRId32 " top: %" PRId32 "\n",
freq, pwm_clk, prescaler, top);
return ret;
}
/****************************************************************************
* Name: nrf53_pwm_setup
*
* Description:
* This method is called when the driver is opened. The lower half driver
* should configure and initialize the device so that it is ready for use.
* It should not, however, output pulses until the start method is called.
*
****************************************************************************/
static int nrf53_pwm_setup(struct pwm_lowerhalf_s *dev)
{
struct nrf53_pwm_s *priv = (struct nrf53_pwm_s *)dev;
int ret = OK;
uint32_t regval = 0;
uint32_t pin = 0;
uint32_t port = 0;
DEBUGASSERT(dev);
/* Configure channels */
if (priv->ch0_pin != 0)
{
nrf53_gpio_config(priv->ch0_pin);
pin = GPIO_PIN_DECODE(priv->ch0_pin);
port = GPIO_PORT_DECODE(priv->ch0_pin);
regval = (port << PWM_PSEL_PORT_SHIFT);
regval |= (pin << PWM_PSEL_PIN_SHIFT);
nrf53_pwm_putreg(priv, NRF53_PWM_PSEL0_OFFSET, regval);
}
if (priv->ch1_pin != 0)
{
nrf53_gpio_config(priv->ch1_pin);
pin = GPIO_PIN_DECODE(priv->ch1_pin);
port = GPIO_PORT_DECODE(priv->ch1_pin);
regval = (port << PWM_PSEL_PORT_SHIFT);
regval |= (pin << PWM_PSEL_PIN_SHIFT);
nrf53_pwm_putreg(priv, NRF53_PWM_PSEL1_OFFSET, regval);
}
if (priv->ch2_pin != 0)
{
nrf53_gpio_config(priv->ch2_pin);
pin = GPIO_PIN_DECODE(priv->ch2_pin);
port = GPIO_PORT_DECODE(priv->ch2_pin);
regval = (port << PWM_PSEL_PORT_SHIFT);
regval |= (pin << PWM_PSEL_PIN_SHIFT);
nrf53_pwm_putreg(priv, NRF53_PWM_PSEL2_OFFSET, regval);
}
if (priv->ch3_pin != 0)
{
nrf53_gpio_config(priv->ch3_pin);
pin = GPIO_PIN_DECODE(priv->ch3_pin);
port = GPIO_PORT_DECODE(priv->ch3_pin);
regval = (port << PWM_PSEL_PORT_SHIFT);
regval |= (pin << PWM_PSEL_PIN_SHIFT);
nrf53_pwm_putreg(priv, NRF53_PWM_PSEL3_OFFSET, regval);
}
/* Configure PWM */
ret = nrf53_pwm_configure(priv);
if (ret < 0)
{
pwmerr("ERROR: nrf53_pwm_configure failed %d\n", ret);
goto errout;
}
/* Enable PWM */
nrf53_pwm_putreg(priv, NRF53_PWM_ENABLE_OFFSET, 1);
errout:
return ret;
}
/****************************************************************************
* Name: nrf53_pwm_shutdown
*
* Description:
* This method is called when the driver is closed. The lower half driver
* stop pulsed output, free any resources, disable the timer hardware, and
* put the system into the lowest possible power usage state
*
****************************************************************************/
static int nrf53_pwm_shutdown(struct pwm_lowerhalf_s *dev)
{
struct nrf53_pwm_s *priv = (struct nrf53_pwm_s *)dev;
int ret = OK;
DEBUGASSERT(dev);
/* Disable PWM */
nrf53_pwm_putreg(priv, NRF53_PWM_ENABLE_OFFSET, 0);
return ret;
}
/****************************************************************************
* Name: nrf53_pwm_start
*
* Description:
* (Re-)initialize the PWM and start the pulsed output
*
****************************************************************************/
#ifdef CONFIG_PWM_PULSECOUNT
static int nrf53_pwm_start(struct pwm_lowerhalf_s *dev,
const struct pwm_info_s *info,
void *handle)
{
#error Not supported
}
#else
static int nrf53_pwm_start(struct pwm_lowerhalf_s *dev,
const struct pwm_info_s *info)
{
struct nrf53_pwm_s *priv = (struct nrf53_pwm_s *)dev;
int ret = OK;
#ifdef CONFIG_PWM_MULTICHAN
int i = 0;
#endif
DEBUGASSERT(dev);
/* If frequency has not changed we just update duty */
if (info->frequency != priv->frequency)
{
/* Update frequency */
ret = nrf53_pwm_freq(priv, info->frequency);
if (ret == OK)
{
priv->frequency = info->frequency;
}
}
#ifdef CONFIG_PWM_MULTICHAN
for (i = 0; ret == OK && i < CONFIG_PWM_NCHANNELS; i++)
{
/* Break the loop if all following channels are not configured */
if (info->channels[i].channel == -1)
{
break;
}
/* Set output if channel configured */
if (info->channels[i].channel != 0)
{
ret = nrf53_pwm_duty(priv,
(info->channels[i].channel - 1),
info->channels[i].duty);
}
}
#else
ret = nrf53_pwm_duty(dev,
(info->channels[0].channel - 1),
info->duty);
#endif /* CONFIG_PWM_MULTICHAN */
/* Start sequence 0 */
nrf53_pwm_putreg(priv, NRF53_PWM_TASKS_SEQSTART0_OFFSET, 1);
/* Wait for sequence started */
while (nrf53_pwm_getreg(priv, NRF53_PWM_EVENTS_SEQSTARTED0_OFFSET) != 1);
return ret;
}
#endif
/****************************************************************************
* Name: nrf53_pwm_stop
*
* Description:
* Stop the PWM
*
****************************************************************************/
static int nrf53_pwm_stop(struct pwm_lowerhalf_s *dev)
{
struct nrf53_pwm_s *priv = (struct nrf53_pwm_s *)dev;
DEBUGASSERT(dev);
/* Stop PWM */
nrf53_pwm_putreg(priv, NRF53_PWM_TASKS_STOP_OFFSET, 1);
/* Wait for PWM stopped */
while (nrf53_pwm_getreg(priv, NRF53_PWM_EVENTS_STOPPED_OFFSET) != 1);
return OK;
}
/****************************************************************************
* Name: nrf53_pwm_ioctl
*
* Description:
* Lower-half logic may support platform-specific ioctl commands
*
****************************************************************************/
static int nrf53_pwm_ioctl(struct pwm_lowerhalf_s *dev,
int cmd, unsigned long arg)
{
struct nrf53_pwm_s *priv = (struct nrf53_pwm_s *)dev;
DEBUGASSERT(dev);
/* There are no platform-specific ioctl commands */
UNUSED(priv);
return -ENOTTY;
}
/****************************************************************************
* Public Function
****************************************************************************/
/****************************************************************************
* Name: nrf53_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 NRF53 lower half PWM driver is returned.
* NULL is returned on any failure.
*
****************************************************************************/
struct pwm_lowerhalf_s *nrf53_pwminitialize(int pwm)
{
struct nrf53_pwm_s *lower = NULL;
pwminfo("Initialize PWM%u\n", pwm);
switch (pwm)
{
#ifdef CONFIG_NRF53_PWM0
case 0:
{
lower = &g_nrf53_pwm0;
break;
}
#endif
#ifdef CONFIG_NRF53_PWM1
case 1:
{
lower = &g_nrf53_pwm1;
break;
}
#endif
#ifdef CONFIG_NRF53_PWM2
case 2:
{
lower = &g_nrf53_pwm2;
break;
}
#endif
default:
{
pwmerr("ERROR: No such PWM device %d\n", pwm);
lower = NULL;
goto errout;
}
}
errout:
return (struct pwm_lowerhalf_s *)lower;
}

View File

@ -0,0 +1,115 @@
/****************************************************************************
* arch/arm/src/nrf53/nrf53_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_NRF53_NRF53_PWM_H
#define __ARCH_ARM_SRC_NRF53_NRF53_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_NRF53_PWM_MULTICHAN
# ifdef CONFIG_NRF53_PWM0
# if !defined(CONFIG_NRF53_PWM0_CHANNEL)
# error "CONFIG_NRF53_PWM0_CHANNEL must be provided"
# elif CONFIG_NRF53_PWM0_CHANNEL == 0
# define CONFIG_NRF53_PWM0_CH0 1
# elif CONFIG_NRF53_PWM0_CHANNEL == 1
# define CONFIG_NRF53_PWM0_CH1 1
# elif CONFIG_NRF53_PWM0_CHANNEL == 2
# define CONFIG_NRF53_PWM0_CH2 1
# elif CONFIG_NRF53_PWM0_CHANNEL == 3
# define CONFIG_NRF53_PWM0_CH3 1
# else
# error "Unsupported value of CONFIG_NRF53_PWM0_CHANNEL"
# endif
# endif
# ifdef CONFIG_NRF53_PWM1
# if !defined(CONFIG_NRF53_PWM1_CHANNEL)
# error "CONFIG_NRF53_PWM1_CHANNEL must be provided"
# elif CONFIG_NRF53_PWM1_CHANNEL == 0
# define CONFIG_NRF53_PWM1_CH0 1
# elif CONFIG_NRF53_PWM1_CHANNEL == 1
# define CONFIG_NRF53_PWM1_CH1 1
# elif CONFIG_NRF53_PWM1_CHANNEL == 2
# define CONFIG_NRF53_PWM1_CH2 1
# elif CONFIG_NRF53_PWM1_CHANNEL == 3
# define CONFIG_NRF53_PWM1_CH3 1
# else
# error "Unsupported value of CONFIG_NRF53_PWM1_CHANNEL"
# endif
# endif
# ifdef CONFIG_NRF53_PWM2
# if !defined(CONFIG_NRF53_PWM2_CHANNEL)
# error "CONFIG_NRF53_PWM2_CHANNEL must be provided"
# elif CONFIG_NRF53_PWM2_CHANNEL == 0
# define CONFIG_NRF53_PWM2_CH0 1
# elif CONFIG_NRF53_PWM2_CHANNEL == 1
# define CONFIG_NRF53_PWM2_CH1 1
# elif CONFIG_NRF53_PWM2_CHANNEL == 2
# define CONFIG_NRF53_PWM2_CH2 1
# elif CONFIG_NRF53_PWM2_CHANNEL == 3
# define CONFIG_NRF53_PWM2_CH3 1
# else
# error "Unsupported value of CONFIG_NRF53_PWM2_CHANNEL"
# endif
# endif
#endif
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: nrf53_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 NRF53 lower half PWM driver is returned.
* NULL is returned on any failure.
*
****************************************************************************/
struct pwm_lowerhalf_s *nrf53_pwminitialize(int pwm);
#endif /* __ARCH_ARM_SRC_NRF53_NRF53_PWM_H */