From 3b308cece82eff3cfa5f469ff386f300a48c0b77 Mon Sep 17 00:00:00 2001 From: Runcheng Lu Date: Fri, 14 Apr 2023 17:38:55 +0800 Subject: [PATCH] arch:risc-v:hpm6750:add pwm driver #16 - add pwm driver Signed-off-by: Runcheng Lu --- arch/risc-v/src/hpmicro/hpm6750/Kconfig | 36 +- arch/risc-v/src/hpmicro/hpm6750/Make.defs | 2 +- .../src/hpmicro/hpm6750/hpm_pwm_lowerhalf.c | 390 ++++++++++++++++++ .../src/hpmicro/hpm6750/hpm_pwm_lowerhalf.h | 97 +++++ arch/risc-v/src/hpmicro/hpm6750/hpm_spi.c | 2 - .../hpm6750evk2-sdk/configs/pwm/defconfig | 79 ++++ .../hpmicro/hpm6750evk2-sdk/src/Makefile | 4 + .../hpm6750evk2-sdk/src/hpm6750_bringup.c | 95 ++--- .../hpmicro/hpm6750evk2-sdk/src/hpm6750_pwm.c | 74 ++++ 9 files changed, 703 insertions(+), 76 deletions(-) create mode 100644 arch/risc-v/src/hpmicro/hpm6750/hpm_pwm_lowerhalf.c create mode 100644 arch/risc-v/src/hpmicro/hpm6750/hpm_pwm_lowerhalf.h create mode 100644 boards/risc-v/hpmicro/hpm6750evk2-sdk/configs/pwm/defconfig create mode 100644 boards/risc-v/hpmicro/hpm6750evk2-sdk/src/hpm6750_pwm.c diff --git a/arch/risc-v/src/hpmicro/hpm6750/Kconfig b/arch/risc-v/src/hpmicro/hpm6750/Kconfig index a50aa22cc0563..53cb522d382f7 100644 --- a/arch/risc-v/src/hpmicro/hpm6750/Kconfig +++ b/arch/risc-v/src/hpmicro/hpm6750/Kconfig @@ -1257,7 +1257,7 @@ config HPM_ADC3 int default 9 depends on ADC3_RES_8BIT - + config HPM_ADC3_RES int default 11 @@ -1293,5 +1293,39 @@ config HPM_ADC3 endchoice # Endi Of Resolution Setting endmenu # ADC3 device driver options + +config HPM_PWM_DRV + bool + default n + +config HPM6750_PWM0 + bool "PWM0" + default n + select HPM_PWM_DRV + +config HPM6750_PWM1 + bool "PWM1" + default n + select HPM_PWM_DRV + +config HPM6750_PWM2 + bool "PWM2" + default n + select HPM_PWM_DRV + +config HPM6750_PWM3 + bool "PWM3" + default n + select HPM_PWM_DRV + +config HPM_PWM_MULTICHAN + bool "PWM Multiple Output Channels" + default n + depends on HPM_PWM_DRV + select ARCH_HAVE_PWM_MULTICHAN + ---help--- + Specifies that the PWM driver supports multiple output + channels per timer. + endmenu diff --git a/arch/risc-v/src/hpmicro/hpm6750/Make.defs b/arch/risc-v/src/hpmicro/hpm6750/Make.defs index 206950c26fbbd..75b6345bfbea3 100644 --- a/arch/risc-v/src/hpmicro/hpm6750/Make.defs +++ b/arch/risc-v/src/hpmicro/hpm6750/Make.defs @@ -30,6 +30,7 @@ CHIP_CSRCS += hpmicro$(DELIM)hpm6750$(DELIM)hpm_spi.c hpmicro$(DELIM)hpm6750$(DE CHIP_CSRCS += hpmicro$(DELIM)hpm6750$(DELIM)hpm_i2c_slave.c hpmicro$(DELIM)hpm6750$(DELIM)hpm_i2c.c CHIP_CSRCS += hpmicro$(DELIM)hpm6750$(DELIM)hpm_rtc_lowerhalf.c CHIP_CSRCS += hpmicro$(DELIM)hpm6750$(DELIM)hpm_tim_lowerhalf.c +CHIP_CSRCS += hpmicro$(DELIM)hpm6750$(DELIM)hpm_pwm_lowerhalf.c ifeq ($(CONFIG_HPM_CAN_CHARDRIVER),y) CHIP_CSRCS += hpmicro$(DELIM)hpm6750$(DELIM)hpm_can.c endif @@ -44,4 +45,3 @@ endif ifeq ($(CONFIG_HPM_ADC16_DRV),y) CHIP_CSRCS += hpmicro$(DELIM)hpm6750$(DELIM)hpm_adc16.c endif - diff --git a/arch/risc-v/src/hpmicro/hpm6750/hpm_pwm_lowerhalf.c b/arch/risc-v/src/hpmicro/hpm6750/hpm_pwm_lowerhalf.c new file mode 100644 index 0000000000000..2eb64cbb63759 --- /dev/null +++ b/arch/risc-v/src/hpmicro/hpm6750/hpm_pwm_lowerhalf.c @@ -0,0 +1,390 @@ +/**************************************************************************** + * arch/risc-v/src/hpmicro/hpm6750/hpm_pwm_lowerhalf.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 + +#include +#include +#include +#include +#include +#include + +#include + +#include "hpm_pwm_lowerhalf.h" +#include "riscv_internal.h" + +#include "hpm_soc.h" +#include "hpm_pwm_drv.h" +#include "hpm_clock_drv.h" + +#if defined(CONFIG_PWM) && \ + (defined(CONFIG_HPM6750_PWM0) || defined(CONFIG_HPM6750_PWM1) || \ + defined(CONFIG_HPM6750_PWM2) || defined(CONFIG_HPM6750_PWM3)) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifdef CONFIG_PWM_NCHANNELS +# if (CONFIG_PWM_NCHANNELS > 8) +# error "The maximum number of HPM6750 PWM channels is 8!" +# endif +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +typedef struct +{ + const struct pwm_ops_s *ops; /* PWM operations */ + int pwm_port; + uint32_t pwm_freq; + uint32_t pwm_reload; + PWM_Type *base; + clock_name_t clock_name; +}hpm_pwm_s; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int motsys_generate_pwm(hpm_pwm_s *pwm, const struct pwm_info_s *info); + +/* PWM driver methods */ + +static int hpm_pwm_setup(struct pwm_lowerhalf_s *dev); +static int hpm_pwm_shutdown(struct pwm_lowerhalf_s *dev); +static int hpm_pwm_start(struct pwm_lowerhalf_s *dev, + const struct pwm_info_s *info); +static int hpm_pwm_stop(struct pwm_lowerhalf_s *dev); +static int hpm_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_hpm_pwmops = +{ + .setup = hpm_pwm_setup, + .shutdown = hpm_pwm_shutdown, + .start = hpm_pwm_start, + .stop = hpm_pwm_stop, + .ioctl = hpm_pwm_ioctl, +}; + +#ifdef CONFIG_HPM6750_PWM0 +hpm_pwm_s g_hpm_pwm0 = +{ + .ops = &g_hpm_pwmops, + .pwm_port = 0, + .base = HPM_PWM0, + .clock_name = clock_mot0, +}; +#endif + +#ifdef CONFIG_HPM6750_PWM1 +hpm_pwm_s g_hpm_pwm1 = +{ + .ops = &g_hpm_pwmops, + .pwm_port = 1, + .base = HPM_PWM1, + .clock_name = clock_mot1, +}; +#endif + +#ifdef CONFIG_HPM6750_PWM2 +hpm_pwm_s g_hpm_pwm2 = +{ + .ops = &g_hpm_pwmops, + .pwm_port = 2, + .base = HPM_PWM2, + .clock_name = clock_mot2, +}; +#endif + +#ifdef CONFIG_HPM6750_PWM3 +hpm_pwm_s g_hpm_pwm3 = +{ + .ops = &g_hpm_pwmops, + .pwm_port = 3, + .base = HPM_PWM3, + .clock_name = clock_mot3, +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static int motsys_generate_pwm(hpm_pwm_s *pwm, const struct pwm_info_s *info) +{ + hpm_stat_t sta = status_invalid_argument; + +#ifdef CONFIG_PWM_NCHANNELS + + uint8_t cmp_index = 0; + uint32_t cmp = 0; + int i; + int8_t chan; + uint8_t _duty; + pwm_cmp_config_t cmp_config; + pwm_config_t pwm_config = {0}; + + pwm_get_default_pwm_config(pwm->base, &pwm_config); + + pwm_stop_counter(pwm->base); + pwm_config.enable_output = true; + pwm_config.dead_zone_in_half_cycle = 0; + pwm_config.invert_output = false; + + uint32_t mot_pwm_freq = clock_get_frequency(pwm->clock_name); + pwm->pwm_reload = mot_pwm_freq/info->frequency; + + pwm_set_reload(pwm->base, 0, pwm->pwm_reload); + pwm_set_start_count(pwm->base, 0, 0); + + cmp_config.mode = pwm_cmp_mode_output_compare; + cmp_config.cmp = 0; + cmp_config.update_trigger = pwm_shadow_register_update_on_modify; + pwm_load_cmp_shadow_on_match(pwm->base, 0, &cmp_config); + + cmp_config.update_trigger = pwm_shadow_register_update_on_hw_event; + + for (i = 0; i < CONFIG_PWM_NCHANNELS; i++) + { + chan = info->channels[i].channel; + _duty = b16toi(info->channels[i].duty * 100); + cmp = (pwm->pwm_reload * _duty)/100; + cmp_config.cmp = cmp; + + /* Break the loop if all following channels are not configured */ + + if (chan == -1) + { + break; + } + + sta = pwm_setup_waveform(pwm->base, chan, &pwm_config, chan, &cmp_config, 1); + } + if (sta != status_success) + { + return -1; + } + pwm_start_counter(pwm->base); + pwm_issue_shadow_register_lock_event(pwm->base); + for (i = 0; i < CONFIG_PWM_NCHANNELS; i++) + { + _duty = b16toi(info->channels[i].duty * 100); + cmp = (pwm->pwm_reload * _duty)/100; + chan = info->channels[i].channel; + + /* Break the loop if all following channels are not configured */ + + if (chan == -1) + { + break; + } + + pwm_update_raw_cmp_edge_aligned(pwm->base, chan, cmp); + } +#endif + return (sta != status_success)? -1 : 0; +} + +/**************************************************************************** + * Name: hpm_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 hpm_pwm_setup(struct pwm_lowerhalf_s *dev) +{ + int i; + int ret = OK; + hpm_pwm_s *priv = (hpm_pwm_s *)dev; + + UNUSED(i); + priv->pwm_freq = 0; + ret = hpm6750_init_pwm_pins(priv->pwm_port); + + return ret; +} + +/**************************************************************************** + * Name: hpm_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 hpm_pwm_shutdown(struct pwm_lowerhalf_s *dev) +{ + int i; + int ret = OK; + hpm_pwm_s *priv = (hpm_pwm_s *)dev; + + UNUSED(i); + for (i = 0; i < CONFIG_PWM_NCHANNELS; i++) + { + pwm_disable_output(priv->base, i); + } + + return ret; +} + +/**************************************************************************** + * Name: hpm_pwm_start + * + * Description: + * (Re-)initialize the PWM and start the pulsed output + * + ****************************************************************************/ + +static int hpm_pwm_start(struct pwm_lowerhalf_s *dev, + const struct pwm_info_s *info) +{ + hpm_pwm_s *priv = (hpm_pwm_s *)dev; + int ret = OK; + int i; + int _duty = 0; + UNUSED(i); + ret = motsys_generate_pwm(priv, info); + return ret; +} + +/**************************************************************************** + * Name: hpm_pwm_stop + * + * Description: + * Stop the PWM + * + ****************************************************************************/ + +static int hpm_pwm_stop(struct pwm_lowerhalf_s *dev) +{ + int i; + hpm_pwm_s *priv = (hpm_pwm_s *)dev; + + UNUSED(priv); + UNUSED(i); + +#ifdef CONFIG_PWM_NCHANNELS + for (i = 0; i < CONFIG_PWM_NCHANNELS; i++) + { + pwm_disable_output(priv->base, i); + } +#endif + + return OK; +} + +/**************************************************************************** + * Name: hpm_pwm_ioctl + * + * Description: + * Lower-half logic may support platform-specific ioctl commands + * + ****************************************************************************/ + +static int hpm_pwm_ioctl(struct pwm_lowerhalf_s *dev, + int cmd, unsigned long arg) +{ + hpm_pwm_s *priv = (hpm_pwm_s *)dev; + + DEBUGASSERT(dev); + + /* There are no platform-specific ioctl commands */ + + UNUSED(priv); + + return -ENOTTY; +} + +/**************************************************************************** + * Public Function + ****************************************************************************/ + +/**************************************************************************** + * Name: hpm6750_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 HPM6750 lower half PWM driver is returned. + * NULL is returned on any failure. + * + ****************************************************************************/ + +struct pwm_lowerhalf_s *hpm6750_pwminitialize(int pwm) +{ + hpm_pwm_s *lower = NULL; + + if (pwm > 4) + { + pwminfo("Initialize PWM%u failed\n", pwm); + return NULL; + } + + pwminfo("Initialize PWM%u\n", pwm); + +#ifdef CONFIG_HPM6750_PWM0 + lower = &g_hpm_pwm0; +#endif + +#ifdef CONFIG_HPM6750_PWM1 + lower = &g_hpm_pwm1; +#endif + +#ifdef CONFIG_HPM6750_PWM2 + lower = &g_hpm_pwm2; +#endif + +#ifdef CONFIG_HPM6750_PWM3 + lower = &g_hpm_pwm3; +#endif + + return (struct pwm_lowerhalf_s *)lower; +} + +#endif + diff --git a/arch/risc-v/src/hpmicro/hpm6750/hpm_pwm_lowerhalf.h b/arch/risc-v/src/hpmicro/hpm6750/hpm_pwm_lowerhalf.h new file mode 100644 index 0000000000000..0e11f2b4e7540 --- /dev/null +++ b/arch/risc-v/src/hpmicro/hpm6750/hpm_pwm_lowerhalf.h @@ -0,0 +1,97 @@ +/**************************************************************************** + * arch/risc-v/src/hpmicro/hpm6750/hpm_pwm_lowerhalf.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. + * + ****************************************************************************/ + +#ifndef __ARCH_RISCV_SRC_HPMICRO_HPM6750_HPM_PWM_LOWERHALF_H +#define __ARCH_RISCV_SRC_HPMICRO_HPM6750_HPM_PWM_LOWERHALF_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "chip.h" + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#if defined(CONFIG_PWM) && \ + (defined(CONFIG_HPM6750_PWM0) || defined(CONFIG_HPM6750_PWM1) || \ + defined(CONFIG_HPM6750_PWM2) || defined(CONFIG_HPM6750_PWM3)) + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: hpm6750_init_pwm_pins + * + * Description: + * Initialize the selected PWM channel pins. + * + * Input Parameters: + * + * Returned Value: + * Valid SPI device structure reference on success; a NULL on failure + * + ****************************************************************************/ + +int hpm6750_init_pwm_pins(int port); + +/**************************************************************************** + * Name: hpm6750_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 HPM6750 lower half PWM driver is returned. + * NULL is returned on any failure. + * + ****************************************************************************/ + +struct pwm_lowerhalf_s *hpm6750_pwminitialize(int pwm); + +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_RISCV_SRC_HPMICRO_HPM6750_HPM_TIM_LOWERHALF_H */ diff --git a/arch/risc-v/src/hpmicro/hpm6750/hpm_spi.c b/arch/risc-v/src/hpmicro/hpm6750/hpm_spi.c index 979b203dfcd8f..3c97c69f03227 100644 --- a/arch/risc-v/src/hpmicro/hpm6750/hpm_spi.c +++ b/arch/risc-v/src/hpmicro/hpm6750/hpm_spi.c @@ -1594,10 +1594,8 @@ static void spi_bus_initialize(struct hpm_spidev_s *priv) #if defined(CONFIG_HPM6750_SPI0_DMA) || defined(CONFIG_HPM6750_SPI1_DMA) || \ defined(CONFIG_HPM6750_SPI2_DMA) || defined(CONFIG_HPM6750_SPI3_DMA) - hpm_dma_resource_t dma_resource; hpm_dmamux_resource_t dmamux_resource; - priv->dma_rxchan = hpm_dma_channel_request(spi_rx_dma_channel_callback, (void *)priv); priv->dma_txchan = hpm_dma_channel_request(spi_tx_dma_channel_callback, (void *)priv); if(priv->dma_rxchan >= 0) diff --git a/boards/risc-v/hpmicro/hpm6750evk2-sdk/configs/pwm/defconfig b/boards/risc-v/hpmicro/hpm6750evk2-sdk/configs/pwm/defconfig new file mode 100644 index 0000000000000..a72e83c5c4505 --- /dev/null +++ b/boards/risc-v/hpmicro/hpm6750evk2-sdk/configs/pwm/defconfig @@ -0,0 +1,79 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +# CONFIG_DISABLE_OS_API is not set +# CONFIG_NDEBUG is not set +# CONFIG_NSH_DISABLEBG is not set +# CONFIG_NSH_DISABLE_CAT is not set +# CONFIG_NSH_DISABLE_CD is not set +# CONFIG_NSH_DISABLE_ECHO is not set +# CONFIG_NSH_DISABLE_ENV is not set +# CONFIG_NSH_DISABLE_EXEC is not set +# CONFIG_NSH_DISABLE_FREE is not set +# CONFIG_NSH_DISABLE_HELP is not set +# CONFIG_NSH_DISABLE_KILL is not set +# CONFIG_NSH_DISABLE_LOSMART is not set +# CONFIG_NSH_DISABLE_LS is not set +# CONFIG_NSH_DISABLE_MOUNT is not set +# CONFIG_NSH_DISABLE_PRINTF is not set +# CONFIG_NSH_DISABLE_PS is not set +# CONFIG_NSH_DISABLE_PWD is not set +# CONFIG_NSH_DISABLE_SLEEP is not set +# CONFIG_NSH_DISABLE_UNAME is not set +# CONFIG_NSH_DISABLE_USLEEP is not set +CONFIG_ARCH="risc-v" +CONFIG_ARCH_BOARD="hpm6750evk2-sdk" +CONFIG_ARCH_BOARD_HPM6750EVK2_SDK=y +CONFIG_ARCH_CHIP="hpmicro" +CONFIG_ARCH_CHIP_HPM6750=y +CONFIG_ARCH_CHIP_HPMICRO=y +CONFIG_ARCH_INTERRUPTSTACK=8192 +CONFIG_ARCH_RISCV=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_BOARD_LOOPSPERMSEC=10000 +CONFIG_BUILTIN=y +CONFIG_DEBUG_ERROR=y +CONFIG_DEBUG_FEATURES=y +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_DEBUG_WARN=y +CONFIG_DEFAULT_SMALL=y +CONFIG_EXAMPLES_PWM=y +CONFIG_EXAMPLES_PWM_DEVPATH="/dev/pwm2" +CONFIG_EXAMPLES_PWM_FREQUENCY=10000 +CONFIG_HPM6750_PWM2=y +CONFIG_HPM_BUILD_TYPE_FLASH_XIP=y +CONFIG_HPM_PWM_MULTICHAN=y +CONFIG_IDLETHREAD_STACKSIZE=3072 +CONFIG_INIT_ENTRYPOINT="nsh_main" +CONFIG_INTELHEX_BINARY=y +CONFIG_LIBC_PERROR_STDOUT=y +CONFIG_LIBC_STRERROR=y +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_FILEIOSIZE=1024 +CONFIG_NSH_LINELEN=80 +CONFIG_PWM=y +CONFIG_PWM_MULTICHAN=y +CONFIG_PWM_NCHANNELS=5 +CONFIG_RAW_BINARY=y +CONFIG_RR_INTERVAL=200 +CONFIG_SCHED_HPWORK=y +CONFIG_SCHED_HPWORKPRIORITY=192 +CONFIG_SCHED_WAITPID=y +CONFIG_SERIAL_TERMIOS=y +CONFIG_STACK_COLORATION=y +CONFIG_START_DAY=15 +CONFIG_START_MONTH=3 +CONFIG_START_YEAR=2023 +CONFIG_SYMTAB_ORDEREDBYNAME=y +CONFIG_SYSTEM_HEAPSIZE=65536 +CONFIG_SYSTEM_NSH=y +CONFIG_TASK_NAME_SIZE=0 +CONFIG_UART0_RXBUFSIZE=128 +CONFIG_UART0_SERIAL_CONSOLE=y +CONFIG_UART0_TXBUFSIZE=128 diff --git a/boards/risc-v/hpmicro/hpm6750evk2-sdk/src/Makefile b/boards/risc-v/hpmicro/hpm6750evk2-sdk/src/Makefile index f3acd3ac3c159..7a8e170f844a2 100644 --- a/boards/risc-v/hpmicro/hpm6750evk2-sdk/src/Makefile +++ b/boards/risc-v/hpmicro/hpm6750evk2-sdk/src/Makefile @@ -46,4 +46,8 @@ ifeq ($(CONFIG_DEV_GPIO),y) CSRCS += hpm6750_gpio.c endif +ifeq ($(CONFIG_PWM),y) + CSRCS += hpm6750_pwm.c +endif + include $(TOPDIR)/boards/Board.mk diff --git a/boards/risc-v/hpmicro/hpm6750evk2-sdk/src/hpm6750_bringup.c b/boards/risc-v/hpmicro/hpm6750evk2-sdk/src/hpm6750_bringup.c index 0380181c3db9a..3d674ef8e2665 100644 --- a/boards/risc-v/hpmicro/hpm6750evk2-sdk/src/hpm6750_bringup.c +++ b/boards/risc-v/hpmicro/hpm6750evk2-sdk/src/hpm6750_bringup.c @@ -73,6 +73,10 @@ # include "hpm_adc16.h" #endif +#ifdef CONFIG_PWM +# include"hpm_pwm_lowerhalf.h" +#endif + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -161,10 +165,10 @@ int hpm6750_bringup(void) struct spi_dev_s *spi; spi = hpm6750_spi2initialize(); if (spi == NULL) - { - syslog(LOG_ERR, "Failed to initialize SPI2 \n"); - return -ENODEV; - } + { + syslog(LOG_ERR, "Failed to initialize SPI2 \n"); + return -ENODEV; + } ret = spi_register(spi, 2); if (ret < 0) @@ -184,77 +188,24 @@ int hpm6750_bringup(void) #endif -#if defined(CONFIG_TIMER) -# if defined(CONFIG_HPM6750_TIMER0) - ret = hpm_timer_initialize("/dev/timer0", 0); - if (ret < 0) - { - syslog(LOG_DEBUG, - "Failed to initialize /dev/timer0 Driver: %d\n", ret); - return ret; - } -# endif -# if defined(CONFIG_HPM6750_TIMER1) - ret = hpm_timer_initialize("/dev/timer1", 1); - if (ret < 0) - { - syslog(LOG_DEBUG, - "Failed to initialize /dev/timer1 Driver: %d\n", ret); - return ret; - } -# endif -# if defined(CONFIG_HPM6750_TIMER2) - ret = hpm_timer_initialize("/dev/timer2", 2); - if (ret < 0) - { - syslog(LOG_DEBUG, - "Failed to initialize /dev/timer2 Driver: %d\n", ret); - return ret; - } -# endif -# if defined(CONFIG_HPM6750_TIMER3) - ret = hpm_timer_initialize("/dev/timer3", 3); - if (ret < 0) - { - syslog(LOG_DEBUG, - "Failed to initialize /dev/timer3 Driver: %d\n", ret); - return ret; - } -# endif -# if defined(CONFIG_HPM6750_TIMER4) - ret = hpm_timer_initialize("/dev/timer4", 4); - if (ret < 0) - { - syslog(LOG_DEBUG, - "Failed to initialize /dev/timer4 Driver: %d\n", ret); - return ret; - } -# endif -# if defined(CONFIG_HPM6750_TIMER5) - ret = hpm_timer_initialize("/dev/timer5", 5); - if (ret < 0) - { - syslog(LOG_DEBUG, - "Failed to initialize /dev/timer5 Driver: %d\n", ret); - return ret; - } -# endif -# if defined(CONFIG_HPM6750_TIMER6) - ret = hpm_timer_initialize("/dev/timer6", 6); - if (ret < 0) +#ifdef CONFIG_PWM +# ifdef CONFIG_HPM6750_PWM2 + struct pwm_lowerhalf_s *pwm; + + /* Initialize PWM and register the PWM driver */ + + pwm = hpm6750_pwminitialize(2); + if (pwm == NULL) { - syslog(LOG_DEBUG, - "Failed to initialize /dev/timer6 Driver: %d\n", ret); - return ret; + syslog(LOG_DEBUG, "ERROR: hpm6750_pwminitialize failed\n"); } -# endif -# if defined(CONFIG_HPM6750_TIMER7) - ret = hpm_timer_initialize("/dev/timer7", 7); - if (ret < 0) + else { - syslog(LOG_DEBUG, - "Failed to initialize /dev/timer7 Driver: %d\n", ret); - return ret; + ret = pwm_register("/dev/pwm2", pwm); + if (ret < 0) + { + syslog(LOG_DEBUG, "ERROR: pwm_register failed: %d\n", ret); + } } # endif #endif diff --git a/boards/risc-v/hpmicro/hpm6750evk2-sdk/src/hpm6750_pwm.c b/boards/risc-v/hpmicro/hpm6750evk2-sdk/src/hpm6750_pwm.c new file mode 100644 index 0000000000000..175219b8e0ea1 --- /dev/null +++ b/boards/risc-v/hpmicro/hpm6750evk2-sdk/src/hpm6750_pwm.c @@ -0,0 +1,74 @@ +/**************************************************************************** + * boards/risc-v/hpmicro/hpm6750evk2/src/hpm6750_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 + +#include +#include +#include +#include + +#include +#include +#include + +#include "board.h" +#include "chip.h" +#include "hpm.h" + +#if defined(CONFIG_PWM) && \ + (defined(CONFIG_HPM6750_PWM0) || defined(CONFIG_HPM6750_PWM1) || \ + defined(CONFIG_HPM6750_PWM2) || defined(CONFIG_HPM6750_PWM3)) + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: hpm6750_init_pwm_pins + * + * Description: + * Initialize the selected PWM channel pins. + * + * Input Parameters: + * + * Returned Value: + * Valid SPI device structure reference on success; a NULL on failure + * + ****************************************************************************/ + +int hpm6750_init_pwm_pins(int port) +{ + int ret = -1; +# ifdef CONFIG_HPM6750_PWM2 + if(port == 2) + { + init_pwm_pins(HPM_PWM2); + ret = 0; + } +#endif + return ret; +} + +#endif