88 lines
2.5 KiB
C
88 lines
2.5 KiB
C
/**
|
||
* Copyright (c) @CompanyNameMagicTag 2023-2023. All rights reserved. \n
|
||
*
|
||
* Description: Provides iot_pwm driver source \n
|
||
* Author: @CompanyNameTag \n
|
||
* History: \n
|
||
* 2023-10-18, Create file. \n
|
||
*/
|
||
#include "common_def.h"
|
||
#include "iot_errno.h"
|
||
#include "pwm.h"
|
||
#include "iot_pwm.h"
|
||
|
||
#define IOT_PWM_MIN_DUTY 0
|
||
#define IOT_PWM_MAX_DUTY 100
|
||
#define IOT_PWM_DUTY_PART 10
|
||
#define IOT_PWM_FREQ_PART 2
|
||
#define IOT_PWM_MAX_DIV_NUM_MAX 8
|
||
#define IOT_PWM_CFG_OFFEST_TIME 0
|
||
#define IOT_PWM_CFG_REPEAT_CYCLE 100
|
||
#define IOT_PWM_CFG_REPEAT_STATE true
|
||
|
||
static bool g_iot_pwm_inited = false;
|
||
|
||
unsigned int IoTPwmInit(unsigned int port)
|
||
{
|
||
unused(port);
|
||
if (!g_iot_pwm_inited) {
|
||
uapi_pwm_init();
|
||
}
|
||
g_iot_pwm_inited = true;
|
||
return IOT_SUCCESS;
|
||
}
|
||
|
||
unsigned int IoTPwmDeinit(unsigned int port)
|
||
{
|
||
unused(port);
|
||
if (g_iot_pwm_inited) {
|
||
uapi_pwm_deinit();
|
||
}
|
||
g_iot_pwm_inited = false;
|
||
return IOT_SUCCESS;
|
||
}
|
||
|
||
unsigned int IoTPwmStart(unsigned int port, unsigned short duty, unsigned int freq)
|
||
{
|
||
if ((duty >= IOT_PWM_MAX_DUTY) || (duty == IOT_PWM_MIN_DUTY)) {
|
||
return IOT_FAILURE;
|
||
}
|
||
|
||
uint32_t clk_freq = uapi_pwm_get_frequency((uint8_t)port);
|
||
uint32_t div_num = (clk_freq + freq / IOT_PWM_FREQ_PART) / freq; // 计算分频数
|
||
if (div_num < IOT_PWM_MAX_DIV_NUM_MAX) {
|
||
return IOT_FAILURE;
|
||
}
|
||
uint32_t high_time = div_num * duty / IOT_PWM_MAX_DUTY; // 计算高电平时钟个数(向下取整)
|
||
if (high_time * IOT_PWM_MAX_DUTY / div_num >= (uint32_t)(duty - duty * IOT_PWM_DUTY_PART / IOT_PWM_MAX_DUTY)) {
|
||
} else if ((high_time + 1) * IOT_PWM_MAX_DUTY / div_num <=
|
||
(uint32_t)(duty + duty * IOT_PWM_DUTY_PART / IOT_PWM_MAX_DUTY)) {
|
||
high_time++;
|
||
} else {
|
||
return IOT_FAILURE;
|
||
}
|
||
uint32_t low_time = div_num - high_time;
|
||
pwm_config_t cfg = {
|
||
.low_time = low_time,
|
||
.high_time = high_time,
|
||
.offset_time = IOT_PWM_CFG_OFFEST_TIME,
|
||
.cycles = IOT_PWM_CFG_REPEAT_CYCLE,
|
||
.repeat = IOT_PWM_CFG_REPEAT_STATE
|
||
};
|
||
if (uapi_pwm_open((uint8_t)port, &cfg) != ERRCODE_SUCC) {
|
||
return IOT_FAILURE;
|
||
}
|
||
|
||
if (uapi_pwm_start((uint8_t)port) != ERRCODE_SUCC) {
|
||
return IOT_FAILURE;
|
||
}
|
||
return IOT_SUCCESS;
|
||
}
|
||
|
||
unsigned int IoTPwmStop(unsigned int port)
|
||
{
|
||
if (uapi_pwm_close((uint8_t)port) != ERRCODE_SUCC) {
|
||
return IOT_FAILURE;
|
||
}
|
||
return IOT_SUCCESS;
|
||
} |