You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by GitBox <gi...@apache.org> on 2021/01/05 11:19:33 UTC
[GitHub] [incubator-nuttx] liangzhanggb opened a new pull request #2655: arch/risc-v/bl602 : add pwm onshot watchdog driver.
liangzhanggb opened a new pull request #2655:
URL: https://github.com/apache/incubator-nuttx/pull/2655
## Summary
arch/risc-v/bl602 : add pwm onshot watchdog driver
## Impact
N/A
## Testing
config:
1. → System Type → BL602 Peripheral Support → TIMER1
2. → Device Drivers → Timer Driver Support → PWM Driver Support → (5)Number of Output Channels Per Timer
3. → Device Drivers → Timer Driver Support → Oneshot timer drive
4. → Device Drivers → Timer Driver Support → Watchdog Timer Support
5. → RTOS Features → Performance Monitoring → Enable CPU load monitoring → Use external clock
6. → Application Configuration → Examples → Watchdog Timer example
7. → Application Configuration → Examples → Pulse width modulation (PWM) example
result:

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [incubator-nuttx] liangzhanggb commented on pull request #2655: arch/risc-v/bl602 : add pwm onshot watchdog driver.
Posted by GitBox <gi...@apache.org>.
liangzhanggb commented on pull request #2655:
URL: https://github.com/apache/incubator-nuttx/pull/2655#issuecomment-755850698
> @liangzhanggb One more minor fix that I think will also get the build to pass. I verified your latest changes and they all look good. Thanks.
>
> ```c
> diff --git a/arch/risc-v/src/bl602/Kconfig b/arch/risc-v/src/bl602/Kconfig
> index 9542d0be9c..0c819f95c8 100644
> --- a/arch/risc-v/src/bl602/Kconfig
> +++ b/arch/risc-v/src/bl602/Kconfig
> @@ -13,6 +13,7 @@ config BL602_HAVE_UART0
> select ARCH_HAVE_UART0
> select UART0_SERIALDRIVER
> select ARCH_HAVE_SERIAL_TERMIOS
> + select ARCH_HAVE_PWM_MULTICHAN
>
> config BL602_UART0
> bool
> @@ -37,6 +38,5 @@ config BL602_TIMER1
>
> config BL602_PWM0
> bool "PWM0"
> - select ARCH_HAVE_PWM_MULTICHAN
>
> endmenu
> diff --git a/boards/risc-v/bl602/bl602evb/configs/timer/defconfig b/boards/risc-v/bl602/bl602evb/configs/timer/defconfig
> index 63ef88f96a..94d63251ff 100644
> --- a/boards/risc-v/bl602/bl602evb/configs/timer/defconfig
> +++ b/boards/risc-v/bl602/bl602evb/configs/timer/defconfig
> @@ -55,6 +55,7 @@ CONFIG_ONESHOT=y
> CONFIG_PREALLOC_TIMERS=0
> CONFIG_PTHREAD_STACK_DEFAULT=8192
> CONFIG_PWM=y
> +CONFIG_PWM_MULTICHAN=y
> CONFIG_PWM_NCHANNELS=2
> CONFIG_RAM_SIZE=134217728
> CONFIG_RAM_START=0xc0800000
> ```
I have fixed it, Thank you very much
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [incubator-nuttx] liangzhanggb commented on a change in pull request #2655: arch/risc-v/bl602 : add pwm onshot watchdog driver.
Posted by GitBox <gi...@apache.org>.
liangzhanggb commented on a change in pull request #2655:
URL: https://github.com/apache/incubator-nuttx/pull/2655#discussion_r552604380
##########
File path: arch/risc-v/src/bl602/Make.defs
##########
@@ -58,7 +54,12 @@ endif
ifeq ($(CONFIG_ONESHOT),y)
CHIP_CSRCS += bl602_oneshot_lowerhalf.c
endif
-
+ifeq ($(CONFIG_WDOG),y)
Review comment:
I have fixed it, Thank you very much
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [incubator-nuttx] liangzhanggb commented on a change in pull request #2655: arch/risc-v/bl602 : add pwm onshot watchdog driver.
Posted by GitBox <gi...@apache.org>.
liangzhanggb commented on a change in pull request #2655:
URL: https://github.com/apache/incubator-nuttx/pull/2655#discussion_r552604254
##########
File path: arch/risc-v/src/bl602/bl602_pwm_lowerhalf.c
##########
@@ -0,0 +1,472 @@
+/****************************************************************************
+ * arch/risc-v/src/bl602/bl602_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 <nuttx/config.h>
+
+#include <inttypes.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <arch/board/board.h>
+
+#include "riscv_arch.h"
+#include "riscv_internal.h"
+
+#include "bl602_gpio.h"
+#include "bl602_pwm_lowerhalf.h"
+#include "hardware/bl602_pwm.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define BL_PWM_FREQ_DEFAULT (1000)
+#define BL_PWM_STOP_TIMEOUT_COUNT (160*1000)
+
+#define BL_PWM_XTAL_CLK (40000000)
+#define BL_PWM_BUS_BCLK (80000000)
+
+#ifdef CONFIG_BL602_PWM0_BUS_BCLK_SRC
+#define BL_PWM_CLK BL_PWM_BUS_BCLK
+#else
+#define BL_PWM_CLK BL_PWM_XTAL_CLK
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct bl602_pwm_ch_cfgs
+{
+ int ch; /* PWM channel */
+ int clk; /* PWM Clock */
+ int stop_mode; /* PWM Stop Mode */
+ int pol; /* PWM mode type */
+ uint16_t clk_div; /* PWM clkDiv num */
+ uint16_t period; /* PWM period set */
+ uint16_t threshold1; /* PWM threshold1 num */
+ uint16_t threshold2; /* PWM threshold2 num */
+ uint16_t int_pulse_cnt; /* PWM interrupt pulse count */
+};
+
+struct bl602_pwm_s
+{
+ FAR const struct pwm_ops_s *ops; /* PWM operations */
+ uint32_t frequency; /* Current frequency setting */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* PWM driver methods */
+
+static int bl602_pwm_setup(FAR struct pwm_lowerhalf_s *dev);
+static int bl602_pwm_shutdown(FAR struct pwm_lowerhalf_s *dev);
+static int bl602_pwm_start(FAR struct pwm_lowerhalf_s *dev,
+ FAR const struct pwm_info_s *info);
+static int bl602_pwm_stop(FAR struct pwm_lowerhalf_s *dev);
+static int bl602_pwm_ioctl(FAR 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_bl602_pwmops =
+{
+ .setup = bl602_pwm_setup,
+ .shutdown = bl602_pwm_shutdown,
+ .start = bl602_pwm_start,
+ .stop = bl602_pwm_stop,
+ .ioctl = bl602_pwm_ioctl,
+};
+
+struct bl602_pwm_s g_bl602_pwm0 =
+{
+ .ops = &g_bl602_pwmops,
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static void gpio_deinit(uint8_t pin)
+{
+ bl602_configgpio(GPIO_INPUT | GPIO_FLOAT | pin);
+}
+
+static void pwm_channel_disable(uint8_t ch)
+{
+ modifyreg32(BL602_PWM_N_CONFIG(ch), 0, CONFIG_PWM_STOP_EN);
+ modifyreg32(BL602_PWM_N_CONFIG(ch), INTERRUPT_PWM_INT_ENABLE, 0);
+}
+
+static void pwm_channel_enable(uint8_t ch)
+{
+ modifyreg32(BL602_PWM_N_CONFIG(ch), CONFIG_PWM_STOP_EN, 0);
+}
+
+static void pwm_channel_init(uint8_t ch, struct bl602_pwm_ch_cfgs *ch_cfg)
+{
+ uint32_t tmp_val;
+ uint32_t timeout_cnt = BL_PWM_STOP_TIMEOUT_COUNT;
+
+ /* Config pwm clock and polarity */
+
+ modifyreg32(BL602_PWM_N_CONFIG(ch), 0, CONFIG_PWM_STOP_EN);
+
+ while (!(getreg32(BL602_PWM_N_CONFIG(ch)) & CONFIG_PWM_STS_TOP))
+ {
+ timeout_cnt--;
+ if (timeout_cnt == 0)
+ {
+ return;
+ }
+ }
+
+ tmp_val = getreg32(BL602_PWM_N_CONFIG(ch));
+ tmp_val = (tmp_val & (~CONFIG_REG_CLK_SEL_MASK)) |
+ (CONFIG_REG_CLK_SEL_MASK & ch_cfg->clk);
+ tmp_val = (tmp_val & (~CONFIG_PWM_OUT_INV)) |
+ (1 & ch_cfg->pol);
+ tmp_val = (tmp_val & (~CONFIG_PWM_STOP_MODE)) |
+ (1 & ch_cfg->stop_mode);
+ putreg32(tmp_val, BL602_PWM_N_CONFIG(ch));
+
+ /* Config pwm division */
+
+ putreg32(ch_cfg->clk_div, BL602_PWM_N_CLKDIV(ch));
+
+ /* Config pwm period and duty */
+
+ putreg32(ch_cfg->threshold1, BL602_PWM_N_THRE1(ch));
+ putreg32(ch_cfg->threshold2, BL602_PWM_N_THRE2(ch));
+ putreg32(ch_cfg->period, BL602_PWM_N_PERIOD(ch));
+
+ /* Config interrupt pulse count */
+
+ modifyreg32(BL602_PWM_N_INTERRUPT(ch), 0,
+ (ch_cfg->int_pulse_cnt & PERIOD_PWM_PERIOD_MASK));
+}
+
+static int32_t pwm_init(uint8_t id, uint32_t freq)
+{
+ struct bl602_pwm_ch_cfgs pwm_cfg =
+ {
+ .ch = BL602_PWM_CH0,
+#ifdef CONFIG_BL602_PWM0_BUS_BCLK_SRC
+ .clk = BL602_PWM_CLK_BCLK,
+#else
+ .clk = BL602_PWM_CLK_XCLK,
+#endif
+ .stop_mode = BL602_PWM_STOP_ABRUPT,
+ .pol = BL602_PWM_POL_NORMAL,
+ .clk_div = 0,
+ .period = 100,
+ .threshold1 = 0,
+ .threshold2 = 0,
+ .int_pulse_cnt = 0,
+ };
+
+ pwm_cfg.period = BL_PWM_CLK / freq;
+ pwm_cfg.ch = id;
+
+ pwm_channel_disable(id);
+ pwm_channel_init(id, &pwm_cfg);
+
+ return 0;
+}
+
+/****************************************************************************
+ * Name: bl602_pwm_duty
+ *
+ * Description:
+ * Configure PWM duty
+ *
+ ****************************************************************************/
+
+static int bl602_pwm_duty(FAR struct bl602_pwm_s *priv, uint8_t chan,
+ ub16_t duty)
+{
+ uint16_t period;
+ uint16_t threshold1;
+ uint16_t threshold2;
+ uint32_t tmp_val;
+
+ /* get pwm period and duty */
+
+ tmp_val = getreg32(BL602_PWM_N_THRE1(chan));
+ threshold1 = tmp_val & THRE1_PWM_THRE1_MASK;
+
+ tmp_val = getreg32(BL602_PWM_N_THRE2(chan));
+ threshold2 = tmp_val & THRE2_PWM_THRE2_MASK;
+
+ tmp_val = getreg32(BL602_PWM_N_PERIOD(chan));
+ period = tmp_val & PERIOD_PWM_PERIOD_MASK;
+
+ threshold1 = 0;
+ threshold2 = (uint16_t)((uint32_t)period * duty / 65535);
+
+ putreg32(threshold1, BL602_PWM_N_THRE1(chan));
+ putreg32(threshold2, BL602_PWM_N_THRE2(chan));
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: bl602_pwm_freq
+ *
+ * Description:
+ * Configure PWM frequency
+ *
+ ****************************************************************************/
+
+static int bl602_pwm_freq(FAR struct bl602_pwm_s *priv, uint8_t chan,
+ uint32_t freq)
+{
+ uint16_t period = BL_PWM_CLK / freq;
+ uint16_t threshold1 = 0;
+ uint16_t threshold2 = 0;
+
+ pwm_channel_disable(chan);
+
+ /* Config pwm period and duty */
+
+ putreg32(threshold1, BL602_PWM_N_THRE1(chan));
+ putreg32(threshold2, BL602_PWM_N_THRE2(chan));
+ putreg32(period, BL602_PWM_N_PERIOD(chan));
+
+ pwm_channel_enable(chan);
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: bl602_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 bl602_pwm_setup(FAR struct pwm_lowerhalf_s *dev)
+{
+ int ret = OK;
+
+#ifdef BOARD_PWM_CH0_PIN
+ bl602_configgpio(BOARD_PWM_CH0_PIN);
+ pwm_init(0, BL_PWM_FREQ_DEFAULT);
+#endif
+
+#ifdef BOARD_PWM_CH1_PIN
+ bl602_configgpio(BOARD_PWM_CH1_PIN);
+ pwm_init(1, BL_PWM_FREQ_DEFAULT);
+#endif
+
+#ifdef BOARD_PWM_CH2_PIN
+ bl602_configgpio(BOARD_PWM_CH2_PIN);
+ pwm_init(2, BL_PWM_FREQ_DEFAULT);
+#endif
+
+#ifdef BOARD_PWM_CH3_PIN
+ bl602_configgpio(BOARD_PWM_CH3_PIN);
+ pwm_init(3, BL_PWM_FREQ_DEFAULT);
+#endif
+
+#ifdef BOARD_PWM_CH4_PIN
Review comment:
I have fixed it, Thank you very much
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [incubator-nuttx] normanr commented on a change in pull request #2655: arch/risc-v/bl602 : add pwm onshot watchdog driver.
Posted by GitBox <gi...@apache.org>.
normanr commented on a change in pull request #2655:
URL: https://github.com/apache/incubator-nuttx/pull/2655#discussion_r775107597
##########
File path: arch/risc-v/src/bl602/bl602_pwm_lowerhalf.c
##########
@@ -0,0 +1,473 @@
+/****************************************************************************
+ * arch/risc-v/src/bl602/bl602_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 <nuttx/config.h>
+
+#include <inttypes.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <arch/board/board.h>
+
+#include "riscv_arch.h"
+#include "riscv_internal.h"
+
+#include "bl602_gpio.h"
+#include "bl602_pwm_lowerhalf.h"
+#include "hardware/bl602_pwm.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define BL_PWM_FREQ_DEFAULT (1000)
+#define BL_PWM_STOP_TIMEOUT_COUNT (160*1000)
+
+#define BL_PWM_XTAL_CLK (40000000)
+#define BL_PWM_BUS_BCLK (80000000)
+
+#ifdef CONFIG_PWM_NCHANNELS
+# if (CONFIG_PWM_NCHANNELS > 5)
+# error "The maximum number of BL602 PWM channels is 5!"
+# endif
+#endif
+
+#ifdef CONFIG_BL602_PWM0_BUS_BCLK_SRC
Review comment:
Is `CONFIG_BL602_PWM0_BUS_BCLK_SRC` configured anywhere? I expected to see it in a Kconfig, but can't find it.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [incubator-nuttx] xiaoxiang781216 commented on a change in pull request #2655: arch/risc-v/bl602 : add pwm onshot watchdog driver.
Posted by GitBox <gi...@apache.org>.
xiaoxiang781216 commented on a change in pull request #2655:
URL: https://github.com/apache/incubator-nuttx/pull/2655#discussion_r775114390
##########
File path: arch/risc-v/src/bl602/bl602_pwm_lowerhalf.c
##########
@@ -0,0 +1,473 @@
+/****************************************************************************
+ * arch/risc-v/src/bl602/bl602_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 <nuttx/config.h>
+
+#include <inttypes.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <arch/board/board.h>
+
+#include "riscv_arch.h"
+#include "riscv_internal.h"
+
+#include "bl602_gpio.h"
+#include "bl602_pwm_lowerhalf.h"
+#include "hardware/bl602_pwm.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define BL_PWM_FREQ_DEFAULT (1000)
+#define BL_PWM_STOP_TIMEOUT_COUNT (160*1000)
+
+#define BL_PWM_XTAL_CLK (40000000)
+#define BL_PWM_BUS_BCLK (80000000)
+
+#ifdef CONFIG_PWM_NCHANNELS
+# if (CONFIG_PWM_NCHANNELS > 5)
+# error "The maximum number of BL602 PWM channels is 5!"
+# endif
+#endif
+
+#ifdef CONFIG_BL602_PWM0_BUS_BCLK_SRC
Review comment:
@liangzhanggb please take a look.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [incubator-nuttx] normanr commented on a change in pull request #2655: arch/risc-v/bl602 : add pwm onshot watchdog driver.
Posted by GitBox <gi...@apache.org>.
normanr commented on a change in pull request #2655:
URL: https://github.com/apache/incubator-nuttx/pull/2655#discussion_r775106788
##########
File path: arch/risc-v/src/bl602/bl602_pwm_lowerhalf.c
##########
@@ -0,0 +1,473 @@
+/****************************************************************************
+ * arch/risc-v/src/bl602/bl602_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 <nuttx/config.h>
+
+#include <inttypes.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <arch/board/board.h>
+
+#include "riscv_arch.h"
+#include "riscv_internal.h"
+
+#include "bl602_gpio.h"
+#include "bl602_pwm_lowerhalf.h"
+#include "hardware/bl602_pwm.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define BL_PWM_FREQ_DEFAULT (1000)
+#define BL_PWM_STOP_TIMEOUT_COUNT (160*1000)
+
+#define BL_PWM_XTAL_CLK (40000000)
+#define BL_PWM_BUS_BCLK (80000000)
+
+#ifdef CONFIG_PWM_NCHANNELS
+# if (CONFIG_PWM_NCHANNELS > 5)
+# error "The maximum number of BL602 PWM channels is 5!"
+# endif
+#endif
+
+#ifdef CONFIG_BL602_PWM0_BUS_BCLK_SRC
+#define BL_PWM_CLK BL_PWM_BUS_BCLK
+#else
+#define BL_PWM_CLK BL_PWM_XTAL_CLK
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct bl602_pwm_ch_cfgs
+{
+ int ch; /* PWM channel */
+ int clk; /* PWM Clock */
+ int stop_mode; /* PWM Stop Mode */
+ int pol; /* PWM mode type */
+ uint16_t clk_div; /* PWM clkDiv num */
+ uint16_t period; /* PWM period set */
+ uint16_t threshold1; /* PWM threshold1 num */
+ uint16_t threshold2; /* PWM threshold2 num */
+ uint16_t int_pulse_cnt; /* PWM interrupt pulse count */
+};
+
+struct bl602_pwm_s
+{
+ FAR const struct pwm_ops_s *ops; /* PWM operations */
+ uint32_t chan_pin[5]; /* Channel pin */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* PWM driver methods */
+
+static int bl602_pwm_setup(FAR struct pwm_lowerhalf_s *dev);
+static int bl602_pwm_shutdown(FAR struct pwm_lowerhalf_s *dev);
+static int bl602_pwm_start(FAR struct pwm_lowerhalf_s *dev,
+ FAR const struct pwm_info_s *info);
+static int bl602_pwm_stop(FAR struct pwm_lowerhalf_s *dev);
+static int bl602_pwm_ioctl(FAR 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_bl602_pwmops =
+{
+ .setup = bl602_pwm_setup,
+ .shutdown = bl602_pwm_shutdown,
+ .start = bl602_pwm_start,
+ .stop = bl602_pwm_stop,
+ .ioctl = bl602_pwm_ioctl,
+};
+
+struct bl602_pwm_s g_bl602_pwm0 =
+{
+ .ops = &g_bl602_pwmops,
+#ifdef BOARD_PWM_CH0_PIN
+ .chan_pin[0] = BOARD_PWM_CH0_PIN,
+#endif
+#ifdef BOARD_PWM_CH1_PIN
+ .chan_pin[1] = BOARD_PWM_CH1_PIN,
+#endif
+#ifdef BOARD_PWM_CH2_PIN
+ .chan_pin[2] = BOARD_PWM_CH2_PIN,
+#endif
+#ifdef BOARD_PWM_CH3_PIN
+ .chan_pin[3] = BOARD_PWM_CH3_PIN,
+#endif
+#ifdef BOARD_PWM_CH4_PIN
+ .chan_pin[4] = BOARD_PWM_CH4_PIN,
+#endif
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static void pwm_channel_disable(uint8_t ch)
+{
+ modifyreg32(BL602_PWM_N_CONFIG(ch), 0, CONFIG_PWM_STOP_EN);
+ modifyreg32(BL602_PWM_N_CONFIG(ch), INTERRUPT_PWM_INT_ENABLE, 0);
+}
+
+static void pwm_channel_enable(uint8_t ch)
+{
+ modifyreg32(BL602_PWM_N_CONFIG(ch), CONFIG_PWM_STOP_EN, 0);
+}
+
+static void pwm_channel_init(uint8_t ch, struct bl602_pwm_ch_cfgs *ch_cfg)
+{
+ uint32_t timeout_cnt = BL_PWM_STOP_TIMEOUT_COUNT;
+
+ /* Config pwm clock and polarity */
+
+ modifyreg32(BL602_PWM_N_CONFIG(ch), 0, CONFIG_PWM_STOP_EN);
+
+ while (!(getreg32(BL602_PWM_N_CONFIG(ch)) & CONFIG_PWM_STS_TOP))
+ {
+ timeout_cnt--;
+ if (timeout_cnt == 0)
+ {
+ return;
+ }
+ }
+
+ modifyreg32(BL602_PWM_N_CONFIG(ch),
+ CONFIG_REG_CLK_SEL_MASK & (~ch_cfg->clk),
+ CONFIG_REG_CLK_SEL_MASK & ch_cfg->clk);
+
+ modifyreg32(BL602_PWM_N_CONFIG(ch),
+ CONFIG_PWM_OUT_INV,
+ ch_cfg->pol ? CONFIG_PWM_OUT_INV : 0);
+
+ modifyreg32(BL602_PWM_N_CONFIG(ch),
+ CONFIG_PWM_STOP_MODE,
+ ch_cfg->stop_mode ? CONFIG_PWM_STOP_MODE : 0);
+
+ /* Config pwm division */
+
+ putreg32(ch_cfg->clk_div, BL602_PWM_N_CLKDIV(ch));
+
+ /* Config pwm period and duty */
+
+ putreg32(ch_cfg->threshold1, BL602_PWM_N_THRE1(ch));
+ putreg32(ch_cfg->threshold2, BL602_PWM_N_THRE2(ch));
+ putreg32(ch_cfg->period, BL602_PWM_N_PERIOD(ch));
+
+ /* Config interrupt pulse count */
+
+ modifyreg32(BL602_PWM_N_INTERRUPT(ch), 0,
+ (ch_cfg->int_pulse_cnt & PERIOD_PWM_PERIOD_MASK));
+}
+
+static int32_t pwm_init(uint8_t id, uint32_t freq)
+{
+ struct bl602_pwm_ch_cfgs pwm_cfg =
+ {
+ .ch = BL602_PWM_CH0,
+#ifdef CONFIG_BL602_PWM0_BUS_BCLK_SRC
+ .clk = BL602_PWM_CLK_BCLK,
+#else
+ .clk = BL602_PWM_CLK_XCLK,
+#endif
+ .stop_mode = BL602_PWM_STOP_ABRUPT,
+ .pol = BL602_PWM_POL_NORMAL,
+ .clk_div = 0,
+ .period = 100,
+ .threshold1 = 0,
+ .threshold2 = 0,
+ .int_pulse_cnt = 0,
+ };
+
+ pwm_cfg.period = BL_PWM_CLK / freq;
+ pwm_cfg.ch = id;
+
+ pwm_channel_disable(id);
+ pwm_channel_init(id, &pwm_cfg);
+
+ return 0;
+}
+
+/****************************************************************************
+ * Name: bl602_pwm_duty
+ *
+ * Description:
+ * Configure PWM duty
+ *
+ ****************************************************************************/
+
+static int bl602_pwm_duty(FAR struct bl602_pwm_s *priv, uint8_t chan,
+ ub16_t duty)
+{
+ uint16_t period;
+ uint16_t threshold1;
+ uint16_t threshold2;
+ uint32_t tmp_val;
+
+ /* get pwm period and duty */
+
+ tmp_val = getreg32(BL602_PWM_N_THRE1(chan));
+ threshold1 = tmp_val & THRE1_PWM_THRE1_MASK;
+
+ tmp_val = getreg32(BL602_PWM_N_THRE2(chan));
+ threshold2 = tmp_val & THRE2_PWM_THRE2_MASK;
+
+ tmp_val = getreg32(BL602_PWM_N_PERIOD(chan));
+ period = tmp_val & PERIOD_PWM_PERIOD_MASK;
+
+ threshold1 = 0;
+ threshold2 = (uint16_t)((uint32_t)period * duty / 65535);
+
+ putreg32(threshold1, BL602_PWM_N_THRE1(chan));
+ putreg32(threshold2, BL602_PWM_N_THRE2(chan));
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: bl602_pwm_freq
+ *
+ * Description:
+ * Configure PWM frequency
+ *
+ ****************************************************************************/
+
+static int bl602_pwm_freq(FAR struct bl602_pwm_s *priv, uint8_t chan,
+ uint32_t freq)
+{
+ uint16_t period = BL_PWM_CLK / freq;
+ uint16_t threshold1 = 0;
+ uint16_t threshold2 = 0;
+
+ pwm_channel_disable(chan);
+
+ /* Config pwm period and duty */
+
+ putreg32(threshold1, BL602_PWM_N_THRE1(chan));
+ putreg32(threshold2, BL602_PWM_N_THRE2(chan));
+ putreg32(period, BL602_PWM_N_PERIOD(chan));
+
+ pwm_channel_enable(chan);
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: bl602_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 bl602_pwm_setup(FAR struct pwm_lowerhalf_s *dev)
+{
+ int i;
+ int ret = OK;
+ FAR struct bl602_pwm_s *priv = (FAR struct bl602_pwm_s *)dev;
+
+ UNUSED(i);
+
+#ifdef CONFIG_PWM_NCHANNELS
+ for (i = 0; i < CONFIG_PWM_NCHANNELS; i++)
+ {
+ bl602_configgpio(priv->chan_pin[i]);
+ pwm_init(i, BL_PWM_FREQ_DEFAULT);
+ }
+#else
+ bl602_configgpio(priv->chan_pin[0]);
+ pwm_init(0, BL_PWM_FREQ_DEFAULT);
+#endif
+
+ return ret;
+}
+
+/****************************************************************************
+ * Name: bl602_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 bl602_pwm_shutdown(FAR struct pwm_lowerhalf_s *dev)
+{
+ int i;
+ int ret = OK;
+ FAR struct bl602_pwm_s *priv = (FAR struct bl602_pwm_s *)dev;
+
+ UNUSED(i);
+
+#ifdef CONFIG_PWM_NCHANNELS
+ for (i = 0; i < CONFIG_PWM_NCHANNELS; i++)
+ {
+ pwm_channel_disable(priv->chan_pin[i]);
+ bl602_gpio_deinit(i);
+ }
+#else
+ pwm_channel_disable(priv->chan_pin[0]);
+ bl602_gpio_deinit(0);
+#endif
+
+ return ret;
+}
+
+/****************************************************************************
+ * Name: bl602_pwm_start
+ *
+ * Description:
+ * (Re-)initialize the PWM and start the pulsed output
+ *
+ ****************************************************************************/
+
+static int bl602_pwm_start(FAR struct pwm_lowerhalf_s *dev,
+ FAR const struct pwm_info_s *info)
+{
+ FAR struct bl602_pwm_s *priv = (FAR struct bl602_pwm_s *)dev;
+ int ret = OK;
+ int i;
+
+ UNUSED(i);
+
+#ifdef CONFIG_PWM_NCHANNELS
+ for (i = 0; i < CONFIG_PWM_NCHANNELS; i++)
+ {
+ bl602_pwm_freq(priv, i, info->frequency);
+ bl602_pwm_duty(priv, i, info->channels[i].duty);
Review comment:
Should the second argument have been `info->channels[i].channel`? Otherwise there's no way to change the order of channels.
Also PR #4227 added an option to break these loops when `channel == -1`, it looks like it was missed here.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [incubator-nuttx] xiaoxiang781216 commented on a change in pull request #2655: arch/risc-v/bl602 : add pwm onshot watchdog driver.
Posted by GitBox <gi...@apache.org>.
xiaoxiang781216 commented on a change in pull request #2655:
URL: https://github.com/apache/incubator-nuttx/pull/2655#discussion_r551922426
##########
File path: arch/risc-v/src/bl602/Kconfig
##########
@@ -34,4 +34,35 @@ config BL602_TIMER0
config BL602_TIMER1
bool "TIMER1"
+
+config BL602_PWM0
+ bool "PWM0"
+ default y
+ depends on PWM
+ select PWM_MULTICHAN
+
endmenu
+
+config BL602_SPIFLASH
Review comment:
@liangzhanggb Please split the SPI related change to another PR.
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [incubator-nuttx] normanr commented on a change in pull request #2655: arch/risc-v/bl602 : add pwm onshot watchdog driver.
Posted by GitBox <gi...@apache.org>.
normanr commented on a change in pull request #2655:
URL: https://github.com/apache/incubator-nuttx/pull/2655#discussion_r775783890
##########
File path: arch/risc-v/src/bl602/bl602_pwm_lowerhalf.c
##########
@@ -0,0 +1,473 @@
+/****************************************************************************
+ * arch/risc-v/src/bl602/bl602_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 <nuttx/config.h>
+
+#include <inttypes.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <arch/board/board.h>
+
+#include "riscv_arch.h"
+#include "riscv_internal.h"
+
+#include "bl602_gpio.h"
+#include "bl602_pwm_lowerhalf.h"
+#include "hardware/bl602_pwm.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define BL_PWM_FREQ_DEFAULT (1000)
+#define BL_PWM_STOP_TIMEOUT_COUNT (160*1000)
+
+#define BL_PWM_XTAL_CLK (40000000)
+#define BL_PWM_BUS_BCLK (80000000)
+
+#ifdef CONFIG_PWM_NCHANNELS
+# if (CONFIG_PWM_NCHANNELS > 5)
+# error "The maximum number of BL602 PWM channels is 5!"
+# endif
+#endif
+
+#ifdef CONFIG_BL602_PWM0_BUS_BCLK_SRC
+#define BL_PWM_CLK BL_PWM_BUS_BCLK
+#else
+#define BL_PWM_CLK BL_PWM_XTAL_CLK
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct bl602_pwm_ch_cfgs
+{
+ int ch; /* PWM channel */
+ int clk; /* PWM Clock */
+ int stop_mode; /* PWM Stop Mode */
+ int pol; /* PWM mode type */
+ uint16_t clk_div; /* PWM clkDiv num */
+ uint16_t period; /* PWM period set */
+ uint16_t threshold1; /* PWM threshold1 num */
+ uint16_t threshold2; /* PWM threshold2 num */
+ uint16_t int_pulse_cnt; /* PWM interrupt pulse count */
+};
+
+struct bl602_pwm_s
+{
+ FAR const struct pwm_ops_s *ops; /* PWM operations */
+ uint32_t chan_pin[5]; /* Channel pin */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* PWM driver methods */
+
+static int bl602_pwm_setup(FAR struct pwm_lowerhalf_s *dev);
+static int bl602_pwm_shutdown(FAR struct pwm_lowerhalf_s *dev);
+static int bl602_pwm_start(FAR struct pwm_lowerhalf_s *dev,
+ FAR const struct pwm_info_s *info);
+static int bl602_pwm_stop(FAR struct pwm_lowerhalf_s *dev);
+static int bl602_pwm_ioctl(FAR 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_bl602_pwmops =
+{
+ .setup = bl602_pwm_setup,
+ .shutdown = bl602_pwm_shutdown,
+ .start = bl602_pwm_start,
+ .stop = bl602_pwm_stop,
+ .ioctl = bl602_pwm_ioctl,
+};
+
+struct bl602_pwm_s g_bl602_pwm0 =
+{
+ .ops = &g_bl602_pwmops,
+#ifdef BOARD_PWM_CH0_PIN
+ .chan_pin[0] = BOARD_PWM_CH0_PIN,
+#endif
+#ifdef BOARD_PWM_CH1_PIN
+ .chan_pin[1] = BOARD_PWM_CH1_PIN,
+#endif
+#ifdef BOARD_PWM_CH2_PIN
+ .chan_pin[2] = BOARD_PWM_CH2_PIN,
+#endif
+#ifdef BOARD_PWM_CH3_PIN
+ .chan_pin[3] = BOARD_PWM_CH3_PIN,
+#endif
+#ifdef BOARD_PWM_CH4_PIN
+ .chan_pin[4] = BOARD_PWM_CH4_PIN,
+#endif
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static void pwm_channel_disable(uint8_t ch)
+{
+ modifyreg32(BL602_PWM_N_CONFIG(ch), 0, CONFIG_PWM_STOP_EN);
+ modifyreg32(BL602_PWM_N_CONFIG(ch), INTERRUPT_PWM_INT_ENABLE, 0);
+}
+
+static void pwm_channel_enable(uint8_t ch)
+{
+ modifyreg32(BL602_PWM_N_CONFIG(ch), CONFIG_PWM_STOP_EN, 0);
+}
+
+static void pwm_channel_init(uint8_t ch, struct bl602_pwm_ch_cfgs *ch_cfg)
+{
+ uint32_t timeout_cnt = BL_PWM_STOP_TIMEOUT_COUNT;
+
+ /* Config pwm clock and polarity */
+
+ modifyreg32(BL602_PWM_N_CONFIG(ch), 0, CONFIG_PWM_STOP_EN);
+
+ while (!(getreg32(BL602_PWM_N_CONFIG(ch)) & CONFIG_PWM_STS_TOP))
+ {
+ timeout_cnt--;
+ if (timeout_cnt == 0)
+ {
+ return;
+ }
+ }
+
+ modifyreg32(BL602_PWM_N_CONFIG(ch),
+ CONFIG_REG_CLK_SEL_MASK & (~ch_cfg->clk),
+ CONFIG_REG_CLK_SEL_MASK & ch_cfg->clk);
+
+ modifyreg32(BL602_PWM_N_CONFIG(ch),
+ CONFIG_PWM_OUT_INV,
+ ch_cfg->pol ? CONFIG_PWM_OUT_INV : 0);
+
+ modifyreg32(BL602_PWM_N_CONFIG(ch),
+ CONFIG_PWM_STOP_MODE,
+ ch_cfg->stop_mode ? CONFIG_PWM_STOP_MODE : 0);
+
+ /* Config pwm division */
+
+ putreg32(ch_cfg->clk_div, BL602_PWM_N_CLKDIV(ch));
+
+ /* Config pwm period and duty */
+
+ putreg32(ch_cfg->threshold1, BL602_PWM_N_THRE1(ch));
+ putreg32(ch_cfg->threshold2, BL602_PWM_N_THRE2(ch));
+ putreg32(ch_cfg->period, BL602_PWM_N_PERIOD(ch));
+
+ /* Config interrupt pulse count */
+
+ modifyreg32(BL602_PWM_N_INTERRUPT(ch), 0,
+ (ch_cfg->int_pulse_cnt & PERIOD_PWM_PERIOD_MASK));
+}
+
+static int32_t pwm_init(uint8_t id, uint32_t freq)
+{
+ struct bl602_pwm_ch_cfgs pwm_cfg =
+ {
+ .ch = BL602_PWM_CH0,
+#ifdef CONFIG_BL602_PWM0_BUS_BCLK_SRC
+ .clk = BL602_PWM_CLK_BCLK,
+#else
+ .clk = BL602_PWM_CLK_XCLK,
+#endif
+ .stop_mode = BL602_PWM_STOP_ABRUPT,
+ .pol = BL602_PWM_POL_NORMAL,
+ .clk_div = 0,
+ .period = 100,
+ .threshold1 = 0,
+ .threshold2 = 0,
+ .int_pulse_cnt = 0,
+ };
+
+ pwm_cfg.period = BL_PWM_CLK / freq;
+ pwm_cfg.ch = id;
+
+ pwm_channel_disable(id);
+ pwm_channel_init(id, &pwm_cfg);
+
+ return 0;
+}
+
+/****************************************************************************
+ * Name: bl602_pwm_duty
+ *
+ * Description:
+ * Configure PWM duty
+ *
+ ****************************************************************************/
+
+static int bl602_pwm_duty(FAR struct bl602_pwm_s *priv, uint8_t chan,
+ ub16_t duty)
+{
+ uint16_t period;
+ uint16_t threshold1;
+ uint16_t threshold2;
+ uint32_t tmp_val;
+
+ /* get pwm period and duty */
+
+ tmp_val = getreg32(BL602_PWM_N_THRE1(chan));
+ threshold1 = tmp_val & THRE1_PWM_THRE1_MASK;
+
+ tmp_val = getreg32(BL602_PWM_N_THRE2(chan));
+ threshold2 = tmp_val & THRE2_PWM_THRE2_MASK;
+
+ tmp_val = getreg32(BL602_PWM_N_PERIOD(chan));
+ period = tmp_val & PERIOD_PWM_PERIOD_MASK;
+
+ threshold1 = 0;
+ threshold2 = (uint16_t)((uint32_t)period * duty / 65535);
+
+ putreg32(threshold1, BL602_PWM_N_THRE1(chan));
+ putreg32(threshold2, BL602_PWM_N_THRE2(chan));
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: bl602_pwm_freq
+ *
+ * Description:
+ * Configure PWM frequency
+ *
+ ****************************************************************************/
+
+static int bl602_pwm_freq(FAR struct bl602_pwm_s *priv, uint8_t chan,
+ uint32_t freq)
+{
+ uint16_t period = BL_PWM_CLK / freq;
+ uint16_t threshold1 = 0;
+ uint16_t threshold2 = 0;
+
+ pwm_channel_disable(chan);
+
+ /* Config pwm period and duty */
+
+ putreg32(threshold1, BL602_PWM_N_THRE1(chan));
+ putreg32(threshold2, BL602_PWM_N_THRE2(chan));
+ putreg32(period, BL602_PWM_N_PERIOD(chan));
+
+ pwm_channel_enable(chan);
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: bl602_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 bl602_pwm_setup(FAR struct pwm_lowerhalf_s *dev)
+{
+ int i;
+ int ret = OK;
+ FAR struct bl602_pwm_s *priv = (FAR struct bl602_pwm_s *)dev;
+
+ UNUSED(i);
+
+#ifdef CONFIG_PWM_NCHANNELS
+ for (i = 0; i < CONFIG_PWM_NCHANNELS; i++)
+ {
+ bl602_configgpio(priv->chan_pin[i]);
+ pwm_init(i, BL_PWM_FREQ_DEFAULT);
+ }
+#else
+ bl602_configgpio(priv->chan_pin[0]);
+ pwm_init(0, BL_PWM_FREQ_DEFAULT);
+#endif
+
+ return ret;
+}
+
+/****************************************************************************
+ * Name: bl602_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 bl602_pwm_shutdown(FAR struct pwm_lowerhalf_s *dev)
+{
+ int i;
+ int ret = OK;
+ FAR struct bl602_pwm_s *priv = (FAR struct bl602_pwm_s *)dev;
+
+ UNUSED(i);
+
+#ifdef CONFIG_PWM_NCHANNELS
+ for (i = 0; i < CONFIG_PWM_NCHANNELS; i++)
+ {
+ pwm_channel_disable(priv->chan_pin[i]);
+ bl602_gpio_deinit(i);
+ }
+#else
+ pwm_channel_disable(priv->chan_pin[0]);
+ bl602_gpio_deinit(0);
+#endif
+
+ return ret;
+}
+
+/****************************************************************************
+ * Name: bl602_pwm_start
+ *
+ * Description:
+ * (Re-)initialize the PWM and start the pulsed output
+ *
+ ****************************************************************************/
+
+static int bl602_pwm_start(FAR struct pwm_lowerhalf_s *dev,
+ FAR const struct pwm_info_s *info)
+{
+ FAR struct bl602_pwm_s *priv = (FAR struct bl602_pwm_s *)dev;
+ int ret = OK;
+ int i;
+
+ UNUSED(i);
+
+#ifdef CONFIG_PWM_NCHANNELS
+ for (i = 0; i < CONFIG_PWM_NCHANNELS; i++)
+ {
+ bl602_pwm_freq(priv, i, info->frequency);
+ bl602_pwm_duty(priv, i, info->channels[i].duty);
Review comment:
PR https://github.com/apache/incubator-nuttx/pull/5091 to add the early exit from PR #4227.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [incubator-nuttx] normanr commented on a change in pull request #2655: arch/risc-v/bl602 : add pwm onshot watchdog driver.
Posted by GitBox <gi...@apache.org>.
normanr commented on a change in pull request #2655:
URL: https://github.com/apache/incubator-nuttx/pull/2655#discussion_r775858152
##########
File path: arch/risc-v/src/bl602/bl602_pwm_lowerhalf.c
##########
@@ -0,0 +1,473 @@
+/****************************************************************************
+ * arch/risc-v/src/bl602/bl602_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 <nuttx/config.h>
+
+#include <inttypes.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <arch/board/board.h>
+
+#include "riscv_arch.h"
+#include "riscv_internal.h"
+
+#include "bl602_gpio.h"
+#include "bl602_pwm_lowerhalf.h"
+#include "hardware/bl602_pwm.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define BL_PWM_FREQ_DEFAULT (1000)
+#define BL_PWM_STOP_TIMEOUT_COUNT (160*1000)
+
+#define BL_PWM_XTAL_CLK (40000000)
+#define BL_PWM_BUS_BCLK (80000000)
+
+#ifdef CONFIG_PWM_NCHANNELS
+# if (CONFIG_PWM_NCHANNELS > 5)
+# error "The maximum number of BL602 PWM channels is 5!"
+# endif
+#endif
+
+#ifdef CONFIG_BL602_PWM0_BUS_BCLK_SRC
+#define BL_PWM_CLK BL_PWM_BUS_BCLK
+#else
+#define BL_PWM_CLK BL_PWM_XTAL_CLK
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct bl602_pwm_ch_cfgs
+{
+ int ch; /* PWM channel */
+ int clk; /* PWM Clock */
+ int stop_mode; /* PWM Stop Mode */
+ int pol; /* PWM mode type */
+ uint16_t clk_div; /* PWM clkDiv num */
+ uint16_t period; /* PWM period set */
+ uint16_t threshold1; /* PWM threshold1 num */
+ uint16_t threshold2; /* PWM threshold2 num */
+ uint16_t int_pulse_cnt; /* PWM interrupt pulse count */
+};
+
+struct bl602_pwm_s
+{
+ FAR const struct pwm_ops_s *ops; /* PWM operations */
+ uint32_t chan_pin[5]; /* Channel pin */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* PWM driver methods */
+
+static int bl602_pwm_setup(FAR struct pwm_lowerhalf_s *dev);
+static int bl602_pwm_shutdown(FAR struct pwm_lowerhalf_s *dev);
+static int bl602_pwm_start(FAR struct pwm_lowerhalf_s *dev,
+ FAR const struct pwm_info_s *info);
+static int bl602_pwm_stop(FAR struct pwm_lowerhalf_s *dev);
+static int bl602_pwm_ioctl(FAR 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_bl602_pwmops =
+{
+ .setup = bl602_pwm_setup,
+ .shutdown = bl602_pwm_shutdown,
+ .start = bl602_pwm_start,
+ .stop = bl602_pwm_stop,
+ .ioctl = bl602_pwm_ioctl,
+};
+
+struct bl602_pwm_s g_bl602_pwm0 =
+{
+ .ops = &g_bl602_pwmops,
+#ifdef BOARD_PWM_CH0_PIN
+ .chan_pin[0] = BOARD_PWM_CH0_PIN,
+#endif
+#ifdef BOARD_PWM_CH1_PIN
+ .chan_pin[1] = BOARD_PWM_CH1_PIN,
+#endif
+#ifdef BOARD_PWM_CH2_PIN
+ .chan_pin[2] = BOARD_PWM_CH2_PIN,
+#endif
+#ifdef BOARD_PWM_CH3_PIN
+ .chan_pin[3] = BOARD_PWM_CH3_PIN,
+#endif
+#ifdef BOARD_PWM_CH4_PIN
+ .chan_pin[4] = BOARD_PWM_CH4_PIN,
+#endif
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static void pwm_channel_disable(uint8_t ch)
+{
+ modifyreg32(BL602_PWM_N_CONFIG(ch), 0, CONFIG_PWM_STOP_EN);
+ modifyreg32(BL602_PWM_N_CONFIG(ch), INTERRUPT_PWM_INT_ENABLE, 0);
+}
+
+static void pwm_channel_enable(uint8_t ch)
+{
+ modifyreg32(BL602_PWM_N_CONFIG(ch), CONFIG_PWM_STOP_EN, 0);
+}
+
+static void pwm_channel_init(uint8_t ch, struct bl602_pwm_ch_cfgs *ch_cfg)
+{
+ uint32_t timeout_cnt = BL_PWM_STOP_TIMEOUT_COUNT;
+
+ /* Config pwm clock and polarity */
+
+ modifyreg32(BL602_PWM_N_CONFIG(ch), 0, CONFIG_PWM_STOP_EN);
+
+ while (!(getreg32(BL602_PWM_N_CONFIG(ch)) & CONFIG_PWM_STS_TOP))
+ {
+ timeout_cnt--;
+ if (timeout_cnt == 0)
+ {
+ return;
+ }
+ }
+
+ modifyreg32(BL602_PWM_N_CONFIG(ch),
+ CONFIG_REG_CLK_SEL_MASK & (~ch_cfg->clk),
+ CONFIG_REG_CLK_SEL_MASK & ch_cfg->clk);
+
+ modifyreg32(BL602_PWM_N_CONFIG(ch),
+ CONFIG_PWM_OUT_INV,
+ ch_cfg->pol ? CONFIG_PWM_OUT_INV : 0);
+
+ modifyreg32(BL602_PWM_N_CONFIG(ch),
+ CONFIG_PWM_STOP_MODE,
+ ch_cfg->stop_mode ? CONFIG_PWM_STOP_MODE : 0);
+
+ /* Config pwm division */
+
+ putreg32(ch_cfg->clk_div, BL602_PWM_N_CLKDIV(ch));
+
+ /* Config pwm period and duty */
+
+ putreg32(ch_cfg->threshold1, BL602_PWM_N_THRE1(ch));
+ putreg32(ch_cfg->threshold2, BL602_PWM_N_THRE2(ch));
+ putreg32(ch_cfg->period, BL602_PWM_N_PERIOD(ch));
+
+ /* Config interrupt pulse count */
+
+ modifyreg32(BL602_PWM_N_INTERRUPT(ch), 0,
+ (ch_cfg->int_pulse_cnt & PERIOD_PWM_PERIOD_MASK));
+}
+
+static int32_t pwm_init(uint8_t id, uint32_t freq)
+{
+ struct bl602_pwm_ch_cfgs pwm_cfg =
+ {
+ .ch = BL602_PWM_CH0,
+#ifdef CONFIG_BL602_PWM0_BUS_BCLK_SRC
+ .clk = BL602_PWM_CLK_BCLK,
+#else
+ .clk = BL602_PWM_CLK_XCLK,
+#endif
+ .stop_mode = BL602_PWM_STOP_ABRUPT,
+ .pol = BL602_PWM_POL_NORMAL,
+ .clk_div = 0,
+ .period = 100,
+ .threshold1 = 0,
+ .threshold2 = 0,
+ .int_pulse_cnt = 0,
+ };
+
+ pwm_cfg.period = BL_PWM_CLK / freq;
+ pwm_cfg.ch = id;
+
+ pwm_channel_disable(id);
+ pwm_channel_init(id, &pwm_cfg);
+
+ return 0;
+}
+
+/****************************************************************************
+ * Name: bl602_pwm_duty
+ *
+ * Description:
+ * Configure PWM duty
+ *
+ ****************************************************************************/
+
+static int bl602_pwm_duty(FAR struct bl602_pwm_s *priv, uint8_t chan,
+ ub16_t duty)
+{
+ uint16_t period;
+ uint16_t threshold1;
+ uint16_t threshold2;
+ uint32_t tmp_val;
+
+ /* get pwm period and duty */
+
+ tmp_val = getreg32(BL602_PWM_N_THRE1(chan));
+ threshold1 = tmp_val & THRE1_PWM_THRE1_MASK;
+
+ tmp_val = getreg32(BL602_PWM_N_THRE2(chan));
+ threshold2 = tmp_val & THRE2_PWM_THRE2_MASK;
+
+ tmp_val = getreg32(BL602_PWM_N_PERIOD(chan));
+ period = tmp_val & PERIOD_PWM_PERIOD_MASK;
+
+ threshold1 = 0;
+ threshold2 = (uint16_t)((uint32_t)period * duty / 65535);
+
+ putreg32(threshold1, BL602_PWM_N_THRE1(chan));
+ putreg32(threshold2, BL602_PWM_N_THRE2(chan));
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: bl602_pwm_freq
+ *
+ * Description:
+ * Configure PWM frequency
+ *
+ ****************************************************************************/
+
+static int bl602_pwm_freq(FAR struct bl602_pwm_s *priv, uint8_t chan,
+ uint32_t freq)
+{
+ uint16_t period = BL_PWM_CLK / freq;
+ uint16_t threshold1 = 0;
+ uint16_t threshold2 = 0;
+
+ pwm_channel_disable(chan);
+
+ /* Config pwm period and duty */
+
+ putreg32(threshold1, BL602_PWM_N_THRE1(chan));
+ putreg32(threshold2, BL602_PWM_N_THRE2(chan));
+ putreg32(period, BL602_PWM_N_PERIOD(chan));
+
+ pwm_channel_enable(chan);
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: bl602_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 bl602_pwm_setup(FAR struct pwm_lowerhalf_s *dev)
+{
+ int i;
+ int ret = OK;
+ FAR struct bl602_pwm_s *priv = (FAR struct bl602_pwm_s *)dev;
+
+ UNUSED(i);
+
+#ifdef CONFIG_PWM_NCHANNELS
+ for (i = 0; i < CONFIG_PWM_NCHANNELS; i++)
+ {
+ bl602_configgpio(priv->chan_pin[i]);
+ pwm_init(i, BL_PWM_FREQ_DEFAULT);
+ }
+#else
+ bl602_configgpio(priv->chan_pin[0]);
+ pwm_init(0, BL_PWM_FREQ_DEFAULT);
+#endif
+
+ return ret;
+}
+
+/****************************************************************************
+ * Name: bl602_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 bl602_pwm_shutdown(FAR struct pwm_lowerhalf_s *dev)
+{
+ int i;
+ int ret = OK;
+ FAR struct bl602_pwm_s *priv = (FAR struct bl602_pwm_s *)dev;
+
+ UNUSED(i);
+
+#ifdef CONFIG_PWM_NCHANNELS
+ for (i = 0; i < CONFIG_PWM_NCHANNELS; i++)
+ {
+ pwm_channel_disable(priv->chan_pin[i]);
+ bl602_gpio_deinit(i);
+ }
+#else
+ pwm_channel_disable(priv->chan_pin[0]);
+ bl602_gpio_deinit(0);
+#endif
+
+ return ret;
+}
+
+/****************************************************************************
+ * Name: bl602_pwm_start
+ *
+ * Description:
+ * (Re-)initialize the PWM and start the pulsed output
+ *
+ ****************************************************************************/
+
+static int bl602_pwm_start(FAR struct pwm_lowerhalf_s *dev,
+ FAR const struct pwm_info_s *info)
+{
+ FAR struct bl602_pwm_s *priv = (FAR struct bl602_pwm_s *)dev;
+ int ret = OK;
+ int i;
+
+ UNUSED(i);
+
+#ifdef CONFIG_PWM_NCHANNELS
+ for (i = 0; i < CONFIG_PWM_NCHANNELS; i++)
+ {
+ bl602_pwm_freq(priv, i, info->frequency);
+ bl602_pwm_duty(priv, i, info->channels[i].duty);
Review comment:
and PR https://github.com/apache/incubator-nuttx/pull/5093 to use `chan` instead of `i`.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [incubator-nuttx] liangzhanggb commented on a change in pull request #2655: arch/risc-v/bl602 : add pwm onshot watchdog driver.
Posted by GitBox <gi...@apache.org>.
liangzhanggb commented on a change in pull request #2655:
URL: https://github.com/apache/incubator-nuttx/pull/2655#discussion_r551937459
##########
File path: arch/risc-v/src/bl602/Kconfig
##########
@@ -34,4 +34,35 @@ config BL602_TIMER0
config BL602_TIMER1
bool "TIMER1"
+
+config BL602_PWM0
+ bool "PWM0"
+ default y
+ depends on PWM
+ select PWM_MULTICHAN
+
endmenu
+
+config BL602_SPIFLASH
Review comment:
Thank you for your reminder, I will delete it immediately
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [incubator-nuttx] btashton commented on a change in pull request #2655: arch/risc-v/bl602 : add pwm onshot watchdog driver.
Posted by GitBox <gi...@apache.org>.
btashton commented on a change in pull request #2655:
URL: https://github.com/apache/incubator-nuttx/pull/2655#discussion_r552405193
##########
File path: arch/risc-v/src/bl602/bl602_pwm_lowerhalf.c
##########
@@ -0,0 +1,472 @@
+/****************************************************************************
+ * arch/risc-v/src/bl602/bl602_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 <nuttx/config.h>
+
+#include <inttypes.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <arch/board/board.h>
+
+#include "riscv_arch.h"
+#include "riscv_internal.h"
+
+#include "bl602_gpio.h"
+#include "bl602_pwm_lowerhalf.h"
+#include "hardware/bl602_pwm.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define BL_PWM_FREQ_DEFAULT (1000)
+#define BL_PWM_STOP_TIMEOUT_COUNT (160*1000)
+
+#define BL_PWM_XTAL_CLK (40000000)
+#define BL_PWM_BUS_BCLK (80000000)
+
+#ifdef CONFIG_BL602_PWM0_BUS_BCLK_SRC
+#define BL_PWM_CLK BL_PWM_BUS_BCLK
+#else
+#define BL_PWM_CLK BL_PWM_XTAL_CLK
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct bl602_pwm_ch_cfgs
+{
+ int ch; /* PWM channel */
+ int clk; /* PWM Clock */
+ int stop_mode; /* PWM Stop Mode */
+ int pol; /* PWM mode type */
+ uint16_t clk_div; /* PWM clkDiv num */
+ uint16_t period; /* PWM period set */
+ uint16_t threshold1; /* PWM threshold1 num */
+ uint16_t threshold2; /* PWM threshold2 num */
+ uint16_t int_pulse_cnt; /* PWM interrupt pulse count */
+};
+
+struct bl602_pwm_s
+{
+ FAR const struct pwm_ops_s *ops; /* PWM operations */
+ uint32_t frequency; /* Current frequency setting */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* PWM driver methods */
+
+static int bl602_pwm_setup(FAR struct pwm_lowerhalf_s *dev);
+static int bl602_pwm_shutdown(FAR struct pwm_lowerhalf_s *dev);
+static int bl602_pwm_start(FAR struct pwm_lowerhalf_s *dev,
+ FAR const struct pwm_info_s *info);
+static int bl602_pwm_stop(FAR struct pwm_lowerhalf_s *dev);
+static int bl602_pwm_ioctl(FAR 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_bl602_pwmops =
+{
+ .setup = bl602_pwm_setup,
+ .shutdown = bl602_pwm_shutdown,
+ .start = bl602_pwm_start,
+ .stop = bl602_pwm_stop,
+ .ioctl = bl602_pwm_ioctl,
+};
+
+struct bl602_pwm_s g_bl602_pwm0 =
+{
+ .ops = &g_bl602_pwmops,
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static void gpio_deinit(uint8_t pin)
+{
+ bl602_configgpio(GPIO_INPUT | GPIO_FLOAT | pin);
+}
+
+static void pwm_channel_disable(uint8_t ch)
+{
+ modifyreg32(BL602_PWM_N_CONFIG(ch), 0, CONFIG_PWM_STOP_EN);
+ modifyreg32(BL602_PWM_N_CONFIG(ch), INTERRUPT_PWM_INT_ENABLE, 0);
+}
+
+static void pwm_channel_enable(uint8_t ch)
+{
+ modifyreg32(BL602_PWM_N_CONFIG(ch), CONFIG_PWM_STOP_EN, 0);
+}
+
+static void pwm_channel_init(uint8_t ch, struct bl602_pwm_ch_cfgs *ch_cfg)
+{
+ uint32_t tmp_val;
+ uint32_t timeout_cnt = BL_PWM_STOP_TIMEOUT_COUNT;
+
+ /* Config pwm clock and polarity */
+
+ modifyreg32(BL602_PWM_N_CONFIG(ch), 0, CONFIG_PWM_STOP_EN);
+
+ while (!(getreg32(BL602_PWM_N_CONFIG(ch)) & CONFIG_PWM_STS_TOP))
+ {
+ timeout_cnt--;
+ if (timeout_cnt == 0)
+ {
+ return;
+ }
+ }
+
+ tmp_val = getreg32(BL602_PWM_N_CONFIG(ch));
Review comment:
This should probably be a `modifyreg32` so it is atomic. That function also makes it nice for this because you can set all the masks without having do do the bit inversions.
##########
File path: arch/risc-v/src/bl602/bl602_pwm_lowerhalf.c
##########
@@ -0,0 +1,472 @@
+/****************************************************************************
+ * arch/risc-v/src/bl602/bl602_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 <nuttx/config.h>
+
+#include <inttypes.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <arch/board/board.h>
+
+#include "riscv_arch.h"
+#include "riscv_internal.h"
+
+#include "bl602_gpio.h"
+#include "bl602_pwm_lowerhalf.h"
+#include "hardware/bl602_pwm.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define BL_PWM_FREQ_DEFAULT (1000)
+#define BL_PWM_STOP_TIMEOUT_COUNT (160*1000)
+
+#define BL_PWM_XTAL_CLK (40000000)
+#define BL_PWM_BUS_BCLK (80000000)
+
+#ifdef CONFIG_BL602_PWM0_BUS_BCLK_SRC
+#define BL_PWM_CLK BL_PWM_BUS_BCLK
+#else
+#define BL_PWM_CLK BL_PWM_XTAL_CLK
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct bl602_pwm_ch_cfgs
+{
+ int ch; /* PWM channel */
+ int clk; /* PWM Clock */
+ int stop_mode; /* PWM Stop Mode */
+ int pol; /* PWM mode type */
+ uint16_t clk_div; /* PWM clkDiv num */
+ uint16_t period; /* PWM period set */
+ uint16_t threshold1; /* PWM threshold1 num */
+ uint16_t threshold2; /* PWM threshold2 num */
+ uint16_t int_pulse_cnt; /* PWM interrupt pulse count */
+};
+
+struct bl602_pwm_s
+{
+ FAR const struct pwm_ops_s *ops; /* PWM operations */
+ uint32_t frequency; /* Current frequency setting */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* PWM driver methods */
+
+static int bl602_pwm_setup(FAR struct pwm_lowerhalf_s *dev);
+static int bl602_pwm_shutdown(FAR struct pwm_lowerhalf_s *dev);
+static int bl602_pwm_start(FAR struct pwm_lowerhalf_s *dev,
+ FAR const struct pwm_info_s *info);
+static int bl602_pwm_stop(FAR struct pwm_lowerhalf_s *dev);
+static int bl602_pwm_ioctl(FAR 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_bl602_pwmops =
+{
+ .setup = bl602_pwm_setup,
+ .shutdown = bl602_pwm_shutdown,
+ .start = bl602_pwm_start,
+ .stop = bl602_pwm_stop,
+ .ioctl = bl602_pwm_ioctl,
+};
+
+struct bl602_pwm_s g_bl602_pwm0 =
+{
+ .ops = &g_bl602_pwmops,
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static void gpio_deinit(uint8_t pin)
Review comment:
Can you move this to be public in `bl602_gpio` we can use this for other drivers as well.
##########
File path: arch/risc-v/src/bl602/Kconfig
##########
@@ -34,4 +34,11 @@ config BL602_TIMER0
config BL602_TIMER1
bool "TIMER1"
+
+config BL602_PWM0
+ bool "PWM0"
+ default y
+ depends on PWM
+ select PWM_MULTICHAN
Review comment:
`PWM_MULTICHAN` requires that the chip have `ARCH_HAVE_PWM_MULTICHAN`
You can find the right place here `nuttx/arch/risc-v/Kconfig`
##########
File path: arch/risc-v/src/bl602/bl602_tim.c
##########
@@ -39,7 +39,7 @@
static void bl602_wdt_access(void)
{
modifyreg32(BL602_TIMER_WFAR, TIMER_WFAR_MASK, 0xbaba);
- modifyreg32(BL602_TIMER_WFAR, TIMER_WSAR_MASK, 0xeb10);
+ modifyreg32(BL602_TIMER_WSAR, TIMER_WSAR_MASK, 0xeb10);
Review comment:
Good catch sorry I made that mistake.
##########
File path: arch/risc-v/src/bl602/Make.defs
##########
@@ -58,7 +54,12 @@ endif
ifeq ($(CONFIG_ONESHOT),y)
CHIP_CSRCS += bl602_oneshot_lowerhalf.c
endif
-
+ifeq ($(CONFIG_WDOG),y)
Review comment:
Should be `CONFIG_WATCHDOG`
##########
File path: arch/risc-v/src/bl602/bl602_pwm_lowerhalf.c
##########
@@ -0,0 +1,472 @@
+/****************************************************************************
+ * arch/risc-v/src/bl602/bl602_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 <nuttx/config.h>
+
+#include <inttypes.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <arch/board/board.h>
+
+#include "riscv_arch.h"
+#include "riscv_internal.h"
+
+#include "bl602_gpio.h"
+#include "bl602_pwm_lowerhalf.h"
+#include "hardware/bl602_pwm.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define BL_PWM_FREQ_DEFAULT (1000)
+#define BL_PWM_STOP_TIMEOUT_COUNT (160*1000)
+
+#define BL_PWM_XTAL_CLK (40000000)
+#define BL_PWM_BUS_BCLK (80000000)
+
+#ifdef CONFIG_BL602_PWM0_BUS_BCLK_SRC
+#define BL_PWM_CLK BL_PWM_BUS_BCLK
+#else
+#define BL_PWM_CLK BL_PWM_XTAL_CLK
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct bl602_pwm_ch_cfgs
+{
+ int ch; /* PWM channel */
+ int clk; /* PWM Clock */
+ int stop_mode; /* PWM Stop Mode */
+ int pol; /* PWM mode type */
+ uint16_t clk_div; /* PWM clkDiv num */
+ uint16_t period; /* PWM period set */
+ uint16_t threshold1; /* PWM threshold1 num */
+ uint16_t threshold2; /* PWM threshold2 num */
+ uint16_t int_pulse_cnt; /* PWM interrupt pulse count */
+};
+
+struct bl602_pwm_s
+{
+ FAR const struct pwm_ops_s *ops; /* PWM operations */
+ uint32_t frequency; /* Current frequency setting */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* PWM driver methods */
+
+static int bl602_pwm_setup(FAR struct pwm_lowerhalf_s *dev);
+static int bl602_pwm_shutdown(FAR struct pwm_lowerhalf_s *dev);
+static int bl602_pwm_start(FAR struct pwm_lowerhalf_s *dev,
+ FAR const struct pwm_info_s *info);
+static int bl602_pwm_stop(FAR struct pwm_lowerhalf_s *dev);
+static int bl602_pwm_ioctl(FAR 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_bl602_pwmops =
+{
+ .setup = bl602_pwm_setup,
+ .shutdown = bl602_pwm_shutdown,
+ .start = bl602_pwm_start,
+ .stop = bl602_pwm_stop,
+ .ioctl = bl602_pwm_ioctl,
+};
+
+struct bl602_pwm_s g_bl602_pwm0 =
+{
+ .ops = &g_bl602_pwmops,
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static void gpio_deinit(uint8_t pin)
+{
+ bl602_configgpio(GPIO_INPUT | GPIO_FLOAT | pin);
+}
+
+static void pwm_channel_disable(uint8_t ch)
+{
+ modifyreg32(BL602_PWM_N_CONFIG(ch), 0, CONFIG_PWM_STOP_EN);
+ modifyreg32(BL602_PWM_N_CONFIG(ch), INTERRUPT_PWM_INT_ENABLE, 0);
+}
+
+static void pwm_channel_enable(uint8_t ch)
+{
+ modifyreg32(BL602_PWM_N_CONFIG(ch), CONFIG_PWM_STOP_EN, 0);
+}
+
+static void pwm_channel_init(uint8_t ch, struct bl602_pwm_ch_cfgs *ch_cfg)
+{
+ uint32_t tmp_val;
+ uint32_t timeout_cnt = BL_PWM_STOP_TIMEOUT_COUNT;
+
+ /* Config pwm clock and polarity */
+
+ modifyreg32(BL602_PWM_N_CONFIG(ch), 0, CONFIG_PWM_STOP_EN);
+
+ while (!(getreg32(BL602_PWM_N_CONFIG(ch)) & CONFIG_PWM_STS_TOP))
+ {
+ timeout_cnt--;
+ if (timeout_cnt == 0)
+ {
+ return;
+ }
+ }
+
+ tmp_val = getreg32(BL602_PWM_N_CONFIG(ch));
+ tmp_val = (tmp_val & (~CONFIG_REG_CLK_SEL_MASK)) |
+ (CONFIG_REG_CLK_SEL_MASK & ch_cfg->clk);
+ tmp_val = (tmp_val & (~CONFIG_PWM_OUT_INV)) |
+ (1 & ch_cfg->pol);
+ tmp_val = (tmp_val & (~CONFIG_PWM_STOP_MODE)) |
+ (1 & ch_cfg->stop_mode);
+ putreg32(tmp_val, BL602_PWM_N_CONFIG(ch));
+
+ /* Config pwm division */
+
+ putreg32(ch_cfg->clk_div, BL602_PWM_N_CLKDIV(ch));
+
+ /* Config pwm period and duty */
+
+ putreg32(ch_cfg->threshold1, BL602_PWM_N_THRE1(ch));
+ putreg32(ch_cfg->threshold2, BL602_PWM_N_THRE2(ch));
+ putreg32(ch_cfg->period, BL602_PWM_N_PERIOD(ch));
+
+ /* Config interrupt pulse count */
+
+ modifyreg32(BL602_PWM_N_INTERRUPT(ch), 0,
+ (ch_cfg->int_pulse_cnt & PERIOD_PWM_PERIOD_MASK));
+}
+
+static int32_t pwm_init(uint8_t id, uint32_t freq)
+{
+ struct bl602_pwm_ch_cfgs pwm_cfg =
+ {
+ .ch = BL602_PWM_CH0,
+#ifdef CONFIG_BL602_PWM0_BUS_BCLK_SRC
+ .clk = BL602_PWM_CLK_BCLK,
+#else
+ .clk = BL602_PWM_CLK_XCLK,
+#endif
+ .stop_mode = BL602_PWM_STOP_ABRUPT,
+ .pol = BL602_PWM_POL_NORMAL,
+ .clk_div = 0,
+ .period = 100,
+ .threshold1 = 0,
+ .threshold2 = 0,
+ .int_pulse_cnt = 0,
+ };
+
+ pwm_cfg.period = BL_PWM_CLK / freq;
+ pwm_cfg.ch = id;
+
+ pwm_channel_disable(id);
+ pwm_channel_init(id, &pwm_cfg);
+
+ return 0;
+}
+
+/****************************************************************************
+ * Name: bl602_pwm_duty
+ *
+ * Description:
+ * Configure PWM duty
+ *
+ ****************************************************************************/
+
+static int bl602_pwm_duty(FAR struct bl602_pwm_s *priv, uint8_t chan,
+ ub16_t duty)
+{
+ uint16_t period;
+ uint16_t threshold1;
+ uint16_t threshold2;
+ uint32_t tmp_val;
+
+ /* get pwm period and duty */
+
+ tmp_val = getreg32(BL602_PWM_N_THRE1(chan));
+ threshold1 = tmp_val & THRE1_PWM_THRE1_MASK;
+
+ tmp_val = getreg32(BL602_PWM_N_THRE2(chan));
+ threshold2 = tmp_val & THRE2_PWM_THRE2_MASK;
+
+ tmp_val = getreg32(BL602_PWM_N_PERIOD(chan));
+ period = tmp_val & PERIOD_PWM_PERIOD_MASK;
+
+ threshold1 = 0;
+ threshold2 = (uint16_t)((uint32_t)period * duty / 65535);
+
+ putreg32(threshold1, BL602_PWM_N_THRE1(chan));
+ putreg32(threshold2, BL602_PWM_N_THRE2(chan));
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: bl602_pwm_freq
+ *
+ * Description:
+ * Configure PWM frequency
+ *
+ ****************************************************************************/
+
+static int bl602_pwm_freq(FAR struct bl602_pwm_s *priv, uint8_t chan,
+ uint32_t freq)
+{
+ uint16_t period = BL_PWM_CLK / freq;
+ uint16_t threshold1 = 0;
+ uint16_t threshold2 = 0;
+
+ pwm_channel_disable(chan);
+
+ /* Config pwm period and duty */
+
+ putreg32(threshold1, BL602_PWM_N_THRE1(chan));
+ putreg32(threshold2, BL602_PWM_N_THRE2(chan));
+ putreg32(period, BL602_PWM_N_PERIOD(chan));
+
+ pwm_channel_enable(chan);
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: bl602_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 bl602_pwm_setup(FAR struct pwm_lowerhalf_s *dev)
+{
+ int ret = OK;
+
+#ifdef BOARD_PWM_CH0_PIN
+ bl602_configgpio(BOARD_PWM_CH0_PIN);
+ pwm_init(0, BL_PWM_FREQ_DEFAULT);
+#endif
+
+#ifdef BOARD_PWM_CH1_PIN
+ bl602_configgpio(BOARD_PWM_CH1_PIN);
+ pwm_init(1, BL_PWM_FREQ_DEFAULT);
+#endif
+
+#ifdef BOARD_PWM_CH2_PIN
+ bl602_configgpio(BOARD_PWM_CH2_PIN);
+ pwm_init(2, BL_PWM_FREQ_DEFAULT);
+#endif
+
+#ifdef BOARD_PWM_CH3_PIN
+ bl602_configgpio(BOARD_PWM_CH3_PIN);
+ pwm_init(3, BL_PWM_FREQ_DEFAULT);
+#endif
+
+#ifdef BOARD_PWM_CH4_PIN
Review comment:
`_setup` / `_shutdown` / `_stop` should probably only configure the number of channels given in `CONFIG_PWM_NCHANNELS` not just based on the defined `BOARD_PWM_CH`.
##########
File path: arch/risc-v/src/bl602/bl602_start.c
##########
@@ -97,9 +86,7 @@ uint32_t boot2_get_flash_addr(void)
{
Review comment:
I get this warning
```
chip/bl602_start.c: In function 'boot2_get_flash_addr':
chip/bl602_start.c:89:44: warning: array subscript 180 is outside array bounds of 'uint8_t[1]' {aka 'unsigned char[1]'} [-Warray-bounds]
89 | return (uint32_t)(&__boot2_flash_cfg_src + 180);
| ~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~
chip/bl602_start.c:87:18: note: while referencing '__boot2_flash_cfg_src'
87 | extern uint8_t __boot2_flash_cfg_src;
| ^~~~~~~~~~~~~~~~~~~~~
```
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [incubator-nuttx] btashton commented on pull request #2655: arch/risc-v/bl602 : add pwm onshot watchdog driver.
Posted by GitBox <gi...@apache.org>.
btashton commented on pull request #2655:
URL: https://github.com/apache/incubator-nuttx/pull/2655#issuecomment-755944366
LGTM I see a couple other unrelated things for this port in the Kconfigs that I can clean in another PR.
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [incubator-nuttx] btashton commented on pull request #2655: arch/risc-v/bl602 : add pwm onshot watchdog driver.
Posted by GitBox <gi...@apache.org>.
btashton commented on pull request #2655:
URL: https://github.com/apache/incubator-nuttx/pull/2655#issuecomment-755479970
@liangzhanggb One more minor fix that I think will also get the build to pass. I verified your latest changes and they all look good. Thanks.
```c
diff --git a/arch/risc-v/src/bl602/Kconfig b/arch/risc-v/src/bl602/Kconfig
index 9542d0be9c..0c819f95c8 100644
--- a/arch/risc-v/src/bl602/Kconfig
+++ b/arch/risc-v/src/bl602/Kconfig
@@ -13,6 +13,7 @@ config BL602_HAVE_UART0
select ARCH_HAVE_UART0
select UART0_SERIALDRIVER
select ARCH_HAVE_SERIAL_TERMIOS
+ select ARCH_HAVE_PWM_MULTICHAN
config BL602_UART0
bool
@@ -37,6 +38,5 @@ config BL602_TIMER1
config BL602_PWM0
bool "PWM0"
- select ARCH_HAVE_PWM_MULTICHAN
endmenu
diff --git a/boards/risc-v/bl602/bl602evb/configs/timer/defconfig b/boards/risc-v/bl602/bl602evb/configs/timer/defconfig
index 63ef88f96a..94d63251ff 100644
--- a/boards/risc-v/bl602/bl602evb/configs/timer/defconfig
+++ b/boards/risc-v/bl602/bl602evb/configs/timer/defconfig
@@ -55,6 +55,7 @@ CONFIG_ONESHOT=y
CONFIG_PREALLOC_TIMERS=0
CONFIG_PTHREAD_STACK_DEFAULT=8192
CONFIG_PWM=y
+CONFIG_PWM_MULTICHAN=y
CONFIG_PWM_NCHANNELS=2
CONFIG_RAM_SIZE=134217728
CONFIG_RAM_START=0xc0800000
```
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [incubator-nuttx] btashton commented on pull request #2655: arch/risc-v/bl602 : add pwm onshot watchdog driver.
Posted by GitBox <gi...@apache.org>.
btashton commented on pull request #2655:
URL: https://github.com/apache/incubator-nuttx/pull/2655#issuecomment-754765246
@liangzhanggb @xiaoxiang781216 I will review and test this evening. First glace there are some things that need to be moved. The hardware/<ip>.h file should only have register information. I see some structs defined there that should be moved to the driver header in the next level up.
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [incubator-nuttx] liangzhanggb commented on a change in pull request #2655: arch/risc-v/bl602 : add pwm onshot watchdog driver.
Posted by GitBox <gi...@apache.org>.
liangzhanggb commented on a change in pull request #2655:
URL: https://github.com/apache/incubator-nuttx/pull/2655#discussion_r552597398
##########
File path: arch/risc-v/src/bl602/bl602_start.c
##########
@@ -97,9 +86,7 @@ uint32_t boot2_get_flash_addr(void)
{
Review comment:
I have fixed it, Thank you very much
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [incubator-nuttx] liangzhanggb commented on pull request #2655: arch/risc-v/bl602 : add pwm onshot watchdog driver.
Posted by GitBox <gi...@apache.org>.
liangzhanggb commented on pull request #2655:
URL: https://github.com/apache/incubator-nuttx/pull/2655#issuecomment-755111337
> @liangzhanggb @xiaoxiang781216 I will review and test this evening. First glace there are some things that need to be moved. The hardware/.h file should only have register information. I see some structs defined there that should be moved to the driver header in the next level up.
I have fixed it, Thank you very much
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [incubator-nuttx] btashton merged pull request #2655: arch/risc-v/bl602 : add pwm onshot watchdog driver.
Posted by GitBox <gi...@apache.org>.
btashton merged pull request #2655:
URL: https://github.com/apache/incubator-nuttx/pull/2655
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org