summaryrefslogtreecommitdiff
path: root/bsp
diff options
context:
space:
mode:
authorsupperthomas <[email protected]>2020-08-01 15:54:31 +0800
committersupperthomas <[email protected]>2020-08-01 20:17:55 +0800
commit58b05abc91b28f2e523c8c9e9cf8ff4940c0b4b4 (patch)
tree527bc50068898420b3cf71ac468f9030f83c149c /bsp
parente22bbf975e46b714b597fa0c69f06eae4cc6826e (diff)
[bsp/nrf5x]: add the driver of pwm
Diffstat (limited to 'bsp')
-rw-r--r--bsp/nrf5x/libraries/drivers/SConscript4
-rw-r--r--bsp/nrf5x/libraries/drivers/drv_pwm.c432
-rw-r--r--bsp/nrf5x/nrf52840/board/Kconfig146
3 files changed, 564 insertions, 18 deletions
diff --git a/bsp/nrf5x/libraries/drivers/SConscript b/bsp/nrf5x/libraries/drivers/SConscript
index 6bbdffce07..b446b7c3b4 100644
--- a/bsp/nrf5x/libraries/drivers/SConscript
+++ b/bsp/nrf5x/libraries/drivers/SConscript
@@ -19,8 +19,12 @@ if GetDepend(['BSP_USING_QSPI_FLASH']):
if GetDepend(['BSP_USING_SPI']):
src += ['drv_spi.c']
+
if GetDepend(['BSP_USING_GPIO']):
src += ['drv_gpio.c']
+
+if GetDepend(['BSP_USING_PWM']):
+ src += ['drv_pwm.c']
path = [cwd]
diff --git a/bsp/nrf5x/libraries/drivers/drv_pwm.c b/bsp/nrf5x/libraries/drivers/drv_pwm.c
new file mode 100644
index 0000000000..4d7c036ce5
--- /dev/null
+++ b/bsp/nrf5x/libraries/drivers/drv_pwm.c
@@ -0,0 +1,432 @@
+/*
+ * Copyright (c) 2006-2020, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-07-26 supperthomas first version
+ *
+ */
+
+
+#include <board.h>
+#include "rtdevice.h"
+#include "rtservice.h"
+
+#ifdef RT_USING_PWM
+
+#include <nrfx_pwm.h>
+
+struct mcu_pwm
+{
+ struct rt_device_pwm pwm_device;
+
+ nrfx_pwm_t *pwm_handle;
+ nrf_pwm_values_individual_t m_demo1_seq_values;
+ nrf_pwm_sequence_t m_demo1_seq;
+
+ rt_uint8_t channel;
+ char *name;
+ rt_uint64_t pwm_src_clk;
+ uint8_t channel_0_pin;
+ uint8_t channel_1_pin;
+ uint8_t channel_2_pin;
+ uint8_t channel_3_pin;
+};
+
+enum
+{
+#ifdef BSP_USING_PWM0
+ PWM0_INDEX,
+#endif
+#ifdef BSP_USING_PWM1
+ PWM1_INDEX,
+#endif
+#ifdef BSP_USING_PWM2
+ PWM2_INDEX,
+#endif
+#ifdef BSP_USING_PWM3
+ PWM3_INDEX,
+#endif
+};
+#ifdef BSP_USING_PWM0
+static nrfx_pwm_t m_pwm0 = NRFX_PWM_INSTANCE(0);
+#define PWM0_CONFIG \
+ { \
+ .pwm_handle = &m_pwm0, \
+ .name = "pwm0", \
+ .pwm_src_clk = 1000000, \
+ }
+#endif
+
+#ifdef BSP_USING_PWM1
+static nrfx_pwm_t m_pwm1 = NRFX_PWM_INSTANCE(1);
+#define PWM1_CONFIG \
+ { \
+ .pwm_handle = &m_pwm1, \
+ .name = "pwm1", \
+ .pwm_src_clk = 1000000, \
+ }
+#endif
+
+#ifdef BSP_USING_PWM2
+static nrfx_pwm_t m_pwm2 = NRFX_PWM_INSTANCE(2);
+#define PWM2_CONFIG \
+ { \
+ .pwm_handle = &m_pwm2, \
+ .name = "pwm2", \
+ .pwm_src_clk = 1000000, \
+ }
+#endif
+
+#ifdef BSP_USING_PWM3
+static nrfx_pwm_t m_pwm3 = NRFX_PWM_INSTANCE(3);
+#define PWM3_CONFIG \
+ { \
+ .pwm_handle = &m_pwm3, \
+ .name = "pwm3", \
+ .pwm_src_clk = 1000000, \
+ }
+#endif
+
+static struct mcu_pwm mcu_pwm_obj[] =
+{
+#ifdef BSP_USING_PWM0
+ PWM0_CONFIG,
+#endif
+#ifdef BSP_USING_PWM1
+ PWM1_CONFIG,
+#endif
+
+#ifdef BSP_USING_PWM2
+ PWM2_CONFIG,
+#endif
+
+#ifdef BSP_USING_PWM3
+ PWM3_CONFIG,
+#endif
+};
+
+static rt_err_t drv_pwm_control(struct rt_device_pwm *device, int cmd, void *arg);
+static struct rt_pwm_ops drv_ops =
+{
+ drv_pwm_control
+};
+
+static rt_err_t drv_pwm_enable(struct mcu_pwm *p_mcu, struct rt_pwm_configuration *configuration, rt_bool_t enable)
+{
+ if (!enable)
+ {
+ nrfx_pwm_stop(p_mcu->pwm_handle, true);
+ }
+ else
+ {
+ (void)nrfx_pwm_simple_playback(p_mcu->pwm_handle, &p_mcu->m_demo1_seq, 1, NRFX_PWM_FLAG_LOOP);
+ }
+
+ return RT_EOK;
+}
+
+uint8_t mcu_get_channel_number(uint8_t channel)
+{
+ if (channel & 0x01)
+ {
+ return 0;
+ }
+ else if (channel & 0x02)
+ {
+ return 1;
+ }
+ else if (channel & 0x04)
+ {
+ return 2;
+ }
+ else if (channel & 0x08)
+ {
+ return 3;
+ }
+ return 0;
+}
+
+static rt_err_t drv_pwm_get(struct mcu_pwm *pwm_handle, struct rt_pwm_configuration *configuration)
+{
+ rt_uint8_t channel_number = mcu_get_channel_number(configuration->channel);
+ uint8_t tick_pscond;
+
+ tick_pscond = pwm_handle->pwm_src_clk / 1000000UL;
+ configuration->period = pwm_handle->pwm_handle->p_registers->COUNTERTOP * 1000UL / tick_pscond;
+ configuration->pulse = pwm_handle->pwm_handle->p_registers->SEQ[channel_number].PTR / tick_pscond;
+
+ return RT_EOK;
+}
+
+static void nrfx_set_prioid(nrfx_pwm_t *pwm_handle, uint32_t perioid)
+{
+ pwm_handle->p_registers->COUNTERTOP = perioid;
+}
+
+static rt_err_t drv_pwm_set(struct mcu_pwm *p_mcu, struct rt_pwm_configuration *configuration)
+{
+ rt_uint32_t period, pulse;
+ uint8_t tick_pscond;
+ tick_pscond = p_mcu->pwm_src_clk / 1000000UL;
+
+ p_mcu->pwm_handle->p_registers->COUNTERTOP = (unsigned long long)configuration->period * tick_pscond;
+ if (configuration->channel & 0x01)
+ {
+ p_mcu->m_demo1_seq_values.channel_0 = configuration->pulse;
+ }
+
+ if (configuration->channel & 0x02)
+ {
+ p_mcu->m_demo1_seq_values.channel_1 = configuration->pulse;
+ }
+
+ if (configuration->channel & 0x04)
+ {
+ p_mcu->m_demo1_seq_values.channel_2 = configuration->pulse;
+ }
+
+ if (configuration->channel & 0x08)
+ {
+ p_mcu->m_demo1_seq_values.channel_3 = configuration->pulse;
+ }
+ return RT_EOK;
+}
+
+static rt_err_t drv_pwm_control(struct rt_device_pwm *device, int cmd, void *arg)
+{
+ struct rt_pwm_configuration *configuration = (struct rt_pwm_configuration *)arg;
+ void *pwm_handle = (void *)device->parent.user_data;
+ nrfx_pwm_t *p_handle = (nrfx_pwm_t *)pwm_handle;
+ struct mcu_pwm *p_mcu = rt_container_of(p_handle, struct mcu_pwm, pwm_handle);
+ switch (cmd)
+ {
+ case PWM_CMD_ENABLE:
+ return drv_pwm_enable(p_mcu, configuration, RT_TRUE);
+ case PWM_CMD_DISABLE:
+ return drv_pwm_enable(p_mcu, configuration, RT_FALSE);
+ case PWM_CMD_SET:
+ return drv_pwm_set(p_mcu, configuration);
+ case PWM_CMD_GET:
+ return drv_pwm_get(p_mcu, configuration);
+ default:
+ return RT_EINVAL;
+ }
+}
+
+static rt_err_t mcu_hw_pwm_init(struct mcu_pwm *device)
+{
+#define NRFX_PWM_PIN_INVERTED 0x80
+#define _PRIO_APP_LOWEST 7
+ nrfx_pwm_config_t config0 =
+ {
+ .irq_priority = _PRIO_APP_LOWEST,
+ .base_clock = NRF_PWM_CLK_1MHz, //default value
+ .count_mode = NRF_PWM_MODE_UP,
+ .top_value = 5000, //default vaule
+ .load_mode = NRF_PWM_LOAD_INDIVIDUAL,
+ .step_mode = NRF_PWM_STEP_AUTO
+ };
+ rt_err_t result = RT_EOK;
+ if (device->pwm_src_clk == 1000000)
+ {
+ config0.base_clock = NRF_PWM_CLK_1MHz;
+ }
+ else if (device->pwm_src_clk == 2000000)
+ {
+ config0.base_clock = NRF_PWM_CLK_2MHz;
+ }
+ else if (device->pwm_src_clk == 8000000)
+ {
+ config0.base_clock = NRF_PWM_CLK_8MHz;
+ }
+ else
+ {
+ config0.base_clock = NRF_PWM_CLK_1MHz;
+ }
+
+ if (device->channel & 0x01)
+ {
+ config0.output_pins[0] = device->channel_0_pin | NRFX_PWM_PIN_INVERTED;
+ }
+
+ if (device->channel & 0x02)
+ {
+ config0.output_pins[1] = device->channel_1_pin | NRFX_PWM_PIN_INVERTED;
+ }
+
+ if (device->channel & 0x04)
+ {
+ config0.output_pins[2] = device->channel_2_pin | NRFX_PWM_PIN_INVERTED;
+ }
+
+ if (device->channel & 0x08)
+ {
+ config0.output_pins[3] = device->channel_3_pin | NRFX_PWM_PIN_INVERTED;
+ }
+ device->m_demo1_seq.values.p_individual = &device->m_demo1_seq_values;
+ device->m_demo1_seq.length = NRF_PWM_VALUES_LENGTH(device->m_demo1_seq_values),
+ nrfx_pwm_init(device->pwm_handle, &config0, NULL, NULL);
+ return result;
+}
+
+static void pwm_get_channel(void)
+{
+#ifdef BSP_USING_PWM0_CH0
+ mcu_pwm_obj[PWM0_INDEX].channel |= 1 << 0;
+ mcu_pwm_obj[PWM0_INDEX].channel_0_pin = BSP_USING_PWM0_CH0;
+#endif
+#ifdef BSP_USING_PWM0_CH1
+ mcu_pwm_obj[PWM0_INDEX].channel |= 1 << 1;
+ mcu_pwm_obj[PWM0_INDEX].channel_1_pin = BSP_USING_PWM0_CH1;
+#endif
+#ifdef BSP_USING_PWM0_CH2
+ mcu_pwm_obj[PWM0_INDEX].channel |= 1 << 2;
+ mcu_pwm_obj[PWM0_INDEX].channel_2_pin = BSP_USING_PWM0_CH2;
+#endif
+#ifdef BSP_USING_PWM0_CH3
+ mcu_pwm_obj[PWM0_INDEX].channel |= 1 << 3;
+ mcu_pwm_obj[PWM0_INDEX].channel_3_pin = BSP_USING_PWM0_CH3;
+#endif
+#ifdef BSP_USING_PWM1_CH0
+ mcu_pwm_obj[PWM1_INDEX].channel |= 1 << 0;
+ mcu_pwm_obj[PWM1_INDEX].channel_0_pin = BSP_USING_PWM1_CH0;
+#endif
+#ifdef BSP_USING_PWM1_CH1
+ mcu_pwm_obj[PWM1_INDEX].channel |= 1 << 1;
+ mcu_pwm_obj[PWM1_INDEX].channel_1_pin = BSP_USING_PWM1_CH1;
+#endif
+#ifdef BSP_USING_PWM1_CH2
+ mcu_pwm_obj[PWM1_INDEX].channel |= 1 << 2;
+ mcu_pwm_obj[PWM1_INDEX].channel_2_pin = BSP_USING_PWM1_CH2;
+#endif
+#ifdef BSP_USING_PWM1_CH3
+ mcu_pwm_obj[PWM1_INDEX].channel |= 1 << 3;
+ mcu_pwm_obj[PWM1_INDEX].channel_3_pin = BSP_USING_PWM1_CH3;
+#endif
+#ifdef BSP_USING_PWM2_CH0
+ mcu_pwm_obj[PWM2_INDEX].channel |= 1 << 0;
+ mcu_pwm_obj[PWM2_INDEX].channel_0_pin = BSP_USING_PWM2_CH0;
+#endif
+#ifdef BSP_USING_PWM2_CH1
+ mcu_pwm_obj[PWM2_INDEX].channel |= 1 << 1;
+ mcu_pwm_obj[PWM2_INDEX].channel_1_pin = BSP_USING_PWM2_CH1;
+#endif
+#ifdef BSP_USING_PWM2_CH2
+ mcu_pwm_obj[PWM2_INDEX].channel |= 1 << 2;
+ mcu_pwm_obj[PWM2_INDEX].channel_2_pin = BSP_USING_PWM2_CH2;
+#endif
+#ifdef BSP_USING_PWM2_CH3
+ mcu_pwm_obj[PWM2_INDEX].channel |= 1 << 3;
+ mcu_pwm_obj[PWM2_INDEX].channel_3_pin = BSP_USING_PWM2_CH3;
+#endif
+#ifdef BSP_USING_PWM3_CH0
+ mcu_pwm_obj[PWM3_INDEX].channel |= 1 << 0;
+ mcu_pwm_obj[PWM3_INDEX].channel_0_pin = BSP_USING_PWM3_CH0;
+#endif
+#ifdef BSP_USING_PWM3_CH1
+ mcu_pwm_obj[PWM3_INDEX].channel |= 1 << 1;
+ mcu_pwm_obj[PWM3_INDEX].channel_1_pin = BSP_USING_PWM3_CH1;
+#endif
+#ifdef BSP_USING_PWM3_CH2
+ mcu_pwm_obj[PWM3_INDEX].channel |= 1 << 2;
+ mcu_pwm_obj[PWM3_INDEX].channel_2_pin = BSP_USING_PWM3_CH2;
+#endif
+#ifdef BSP_USING_PWM3_CH3
+ mcu_pwm_obj[PWM3_INDEX].channel |= 1 << 3;
+ mcu_pwm_obj[PWM3_INDEX].channel_3_pin = BSP_USING_PWM3_CH3;
+#endif
+}
+
+static int mcu_pwm_init(void)
+{
+ int i = 0;
+ int result = RT_EOK;
+
+ pwm_get_channel();
+ for (i = 0; i < sizeof(mcu_pwm_obj) / sizeof(mcu_pwm_obj[0]); i++)
+ {
+ /* pwm init */
+ if (mcu_hw_pwm_init(&mcu_pwm_obj[i]) != RT_EOK)
+ {
+ rt_kprintf("\r\n %s init failed", mcu_pwm_obj[i].name);
+ result = -RT_ERROR;
+ goto __exit;
+ }
+ else
+ {
+ rt_kprintf("\r\n %s init success", mcu_pwm_obj[i].name);
+
+ /* register pwm device */
+ if (rt_device_pwm_register(&mcu_pwm_obj[i].pwm_device, mcu_pwm_obj[i].name, &drv_ops, &mcu_pwm_obj[i].pwm_handle) == RT_EOK)
+ {
+ rt_kprintf("\r\n %s register success", mcu_pwm_obj[i].name);
+ }
+ else
+ {
+ rt_kprintf("\r\n %s register failed", mcu_pwm_obj[i].name);
+ result = -RT_ERROR;
+ }
+ }
+ }
+__exit:
+ return result;
+}
+INIT_DEVICE_EXPORT(mcu_pwm_init);
+
+
+
+/* test example */
+#define PWM_DEV_NAME "pwm0" /* PWM name*/
+#define PWM_DEV_CHANNEL 15 /* PWM channel */
+
+struct rt_device_pwm *pwm_dev;
+
+static int pwm_led_sample(int argc, char *argv[])
+{
+ rt_uint32_t period, pulse, dir;
+
+ period = 50000; /* 50ms*/
+ dir = 1;
+ pulse = 0;
+
+
+ pwm_dev = (struct rt_device_pwm *)rt_device_find(PWM_DEV_NAME);
+ if (pwm_dev == RT_NULL)
+ {
+ rt_kprintf("pwm sample run failed! can't find %s device!\n", PWM_DEV_NAME);
+ return RT_ERROR;
+ }
+
+ rt_pwm_set(pwm_dev, PWM_DEV_CHANNEL, period, pulse);
+ rt_pwm_enable(pwm_dev, PWM_DEV_CHANNEL);
+
+ while (1)
+ {
+ rt_thread_mdelay(50);
+ if (dir)
+ {
+ pulse += 500;
+ }
+ else
+ {
+ pulse -= 500;
+ }
+ if (pulse >= period)
+ {
+ dir = 0;
+ }
+ if (0 == pulse)
+ {
+ dir = 1;
+ }
+
+
+ rt_pwm_set(pwm_dev, PWM_DEV_CHANNEL, period, pulse);
+ }
+}
+MSH_CMD_EXPORT(pwm_led_sample, pwm sample);
+
+#endif \ No newline at end of file
diff --git a/bsp/nrf5x/nrf52840/board/Kconfig b/bsp/nrf5x/nrf52840/board/Kconfig
index 9f95a9177e..1bf97f6e4d 100644
--- a/bsp/nrf5x/nrf52840/board/Kconfig
+++ b/bsp/nrf5x/nrf52840/board/Kconfig
@@ -7,6 +7,12 @@ config SOC_NRF52840
select RT_USING_USER_MAIN
default y
+config SOC_NORDIC
+ bool
+ config SOC_NORDIC
+ default y
+
+
menu "Onboard Peripheral Drivers"
config BSP_USING_JLINK_TO_USART
bool "Enable JLINK TO USART (uart0|RX_PIN:8|TX_PIN:6)"
@@ -55,38 +61,142 @@ menu "On-chip Peripheral Drivers"
bool "Enable GPIO"
select RT_USING_PIN
default y
+ menuconfig BSP_USING_PWM
+ bool "Enable PWM"
+ select RT_USING_PWM
+ default n
+ if BSP_USING_PWM
+ config NRFX_PWM_ENABLED
+ int
+ default 1
+ config BSP_USING_PWM0
+ bool "Enable PWM0 bus"
+ default y
+ if BSP_USING_PWM0
+ config NRFX_PWM0_ENABLED
+ int
+ default 1
+ config BSP_USING_PWM0_CH0
+ int "PWM0 channel 0 pin number set"
+ range 0 47
+ default 13
+ config BSP_USING_PWM0_CH1
+ int "PWM0 channel 1 pin number set"
+ range 0 47
+ default 14
+ config BSP_USING_PWM0_CH2
+ int "PWM0 channel 2 pin number set"
+ range 0 47
+ default 15
+ config BSP_USING_PWM0_CH3
+ int "PWM0 channel 3 pin number set"
+ range 0 47
+ default 16
+ endif
+ config BSP_USING_PWM1
+ bool "Enable PWM1 bus"
+ default n
+ if BSP_USING_PWM1
+ config NRFX_PWM1_ENABLED
+ int
+ default 1
+ config BSP_USING_PWM1_CH0
+ int "PWM1 channel 0 pin number set"
+ range 0 47
+ default 13
+ config BSP_USING_PWM1_CH1
+ int "PWM1 channel 1 pin number set"
+ range 0 47
+ default 14
+ config BSP_USING_PWM1_CH2
+ int "PWM1 channel 2 pin number set"
+ range 0 47
+ default 15
+ config BSP_USING_PWM1_CH3
+ int "PWM1 channel 3 pin number set"
+ range 0 47
+ default 16
+ endif
+ config BSP_USING_PWM2
+ bool "Enable PWM2 bus"
+ default n
+ if BSP_USING_PWM2
+ config NRFX_PWM2_ENABLED
+ int
+ default 1
+ config BSP_USING_PWM2_CH0
+ int "PWM2 channel 0 pin number set"
+ range 0 47
+ default 13
+ config BSP_USING_PWM2_CH1
+ int "PWM2 channel 1 pin number set"
+ range 0 47
+ default 14
+ config BSP_USING_PWM2_CH2
+ int "PWM2 channel 2 pin number set"
+ range 0 47
+ default 15
+ config BSP_USING_PWM2_CH3
+ int "PWM2 channel 3 pin number set"
+ range 0 47
+ default 16
+ endif
+ config BSP_USING_PWM3
+ bool "Enable PWM3 bus"
+ default n
+ if BSP_USING_PWM3
+ config NRFX_PWM3_ENABLED
+ int
+ default 1
+ config BSP_USING_PWM3_CH0
+ int "PWM3 channel 0 pin number set"
+ range 0 47
+ default 13
+ config BSP_USING_PWM3_CH1
+ int "PWM3 channel 1 pin number set"
+ range 0 47
+ default 14
+ config BSP_USING_PWM3_CH2
+ int "PWM3 channel 2 pin number set"
+ range 0 47
+ default 15
+ config BSP_USING_PWM3_CH3
+ int "PWM3 channel 3 pin number set"
+ range 0 47
+ default 16
+ endif
+ endif
menuconfig BSP_USING_SOFTDEVICE
bool "Enable NRF SOFTDEVICE"
select PKG_USING_NRF5X_SDK
+ select NRFX_CLOCK_ENABLED
default n
if BSP_USING_SOFTDEVICE
config NRFX_CLOCK_ENABLED
- int "NRFX_CLOCK_ENABLED"
+ int
default 1
- config NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY
- int "NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY"
+ config NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY
+ int
default 7
- config NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY
- int "NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY"
- default 7
- config NRFX_RTC_ENABLED
- int "NRFX_RTC_ENABLED"
+ config NRFX_RTC_ENABLED
+ int
+ default 1
+ config NRFX_RTC1_ENABLED
+ int
default 1
- config NRF_CLOCK_ENABLED
- int "NRF_CLOCK_ENABLED"
+ config NRF_CLOCK_ENABLED
+ int
default 1
- config NRF_SDH_BLE_ENABLED
- int "NRF_SDH_BLE_ENABLED"
+ config NRF_SDH_BLE_ENABLED
+ int
default 1
- config NRF_SDH_ENABLED
- int "NRF_SDH_ENABLED"
+ config NRF_SDH_ENABLED
+ int
default 1
- config NRF_SDH_SOC_ENABLED
- int "NRF_SDH_SOC_ENABLED"
+ config NRF_SDH_SOC_ENABLED
+ int
default 1
-
endif
-
menuconfig BSP_USING_UART
bool "Enable UART"
default y