#include #include #include "nrf_drv_pwm.h" #include "app_util_platform.h" #include "app_timer.h" #include "nrf_drv_clock.h" #include "app_error.h" #include "nrf_log.h" #include "nrf_log_ctrl.h" #include "nrf_log_default_backends.h" #include "xclk.h" #include "nrf_camera.h" static nrf_drv_pwm_t pwm_instance = NRF_DRV_PWM_INSTANCE(0); static void xclk_init(camera_config_t* config) { nrfx_pwm_config_t const pwm_cfg = { .output_pins = { config->pin_xclk | NRF_DRV_PWM_PIN_INVERTED, //将pwm0的通道0映射到引脚17 NRF_DRV_PWM_PIN_NOT_USED, NRF_DRV_PWM_PIN_NOT_USED, NRF_DRV_PWM_PIN_NOT_USED, //其他通道不使用 }, .irq_priority = APP_IRQ_PRIORITY_LOWEST, //设置优先级 .base_clock = NRF_PWM_CLK_16MHz, //设置时钟频率1M .count_mode = NRF_PWM_MODE_UP, //设置向上计数模式 .top_value = 16, //设置top值 .load_mode = NRF_PWM_LOAD_COMMON, //设置装载模式common .step_mode = NRF_PWM_STEP_AUTO //序列周期自动推进 }; return nrfx_pwm_init(&pwm_instance, &pwm_cfg, pwm_handler); } /** * 开启pwm函数 */ static void xclk_play(void) { static nrf_pwm_values_common_t seq0_values = 8; //设置pwm播放设置 nrf_pwm_sequence_t const seq0 = { .values.p_individual = &seq0_values, //指向pwm占空比序列 .length = NRF_PWM_VALUES_LENGTH(seq0_values), //计算pwm包含周期数200 .repeats = 0, //序列中周期重复数为0 .end_delay = 0 //序列后不插入延时 }; //自动触发pwm重新播放 (void)nrfx_pwm_simple_playback(&pwm_instance,&seq0,1,NRFX_PWM_FLAG_LOOP); } static void xclk_stop(void) { nrfx_pwm_stop(&pwm_instance, true); } static void xclk_uninit(void) { nrfx_pwm_uninit(&pwm_instance); } ret_code_t xclk_timer_conf(camera_config_t* config) { ret_code_t err = xclk_init(&timer_conf); if (err != NRF_SUCCESS) { NRF_LOG_INFO("xclk pwm failed for rc=%x", err); } return err; } ret_code_t camera_enable_out_clock(camera_config_t* config) { xclk_play(); return ESP_OK; } void camera_disable_out_clock() { xclk_stop(); }