arch/risc-v/bl602 : add pwm onshot watchdog driver.

This commit is contained in:
liang 2021-01-07 08:49:49 +08:00 committed by Brennan Ashton
parent 84283d0911
commit 2889315c20
17 changed files with 1188 additions and 66 deletions

View File

@ -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
@ -23,7 +24,7 @@ config BL602_HAVE_UART1
select BL602_UART1
select ARCH_HAVE_UART1
select UART1_SERIALDRIVER
select ARCH_HAVE_SERIAL_TERMIOS
select ARCH_HAVE_SERIAL_TERMIOS
config BL602_UART1
bool
@ -34,4 +35,8 @@ config BL602_TIMER0
config BL602_TIMER1
bool "TIMER1"
config BL602_PWM0
bool "PWM0"
endmenu

View File

@ -1,9 +1,6 @@
############################################################################
# arch/risc-v/src/bl602/Make.defs
#
# Copyright (C) 2012, 2015 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# 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
@ -37,7 +34,6 @@ CMN_CSRCS += riscv_releasepending.c riscv_reprioritizertr.c
CMN_CSRCS += riscv_releasestack.c riscv_stackframe.c riscv_schedulesigaction.c
CMN_CSRCS += riscv_sigdeliver.c riscv_udelay.c riscv_unblocktask.c riscv_usestack.c
ifeq ($(CONFIG_STACK_COLORATION),y)
CMN_CSRCS += riscv_checkstack.c
endif
@ -58,7 +54,12 @@ endif
ifeq ($(CONFIG_ONESHOT),y)
CHIP_CSRCS += bl602_oneshot_lowerhalf.c
endif
ifeq ($(CONFIG_WATCHDOG),y)
CHIP_CSRCS += bl602_wdt_lowerhalf.c
endif
ifeq ($(CONFIG_PWM),y)
CHIP_CSRCS += bl602_pwm_lowerhalf.c
endif
CHIP_CSRCS += bl602_glb.c bl602_gpio.c bl602_hbn.c bl602_systemreset.c
# INCLUDES += ${shell $(INCDIR) "$(CC)" $(ARCH_SRCDIR)$(DELIM)chip$(DELIM)hardware}

View File

@ -95,5 +95,12 @@ struct pt_stuff_config_s
uint32_t crc32; /* Entries crc32 */
};
struct boot2_partition_table_s
{
uint8_t partition_active_idx;
uint8_t pad[3];
struct pt_stuff_config_s table;
};
#endif /* __ASSEMBLY__ */
#endif /* __ARCH_RISCV_SRC_BL602_HARDWARE_BL602_BOOT2_H */

View File

@ -132,6 +132,24 @@ int bl602_configgpio(gpio_pinset_t cfgset)
return OK;
}
/****************************************************************************
* Name: bl602_gpio_deinit
*
* Description:
* Deinit a GPIO (Set GPIO to floating input state)
*
* Returned Value:
* OK on success
* ERROR on invalid port.
*
****************************************************************************/
int bl602_gpio_deinit(uint8_t pin)
{
bl602_configgpio(GPIO_INPUT | GPIO_FLOAT | pin);
return OK;
}
/****************************************************************************
* Name: bl602_config_uart_sel
*

View File

@ -71,6 +71,7 @@
#define GPIO_MODE_SHIFT (14) /* Bits 14: Port Mode */
#define GPIO_MODE_MASK (1 << GPIO_MODE_SHIFT)
# define GPIO_INPUT (1 << GPIO_MODE_SHIFT) /* Input Enable */
# define GPIO_OUTPUT (0 << GPIO_MODE_SHIFT) /* Output Enable */
/* Input/output pull-ups/downs:
*
@ -216,6 +217,20 @@ extern "C"
int bl602_configgpio(gpio_pinset_t cfgset);
/****************************************************************************
* Name: bl602_gpio_deinit
*
* Description:
* Deinit a GPIO (Set GPIO to floating input state)
*
* Returned Value:
* OK on success
* ERROR on invalid port.
*
****************************************************************************/
int bl602_gpio_deinit(uint8_t pin);
/****************************************************************************
* Name: bl602_config_uart_sel
*

View File

@ -18,8 +18,8 @@
*
****************************************************************************/
#ifndef __ARCH_ARM_SRC_BL602_ONESHOT_H
#define __ARCH_ARM_SRC_BL602_ONESHOT_H
#ifndef __ARCH_RISCV_SRC_BL602_BL602_ONESHOT_LOWERHALF_H
#define __ARCH_RISCV_SRC_BL602_BL602_ONESHOT_LOWERHALF_H
/****************************************************************************
* Included Files
@ -196,4 +196,4 @@ int bl602_oneshot_cancel(struct bl602_oneshot_s *oneshot,
#endif /* __ASSEMBLY__ */
#endif /* CONFIG_BL602_ONESHOT */
#endif /* __ARCH_ARM_SRC_BL602_ONESHOT_H */
#endif /* __ARCH_RISCV_SRC_BL602_BL602_ONESHOT_LOWERHALF_H */

View File

@ -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);
pwm_channel_enable(i);
}
#else
bl602_pwm_freq(priv, 0, info->frequency);
bl602_pwm_duty(priv, 0, info->duty);
pwm_channel_enable(0);
#endif
return ret;
}
/****************************************************************************
* Name: bl602_pwm_stop
*
* Description:
* Stop the PWM
*
****************************************************************************/
static int bl602_pwm_stop(FAR struct pwm_lowerhalf_s *dev)
{
int i;
FAR struct bl602_pwm_s *priv = (FAR struct bl602_pwm_s *)dev;
UNUSED(priv);
UNUSED(i);
#ifdef CONFIG_PWM_NCHANNELS
for (i = 0; i < CONFIG_PWM_NCHANNELS; i++)
{
pwm_channel_disable(i);
}
#else
pwm_channel_disable(0);
#endif
return OK;
}
/****************************************************************************
* Name: bl602_pwm_ioctl
*
* Description:
* Lower-half logic may support platform-specific ioctl commands
*
****************************************************************************/
static int bl602_pwm_ioctl(FAR struct pwm_lowerhalf_s *dev,
int cmd, unsigned long arg)
{
FAR struct bl602_pwm_s *priv = (FAR struct bl602_pwm_s *)dev;
DEBUGASSERT(dev);
/* There are no platform-specific ioctl commands */
UNUSED(priv);
return -ENOTTY;
}
/****************************************************************************
* Public Function
****************************************************************************/
/****************************************************************************
* Name: bl602_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 BL602 lower half PWM driver is returned.
* NULL is returned on any failure.
*
****************************************************************************/
FAR struct pwm_lowerhalf_s *bl602_pwminitialize(int pwm)
{
struct bl602_pwm_s *lower = NULL;
if (pwm > 0)
{
pwminfo("Initialize PWM%u failed\n", pwm);
return NULL;
}
pwminfo("Initialize PWM%u\n", pwm);
lower = &g_bl602_pwm0;
return (struct pwm_lowerhalf_s *)lower;
}

View File

@ -0,0 +1,55 @@
/****************************************************************************
* arch/risc-v/src/bl602/bl602_pwm_lowerhalf.h
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
#ifndef __ARCH_RISCV_SRC_BL602_BL602_PWM_LOWERHALF_H
#define __ARCH_RISCV_SRC_BL602_BL602_PWM_LOWERHALF_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/timers/pwm.h>
#include "chip.h"
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: bl602_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 BL602 lower half PWM driver is returned.
* NULL is returned on any failure.
*
****************************************************************************/
FAR struct pwm_lowerhalf_s *bl602_pwminitialize(int pwm);
#endif /* __ARCH_RISCV_SRC_BL602_BL602_PWM_LOWERHALF_H */

View File

@ -65,15 +65,11 @@
static uint8_t g_idle_stack[BL602_IDLESTACK_SIZE];
/* Dont change the name of variable, since we refer this
* boot2_partition_table in linker script
* g_boot2_partition_table in linker script
*/
static struct
{
uint8_t partition_active_idx;
uint8_t pad[3];
struct pt_stuff_config_s table;
} boot2_partition_table;
static struct boot2_partition_table_s g_boot2_partition_table \
__attribute__((used));
/****************************************************************************
* Public Data
@ -98,8 +94,8 @@ uint32_t boot2_get_flash_addr(void)
extern uint8_t __boot2_flash_cfg_src;
return (uint32_t)(&__boot2_flash_cfg_src +
(sizeof(boot2_partition_table.table.entries[0]) *
boot2_partition_table.table.table.entry_cnt));
(sizeof(g_boot2_partition_table.table.entries[0]) *
g_boot2_partition_table.table.table.entry_cnt));
}
/****************************************************************************

View File

@ -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);
}
/****************************************************************************

View File

@ -0,0 +1,346 @@
/****************************************************************************
* arch/risc-v/src/bl602/bl602_wdt_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 <nuttx/arch.h>
#include <inttypes.h>
#include <stdint.h>
#include <errno.h>
#include <debug.h>
#include <nuttx/irq.h>
#include <nuttx/clock.h>
#include <nuttx/timers/watchdog.h>
#include <arch/board/board.h>
#include "hardware/bl602_timer.h"
#include "bl602_tim.h"
#include "bl602_wdt_lowerhalf.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define WDT_MAXTIMEOUT (65535)
/****************************************************************************
* Private Types
****************************************************************************/
/* This structure provides the private representation of the "lower-half"
* driver state structure. This structure must be cast-compatible with the
* well-known watchdog_lowerhalf_s structure.
*/
struct bl602_wdt_lowerhalf_s
{
FAR const struct watchdog_ops_s *ops; /* Lower half operations */
uint32_t lastreset; /* The last reset time */
uint32_t timeout;
uint8_t started;
};
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/* "Lower half" driver methods **********************************************/
static int bl602_start(FAR struct watchdog_lowerhalf_s *lower);
static int bl602_stop(FAR struct watchdog_lowerhalf_s *lower);
static int bl602_keepalive(FAR struct watchdog_lowerhalf_s *lower);
static int bl602_getstatus(FAR struct watchdog_lowerhalf_s *lower,
FAR struct watchdog_status_s *status);
static int bl602_settimeout(FAR struct watchdog_lowerhalf_s *lower,
uint32_t timeout);
/****************************************************************************
* Private Data
****************************************************************************/
/* "Lower half" driver methods */
static const struct watchdog_ops_s g_wdtops =
{
.start = bl602_start,
.stop = bl602_stop,
.keepalive = bl602_keepalive,
.getstatus = bl602_getstatus,
.settimeout = bl602_settimeout,
.capture = NULL,
.ioctl = NULL,
};
/* "Lower half" driver state */
static struct bl602_wdt_lowerhalf_s g_wdtdev =
{
.ops = &g_wdtops,
.lastreset = 0,
.started = false,
.timeout = 10000,
};
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: bl602_start
*
* Description:
* Start the watchdog timer, resetting the time to the current timeout,
*
* Input Parameters:
* lower - A pointer the publicly visible representation of the
* "lower-half" driver state structure.
*
* Returned Values:
* Zero on success; a negated errno value on failure.
*
****************************************************************************/
static int bl602_start(FAR struct watchdog_lowerhalf_s *lower)
{
FAR struct bl602_wdt_lowerhalf_s *priv =
(FAR struct bl602_wdt_lowerhalf_s *)lower;
irqstate_t flags;
DEBUGASSERT(priv);
/* Have we already been started? */
if (!priv->started)
{
flags = enter_critical_section();
bl602_wdt_disable();
bl602_wdt_set_clock(TIMER_CLKSRC_32K, 31);
bl602_wdt_setcompvalue(priv->timeout);
bl602_wdt_resetcountervalue();
bl602_wdt_intmask(WDT_INT, 1);
bl602_wdt_enable();
priv->lastreset = clock_systime_ticks();
priv->started = true;
leave_critical_section(flags);
}
return OK;
}
/****************************************************************************
* Name: bl602_stop
*
* Description:
* Stop the watchdog timer
*
* Input Parameters:
* lower - A pointer the publicly visible representation of the
* "lower-half" driver state structure.
*
* Returned Values:
* Zero on success; a negated errno value on failure.
*
****************************************************************************/
static int bl602_stop(FAR struct watchdog_lowerhalf_s *lower)
{
FAR struct bl602_wdt_lowerhalf_s *priv =
(FAR struct bl602_wdt_lowerhalf_s *)lower;
bl602_wdt_disable();
priv->started = false;
return OK;
}
/****************************************************************************
* Name: bl602_keepalive
*
* Description:
* Reset the watchdog timer to the current timeout value, prevent any
* imminent watchdog timeouts. This is sometimes referred as "pinging"
* the watchdog timer or "petting the dog".
*
* Input Parameters:
* lower - A pointer the publicly visible representation of the
* "lower-half" driver state structure.
*
* Returned Values:
* Zero on success; a negated errno value on failure.
*
****************************************************************************/
static int bl602_keepalive(FAR struct watchdog_lowerhalf_s *lower)
{
FAR struct bl602_wdt_lowerhalf_s *priv =
(FAR struct bl602_wdt_lowerhalf_s *)lower;
irqstate_t flags;
/* Reload the WDT timer */
flags = enter_critical_section();
priv->lastreset = clock_systime_ticks();
bl602_wdt_resetcountervalue();
leave_critical_section(flags);
return OK;
}
/****************************************************************************
* Name: bl602_getstatus
*
* Description:
* Get the current watchdog timer status
*
* Input Parameters:
* lower - A pointer the publicly visible representation of
* the "lower-half" driver state structure.
* status - The location to return the watchdog status information.
*
* Returned Values:
* Zero on success; a negated errno value on failure.
*
****************************************************************************/
static int bl602_getstatus(FAR struct watchdog_lowerhalf_s *lower,
FAR struct watchdog_status_s *status)
{
FAR struct bl602_wdt_lowerhalf_s *priv =
(FAR struct bl602_wdt_lowerhalf_s *)lower;
uint32_t ticks;
uint32_t elapsed;
DEBUGASSERT(priv);
/* Return the status bit */
status->flags = WDFLAGS_RESET;
if (priv->started)
{
status->flags |= WDFLAGS_ACTIVE;
}
/* Return the actual timeout in milliseconds */
status->timeout = priv->timeout;
/* Get the elapsed time since the last ping */
ticks = clock_systime_ticks() - priv->lastreset;
elapsed = (int32_t)TICK2MSEC(ticks);
if (elapsed > status->timeout)
{
elapsed = status->timeout;
}
/* Return the approximate time until the watchdog timer expiration */
status->timeleft = status->timeout - elapsed;
return OK;
}
/****************************************************************************
* Name: bl602_settimeout
*
* Description:
* Set a new timeout value (and reset the watchdog timer)
*
* Input Parameters:
* lower - A pointer the publicly visible representation of
* the "lower-half" driver state structure.
* timeout - The new timeout value in milliseconds.
*
* Returned Values:
* Zero on success; a negated errno value on failure.
*
****************************************************************************/
static int bl602_settimeout(FAR struct watchdog_lowerhalf_s *lower,
uint32_t timeout)
{
FAR struct bl602_wdt_lowerhalf_s *priv =
(FAR struct bl602_wdt_lowerhalf_s *)lower;
DEBUGASSERT(priv);
/* Can this timeout be represented? */
if (timeout < 1 || timeout > WDT_MAXTIMEOUT)
{
wderr("ERROR: Cannot represent timeout=%" PRId32 " > %d\n",
timeout, WDT_MAXTIMEOUT);
return -ERANGE;
}
if (priv->started)
{
wdwarn("WARNING: Watchdog is already started\n");
return -EBUSY;
}
priv->timeout = timeout;
return OK;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: bl602_wdt_initialize
*
* Description:
* Initialize the WDT watchdog time. The watchdog timer is initialized and
* registers as 'devpath. The initial state of the watchdog time is
* disabled.
*
* Input Parameters:
* devpath - The full path to the watchdog. This should be of the form
* /dev/watchdog0
* Returned Values:
* Zero (OK) is returned on success; a negated errno value is returned on
* any failure.
*
****************************************************************************/
int bl602_wdt_initialize(FAR const char *devpath)
{
FAR struct bl602_wdt_lowerhalf_s *priv = &g_wdtdev;
FAR void *handle;
/* Register the watchdog driver as /dev/watchdog0 */
handle = watchdog_register(devpath,
(FAR struct watchdog_lowerhalf_s *)priv);
return (handle != NULL) ? OK : -ENODEV;
}

View File

@ -0,0 +1,69 @@
/****************************************************************************
* 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.
*
****************************************************************************/
#ifndef __ARCH_RISCV_SRC_BL602_BL602_WDT_LOWERHALF_H
#define __ARCH_RISCV_SRC_BL602_BL602_WDT_LOWERHALF_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Public Data
****************************************************************************/
#ifdef __cplusplus
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: bl602_wdt_initialize
*
* Description:
* Initialize the WDT watchdog time. The watchdog timer is initialized and
* registers as 'devpath. The initial state of the watchdog time is
* disabled.
*
* Input Parameters:
* devpath - The full path to the watchdog. This should be of the form
* /dev/watchdog0
* Returned Values:
* Zero (OK) is returned on success; a negated errno value is returned on
* any failure.
*
****************************************************************************/
int bl602_wdt_initialize(FAR const char *devpath);
#endif /* __ARCH_RISCV_SRC_BL602_BL602_WDT_LOWERHALF_H */

View File

@ -34,7 +34,7 @@
/* PWM0,1,2,3,4 are the same so create this helper for register offsets */
#define BL602_PWM_N_BASE_OFFSET(n) (BL602_PWM_BASE + (BL602_PWM1_BASE_OFFSET - BL602_PWM0_BASE_OFFSET))
#define BL602_PWM_N_BASE_OFFSET(n) (BL602_PWM_BASE + ((n) * 0x20))
/* Register offsets *********************************************************/
@ -85,59 +85,74 @@
#define BL602_PWM_N_CONFIG(n) (BL602_PWM_N_BASE_OFFSET(n) + BL602_PWM0_CONFIG_OFFSET)
#define BL602_PWM_N_INTERRUPT(n) (BL602_PWM_N_BASE_OFFSET(n) + BL602_PWM0_INTERRUPT_OFFSET)
#define BL602_PWM0_CLKDIV BL602_PWM_N_CLKDIV(0)
#define BL602_PWM0_THRE1 BL602_PWM_N_THRE1(0)
#define BL602_PWM0_THRE2 BL602_PWM_N_THRE2(0)
#define BL602_PWM0_PERIOD BL602_PWM_N_PERIOD(0)
#define BL602_PWM0_CONFIG BL602_PWM_N_CONFIG(0)
#define BL602_PWM0_THRE1 BL602_PWM_N_THRE1(0)
#define BL602_PWM0_THRE2 BL602_PWM_N_THRE2(0)
#define BL602_PWM0_PERIOD BL602_PWM_N_PERIOD(0)
#define BL602_PWM0_CONFIG BL602_PWM_N_CONFIG(0)
#define BL602_PWM0_INTERRUPT BL602_PWM_N_INTERRUPT(0)
#define BL602_PWM1_CLKDIV BL602_PWM_N_CLKDIV(1)
#define BL602_PWM1_THRE1 BL602_PWM_N_THRE1(1)
#define BL602_PWM1_THRE2 BL602_PWM_N_THRE2(1)
#define BL602_PWM1_PERIOD BL602_PWM_N_PERIOD(1)
#define BL602_PWM1_CONFIG BL602_PWM_N_CONFIG(1)
#define BL602_PWM1_THRE1 BL602_PWM_N_THRE1(1)
#define BL602_PWM1_THRE2 BL602_PWM_N_THRE2(1)
#define BL602_PWM1_PERIOD BL602_PWM_N_PERIOD(1)
#define BL602_PWM1_CONFIG BL602_PWM_N_CONFIG(1)
#define BL602_PWM1_INTERRUPT BL602_PWM_N_INTERRUPT(1)
#define BL602_PWM2_CLKDIV BL602_PWM_N_CLKDIV(2)
#define BL602_PWM2_THRE1 BL602_PWM_N_THRE1(2)
#define BL602_PWM2_THRE2 BL602_PWM_N_THRE2(2)
#define BL602_PWM2_PERIOD BL602_PWM_N_PERIOD(2)
#define BL602_PWM2_CONFIG BL602_PWM_N_CONFIG(2)
#define BL602_PWM2_THRE1 BL602_PWM_N_THRE1(2)
#define BL602_PWM2_THRE2 BL602_PWM_N_THRE2(2)
#define BL602_PWM2_PERIOD BL602_PWM_N_PERIOD(2)
#define BL602_PWM2_CONFIG BL602_PWM_N_CONFIG(2)
#define BL602_PWM2_INTERRUPT BL602_PWM_N_INTERRUPT(2)
#define BL602_PWM3_CLKDIV BL602_PWM_N_CLKDIV(3)
#define BL602_PWM3_THRE1 BL602_PWM_N_THRE1(3)
#define BL602_PWM3_THRE2 BL602_PWM_N_THRE2(3)
#define BL602_PWM3_PERIOD BL602_PWM_N_PERIOD(3)
#define BL602_PWM3_CONFIG BL602_PWM_N_CONFIG(3)
#define BL602_PWM3_THRE1 BL602_PWM_N_THRE1(3)
#define BL602_PWM3_THRE2 BL602_PWM_N_THRE2(3)
#define BL602_PWM3_PERIOD BL602_PWM_N_PERIOD(3)
#define BL602_PWM3_CONFIG BL602_PWM_N_CONFIG(3)
#define BL602_PWM3_INTERRUPT BL602_PWM_N_INTERRUPT(3)
#define BL602_PWM4_CLKDIV BL602_PWM_N_CLKDIV(4)
#define BL602_PWM4_THRE1 BL602_PWM_N_THRE1(4)
#define BL602_PWM4_THRE2 BL602_PWM_N_THRE2(4)
#define BL602_PWM4_PERIOD BL602_PWM_N_PERIOD(4)
#define BL602_PWM4_CONFIG BL602_PWM_N_CONFIG(4)
#define BL602_PWM4_THRE1 BL602_PWM_N_THRE1(4)
#define BL602_PWM4_THRE2 BL602_PWM_N_THRE2(4)
#define BL602_PWM4_PERIOD BL602_PWM_N_PERIOD(4)
#define BL602_PWM4_CONFIG BL602_PWM_N_CONFIG(4)
#define BL602_PWM4_INTERRUPT BL602_PWM_N_INTERRUPT(4)
/* Register bit definitions *************************************************/
#define INT_CONFIG_PWM_INT_CLEAR_SHIFT (8)
#define INT_CONFIG_PWM_INT_CLEAR_MASK (0x3f << INT_CONFIG_PWM_INT_CLEAR_SHIFT)
#define INT_CONFIG_PWM_INTERRUPT_STS_MASK (0x3f)
#define INT_CONFIG_PWM_INT_CLEAR_MASK (0x3f << 8)
#define INT_CONFIG_PWM_INTERRUPT_STS_MASK (0x3f)
#define CLKDIV_PWM_CLK_DIV_MASK (0xffff)
#define CLKDIV_PWM_CLK_DIV_MASK (0xffff)
#define THRE1_PWM_THRE1_MASK (0xffff)
#define THRE1_PWM_THRE1_MASK (0xffff)
#define THRE2_PWM_THRE2_MASK (0xffff)
#define THRE2_PWM_THRE2_MASK (0xffff)
#define PERIOD_PWM_PERIOD_MASK (0xffff)
#define PERIOD_PWM_PERIOD_MASK (0xffff)
#define CONFIG_PWM_STS_TOP (1 << 7)
#define CONFIG_PWM_STOP_EN (1 << 6)
#define CONFIG_PWM_SW_MODE (1 << 5)
#define CONFIG_PWM_SW_FORCE_VAL (1 << 4)
#define CONFIG_PWM_STOP_MODE (1 << 3)
#define CONFIG_PWM_OUT_INV (1 << 2)
#define CONFIG_REG_CLK_SEL_MASK (0x03)
#define CONFIG_PWM_STS_TOP (1 << 7)
#define CONFIG_PWM_STOP_EN (1 << 6)
#define CONFIG_PWM_SW_MODE (1 << 5)
#define CONFIG_PWM_SW_FORCE_VAL (1 << 4)
#define CONFIG_PWM_STOP_MODE (1 << 3)
#define CONFIG_PWM_OUT_INV (1 << 2)
#define CONFIG_REG_CLK_SEL_MASK (0x03)
#define INTERRUPT_PWM_INT_ENABLE (1 << 16)
#define INTERRUPT_PWM_INT_PERIOD_CNT_MASK (0xffff)
#define INTERRUPT_PWM_INT_ENABLE (1 << 16)
#define INTERRUPT_PWM_INT_PERIOD_CNT_MASK (0xffff)
#define BL602_PWM_CH0 0 /* PWM Channel 0 */
#define BL602_PWM_CH1 1 /* PWM Channel 1 define */
#define BL602_PWM_CH2 2 /* PWM Channel 2 define */
#define BL602_PWM_CH3 3 /* PWM Channel 3 define */
#define BL602_PWM_CH4 4 /* PWM Channel 4 define */
#define BL602_PWM_CLK_XCLK 0 /* PWM Clock source :XTAL */
#define BL602_PWM_CLK_BCLK 1 /* PWM Clock source :Bus */
#define BL602_PWM_CLK_32K 2 /* PWM Clock source :32K */
#define BL602_PWM_STOP_ABRUPT 0 /* PWM stop abrupt */
#define BL602_PWM_STOP_GRACEFUL 1 /* PWM stop graceful */
#define BL602_PWM_POL_NORMAL 0 /* PWM normal polarity */
#define BL602_PWM_POL_INVERT 1 /* PWM invert polarity */
#endif /* __ARCH_RISCV_SRC_BL602_HARDWARE_BL602_PWM_H */

View File

@ -0,0 +1,85 @@
#
# 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_NSH_DISABLEBG is not set
# CONFIG_NSH_DISABLE_LOSMART is not set
# CONFIG_NSH_DISABLE_UNAME is not set
CONFIG_ARCH="risc-v"
CONFIG_ARCH_BOARD="bl602evb"
CONFIG_ARCH_BOARD_BL602EVB=y
CONFIG_ARCH_CHIP="bl602"
CONFIG_ARCH_CHIP_BL602=y
CONFIG_ARCH_INTERRUPTSTACK=8192
CONFIG_ARCH_RISCV=y
CONFIG_ARCH_STACKDUMP=y
CONFIG_BINFMT_DISABLE=y
CONFIG_BL602_HAVE_UART0=y
CONFIG_BL602_TIMER0=y
CONFIG_BL602_TIMER1=y
CONFIG_BOARD_LOOPSPERMSEC=10000
CONFIG_BUILTIN=y
CONFIG_DEBUG_FEATURES=y
CONFIG_DEBUG_FULLOPT=y
CONFIG_DEBUG_SYMBOLS=y
CONFIG_DEFAULT_SMALL=y
CONFIG_DEV_ZERO=y
CONFIG_DISABLE_MQUEUE=y
CONFIG_EXAMPLES_HELLO=y
CONFIG_EXAMPLES_HELLO_STACKSIZE=8192
CONFIG_EXAMPLES_PWM=y
CONFIG_EXAMPLES_TIMER=y
CONFIG_EXAMPLES_WATCHDOG=y
CONFIG_FS_PROCFS=y
CONFIG_IDLETHREAD_STACKSIZE=8192
CONFIG_INTELHEX_BINARY=y
CONFIG_LIBC_PERROR_STDOUT=y
CONFIG_LIBC_STRERROR=y
CONFIG_MAX_TASKS=8
CONFIG_NFILE_DESCRIPTORS=6
CONFIG_NSH_ARCHINIT=y
CONFIG_NSH_BUILTIN_APPS=y
CONFIG_NSH_DISABLE_CD=y
CONFIG_NSH_DISABLE_CP=y
CONFIG_NSH_DISABLE_IFUPDOWN=y
CONFIG_NSH_DISABLE_MKDIR=y
CONFIG_NSH_DISABLE_RM=y
CONFIG_NSH_DISABLE_RMDIR=y
CONFIG_NSH_DISABLE_UMOUNT=y
CONFIG_NSH_FILEIOSIZE=64
CONFIG_NSH_STRERROR=y
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
CONFIG_RAW_BINARY=y
CONFIG_RR_INTERVAL=200
CONFIG_RV32IM_CUSTOM_IRQ_SUPPORT=y
CONFIG_SCHED_CPULOAD=y
CONFIG_SCHED_CPULOAD_EXTCLK=y
CONFIG_SCHED_WAITPID=y
CONFIG_STACK_COLORATION=y
CONFIG_START_DAY=20
CONFIG_START_MONTH=3
CONFIG_START_YEAR=2020
CONFIG_STDIO_DISABLE_BUFFERING=y
CONFIG_SYSTEM_NSH=y
CONFIG_TASK_NAME_SIZE=12
CONFIG_TASK_SPAWN_DEFAULT_STACKSIZE=8192
CONFIG_TESTING_GETPRIME=y
CONFIG_TIMER=y
CONFIG_TIMER_ARCH=y
CONFIG_UART0_BAUD=2000000
CONFIG_UART0_RXBUFSIZE=128
CONFIG_UART0_SERIAL_CONSOLE=y
CONFIG_UART0_TXBUFSIZE=128
CONFIG_USERMAIN_STACKSIZE=8192
CONFIG_USER_ENTRYPOINT="nsh_main"
CONFIG_WATCHDOG=y

View File

@ -40,6 +40,14 @@
#define BOARD_UART_1_RX_PIN (GPIO_INPUT | GPIO_PULLUP | GPIO_FUNC_UART | GPIO_PIN3)
#define BOARD_UART_1_TX_PIN (GPIO_INPUT | GPIO_PULLUP | GPIO_FUNC_UART | GPIO_PIN4)
/* PWM Configuration */
#define BOARD_PWM_CH0_PIN (GPIO_OUTPUT | GPIO_PULLDOWN | GPIO_FUNC_PWM | GPIO_PIN0)
#define BOARD_PWM_CH1_PIN (GPIO_OUTPUT | GPIO_PULLDOWN | GPIO_FUNC_PWM | GPIO_PIN1)
#define BOARD_PWM_CH2_PIN (GPIO_OUTPUT | GPIO_PULLDOWN | GPIO_FUNC_PWM | GPIO_PIN2)
#define BOARD_PWM_CH3_PIN (GPIO_OUTPUT | GPIO_PULLDOWN | GPIO_FUNC_PWM | GPIO_PIN3)
#define BOARD_PWM_CH4_PIN (GPIO_OUTPUT | GPIO_PULLDOWN | GPIO_FUNC_PWM | GPIO_PIN4)
/****************************************************************************
* Public Types
****************************************************************************/

View File

@ -100,7 +100,7 @@ SECTIONS
*(.srodata.cst4)
*(.srodata.cst2)
*(.srodata .srodata.*)
. = ALIGN(8);
*(._k_queue.static.*)
*(._k_sem.static.*)
@ -117,14 +117,13 @@ SECTIONS
.boot2 (NOLOAD) :
{
PROVIDE ( __boot2_pt_addr_start = . );
*(.bss.boot2_partition_table)
PROVIDE ( __boot2_pt_addr_end = . );
PROVIDE ( __boot2_flash_cfg_start = . );
*(.bss.boot2_flashCfg)
PROVIDE ( __boot2_flash_cfg_end = . );
PROVIDE ( __boot2_pt_addr_start = . );
*(.bss.g_boot2_partition_table)
PROVIDE ( __boot2_pt_addr_end = . );
PROVIDE ( __boot2_flash_cfg_start = . );
*(.bss.g_bl602_romflash_cfg)
PROVIDE ( __boot2_flash_cfg_end = . );
} > ram_tcm
.bss (NOLOAD) :
@ -154,8 +153,8 @@ SECTIONS
/*CFG FW used in code*/
PROVIDE( _ld_bl_static_cfg_entry_start = _bl_static_fw_cfg_entry_start );
PROVIDE( _ld_bl_static_cfg_entry_end = _bl_static_fw_cfg_entry_end );
/*BOOT2 sections*/
PROVIDE ( __boot2_pt_addr_src = BOOT2_PT_ADDR );
PROVIDE ( __boot2_flash_cfg_src = BOOT2_FLASHCFG_ADDR );
PROVIDE ( __boot2_flash_cfg_src = BOOT2_FLASHCFG_ADDR );
}

View File

@ -35,6 +35,8 @@
#include <nuttx/input/buttons.h>
#include <bl602_tim_lowerhalf.h>
#include <bl602_oneshot_lowerhalf.h>
#include <bl602_pwm_lowerhalf.h>
#include <bl602_wdt_lowerhalf.h>
#include "chip.h"
@ -109,5 +111,33 @@ int bl602_bringup(void)
#endif
#endif
#ifdef CONFIG_PWM
struct pwm_lowerhalf_s *pwm;
/* Initialize PWM and register the PWM driver. */
pwm = bl602_pwminitialize(0);
if (pwm == NULL)
{
syslog(LOG_ERR, "ERROR: bl602_pwminitialize failed\n");
}
else
{
ret = pwm_register("/dev/pwm0", pwm);
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: pwm_register failed: %d\n", ret);
}
}
#endif
#ifdef CONFIG_WATCHDOG
ret = bl602_wdt_initialize(CONFIG_WATCHDOG_DEVPATH);
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: bl602_wdt_initialize failed: %d\n", ret);
}
#endif
return ret;
}