/*********************************************************************
 * 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

/*********************************************************************
 * LOCAL VARIABLES
 */
static nrf_drv_pwm_t m_pwm = NRF_DRV_PWM_INSTANCE(PWM_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 nrfx_pwm_handler_t m_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);
	}
}

/*********************************************************************
 * 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,"pwm_init",bsp_pwm_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;
}
/*********************************************************************
 * 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);
}

