/********************************************************************* * INCLUDES */ #include "sdk_common.h" #include "SEGGER_RTT.h" #include "usr_config.h" #include "exception.h" #include "system.h" #include "nrf_gpio.h" #include "bsp_pwm.h" /********************************************************************* * DEFINITIONS */ #define PWM_INSTANCE 0 #define PWM1_INSTANCE 1 /********************************************************************* * LOCAL VARIABLES */ static nrf_drv_pwm_t m_pwm = NRF_DRV_PWM_INSTANCE(PWM_INSTANCE); static nrf_drv_pwm_t m1_pwm = NRF_DRV_PWM_INSTANCE(PWM1_INSTANCE); static nrf_drv_pwm_config_t m_config = { .output_pins = { NRF_DRV_PWM_PIN_NOT_USED, // channel 0 NRF_DRV_PWM_PIN_NOT_USED, // channel 1 NRF_DRV_PWM_PIN_NOT_USED, // channel 2 NRF_DRV_PWM_PIN_NOT_USED // channel 3 }, .irq_priority = PWM0_IRQ_PRIORITY, .base_clock = NRF_PWM_CLK_125kHz, .count_mode = NRF_PWM_MODE_UP, .top_value = 15612, .load_mode = NRF_PWM_LOAD_INDIVIDUAL, .step_mode = NRF_PWM_STEP_AUTO }; static nrf_drv_pwm_config_t m1_config = { .output_pins = { NRF_DRV_PWM_PIN_NOT_USED, // channel 0 NRF_DRV_PWM_PIN_NOT_USED, // channel 1 NRF_DRV_PWM_PIN_NOT_USED, // channel 2 NRF_DRV_PWM_PIN_NOT_USED // channel 3 }, .irq_priority = PWM0_IRQ_PRIORITY, .base_clock = NRF_PWM_CLK_125kHz, .count_mode = NRF_PWM_MODE_UP, .top_value = 15612, .load_mode = NRF_PWM_LOAD_INDIVIDUAL, .step_mode = NRF_PWM_STEP_AUTO }; static nrfx_pwm_handler_t m_pwm_callback = NULL; static nrfx_pwm_handler_t m1_pwm_callback = NULL; static void bsp_pwm_init_process(void) { if(Except_TxError(EXCEPT_PWM_INIT,"bsp_pwm_init_error\r\n") == 0) { Process_Stop(bsp_pwm_init_process); } } static void bsp_pwm1_init_process(void) { if(Except_TxError(EXCEPT_PWM_INIT,"bsp_pwm1_init_error\r\n") == 0) { Process_Stop(bsp_pwm1_init_process); } } /********************************************************************* * LOCAL FUNCTIONS */ /** @brief PWM 初始化 @prama 无 @return 无 */ static void Pwm_init(void) { int ret = 0; ret_code_t errCode; errCode = nrf_drv_pwm_init(&m_pwm, &m_config, m_pwm_callback); if(errCode != NRF_SUCCESS)ret = -1; if(ret == -1) { Process_Start(0,"bsp_pwm_init_process",bsp_pwm_init_process); } } /** @brief PWM 初始化 @prama 无 @return 无 */ static void Pwm1_init(void) { int ret = 0; ret_code_t errCode; errCode = nrf_drv_pwm_init(&m1_pwm, &m1_config, m1_pwm_callback); if(errCode != NRF_SUCCESS)ret = -1; if(ret == -1) { Process_Start(0,"bsp_pwm1_init_process",bsp_pwm1_init_process); } } ///** // @brief PWM 唤醒操作 // @prama t - [in] 唤醒时间 // @return 无 //*/ //static void cb_pwmWakeup(uint32_t t) //{ // Pwm_init(); //} ///** // @brief PWM 睡眠操作 // @prama t - [in] 睡眠时间 // @return 无 //*/ //static void cb_pwmSleep(uint32_t t) //{ // nrfx_pwm_uninit(&m_pwm); //} /** @brief 设置PWM的通道的加载模式 @param load_mode -[in] 加载模式 @return 无 */ static void SetPwm_ChannelsLoadMode(nrf_pwm_dec_load_t load_mode) { m_config.load_mode = load_mode; } /** @brief 设置PWM1的通道的加载模式 @param load_mode -[in] 加载模式 @return 无 */ static void SetPwm1_ChannelsLoadMode(nrf_pwm_dec_load_t load_mode) { m1_config.load_mode = load_mode; } /********************************************************************* * PUBLIC FUNCTIONS */ /** @brief 设置PWM的引脚通道 @param p_pins -[in] 输入的引脚通道 @return 无 */ void SetPwm_Channels(uint32_t channel_1, uint32_t channel_2, uint32_t channel_3, uint32_t channel_4) { m_config.output_pins[0] = channel_1; m_config.output_pins[1] = channel_2; m_config.output_pins[2] = channel_3; m_config.output_pins[3] = channel_4; } /** @brief 设置PWM的中断回调函数 @param pwm_callback -[in] 中断函数的地址 @param irq_priority -[in] 中断函数的优先级 @return 无 */ void SetPwm_IRQ(nrfx_pwm_handler_t pwm_callback, uint8_t irq_priority) { m_pwm_callback = pwm_callback; m_config.irq_priority = irq_priority; } /** @brief 设置PWM的基础时钟 @param clock -[in] 时钟频率 @return 无 */ void SetPwm_BaseClock(nrf_pwm_clk_t clock) { m_config.base_clock = clock; } /** @brief 设置PWM的计数模式 @param count_mode -[in] 计数模式 @return 无 */ void SetPwm_CountMode(nrf_pwm_mode_t count_mode) { m_config.count_mode = count_mode; } /** @brief 设置PWM的最大的占空比阈值 @param Max_duty_cycle_value -[in] 最大的占空比阈值,根据频率决定。 @return 无 */ void SetPwm_DutyCycleThreshold(uint16_t Max_duty_cycle_value) { m_config.top_value = Max_duty_cycle_value; } /** @brief 设置PWM的序列的推进模式,定义下一个cycle的进行方式。 @param step_mode -[in] 推进模式 @return 无 */ void SetPwm_SequenceStepMode(nrf_pwm_dec_step_t step_mode) { m_config.step_mode = step_mode; } /** @brief PWM 的初始化 @param 无 @return 无 */ void Pwm_Initialize(void){ Pwm_init(); } /** @brief PWM 的未初始化 @param 无 @return 无 */ void Pwm_UnInitialize(void) { nrfx_pwm_uninit(&m_pwm); } /** @brief 设置一个独立通道序列 @param p_seqValues -[in] 指向一个独立通道序列 @param seqValues_length - [in] 序列的大小 @param seqValues_repeats -[in] 序列的每个占空比重复的次数 @param seqValues_end_delay - [in] 每个序列中,最后一个占空比重复的次数 @return 无 */ nrf_pwm_sequence_t* Pwm_SetIndSequence(pwm_values_individual_t *p_seqValues, uint16_t seqValues_length, uint32_t seqValues_repeats, uint32_t seqValues_end_delay) { static nrf_pwm_sequence_t m_sequence; if(m_config.load_mode != NRF_PWM_LOAD_INDIVIDUAL) { SetPwm_ChannelsLoadMode(NRF_PWM_LOAD_INDIVIDUAL); Pwm_UnInitialize(); Pwm_Initialize(); } m_sequence.values.p_individual = (nrf_pwm_values_individual_t*)p_seqValues; m_sequence.length = seqValues_length; m_sequence.repeats = seqValues_repeats; m_sequence.end_delay = seqValues_end_delay; return &m_sequence; } /** @brief 设置一个共用通道序列 @param p_seqValues -[in] 指向一个共用通道序列 @param seqValues_length - [in] 序列的大小 @param seqValues_repeats -[in] 序列的每个占空比重复的次数 @param seqValues_end_delay - [in] 每个序列中,最后一个占空比重复的次数 @return 无 */ nrf_pwm_sequence_t* Pwm_SetComSequence(pwm_values_common_t *p_seqValues, uint16_t seqValues_length, uint32_t seqValues_repeats, uint32_t seqValues_end_delay) { static nrf_pwm_sequence_t m_sequence; if(m_config.load_mode != NRF_PWM_LOAD_COMMON) { SetPwm_ChannelsLoadMode(NRF_PWM_LOAD_COMMON); Pwm_UnInitialize(); Pwm_Initialize(); } m_sequence.values.p_common = (nrf_pwm_values_common_t*)p_seqValues; m_sequence.length = seqValues_length; m_sequence.repeats = seqValues_repeats; m_sequence.end_delay = seqValues_end_delay; return &m_sequence; } /** @brief 设置PWM的指定单个序列的播放 @param pwm_sequence -[in] 输入序列的值 @param playback_count -[in] 播放次数 @param flags - [in] 播放模式 @return 错误代码 */ uint32_t SetSimplePwmPlayBack(nrf_pwm_sequence_t *pwm_sequence, uint16_t playback_count, uint32_t flags) { return nrf_drv_pwm_simple_playback(&m_pwm, pwm_sequence, playback_count, flags); } /** @brief 设置PWM的指定多个序列的播放 @param pwm_sequence0 -[in] 输入序列的值 @param pwm_sequence1 -[in] 输入序列的值 @param playback_count -[in] 播放次数 @param flags - [in] 播放模式 @return 错误代码 */ uint32_t SetComplexPwmPlayBack(nrf_pwm_sequence_t *pwm_sequence0, nrf_pwm_sequence_t *pwm_sequence1, uint16_t playback_count, uint32_t flags) { return nrf_drv_pwm_complex_playback(&m_pwm, pwm_sequence0, pwm_sequence1, playback_count, flags); } /****************************************************************************************************************************************************************************/ /** @brief 设置PWM1的引脚通道 @param p_pins -[in] 输入的引脚通道 @return 无 */ void SetPwm1_Channels(uint32_t channel_1, uint32_t channel_2, uint32_t channel_3, uint32_t channel_4) { m1_config.output_pins[0] = channel_1; m1_config.output_pins[1] = channel_2; m1_config.output_pins[2] = channel_3; m1_config.output_pins[3] = channel_4; } /** @brief 设置PWM1的中断回调函数 @param pwm_callback -[in] 中断函数的地址 @param irq_priority -[in] 中断函数的优先级 @return 无 */ void SetPwm1_IRQ(nrfx_pwm_handler_t pwm_callback, uint8_t irq_priority) { m1_pwm_callback = pwm_callback; m1_config.irq_priority = irq_priority; } /** @brief 设置PWM1的基础时钟 @param clock -[in] 时钟频率 @return 无 */ void SetPwm1_BaseClock(nrf_pwm_clk_t clock) { m1_config.base_clock = clock; } /** @brief 设置PWM1的计数模式 @param count_mode -[in] 计数模式 @return 无 */ void SetPwm1_CountMode(nrf_pwm_mode_t count_mode) { m1_config.count_mode = count_mode; } /** @brief 设置PWM1的最大的占空比阈值 @param Max_duty_cycle_value -[in] 最大的占空比阈值,根据频率决定。 @return 无 */ void SetPwm1_DutyCycleThreshold(uint16_t Max_duty_cycle_value) { m1_config.top_value = Max_duty_cycle_value; } /** @brief 设置PWM1的序列的推进模式,定义下一个cycle的进行方式。 @param step_mode -[in] 推进模式 @return 无 */ void SetPwm1_SequenceStepMode(nrf_pwm_dec_step_t step_mode) { m1_config.step_mode = step_mode; } /** @brief PWM1 的初始化 @param 无 @return 无 */ void Pwm1_Initialize(void){ Pwm1_init(); } /** @brief PWM 的未初始化 @param 无 @return 无 */ void Pwm1_UnInitialize(void) { nrfx_pwm_uninit(&m1_pwm); } /** @brief 设置一个独立通道序列 @param p_seqValues -[in] 指向一个独立通道序列 @param seqValues_length - [in] 序列的大小 @param seqValues_repeats -[in] 序列的每个占空比重复的次数 @param seqValues_end_delay - [in] 每个序列中,最后一个占空比重复的次数 @return 无 */ nrf_pwm_sequence_t* Pwm1_SetIndSequence(pwm_values_individual_t *p_seqValues, uint16_t seqValues_length, uint32_t seqValues_repeats, uint32_t seqValues_end_delay) { static nrf_pwm_sequence_t m1_sequence; if(m1_config.load_mode != NRF_PWM_LOAD_INDIVIDUAL) { SetPwm1_ChannelsLoadMode(NRF_PWM_LOAD_INDIVIDUAL); Pwm1_UnInitialize(); Pwm1_Initialize(); } m1_sequence.values.p_individual = (nrf_pwm_values_individual_t*)p_seqValues; m1_sequence.length = seqValues_length; m1_sequence.repeats = seqValues_repeats; m1_sequence.end_delay = seqValues_end_delay; return &m1_sequence; } /** @brief 设置一个共用通道序列 @param p_seqValues -[in] 指向一个共用通道序列 @param seqValues_length - [in] 序列的大小 @param seqValues_repeats -[in] 序列的每个占空比重复的次数 @param seqValues_end_delay - [in] 每个序列中,最后一个占空比重复的次数 @return 无 */ nrf_pwm_sequence_t* Pwm1_SetComSequence(pwm_values_common_t *p_seqValues, uint16_t seqValues_length, uint32_t seqValues_repeats, uint32_t seqValues_end_delay) { static nrf_pwm_sequence_t m1_sequence; if(m1_config.load_mode != NRF_PWM_LOAD_COMMON) { SetPwm1_ChannelsLoadMode(NRF_PWM_LOAD_COMMON); Pwm1_UnInitialize(); Pwm1_Initialize(); } m1_sequence.values.p_common = (nrf_pwm_values_common_t*)p_seqValues; m1_sequence.length = seqValues_length; m1_sequence.repeats = seqValues_repeats; m1_sequence.end_delay = seqValues_end_delay; return &m1_sequence; } /** @brief 设置PWM的指定单个序列的播放 @param pwm_sequence -[in] 输入序列的值 @param playback_count -[in] 播放次数 @param flags - [in] 播放模式 @return 错误代码 */ uint32_t SetSimplePwm1PlayBack(nrf_pwm_sequence_t *pwm_sequence, uint16_t playback_count, uint32_t flags) { return nrf_drv_pwm_simple_playback(&m1_pwm, pwm_sequence, playback_count, flags); } /** @brief 设置PWM的指定多个序列的播放 @param pwm_sequence0 -[in] 输入序列的值 @param pwm_sequence1 -[in] 输入序列的值 @param playback_count -[in] 播放次数 @param flags - [in] 播放模式 @return 错误代码 */ uint32_t SetComplexPwm1PlayBack(nrf_pwm_sequence_t *pwm_sequence0, nrf_pwm_sequence_t *pwm_sequence1, uint16_t playback_count, uint32_t flags) { return nrf_drv_pwm_complex_playback(&m1_pwm, pwm_sequence0, pwm_sequence1, playback_count, flags); }