arch/arm64/src/imx9: Add TPM based PWM driver for IMX9
Signed-off-by: Jukka Laitinen <jukkax@ssrc.tii.ae>
This commit is contained in:
parent
65bd548521
commit
0f596ec496
@ -67,6 +67,107 @@ config IMX9_FLEXIO2_PWM_CHANNEL_PINS
|
||||
hex "FlexIO outputs used for FLEXIO2 timers"
|
||||
default 0x0000000000000000
|
||||
|
||||
config IMX9_TPM_PWM
|
||||
bool
|
||||
select PWM_MULTICHAN
|
||||
default n
|
||||
|
||||
config IMX9_TPM1_PWM
|
||||
depends on PWM
|
||||
bool "Enable TPM1 based PWM generation"
|
||||
select IMX9_TPM_PWM
|
||||
default n
|
||||
|
||||
config IMX9_TPM1_PWM_NCHANNELS
|
||||
depends on IMX9_TPM1_PWM
|
||||
int "Number of channels for TPM1"
|
||||
default 1
|
||||
|
||||
config IMX9_TPM1_PWM_CHMUX
|
||||
depends on IMX9_TPM1_PWM
|
||||
hex "Channel mux for TPM1"
|
||||
default 0x03020100
|
||||
|
||||
config IMX9_TPM2_PWM
|
||||
depends on PWM
|
||||
bool "Enable TPM2 based PWM generation"
|
||||
select IMX9_TPM_PWM
|
||||
default n
|
||||
|
||||
config IMX9_TPM2_PWM_NCHANNELS
|
||||
depends on IMX9_TPM2_PWM
|
||||
int "Number of channels for TPM2"
|
||||
default 1
|
||||
|
||||
config IMX9_TPM2_PWM_CHMUX
|
||||
depends on IMX9_TPM2_PWM
|
||||
hex "Channel mux for TPM2"
|
||||
default 0x03020100
|
||||
|
||||
config IMX9_TPM3_PWM
|
||||
depends on PWM
|
||||
bool "Enable TPM3 based PWM generation"
|
||||
select IMX9_TPM_PWM
|
||||
default n
|
||||
|
||||
config IMX9_TPM3_PWM_NCHANNELS
|
||||
depends on IMX9_TPM3_PWM
|
||||
int "Number of channels for TPM3"
|
||||
default 1
|
||||
|
||||
config IMX9_TPM3_PWM_CHMUX
|
||||
depends on IMX9_TPM3_PWM
|
||||
hex "Channel mux for TPM3"
|
||||
default 0x03020100
|
||||
|
||||
config IMX9_TPM4_PWM
|
||||
depends on PWM
|
||||
bool "Enable TPM4 based PWM generation"
|
||||
select IMX9_TPM_PWM
|
||||
default n
|
||||
|
||||
config IMX9_TPM4_PWM_NCHANNELS
|
||||
depends on IMX9_TPM4_PWM
|
||||
int "Number of channels for TPM4"
|
||||
default 1
|
||||
|
||||
config IMX9_TPM4_PWM_CHMUX
|
||||
depends on IMX9_TPM4_PWM
|
||||
hex "Channel mux for TPM4"
|
||||
default 0x03020100
|
||||
|
||||
config IMX9_TPM5_PWM
|
||||
depends on PWM
|
||||
bool "Enable TPM5 based PWM generation"
|
||||
select IMX9_TPM_PWM
|
||||
default n
|
||||
|
||||
config IMX9_TPM5_PWM_NCHANNELS
|
||||
depends on IMX9_TPM5_PWM
|
||||
int "Number of channels for TPM5"
|
||||
default 1
|
||||
|
||||
config IMX9_TPM5_PWM_CHMUX
|
||||
depends on IMX9_TPM5_PWM
|
||||
hex "Channel mux for TPM5"
|
||||
default 0x03020100
|
||||
|
||||
config IMX9_TPM6_PWM
|
||||
depends on PWM
|
||||
bool "Enable TPM6 based PWM generation"
|
||||
select IMX9_TPM_PWM
|
||||
default n
|
||||
|
||||
config IMX9_TPM6_PWM_NCHANNELS
|
||||
depends on IMX9_TPM6_PWM
|
||||
int "Number of channels for TPM6"
|
||||
default 1
|
||||
|
||||
config IMX9_TPM6_PWM_CHMUX
|
||||
depends on IMX9_TPM6_PWM
|
||||
hex "Channel mux for TPM6"
|
||||
default 0x03020100
|
||||
|
||||
config IMX9_USBDEV
|
||||
bool
|
||||
default n
|
||||
|
@ -39,6 +39,10 @@ ifeq ($(CONFIG_IMX9_FLEXIO_PWM),y)
|
||||
CHIP_CSRCS += imx9_flexio_pwm.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_IMX9_TPM_PWM),y)
|
||||
CHIP_CSRCS += imx9_tpm_pwm.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_IMX9_USBDEV),y)
|
||||
CHIP_CSRCS += imx9_usbdev.c
|
||||
endif
|
||||
|
206
arch/arm64/src/imx9/hardware/imx9_tpm.h
Normal file
206
arch/arm64/src/imx9/hardware/imx9_tpm.h
Normal file
@ -0,0 +1,206 @@
|
||||
/****************************************************************************
|
||||
* arch/arm64/src/imx9/hardware/imx9_tpm.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_ARM64_SRC_IMX9_HARDWARE_IMX9_TPM_H
|
||||
#define __ARCH_ARM64_SRC_IMX9_HARDWARE_IMX9_TPM_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Register Offsets *********************************************************/
|
||||
|
||||
#define IMX9_TPM_VERID_OFFSET 0x0000 /* Version ID */
|
||||
#define IMX9_TPM_PARAM_OFFSET 0x0004 /* Parameter */
|
||||
#define IMX9_TPM_GLOBAL_OFFSET 0x0008 /* TPM Global */
|
||||
#define IMX9_TPM_SC_OFFSET 0x0010 /* Status and Control */
|
||||
#define IMX9_TPM_CNT_OFFSET 0x0014 /* Counter */
|
||||
#define IMX9_TPM_MOD_OFFSET 0x0018 /* Modulo */
|
||||
#define IMX9_TPM_STATUS_OFFSET 0x001c /* Capture and Compare Status */
|
||||
#define IMX9_TPM_CXSC_OFFSET(ch) (0x0020 + (ch) * 8) /* Channel Status and Control */
|
||||
#define IMX9_TPM_CXV_OFFSET(ch) (0x0024 + (ch) * 8) /* Channel Value */
|
||||
#define IMX9_TPM_C1SC_OFFSET 0x0028 /* Channel n Status and Control */
|
||||
#define IMX9_TPM_C1V_OFFSET 0x002c /* Channel n Value */
|
||||
#define IMX9_TPM_C2SC_OFFSET 0x0030 /* Channel n Status and Control */
|
||||
#define IMX9_TPM_C2V_OFFSET 0x0034 /* Channel n Value */
|
||||
#define IMX9_TPM_C3SC_OFFSET 0x0038 /* Channel n Status and Control */
|
||||
#define IMX9_TPM_C3V_OFFSET 0x003c /* Channel n Value */
|
||||
#define IMX9_TPM_COMBINE_OFFSET 0x0064 /* Combine Channel */
|
||||
#define IMX9_TPM_TRIG_OFFSET 0x006c /* Channel Trigger */
|
||||
#define IMX9_TPM_POL_OFFSET 0x0070 /* Channel Polarity */
|
||||
#define IMX9_TPM_FILTER_OFFSET 0x0078 /* Filter Control */
|
||||
#define IMX9_TPM_QDCTRL_OFFSET 0x0080 /* Quadrature Decoder Control and Status */
|
||||
#define IMX9_TPM_CONF_OFFSET 0x0084 /* Configuration */
|
||||
|
||||
/* Register Bitfield Definitions ********************************************/
|
||||
|
||||
/* PARAM */
|
||||
|
||||
#define TPM_PARAM_WIDTH_SHIFT (16) /* Bit[23:16]: Width of the counter and timer channels */
|
||||
#define TPM_PARAM_WIDTH_MASK (0xff << TPM_PARAM_WIDTH_SHIFT)
|
||||
|
||||
#define TPM_PARAM_TRIG_SHIFT (8) /* Bit[15:8]: Number of triggers that TPM implements */
|
||||
#define TPM_PARAM_TRIG_MASK (0xff << LPIT_PARAM_TRIG_SHIFT)
|
||||
|
||||
#define TPM_PARAM_CHAN_SHIFT (0) /* Bit[7:0]: Number of timer channels */
|
||||
#define TPM_PARAM_CHAN_MASK (0xff << TPM_PARAM_CHAN_SHIFT)
|
||||
|
||||
/* GLOBAL */
|
||||
|
||||
#define TPM_GLOBAL_RST_SHIFT (1) /* Bit[1]: Software Reset */
|
||||
#define TPM_GLOBAL_RST_MASK (0x1 << TPM_GLOBAL_RST_SHIFT)
|
||||
|
||||
#define TPM_GLOBAL_NOUPDATE_SHIFT (0) /* Bit[0]: Block updates to internal registers */
|
||||
#define TPM_GLOBAL_NOUPDATE_MASK (0x1 << TPM_GLOBAL_NOUPDATE_SHIFT)
|
||||
|
||||
/* SC */
|
||||
|
||||
#define TPM_SC_DMA_SHIFT (8) /* Bit[8]: DMA Enable */
|
||||
#define TPM_SC_DMA_MASK (0x1 << TPM_SC_DMA_SHIFT)
|
||||
|
||||
#define TPM_SC_TOF_SHIFT (7) /* Bit[7]: Timer Overflow Flag */
|
||||
#define TPM_SC_TOF_MASK (0x1 << TPM_SC_TOF_SHIFT)
|
||||
|
||||
#define TPM_SC_TOIE_SHIFT (6) /* Bit[6]: Timer Overflow Interrupt Enable */
|
||||
#define TPM_SC_TOIE_MASK (0x1 << TPM_SC_TOIE_SHIFT)
|
||||
|
||||
#define TPM_SC_CPWMS_SHIFT (5) /* Bit[5]: Center-Aligned PWM Select */
|
||||
#define TPM_SC_CPWMS_MASK (0x1 << TPM_SC_CPWMS_SHIFT)
|
||||
|
||||
#define TPM_SC_CMOD_SHIFT (3) /* Bit[4:3]: Clock Mode Selection */
|
||||
#define TPM_SC_CMOD_MASK (0x3 << TPM_SC_CMOD_SHIFT)
|
||||
|
||||
#define TPM_SC_PS_SHIFT (0) /* Bit[2:0]: Prescale Factor Selection */
|
||||
#define TPM_SC_PS_MASK (0x7 << TPM_SC_PS_SHIFT)
|
||||
|
||||
/* STATUS */
|
||||
|
||||
#define TPM_STATUS_TOF_SHIFT (8) /* Bit[8]: Timer Overflow Flag */
|
||||
#define TPM_STATUS_TOF_MASK (0x1 << TPM_STATUS_TOF_SHIFT)
|
||||
|
||||
#define TPM_STATUS_CH3F_SHIFT (3) /* Bit[3]: Channel 3 Flag */
|
||||
#define TPM_STATUS_CH3F_MASK (0x1 << TPM_STATUS_CH3F_SHIFT)
|
||||
|
||||
#define TPM_STATUS_CH2F_SHIFT (2) /* Bit[2]: Channel 2 Flag */
|
||||
#define TPM_STATUS_CH2F_MASK (0x1 << TPM_STATUS_CH2F_SHIFT)
|
||||
|
||||
#define TPM_STATUS_CH1F_SHIFT (1) /* Bit[1]: Channel 1 Flag */
|
||||
#define TPM_STATUS_CH1F_MASK (0x1 << TPM_STATUS_CH1F_SHIFT)
|
||||
|
||||
#define TPM_STATUS_CH0F_SHIFT (0) /* Bit[0]: Channel 0 Flag */
|
||||
#define TPM_STATUS_CH0F_MASK (0x1 << TPM_STATUS_CH0F_SHIFT)
|
||||
|
||||
/* C0SC - C3SC */
|
||||
|
||||
#define TPM_CXSC_CHF_SHIFT (7) /* Bit[7]: Channel Flag */
|
||||
#define TPM_CXSC_CHF_MASK (0x1 << TPM_CXSC_CHF_SHIFT)
|
||||
|
||||
#define TPM_CXSC_CHIE_SHIFT (6) /* Bit[6]: Channel Interrupt Enable */
|
||||
#define TPM_CXSC_CHIE_MASK (0x1 << TPM_CXSC_CHIE_SHIFT)
|
||||
|
||||
#define TPM_CXSC_MSB_SHIFT (5) /* Bit[5]: Channel Mode Select B */
|
||||
#define TPM_CXSC_MSB_MASK (0x1 << TPM_CXSC_MSB_SHIFT)
|
||||
|
||||
#define TPM_CXSC_MSA_SHIFT (4) /* Bit[4]: Channel Mode Select A */
|
||||
#define TPM_CXSC_MSA_MASK (0x1 << TPM_CXSC_MSA_SHIFT)
|
||||
|
||||
#define TPM_CXSC_ELSB_SHIFT (3) /* Bit[3]: Edge or Level Select B */
|
||||
#define TPM_CXSC_ELSB_MASK (0x1 << TPM_CXSC_ELSB_SHIFT)
|
||||
|
||||
#define TPM_CXSC_ELSA_SHIFT (2) /* Bit[2]: Edge or Level Select A */
|
||||
#define TPM_CXSC_ELSA_MASK (0x1 << TPM_CXSC_ELSA_SHIFT)
|
||||
|
||||
#define TPM_CXSC_DMA_SHIFT (0) /* Bit[0]: DMA Enable */
|
||||
#define TPM_CXSC_DMA_MASK (0x1 << TPM_CXSC_DMA_SHIFT)
|
||||
|
||||
/* COMBINE */
|
||||
|
||||
#define TPM_COMBINE_COMSWAP1_SHIFT (9) /* Bit[9]: Combine Channels 2 and 3 Swap */
|
||||
#define TPM_COMBINE_COMSWAP1_MASK (0x1 << TPM_COMBINE_COMSWAP1_SHIFT)
|
||||
|
||||
#define TPM_COMBINE_COMBINE1_SHIFT (8) /* Bit[8]: Combine Channels 2 and 3 */
|
||||
#define TPM_COMBINE_COMBINE1_MASK (0x1 << TPM_COMBINE_COMBINE1_SHIFT)
|
||||
|
||||
#define TPM_COMBINE_COMSWAP0_SHIFT (1) /* Bit[1]: Combine Channel 0 and 1 Swap */
|
||||
#define TPM_COMBINE_COMSWAP0_MASK (0x1 << TPM_COMBINE_COMSWAP0_SHIFT)
|
||||
|
||||
#define TPM_COMBINE_COMBINE0_SHIFT (0) /* Bit[0]: Combine Channels 0 and 1 */
|
||||
#define TPM_COMBINE_COMBINE0_MASK (0x1 << TPM_COMBINE_COMBINE0_SHIFT)
|
||||
|
||||
/* TRIG */
|
||||
|
||||
#define TPM_TRIG_TRIGX_MASK(ch) (0x1 << (ch)) /* Channel trigger configure */
|
||||
|
||||
/* POL */
|
||||
|
||||
#define TPM_POL_POLX_MASK(ch) (0x1 < (ch)) /* Channel polarity active low */
|
||||
|
||||
/* FILTER */
|
||||
|
||||
#define TPM_FILTER_CHXFVAL_MASK(ch) (0xf << ((ch) * 4))) /* Channel filter value */
|
||||
|
||||
/* QDCTRL */
|
||||
|
||||
#define TPM_QDCTRL_QUADMODE_SHIFT (3) /* Bit[3]: Quadrature Decoder Mode */
|
||||
#define TPM_QDCTRL_QUADMODE_MASK (0x1 << TPM_QDCTRL_QUADMODE_SHIFT)
|
||||
|
||||
#define TPM_QDCTRL_QUADIR_SHIFT (2) /* Bit[2]: Counter Direction */
|
||||
#define TPM_QDCTRL_QUADIR_MASK (0x1 << TPM_QDCTRL_QUADIR_SHIFT)
|
||||
|
||||
#define TPM_QDCTRL_TOFDIR_SHIFT (1) /* Bit[1]: Timer Overflow Direction */
|
||||
#define TPM_QDCTRL_TOFDIR_MASK (0x1 << TPM_QDCTRL_TOFDIR_SHIFT)
|
||||
|
||||
#define TPM_QDCTRL_QUADEN_SHIFT (0) /* Bit[0]: Quadrature Decoder Enable */
|
||||
#define TPM_QDCTRL_QUADEN_MASK (0x1 << TPM_QDCTRL_QUADEN_SHIFT)
|
||||
|
||||
/* CONF */
|
||||
|
||||
#define TPM_CONF_TRGSEL_SHIFT (24) /* Bit[25:24]: Trigger Select */
|
||||
#define TPM_CONF_TRGSEL_MASK (0x3 << TPM_CONF_TRGSEL_SHIFT)
|
||||
|
||||
#define TPM_CONF_TRGSRC_SHIFT (23) /* Bit[23]: Trigger Source select */
|
||||
#define TPM_CONF_TRGSRC_MASK (0x1 << TPM_CONF_TRGSRC_SHIFT)
|
||||
|
||||
#define TPM_CONF_TRGPOL_SHIFT (22) /* Bit[22]: Trigger Polarity */
|
||||
#define TPM_CONF_TRGPOL_MASK (0x1 << TPM_CONF_TRGPOL_SHIFT)
|
||||
|
||||
#define TPM_CONF_CPOT_SHIFT (19) /* Bit[19]: Counter Pause on Trigger */
|
||||
#define TPM_CONF_CPOT_MASK (0x1 << TPM_CONF_CPOT_SHIFT)
|
||||
|
||||
#define TPM_CONF_CROT_SHIFT (18) /* Bit[18]: Counter Reload on Trigger */
|
||||
#define TPM_CONF_CROT_MASK (0x1 << TPM_CONF_CROT_SHIFT)
|
||||
|
||||
#define TPM_CONF_CSOO_SHIFT (17) /* Bit[17]: Counter Stop on Overflow */
|
||||
#define TPM_CONF_CSOO_MASK (0x1 << TPM_CONF_CSOO_SHIFT)
|
||||
|
||||
#define TPM_CONF_CSOT_SHIFT (16) /* Bit[16]: Counter Start on Trigger */
|
||||
#define TPM_CONF_CSOT_MASK (0x1 << TPM_CONF_CSOT_SHIFT)
|
||||
|
||||
#define TPM_CONF_DBGMODE_SHIFT (6) /* Bit[7:6]: Debug Mode */
|
||||
#define TPM_CONF_DBGMODE_MASK (0x3 << TPM_CONF_DBGMODE_SHIFT)
|
||||
|
||||
#define TPM_CONF_DOZEEN_SHIFT (5) /* Bit[5]: Doze Enable */
|
||||
#define TPM_CONF_DOZEEN_MASK (0x1 << TPM_CONF_DOZEEN_SHIFT)
|
||||
|
||||
#endif /* __ARCH_ARM64_SRC_IMX9_HARDWARE_IMX9_TPM_H */
|
693
arch/arm64/src/imx9/imx9_tpm_pwm.c
Normal file
693
arch/arm64/src/imx9/imx9_tpm_pwm.c
Normal file
@ -0,0 +1,693 @@
|
||||
/****************************************************************************
|
||||
* arch/arm64/src/imx9/imx9_tpm_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 <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
#include <time.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/clock.h>
|
||||
#include <nuttx/semaphore.h>
|
||||
#include <nuttx/timers/pwm.h>
|
||||
|
||||
#include <arch/board/board.h>
|
||||
|
||||
#include "arm64_arch.h"
|
||||
#include "imx9_tpm_pwm.h"
|
||||
#include "imx9_iomuxc.h"
|
||||
#include "imx9_ccm.h"
|
||||
|
||||
#include "hardware/imx9_iomuxc.h"
|
||||
#include "hardware/imx9_pinmux.h"
|
||||
#include "hardware/imx9_ccm.h"
|
||||
|
||||
#ifdef CONFIG_IMX9_TPM_PWM
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define CHMUX(priv, x) ((((priv)->chmux) >> (x)) & 0xff)
|
||||
|
||||
/* This is a temporary shortcut to configure TPM1 and TPM3
|
||||
* frequencies correctly; they don't have an own root clock
|
||||
*
|
||||
* TODO: Determine the frequencies in a more proper way
|
||||
*/
|
||||
|
||||
#define AON_CLK_FREQ 133333333
|
||||
#define WAKEUP_CLK_FREQ 133333333
|
||||
#define OSC_24_CLK_FREQ 24000000
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/* This structure represents the state of one PWM timer */
|
||||
|
||||
struct imx9_pwmtimer_s
|
||||
{
|
||||
const struct pwm_ops_s *ops; /* PWM operations */
|
||||
const tpm_pwm_id_t id; /* PWM_TPM1...PWM_TPM6 */
|
||||
const uintptr_t base; /* The base address of the TPM */
|
||||
const int n_channels; /* Number of channels used for TPM block */
|
||||
const uint32_t chmux; /* Additional muxing of TPM outputs */
|
||||
const int clk; /* Input clock frequency for the TPM */
|
||||
uint32_t period;
|
||||
unsigned frequency; /* Current frequency setting */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Static Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/* PWM driver methods */
|
||||
|
||||
static int pwm_setup(struct pwm_lowerhalf_s *dev);
|
||||
static int pwm_shutdown(struct pwm_lowerhalf_s *dev);
|
||||
|
||||
static int pwm_start(struct pwm_lowerhalf_s *dev,
|
||||
const struct pwm_info_s *info);
|
||||
|
||||
static int pwm_stop(struct pwm_lowerhalf_s *dev);
|
||||
static int 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_pwmops =
|
||||
{
|
||||
.setup = pwm_setup,
|
||||
.shutdown = pwm_shutdown,
|
||||
.start = pwm_start,
|
||||
.stop = pwm_stop,
|
||||
.ioctl = pwm_ioctl,
|
||||
};
|
||||
|
||||
static struct imx9_pwmtimer_s g_pwmdev[] =
|
||||
{
|
||||
#ifdef CONFIG_IMX9_TPM1_PWM
|
||||
{
|
||||
.ops = &g_pwmops,
|
||||
.id = PWM_TPM1,
|
||||
.base = IMX9_TPM1_BASE,
|
||||
.n_channels = CONFIG_IMX9_TPM1_PWM_NCHANNELS,
|
||||
.chmux = CONFIG_IMX9_TPM1_PWM_CHMUX,
|
||||
.clk = AON_CLK_FREQ,
|
||||
},
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_IMX9_TPM2_PWM
|
||||
{
|
||||
.ops = &g_pwmops,
|
||||
.id = PWM_TPM2,
|
||||
.base = IMX9_TPM2_BASE,
|
||||
.n_channels = CONFIG_IMX9_TPM2_PWM_NCHANNELS,
|
||||
.chmux = CONFIG_IMX9_TPM2_PWM_CHMUX,
|
||||
.clk = OSC_24_CLK_FREQ,
|
||||
},
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_IMX9_TPM3_PWM
|
||||
{
|
||||
.ops = &g_pwmops,
|
||||
.id = PWM_TPM3,
|
||||
.base = IMX9_TPM3_BASE,
|
||||
.n_channels = CONFIG_IMX9_TPM3_PWM_NCHANNELS,
|
||||
.chmux = CONFIG_IMX9_TPM3_PWM_CHMUX,
|
||||
.clk = WAKEUP_CLK_FREQ,
|
||||
},
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_IMX9_TPM4_PWM
|
||||
{
|
||||
.ops = &g_pwmops,
|
||||
.id = PWM_TPM4,
|
||||
.base = IMX9_TPM4_BASE,
|
||||
.n_channels = CONFIG_IMX9_TPM4_PWM_NCHANNELS,
|
||||
.chmux = CONFIG_IMX9_TPM4_PWM_CHMUX,
|
||||
.clk = OSC_24_CLK_FREQ,
|
||||
},
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_IMX9_TPM5_PWM
|
||||
{
|
||||
.ops = &g_pwmops,
|
||||
.id = PWM_TPM5,
|
||||
.base = IMX9_TPM5_BASE,
|
||||
.n_channels = CONFIG_IMX9_TPM5_PWM_NCHANNELS,
|
||||
.chmux = CONFIG_IMX9_TPM5_PWM_CHMUX,
|
||||
.clk = OSC_24_CLK_FREQ,
|
||||
},
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_IMX9_TPM6_PWM
|
||||
{
|
||||
.ops = &g_pwmops,
|
||||
.id = PWM_TPM6,
|
||||
.base = IMX9_TPM6_BASE,
|
||||
.n_channels = CONFIG_IMX9_TPM6_PWM_NCHANNELS,
|
||||
.chmux = CONFIG_IMX9_TPM6_PWM_CHMUX,
|
||||
.clk = OSC_24_CLK_FREQ,
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pwm_getreg
|
||||
*
|
||||
* Description:
|
||||
* Read the value of an PWM timer register.
|
||||
*
|
||||
* Input Parameters:
|
||||
* priv - A reference to the PWM block status
|
||||
* offset - The offset to the register to read
|
||||
*
|
||||
* Returned Value:
|
||||
* The current contents of the specified register
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline uint32_t pwm_getreg(struct imx9_pwmtimer_s *priv, int offset)
|
||||
{
|
||||
return getreg32(priv->base + offset);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pwm_putreg
|
||||
*
|
||||
* Description:
|
||||
* Read the value of an PWM timer register.
|
||||
*
|
||||
* Input Parameters:
|
||||
* priv - A reference to the PWM block status
|
||||
* offset - The offset to the register to read
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void pwm_putreg(struct imx9_pwmtimer_s *priv, int offset,
|
||||
uint32_t value)
|
||||
{
|
||||
putreg32(value, priv->base + offset);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tpm_mux
|
||||
*
|
||||
* Description:
|
||||
* Mux the tpm output pins to pads. The macros TPMn_PWMx_MUX
|
||||
* need to be defined in the board.h file
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void tpm_mux(void)
|
||||
{
|
||||
#ifdef CONFIG_IMX9_TPM1_PWM
|
||||
# ifdef TPM1_PWM0_MUX
|
||||
imx9_iomux_configure(TPM1_PWM0_MUX);
|
||||
# endif
|
||||
|
||||
# ifdef TPM1_PWM1_MUX
|
||||
imx9_iomux_configure(TPM1_PWM1_MUX);
|
||||
# endif
|
||||
|
||||
# ifdef TPM1_PWM2_MUX
|
||||
imx9_iomux_configure(TPM1_PWM2_MUX);
|
||||
# endif
|
||||
|
||||
# ifdef TPM1_PWM3_MUX
|
||||
imx9_iomux_configure(TPM1_PWM3_MUX);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_IMX9_TPM2_PWM
|
||||
# ifdef TPM2_PWM0_MUX
|
||||
imx9_iomux_configure(TPM2_PWM0_MUX);
|
||||
# endif
|
||||
|
||||
# ifdef TPM2_PWM1_MUX
|
||||
imx9_iomux_configure(TPM2_PWM1_MUX);
|
||||
# endif
|
||||
|
||||
# ifdef TPM2_PWM2_MUX
|
||||
imx9_iomux_configure(TPM2_PWM2_MUX);
|
||||
# endif
|
||||
|
||||
# ifdef TPM2_PWM3_MUX
|
||||
imx9_iomux_configure(TPM2_PWM3_MUX);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_IMX9_TPM3_PWM
|
||||
# ifdef TPM3_PWM0_MUX
|
||||
imx9_iomux_configure(TPM3_PWM0_MUX);
|
||||
# endif
|
||||
|
||||
# ifdef TPM3_PWM1_MUX
|
||||
imx9_iomux_configure(TPM3_PWM1_MUX);
|
||||
# endif
|
||||
|
||||
# ifdef TPM3_PWM2_MUX
|
||||
imx9_iomux_configure(TPM3_PWM2_MUX);
|
||||
# endif
|
||||
|
||||
# ifdef TPM3_PWM3_MUX
|
||||
imx9_iomux_configure(TPM3_PWM3_MUX);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_IMX9_TPM4_PWM
|
||||
# ifdef TPM4_PWM0_MUX
|
||||
imx9_iomux_configure(TPM4_PWM0_MUX);
|
||||
# endif
|
||||
|
||||
# ifdef TPM4_PWM1_MUX
|
||||
imx9_iomux_configure(TPM4_PWM1_MUX);
|
||||
# endif
|
||||
|
||||
# ifdef TPM4_PWM2_MUX
|
||||
imx9_iomux_configure(TPM4_PWM2_MUX);
|
||||
# endif
|
||||
|
||||
# ifdef TPM4_PWM3_MUX
|
||||
imx9_iomux_configure(TPM4_PWM3_MUX);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_IMX9_TPM5_PWM
|
||||
# ifdef TPM5_PWM0_MUX
|
||||
imx9_iomux_configure(TPM5_PWM0_MUX);
|
||||
# endif
|
||||
|
||||
# ifdef TPM5_PWM1_MUX
|
||||
imx9_iomux_configure(TPM5_PWM1_MUX);
|
||||
# endif
|
||||
|
||||
# ifdef TPM5_PWM2_MUX
|
||||
imx9_iomux_configure(TPM5_PWM2_MUX);
|
||||
# endif
|
||||
|
||||
# ifdef TPM5_PWM3_MUX
|
||||
imx9_iomux_configure(TPM5_PWM3_MUX);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_IMX9_TPM6_PWM
|
||||
# ifdef TPM6_PWM0_MUX
|
||||
imx9_iomux_configure(TPM6_PWM0_MUX);
|
||||
# endif
|
||||
|
||||
# ifdef TPM6_PWM1_MUX
|
||||
imx9_iomux_configure(TPM6_PWM1_MUX);
|
||||
# endif
|
||||
|
||||
# ifdef TPM6_PWM2_MUX
|
||||
imx9_iomux_configure(TPM6_PWM2_MUX);
|
||||
# endif
|
||||
|
||||
# ifdef TPM6_PWM3_MUX
|
||||
imx9_iomux_configure(TPM6_PWM3_MUX);
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pwm_update_frequency
|
||||
*
|
||||
* Description:
|
||||
* Initialize the timer trigger, generating the PWM freuency
|
||||
*
|
||||
* Input Parameters:
|
||||
* priv - A reference to the lower half PWM driver state structure
|
||||
* freq - The requested PWM frequency for this flexio block
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero on success, negated error value on failure
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int pwm_update_frequency(struct imx9_pwmtimer_s *priv, int freq)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (freq != priv->frequency)
|
||||
{
|
||||
/* Start PWM on all channels if it was previously stopped */
|
||||
|
||||
if (freq > 0 && priv->frequency == 0)
|
||||
{
|
||||
/* Set the EPWM mode for all the configured channels:
|
||||
*
|
||||
* High-true pulses (clear output on counter match, set output
|
||||
* on counter reload, clear output when counter first enabled
|
||||
* or paused)
|
||||
* SC[CPWMS] = 0, MSnB:MSnA = 1:0 ELSnB:ELSnA = 0
|
||||
*/
|
||||
|
||||
for (i = 0; i < priv->n_channels; i++)
|
||||
{
|
||||
pwm_putreg(priv, IMX9_TPM_CXSC_OFFSET(CHMUX(priv, i)),
|
||||
TPM_CXSC_MSB_MASK);
|
||||
}
|
||||
}
|
||||
|
||||
priv->period = freq > 0 ? priv->clk / freq : 0;
|
||||
|
||||
pwminfo("PWM%d frequency: %" PRIu32" period: %" PRIu32 "\n", priv->id,
|
||||
freq, priv->period);
|
||||
|
||||
/* Set the period */
|
||||
|
||||
pwm_putreg(priv, IMX9_TPM_MOD_OFFSET, priv->period);
|
||||
|
||||
priv->frequency = freq;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pwm_update_duty
|
||||
*
|
||||
* Description:
|
||||
* Change the channel duty cycle.
|
||||
*
|
||||
* Input Parameters:
|
||||
* priv - A reference to the lower half PWM driver state structure
|
||||
* period - PWM pulse width in timer ticks
|
||||
* channel - Channel to by updated
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero on success; a negated errno value on failure
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int pwm_update_duty(struct imx9_pwmtimer_s *priv, int pwm_ch,
|
||||
ub16_t duty16)
|
||||
{
|
||||
uint64_t duty = duty16 & 0xffffffff;
|
||||
uint32_t edge = (duty * priv->period + 0x8000) >> 16;
|
||||
int timer = pwm_ch - 1;
|
||||
|
||||
if (pwm_ch == 0 || timer > priv->n_channels)
|
||||
{
|
||||
pwmerr("ERROR: PWM%d has no such channel: %d\n", priv->id, timer);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pwminfo("PWM%d channel %d, p: %d e: %" PRIu32 "\n", priv->id,
|
||||
CHMUX(priv, timer), priv->period, edge);
|
||||
|
||||
pwm_putreg(priv, IMX9_TPM_CXV_OFFSET(CHMUX(priv, timer)), edge);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: 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.
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - A reference to the lower half PWM driver state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero on success; a negated errno value on failure
|
||||
*
|
||||
* Assumptions:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int pwm_setup(struct pwm_lowerhalf_s *dev)
|
||||
{
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: 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
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - A reference to the lower half PWM driver state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero on success; a negated errno value on failure
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int pwm_shutdown(struct pwm_lowerhalf_s *dev)
|
||||
{
|
||||
/* Make sure that the output has been stopped */
|
||||
|
||||
pwm_stop(dev);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pwm_start
|
||||
*
|
||||
* Description:
|
||||
* (Re-)initialize the timer resources and start the pulsed output
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - A reference to the lower half PWM driver state structure
|
||||
* info - A reference to the characteristics of the pulsed output
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero on success; a negated errno value on failure
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int pwm_start(struct pwm_lowerhalf_s *dev,
|
||||
const struct pwm_info_s *info)
|
||||
{
|
||||
struct imx9_pwmtimer_s *priv = (struct imx9_pwmtimer_s *)dev;
|
||||
int ret = OK;
|
||||
int i;
|
||||
|
||||
if (priv == NULL || info == NULL || info->frequency == 0)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Set the frequency if not changed */
|
||||
|
||||
if (pwm_update_frequency(priv, info->frequency) == OK)
|
||||
{
|
||||
/* Handle channel specific setup */
|
||||
|
||||
for (i = 0; i < CONFIG_PWM_NCHANNELS; i++)
|
||||
{
|
||||
if (ret != OK || info->channels[i].channel == -1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
pwm_update_duty(priv, info->channels[i].channel,
|
||||
info->channels[i].duty);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pwm_stop
|
||||
*
|
||||
* Description:
|
||||
* Stop the pulsed output and reset the timer resources
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - A reference to the lower half PWM driver state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero on success; a negated errno value on failure
|
||||
*
|
||||
* Assumptions:
|
||||
* This function is called to stop the pulsed output at anytime.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int pwm_stop(struct pwm_lowerhalf_s *dev)
|
||||
{
|
||||
struct imx9_pwmtimer_s *priv = (struct imx9_pwmtimer_s *)dev;
|
||||
int i;
|
||||
|
||||
pwminfo("PWM%d stop\n", priv->id);
|
||||
|
||||
/* Check that timer is valid */
|
||||
|
||||
if (priv == NULL)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Disable the channels */
|
||||
|
||||
for (i = 0; i < priv->n_channels; i++)
|
||||
{
|
||||
pwm_putreg(priv, IMX9_TPM_CXSC_OFFSET(CHMUX(priv, i)), 0);
|
||||
}
|
||||
|
||||
/* Set frequency to 0 */
|
||||
|
||||
pwm_update_frequency(priv, 0);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pwm_ioctl
|
||||
*
|
||||
* Description:
|
||||
* Lower-half logic may support platform-specific ioctl commands
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - A reference to the lower half PWM driver state structure
|
||||
* cmd - The ioctl command
|
||||
* arg - The argument accompanying the ioctl command
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero on success; a negated errno value on failure
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int pwm_ioctl(struct pwm_lowerhalf_s *dev, int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
return -ENOTTY;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imx9_tpm_pwm_init
|
||||
*
|
||||
* Description:
|
||||
* Initialize tpm blocks to generate EPWM.
|
||||
*
|
||||
* Input Parameters:
|
||||
* pwmid - A number identifying the pwm block. The number of valid
|
||||
* IDs varies depending on the configuration.
|
||||
*
|
||||
* Returned Value:
|
||||
* On success, a pointer to the lower half PWM driver is
|
||||
* returned. NULL is returned on any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
struct pwm_lowerhalf_s *imx9_tpm_pwm_init(tpm_pwm_id_t pwmid)
|
||||
{
|
||||
struct imx9_pwmtimer_s *lower = NULL;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sizeof(g_pwmdev) / sizeof(g_pwmdev[0]); i++)
|
||||
{
|
||||
if (pwmid == g_pwmdev[i].id)
|
||||
{
|
||||
lower = &g_pwmdev[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (lower)
|
||||
{
|
||||
/* IO mux */
|
||||
|
||||
tpm_mux();
|
||||
|
||||
/* Reset TPM */
|
||||
|
||||
pwm_putreg(lower, IMX9_TPM_GLOBAL_OFFSET, TPM_GLOBAL_RST_MASK);
|
||||
pwm_putreg(lower, IMX9_TPM_GLOBAL_OFFSET, 0);
|
||||
while (pwm_getreg(lower, IMX9_TPM_GLOBAL_OFFSET) != 0);
|
||||
|
||||
/* TPM 1 is always clocked by AON bus and TPM3 by WAKEUP bus */
|
||||
|
||||
if (pwmid != PWM_TPM1 && pwmid != PWM_TPM3)
|
||||
{
|
||||
/* 24 MHz source clock */
|
||||
|
||||
imx9_ccm_configure_root_clock(CCM_CR_TPM1 + pwmid, OSC_24M, 1);
|
||||
|
||||
/* Enable peripheral clock */
|
||||
|
||||
imx9_ccm_gate_on(CCM_LPCG_TPM1 + pwmid, true);
|
||||
}
|
||||
|
||||
/* Set status and control:
|
||||
* CMOD = 1 (increment on every clock)
|
||||
* PS = 0 (clock divider 1)
|
||||
*/
|
||||
|
||||
pwm_putreg(lower, IMX9_TPM_SC_OFFSET, 1 << TPM_SC_CMOD_SHIFT);
|
||||
|
||||
pwminfo("PWM%d at %" PRIxPTR " configured\n", pwmid, lower->base);
|
||||
}
|
||||
else
|
||||
{
|
||||
pwmerr("ERROR: No such timer configured %d\n", pwmid);
|
||||
}
|
||||
|
||||
return (struct pwm_lowerhalf_s *)lower;
|
||||
}
|
||||
|
||||
#endif
|
97
arch/arm64/src/imx9/imx9_tpm_pwm.h
Normal file
97
arch/arm64/src/imx9/imx9_tpm_pwm.h
Normal file
@ -0,0 +1,97 @@
|
||||
/****************************************************************************
|
||||
* arch/arm64/src/imx9/imx9_tpm_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_ARM64_SRC_IMX9_IMX9_TPM_PWM_H
|
||||
#define __ARCH_ARM64_SRC_IMX9_IMX9_TPM_PWM_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <arch/board/board.h>
|
||||
#include "hardware/imx9_tpm.h"
|
||||
|
||||
/* Check if PWM support for any channel is enabled. */
|
||||
|
||||
#ifdef CONFIG_IMX9_TPM_PWM
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
PWM_TPM1 = 0,
|
||||
PWM_TPM2 = 1,
|
||||
PWM_TPM3 = 2,
|
||||
PWM_TPM4 = 3,
|
||||
PWM_TPM5 = 4,
|
||||
PWM_TPM6 = 5,
|
||||
} tpm_pwm_id_t;
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
#define EXTERN extern "C"
|
||||
extern "C"
|
||||
{
|
||||
#else
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imx9_tpm_pwm_init
|
||||
*
|
||||
* Description:
|
||||
* Initialize a TPM block for EPWM usage.
|
||||
*
|
||||
* Input Parameters:
|
||||
* pwmid - A number identifying the pwm block.
|
||||
*
|
||||
* Returned Value:
|
||||
* On success, a pointer to the lower half of the PWM driver is
|
||||
* returned. NULL is returned on any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
struct pwm_lowerhalf_s *imx9_tpm_pwm_init(tpm_pwm_id_t pwmid);
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
#endif /* CONFIG_IMX9_TPM_PWM */
|
||||
#endif /* __ARCH_ARM64_SRC_IMX9_IMX9_TPM_PWM_H */
|
Loading…
Reference in New Issue
Block a user