904 lines
21 KiB
C
904 lines
21 KiB
C
/****************************************************************************
|
|
|
|
Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
|
|
|
|
This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
|
|
be copied by any method or incorporated into another program without
|
|
the express written consent of Aerospace C.Power. This Information or any portion
|
|
thereof remains the property of Aerospace C.Power. The Information contained herein
|
|
is believed to be accurate and Aerospace C.Power assumes no responsibility or
|
|
liability for its use in any way and conveys no license or title under
|
|
any patent or copyright and makes no representation or warranty that this
|
|
Information is free from patent or copyright infringement.
|
|
|
|
****************************************************************************/
|
|
/* os shim includes */
|
|
#include "os_types.h"
|
|
#include "ledc.h"
|
|
#include "ledc_reg.h"
|
|
#include "iot_errno.h"
|
|
#include "iot_oem.h"
|
|
#include "apb.h"
|
|
#include "gpio_mtx.h"
|
|
#include "chip_reg_base.h"
|
|
#include "hw_reg_api.h"
|
|
#include "ledc_hw.h"
|
|
#include "board_info_hw.h"
|
|
#include "iot_io_api.h"
|
|
#include "iot_irq.h"
|
|
#include "ledc_hw.h"
|
|
|
|
#define LEDC_ADDR_MAP(port, reg) (((port % 4) << 5) | 0x200 | (reg))
|
|
#define TIMER_ADDR_MAP(port, reg) (((port % 4) << 4) | 0x600 | (reg))
|
|
#define LEDC_PORT_INVALID(port) ((port) >= LEDC_PORT_MAX ? 1:0)
|
|
#define COMMON_TIMER_SEL_INVALID(port) ((port) >= COMMON_TIMER_SEL_MAX ? 1:0)
|
|
|
|
static ledc_interrrupt_cb_typedef g_ledc_cbs[LEDC_PORT_MAX] = {0, 0, 0, 0, 0, 0, 0, 0};
|
|
|
|
uint32_t ledc_read_reg(LEDC_PORT port, uint32_t addr)
|
|
{
|
|
if (port >= LEDC_PORT_4 ) {
|
|
return (uint32_t)LEDC1_READ_REG(addr);
|
|
} else {
|
|
return (uint32_t)LEDC0_READ_REG(addr);
|
|
}
|
|
}
|
|
|
|
void ledc_write_reg(LEDC_PORT port, uint32_t addr, uint32_t data)
|
|
{
|
|
if (port >= LEDC_PORT_4 ) {
|
|
LEDC1_WRITE_REG(addr, data);
|
|
} else {
|
|
LEDC0_WRITE_REG(addr, data);
|
|
}
|
|
}
|
|
|
|
static uint32_t ledc_hw_read_reg(LEDC_PORT port, uint32_t reg)
|
|
{
|
|
uint32_t addr;
|
|
|
|
if (LEDC_PORT_INVALID(port)) {
|
|
return 0;
|
|
}
|
|
|
|
addr = LEDC_ADDR_MAP(port, reg);
|
|
|
|
return (uint32_t)ledc_read_reg(port, addr);
|
|
}
|
|
|
|
static void ledc_hw_write_reg(LEDC_PORT port, uint32_t reg, uint32_t data)
|
|
{
|
|
uint32_t addr;
|
|
|
|
if (LEDC_PORT_INVALID(port)) {
|
|
return ;
|
|
}
|
|
|
|
addr = LEDC_ADDR_MAP(port, reg);
|
|
|
|
ledc_write_reg(port, addr, data);
|
|
}
|
|
|
|
static uint32_t timer_hw_read_reg(LEDC_PORT port, uint32_t reg)
|
|
{
|
|
uint32_t addr;
|
|
|
|
if (LEDC_PORT_INVALID(port)) {
|
|
return 0;
|
|
}
|
|
|
|
addr = TIMER_ADDR_MAP(port, reg);
|
|
|
|
return (uint32_t)ledc_read_reg(port, addr);
|
|
}
|
|
|
|
void timer_hw_write_reg(LEDC_PORT port, uint32_t reg, uint32_t data)
|
|
{
|
|
uint32_t addr;
|
|
|
|
if (LEDC_PORT_INVALID(port)) {
|
|
return ;
|
|
}
|
|
|
|
addr = TIMER_ADDR_MAP(port, reg);
|
|
|
|
ledc_write_reg(port, addr, data);
|
|
}
|
|
|
|
void ledc_ena_rst(void)
|
|
{
|
|
apb_enable(APB_LEDC);
|
|
apb_enable(APB_LEDC1);
|
|
}
|
|
|
|
void ledc_gpio_config(LEDC_PORT port, uint8_t gpio)
|
|
{
|
|
if (LEDC_PORT_INVALID(port)) {
|
|
return ;
|
|
}
|
|
|
|
gpio_sig_info_t info = {0};
|
|
uint8_t index = 0;
|
|
|
|
info.CFG[0].outid = SIG_OUT_LED0 + port;
|
|
|
|
if(gpio != 0xff) {
|
|
info.CFG[index].type = IO_TYPE_OUT;
|
|
info.CFG[index].func = gpio_pin_func_get(gpio);
|
|
info.CFG[index].gpio = gpio;
|
|
info.CFG[index].inid = 0xff;
|
|
}
|
|
index++;
|
|
|
|
info.sig_type = index;
|
|
|
|
gpio_mtx_enable();
|
|
gpio_module_pin_select(&info);
|
|
gpio_module_sig_select(&info, GPIO_MTX_MODE_MATRIX);
|
|
}
|
|
|
|
void ledc_timer_rst(LEDC_PORT port)
|
|
{
|
|
uint32_t tmp;
|
|
|
|
if (LEDC_PORT_INVALID(port)) {
|
|
return ;
|
|
}
|
|
|
|
tmp = timer_hw_read_reg(port, CFG_LEDC_TIMER0_CONF_ADDR);
|
|
REG_FIELD_SET(LEDC_TIMER0_RST, tmp, 1);
|
|
timer_hw_write_reg(port, CFG_LEDC_TIMER0_CONF_ADDR, tmp);
|
|
REG_FIELD_SET(LEDC_TIMER0_RST, tmp, 0);
|
|
timer_hw_write_reg(port, CFG_LEDC_TIMER0_CONF_ADDR, tmp);
|
|
}
|
|
|
|
void ledc_timer_init(LEDC_PORT port, uint16_t div)
|
|
{
|
|
uint32_t tmp;
|
|
|
|
if (LEDC_PORT_INVALID(port)) {
|
|
return ;
|
|
}
|
|
|
|
tmp = timer_hw_read_reg(port, CFG_LEDC_TIMER0_CONF_ADDR);
|
|
REG_FIELD_SET(LEDC_TIMER0_DIV, tmp, div);
|
|
timer_hw_write_reg(port, CFG_LEDC_TIMER0_CONF_ADDR, tmp);
|
|
}
|
|
|
|
void ledc_timer_ctrl(LEDC_PORT port, uint8_t status)
|
|
{
|
|
uint32_t tmp;
|
|
|
|
if (LEDC_PORT_INVALID(port)) {
|
|
return ;
|
|
}
|
|
|
|
tmp = timer_hw_read_reg(port, CFG_LEDC_TIMER0_CONF_ADDR);
|
|
if(0 == status) {
|
|
REG_FIELD_SET(LEDC_TIMER0_START, tmp, 0);
|
|
REG_FIELD_SET(LEDC_TIMER0_PAUSE, tmp, 1);
|
|
} else {
|
|
REG_FIELD_SET(LEDC_TIMER0_START, tmp, 1);
|
|
REG_FIELD_SET(LEDC_TIMER0_PAUSE, tmp, 0);
|
|
}
|
|
|
|
timer_hw_write_reg(port, CFG_LEDC_TIMER0_CONF_ADDR, tmp);
|
|
}
|
|
|
|
void ledc_polarity_sel(LEDC_PORT port, uint8_t polarity)
|
|
{
|
|
uint32_t tmp;
|
|
|
|
if (LEDC_PORT_INVALID(port)) {
|
|
return ;
|
|
}
|
|
|
|
tmp = ledc_hw_read_reg(port, CFG_LEDC0_CONF_ADDR);
|
|
REG_FIELD_SET(LEDC0_OUT_INV, tmp, polarity);
|
|
ledc_hw_write_reg(port, CFG_LEDC0_CONF_ADDR, tmp);
|
|
}
|
|
|
|
void ledc_idle_level_sel(LEDC_PORT port, uint8_t level)
|
|
{
|
|
uint32_t tmp;
|
|
|
|
if (LEDC_PORT_INVALID(port)) {
|
|
return ;
|
|
}
|
|
|
|
tmp = ledc_hw_read_reg(port, CFG_LEDC0_CONF_ADDR);
|
|
REG_FIELD_SET(LEDC0_IDLE_LV, tmp, level);
|
|
ledc_hw_write_reg(port, CFG_LEDC0_CONF_ADDR, tmp);
|
|
}
|
|
|
|
void ledc_phase1_blink_times_set(LEDC_PORT port, uint16_t times)
|
|
{
|
|
uint32_t tmp;
|
|
|
|
if (LEDC_PORT_INVALID(port)) {
|
|
return ;
|
|
}
|
|
|
|
tmp = ledc_hw_read_reg(port, CFG_LEDC0_DUTY_CONF3_ADDR);
|
|
REG_FIELD_SET(LEDC0_DUTY_NUM, tmp, times);
|
|
ledc_hw_write_reg(port, CFG_LEDC0_DUTY_CONF3_ADDR, tmp);
|
|
|
|
}
|
|
|
|
void ledc_phase2_blink_times_set(LEDC_PORT port, uint16_t times)
|
|
{
|
|
uint32_t tmp;
|
|
|
|
if (LEDC_PORT_INVALID(port)) {
|
|
return ;
|
|
}
|
|
|
|
tmp = ledc_hw_read_reg(port, CFG_LEDC0_DUTY_CONF3_ADDR);
|
|
REG_FIELD_SET(LEDC0_DUTY_PHASE_NUM, tmp, times);
|
|
ledc_hw_write_reg(port, CFG_LEDC0_DUTY_CONF3_ADDR, tmp);
|
|
|
|
}
|
|
|
|
void ledc_h2l_point_set(LEDC_PORT port, uint16_t point)
|
|
{
|
|
uint32_t tmp;
|
|
|
|
if (LEDC_PORT_INVALID(port)) {
|
|
return ;
|
|
}
|
|
|
|
tmp = ledc_hw_read_reg(port, CFG_LEDC0_DUTY_CONF0_ADDR);
|
|
REG_FIELD_SET(LEDC0_DUTY_H2L_POINT, tmp, point);
|
|
ledc_hw_write_reg(port, CFG_LEDC0_DUTY_CONF0_ADDR, tmp);
|
|
}
|
|
|
|
void ledc_l2h_point_set(LEDC_PORT port, uint16_t point)
|
|
{
|
|
uint32_t tmp;
|
|
|
|
if (LEDC_PORT_INVALID(port)) {
|
|
return ;
|
|
}
|
|
|
|
tmp = ledc_hw_read_reg(port, CFG_LEDC0_DUTY_CONF0_ADDR);
|
|
REG_FIELD_SET(LEDC0_DUTY_L2H_POINT, tmp, point);
|
|
ledc_hw_write_reg(port, CFG_LEDC0_DUTY_CONF0_ADDR, tmp);
|
|
}
|
|
|
|
void ledc_duty_cnt_sel(LEDC_PORT port, uint8_t duty_cnt)
|
|
{
|
|
uint32_t tmp;
|
|
|
|
if (LEDC_PORT_INVALID(port)) {
|
|
return ;
|
|
}
|
|
|
|
tmp = ledc_hw_read_reg(port, CFG_LEDC0_DUTY_CONF1_ADDR);
|
|
REG_FIELD_SET(LEDC0_DUTY_CNT_SEL, tmp, duty_cnt);
|
|
ledc_hw_write_reg(port, CFG_LEDC0_DUTY_CONF1_ADDR, tmp);
|
|
}
|
|
|
|
void ledc_cnt_ena(LEDC_PORT port, uint8_t en)
|
|
{
|
|
uint32_t tmp;
|
|
|
|
if (LEDC_PORT_INVALID(port)) {
|
|
return ;
|
|
}
|
|
|
|
tmp = ledc_hw_read_reg(port, CFG_LEDC0_DUTY_CONF1_ADDR);
|
|
REG_FIELD_SET(LEDC0_DUTY_ENA, tmp, en);
|
|
ledc_hw_write_reg(port, CFG_LEDC0_DUTY_CONF1_ADDR, tmp);
|
|
}
|
|
|
|
void ledc_thrs_set(LEDC_PORT port, uint16_t thrs)
|
|
{
|
|
uint32_t tmp;
|
|
|
|
if (LEDC_PORT_INVALID(port)) {
|
|
return ;
|
|
}
|
|
|
|
tmp = ledc_hw_read_reg(port, CFG_LEDC0_DUTY_CONF1_ADDR);
|
|
REG_FIELD_SET(LEDC0_DUTY_THRS, tmp, thrs);
|
|
ledc_hw_write_reg(port, CFG_LEDC0_DUTY_CONF1_ADDR, tmp);
|
|
}
|
|
|
|
void ledc_phase_opt_sel(LEDC_PORT port, uint8_t opt)
|
|
{
|
|
uint32_t tmp;
|
|
|
|
if (LEDC_PORT_INVALID(port)) {
|
|
return ;
|
|
}
|
|
|
|
tmp = ledc_hw_read_reg(port, CFG_LEDC0_DUTY_CONF5_ADDR);
|
|
REG_FIELD_SET(LEDC0_DUTY_PHASE_OPT, tmp, opt);
|
|
ledc_hw_write_reg(port, CFG_LEDC0_DUTY_CONF5_ADDR, tmp);
|
|
}
|
|
|
|
void ledc_phase_num_sel(LEDC_PORT port, uint8_t num)
|
|
{
|
|
uint32_t tmp;
|
|
|
|
if (LEDC_PORT_INVALID(port)) {
|
|
return ;
|
|
}
|
|
|
|
tmp = ledc_hw_read_reg(port, CFG_LEDC0_DUTY_CONF5_ADDR);
|
|
REG_FIELD_SET(LEDC0_DUTY_PHASE_MODE_NUM, tmp, num);
|
|
ledc_hw_write_reg(port, CFG_LEDC0_DUTY_CONF5_ADDR, tmp);
|
|
}
|
|
|
|
void ledc_phase1_mode_sel(LEDC_PORT port, uint8_t mode)
|
|
{
|
|
uint32_t tmp;
|
|
|
|
if (LEDC_PORT_INVALID(port)) {
|
|
return ;
|
|
}
|
|
|
|
tmp = ledc_hw_read_reg(port, CFG_LEDC0_DUTY_CONF5_ADDR);
|
|
tmp &= ~0x03000000;
|
|
tmp |= (mode << LEDC0_DUTY_PHASE_MODE_OFFSET);
|
|
ledc_hw_write_reg(port, CFG_LEDC0_DUTY_CONF5_ADDR, tmp);
|
|
}
|
|
|
|
void ledc_phase2_mode_sel(LEDC_PORT port, uint8_t mode)
|
|
{
|
|
uint32_t tmp;
|
|
|
|
if (LEDC_PORT_INVALID(port)) {
|
|
return ;
|
|
}
|
|
|
|
tmp = ledc_hw_read_reg(port, CFG_LEDC0_DUTY_CONF5_ADDR);
|
|
|
|
tmp &= ~0x0c000000;
|
|
tmp |= (mode << (LEDC0_DUTY_PHASE_MODE_OFFSET + 2));
|
|
ledc_hw_write_reg(port, CFG_LEDC0_DUTY_CONF5_ADDR, tmp);
|
|
}
|
|
|
|
void ledc_phase1_scale_set(LEDC_PORT port, uint8_t scale)
|
|
{
|
|
uint32_t tmp;
|
|
|
|
if (LEDC_PORT_INVALID(port)) {
|
|
return ;
|
|
}
|
|
|
|
tmp = ledc_hw_read_reg(port, CFG_LEDC0_DUTY_CONF1_ADDR);
|
|
REG_FIELD_SET(LEDC0_DUTY_SCALE, tmp, scale);
|
|
ledc_hw_write_reg(port, CFG_LEDC0_DUTY_CONF1_ADDR, tmp);
|
|
}
|
|
|
|
void ledc_phase2_scale_set(LEDC_PORT port, uint8_t scale)
|
|
{
|
|
uint32_t tmp;
|
|
|
|
if (LEDC_PORT_INVALID(port)) {
|
|
return ;
|
|
}
|
|
|
|
tmp = ledc_hw_read_reg(port, CFG_LEDC0_DUTY_CONF5_ADDR);
|
|
REG_FIELD_SET(LEDC0_DUTY_PHASE_SCALE, tmp, scale);
|
|
ledc_hw_write_reg(port, CFG_LEDC0_DUTY_CONF5_ADDR, tmp);
|
|
}
|
|
|
|
void ledc_cycle_times_set(LEDC_PORT port, uint8_t times)
|
|
{
|
|
uint32_t tmp;
|
|
|
|
if (LEDC_PORT_INVALID(port)) {
|
|
return ;
|
|
}
|
|
|
|
tmp = ledc_hw_read_reg(port, CFG_LEDC0_DUTY_CONF4_ADDR);
|
|
REG_FIELD_SET(LEDC0_DUTY_CYCLE_NUM, tmp, times);
|
|
ledc_hw_write_reg(port, CFG_LEDC0_DUTY_CONF4_ADDR, tmp);
|
|
}
|
|
|
|
void ledc_loop_times_set(LEDC_PORT port, uint8_t times)
|
|
{
|
|
uint32_t tmp;
|
|
|
|
if (LEDC_PORT_INVALID(port)) {
|
|
return ;
|
|
}
|
|
|
|
tmp = ledc_hw_read_reg(port, CFG_LEDC0_DUTY_CONF4_ADDR);
|
|
REG_FIELD_SET(LEDC0_DUTY_LOOP_NUM, tmp, times);
|
|
ledc_hw_write_reg(port, CFG_LEDC0_DUTY_CONF4_ADDR, tmp);
|
|
}
|
|
|
|
void ledc_nop_num_set(LEDC_PORT port, uint16_t num)
|
|
{
|
|
uint32_t tmp;
|
|
|
|
if (LEDC_PORT_INVALID(port)) {
|
|
return ;
|
|
}
|
|
|
|
tmp = ledc_hw_read_reg(port, CFG_LEDC0_DUTY_CONF4_ADDR);
|
|
REG_FIELD_SET(LEDC0_DUTY_NOP_NUM, tmp, num);
|
|
ledc_hw_write_reg(port, CFG_LEDC0_DUTY_CONF4_ADDR, tmp);
|
|
}
|
|
|
|
void ledc_common_cnt_ena(uint8_t en)
|
|
{
|
|
uint32_t tmp;
|
|
|
|
tmp = LEDC0_READ_REG(CFG_LEDC_COMMON_DUTY_CNT_ADDR);
|
|
REG_FIELD_SET(LEDC_COMMON_DUTY_CNT_ENA, tmp, en);
|
|
LEDC0_WRITE_REG(CFG_LEDC_COMMON_DUTY_CNT_ADDR, tmp);
|
|
}
|
|
|
|
void ledc_common_thrs_set(uint16_t thrs)
|
|
{
|
|
uint32_t tmp;
|
|
|
|
tmp = LEDC0_READ_REG(CFG_LEDC_COMMON_DUTY_CNT_ADDR);
|
|
REG_FIELD_SET(LEDC_COMMON_DUTY_CNT_THRS, tmp, thrs);
|
|
LEDC0_WRITE_REG(CFG_LEDC_COMMON_DUTY_CNT_ADDR, tmp);
|
|
}
|
|
|
|
void ledc_common_timer_sel(COMMON_TIMER_SEL timer_num)
|
|
{
|
|
uint32_t tmp;
|
|
|
|
if (COMMON_TIMER_SEL_INVALID(timer_num)) {
|
|
return ;
|
|
}
|
|
|
|
tmp = LEDC0_READ_REG(CFG_LEDC_COMMON_DUTY_CNT_ADDR);
|
|
REG_FIELD_SET(LEDC0_TIMER_SEL, tmp, timer_num);
|
|
LEDC0_WRITE_REG(CFG_LEDC_COMMON_DUTY_CNT_ADDR, tmp);
|
|
}
|
|
|
|
void ledc_interrupt_enable(LEDC_PORT port, uint32_t mask)
|
|
{
|
|
uint32_t tmp;
|
|
|
|
if (LEDC_PORT_INVALID(port)) {
|
|
return ;
|
|
}
|
|
|
|
tmp = ledc_hw_read_reg(port, CFG_LEDC0_INT_ADDR);
|
|
tmp |= mask;
|
|
ledc_hw_write_reg(port, CFG_LEDC0_INT_ADDR, tmp);
|
|
}
|
|
|
|
void ledc_interrupt_disable(LEDC_PORT port, uint32_t mask)
|
|
{
|
|
uint32_t tmp;
|
|
|
|
if (LEDC_PORT_INVALID(port)) {
|
|
return ;
|
|
}
|
|
|
|
tmp = ledc_hw_read_reg(port, CFG_LEDC0_INT_ADDR);
|
|
tmp &= ~mask;
|
|
ledc_hw_write_reg(port, CFG_LEDC0_INT_ADDR, tmp);
|
|
}
|
|
|
|
void ledc_interrupt_clear(LEDC_PORT port, uint32_t mask)
|
|
{
|
|
uint32_t tmp;
|
|
|
|
if (LEDC_PORT_INVALID(port)) {
|
|
return ;
|
|
}
|
|
|
|
tmp = ledc_hw_read_reg(port, CFG_LEDC0_INT_ADDR);
|
|
tmp |= mask;
|
|
ledc_hw_write_reg(port, CFG_LEDC0_INT_ADDR, tmp);
|
|
}
|
|
|
|
uint32_t ledc_interrupt_status_get(LEDC_PORT port)
|
|
{
|
|
uint32_t tmp;
|
|
|
|
if (LEDC_PORT_INVALID(port)) {
|
|
return 0;
|
|
}
|
|
|
|
tmp = ledc_hw_read_reg(port, CFG_LEDC0_INT_ADDR);
|
|
|
|
tmp &=(LEDC0_DONE_INT_ST_MASK | LEDC0_DUTY_NUM_CNT_RELOAD_INT_ST_MASK |
|
|
LEDC0_SHADOW_INT_ST_MASK | LEDC0_NOP_INT_ST_MASK |
|
|
LEDC0_DUTY_PHASE_RELOAD_INT_ST_MASK);
|
|
|
|
return tmp;
|
|
}
|
|
|
|
static uint32_t IRAM_ATTR ledc_interupt_handler(uint32_t vector,
|
|
iot_addrword_t data)
|
|
{
|
|
uint32_t status = 0;
|
|
int i = 0;
|
|
int max;
|
|
|
|
if (HAL_VECTOR_LEDC == vector) {
|
|
i = LEDC_PORT_0;
|
|
max = LEDC_PORT_4;
|
|
} else if (HAL_VECTOR_LEDC_FREE == vector) {
|
|
i = LEDC_PORT_4;
|
|
max = LEDC_PORT_MAX;
|
|
} else {
|
|
return 0;
|
|
}
|
|
|
|
for ( ; i < max; i ++) {
|
|
/* get int status */
|
|
status = ledc_interrupt_status_get(i);
|
|
if ( 0 == status) {
|
|
continue;
|
|
}
|
|
if (g_ledc_cbs[i]) {
|
|
g_ledc_cbs[i](i);
|
|
}
|
|
/* clr intr */
|
|
ledc_interrupt_clear(i, LEDC0_DONE_INT_CLR_MASK);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void ledc_interrupt_init(uint8_t port, ledc_interrrupt_cb_typedef cb)
|
|
{
|
|
uint32_t mask = LEDC0_DONE_INT_ENA_MASK;
|
|
static iot_irq_t irq_handle = 0;
|
|
static iot_irq_t irq_handle_free = 0;
|
|
|
|
if (LEDC_PORT_INVALID(port)) {
|
|
return ;
|
|
}
|
|
|
|
g_ledc_cbs[port] = cb;
|
|
|
|
/* clr pwm int */
|
|
ledc_interrupt_clear(port, LEDC0_DONE_INT_CLR_MASK);
|
|
/* inner int enable */
|
|
ledc_interrupt_enable(port, mask);
|
|
|
|
if (port <= LEDC_PORT_3) {
|
|
if (irq_handle) {
|
|
return ; /* 已经赋值过了就不再赋值了 */
|
|
}
|
|
|
|
irq_handle = iot_interrupt_create(HAL_VECTOR_LEDC,
|
|
HAL_INTR_PRI_0, 0, ledc_interupt_handler);
|
|
iot_interrupt_attach(irq_handle);
|
|
iot_interrupt_unmask(irq_handle);
|
|
} else {
|
|
if (irq_handle_free) {
|
|
return ;
|
|
}
|
|
|
|
irq_handle_free = iot_interrupt_create(HAL_VECTOR_LEDC_FREE,
|
|
HAL_INTR_PRI_0, 0, ledc_interupt_handler);
|
|
iot_interrupt_attach(irq_handle_free);
|
|
iot_interrupt_unmask(irq_handle_free);
|
|
}
|
|
}
|
|
|
|
|
|
void ledc_reload_nop_set(LEDC_PORT port, uint16_t nop)
|
|
{
|
|
uint32_t tmp;
|
|
|
|
if (LEDC_PORT_INVALID(port)) {
|
|
return ;
|
|
}
|
|
|
|
tmp = ledc_hw_read_reg(port, CFG_LEDC0_CONF_ADDR);
|
|
REG_FIELD_SET(LEDC0_DUTY_RELOAD_NOP, tmp, nop);
|
|
ledc_hw_write_reg(port, CFG_LEDC0_CONF_ADDR, tmp);
|
|
|
|
}
|
|
|
|
void ledc_reload_num_cnt_set(LEDC_PORT port, uint16_t cnt)
|
|
{
|
|
uint32_t tmp;
|
|
|
|
if (LEDC_PORT_INVALID(port)) {
|
|
return ;
|
|
}
|
|
|
|
tmp = ledc_hw_read_reg(port, CFG_LEDC0_DUTY_CONF2_ADDR);
|
|
REG_FIELD_SET(LEDC0_DUTY_NUM_CNT_RELOAD, tmp, cnt);
|
|
ledc_hw_write_reg(port, CFG_LEDC0_DUTY_CONF2_ADDR, tmp);
|
|
|
|
}
|
|
|
|
void ledc_reload_loop_set(LEDC_PORT port, uint8_t loop)
|
|
{
|
|
uint32_t tmp;
|
|
|
|
if (LEDC_PORT_INVALID(port)) {
|
|
return ;
|
|
}
|
|
|
|
tmp = ledc_hw_read_reg(port, CFG_LEDC0_DUTY_CONF5_ADDR);
|
|
REG_FIELD_SET(LEDC0_DUTY_RELOAD_LOOP, tmp, loop);
|
|
ledc_hw_write_reg(port, CFG_LEDC0_DUTY_CONF5_ADDR, tmp);
|
|
|
|
}
|
|
|
|
void ledc_reload_cycle_set(LEDC_PORT port, uint8_t cycle)
|
|
{
|
|
uint32_t tmp;
|
|
|
|
if (LEDC_PORT_INVALID(port)) {
|
|
return ;
|
|
}
|
|
|
|
tmp = ledc_hw_read_reg(port, CFG_LEDC0_DUTY_CONF5_ADDR);
|
|
REG_FIELD_SET(LEDC0_DUTY_RELOAD_CYCLE, tmp, cycle);
|
|
ledc_hw_write_reg(port, CFG_LEDC0_DUTY_CONF5_ADDR, tmp);
|
|
|
|
}
|
|
|
|
void ledc_set_l2h_val(uint8_t port, uint32_t value)
|
|
{
|
|
|
|
}
|
|
|
|
void ledc_target_cfg(uint8_t port, uint8_t shadow, uint8_t inc,
|
|
uint32_t num, uint32_t cycle, uint32_t scope)
|
|
{
|
|
|
|
}
|
|
void ledc_timer_cfg(uint8_t port, uint8_t tick, uint8_t init,
|
|
uint8_t pause, uint32_t div, uint8_t uplim)
|
|
{
|
|
|
|
}
|
|
|
|
void ledc_target_value(uint8_t port, uint32_t value)
|
|
{
|
|
|
|
}
|
|
|
|
void ledc_cfg(uint8_t port, uint8_t idle_val, uint8_t ena, uint8_t timer_sel)
|
|
{
|
|
|
|
}
|
|
|
|
void ledc_out_ref(uint8_t port, uint8_t ena)
|
|
{
|
|
|
|
}
|
|
|
|
|
|
uint32_t led_blink(uint8_t id, uint8_t cnt)
|
|
{
|
|
#if IOT_LEDC_SOFT_MODE
|
|
if (g_led_sts.led_cnt == 0 || !g_led_sts.blink_allow) {
|
|
return ERR_FAIL;
|
|
}
|
|
for(int i = 0; i < g_led_sts.led_cnt; i++) {
|
|
if (g_led_sts.led_id[i] == id) {
|
|
g_led_sts.status[i] = IOT_LED_STS_BLINK;
|
|
g_led_sts.blink_cnt[i] = cnt;
|
|
return ERR_OK;
|
|
}
|
|
}
|
|
return ERR_FAIL;
|
|
#else
|
|
ledc_cnt_ena(id, LEDC_ENA_DISABLE);
|
|
ledc_phase1_blink_times_set(id, cnt);
|
|
ledc_cnt_ena(id, LEDC_ENA_ENABLE);
|
|
return ERR_OK;
|
|
#endif
|
|
}
|
|
|
|
uint32_t led_on(uint8_t id)
|
|
{
|
|
#if IOT_LEDC_SOFT_MODE
|
|
if (g_led_sts.led_cnt == 0) {
|
|
return ERR_FAIL;
|
|
}
|
|
for(int i = 0; i < g_led_sts.led_cnt; i++) {
|
|
if (g_led_sts.led_id[i] == id) {
|
|
g_led_sts.status[i] = IOT_LED_STS_ON;
|
|
g_led_sts.remain[i] = IOT_LED_STS_ON;
|
|
return ERR_OK;
|
|
}
|
|
}
|
|
|
|
return ERR_FAIL;
|
|
#else
|
|
ledc_idle_level_sel(id, IDLE_LEVEL_LOW);
|
|
ledc_cnt_ena(id, LEDC_ENA_DISABLE);
|
|
|
|
return ERR_OK;
|
|
#endif
|
|
}
|
|
|
|
uint32_t led_off(uint8_t id)
|
|
{
|
|
#if IOT_LEDC_SOFT_MODE
|
|
if (g_led_sts.led_cnt == 0) {
|
|
return ERR_FAIL;
|
|
}
|
|
|
|
for(int i = 0; i < g_led_sts.led_cnt; i++) {
|
|
if (g_led_sts.led_id[i] == id) {
|
|
g_led_sts.status[i] = IOT_LED_STS_OFF;
|
|
g_led_sts.remain[i] = IOT_LED_STS_OFF;
|
|
return ERR_OK;
|
|
}
|
|
}
|
|
|
|
return ERR_FAIL;
|
|
#else
|
|
ledc_idle_level_sel(id, IDLE_LEVEL_HIGH);
|
|
ledc_cnt_ena(id, LEDC_ENA_DISABLE);
|
|
|
|
return ERR_OK;
|
|
#endif
|
|
}
|
|
|
|
void led_set_blink_interval(uint16_t interval)
|
|
{
|
|
#if IOT_LEDC_SOFT_MODE
|
|
IOT_ASSERT(interval >= 64 && interval <= 10000);
|
|
if (interval & 1) {
|
|
g_led_sts.whole_period = interval + 1;
|
|
} else {
|
|
g_led_sts.whole_period = interval;
|
|
}
|
|
g_led_sts.half_period = g_led_sts.whole_period / 2;
|
|
#else
|
|
for (int ch = 0; ch < g_led_sts.led_cnt; ch++) {
|
|
ledc_h2l_point_set(ch, interval - 1);
|
|
ledc_l2h_point_set(ch, interval / 2);
|
|
|
|
ledc_thrs_set(ch, interval -1 );
|
|
}
|
|
#endif
|
|
}
|
|
|
|
//使能或失能闪烁
|
|
void led_enable_blink(uint8_t enable)
|
|
{
|
|
#if IOT_LEDC_SOFT_MODE
|
|
g_led_sts.blink_allow = enable;
|
|
#else
|
|
for (int ch = 0; ch < g_led_sts.led_cnt; ch++) {
|
|
if (enable) {
|
|
ledc_cnt_ena(ch, LEDC_ENA_ENABLE);
|
|
} else {
|
|
ledc_cnt_ena(ch, LEDC_ENA_DISABLE);
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
uint32_t led_duty_conf(uint8_t target, uint8_t id,
|
|
uint8_t idle, uint8_t ena)
|
|
{
|
|
int ch = target;
|
|
|
|
ledc_cnt_ena(ch, LEDC_ENA_DISABLE);
|
|
ledc_gpio_config(ch, g_led_sts.gpio[ch]);
|
|
|
|
//2
|
|
ledc_timer_rst(ch);
|
|
if (id == IOT_PWR_LED) {
|
|
ledc_timer_init(ch, 24999);//clk 25M,div = 24999,thrs = 2000 ->0.5hz
|
|
|
|
}else {
|
|
ledc_timer_init(ch, 3); //clk 25M, div = 7 ,thrs = 60000 -> 52hz
|
|
}
|
|
|
|
//3
|
|
ledc_polarity_sel(ch, OUT_POL_INVERT);
|
|
ledc_idle_level_sel(ch, IDLE_LEVEL_LOW);
|
|
|
|
//4
|
|
if (id == IOT_PWR_LED) {
|
|
ledc_h2l_point_set(ch, 2000);
|
|
ledc_l2h_point_set(ch, 1000);
|
|
|
|
} else {
|
|
ledc_h2l_point_set(ch, 60000 / g_led_sts.led_cnt * (ch + 1));
|
|
ledc_l2h_point_set(ch, 60000 / g_led_sts.led_cnt * (ch + 0));
|
|
}
|
|
|
|
//5
|
|
ledc_phase1_blink_times_set(ch, 0); // 0 always
|
|
ledc_phase2_blink_times_set(ch, 0);
|
|
|
|
//6
|
|
|
|
ledc_duty_cnt_sel(ch, DUTY_CNT_OWN);
|
|
if (id == IOT_PWR_LED) {
|
|
ledc_thrs_set(ch, 2000);
|
|
} else {
|
|
ledc_thrs_set(ch, 60000);
|
|
}
|
|
|
|
//7
|
|
ledc_phase_opt_sel(ch, DUTY_OPT_MODE_NEW);
|
|
|
|
ledc_phase_num_sel(ch, PHASE_NUM_ONE);
|
|
|
|
ledc_phase1_mode_sel(ch, PHASE_MODE_FIXED_DUTY);
|
|
ledc_phase2_mode_sel(ch, PHASE_MODE_FIXED_DUTY);
|
|
|
|
ledc_phase1_scale_set(ch, 1);
|
|
ledc_phase2_scale_set(ch, 1);
|
|
|
|
|
|
ledc_cycle_times_set(ch, 1);
|
|
ledc_loop_times_set(ch, 1);
|
|
|
|
ledc_nop_num_set(ch, 1);
|
|
|
|
ledc_cnt_ena(ch, ena);
|
|
|
|
return 0;
|
|
}
|
|
|
|
uint32_t led_init()
|
|
{
|
|
#if IOT_LEDC_SOFT_MODE
|
|
for (int ch = 0; ch < g_led_sts.led_cnt; ch ++) {
|
|
ledc_timer_ctrl(ch, TIMER_CTRL_START);
|
|
}
|
|
#else
|
|
/* init led config */
|
|
for (int ch = 0; ch < g_led_sts.led_cnt; ch++) {
|
|
ledc_gpio_config(ch, g_led_sts.gpio[ch]);
|
|
|
|
iot_led_on(ch);
|
|
ledc_timer_rst(ch);
|
|
ledc_timer_init(ch, 25000); // 25000 --> 1k
|
|
ledc_timer_ctrl(ch, TIMER_CTRL_START);
|
|
|
|
//3
|
|
ledc_polarity_sel(ch, OUT_POL_ORIGINAL);//OUT_POL_INVERT);
|
|
ledc_idle_level_sel(ch, IDLE_LEVEL_LOW);//IDLE_LEVEL_HIGH);
|
|
|
|
//4
|
|
ledc_h2l_point_set(ch, 1000);
|
|
ledc_l2h_point_set(ch, 500);
|
|
|
|
//5
|
|
ledc_phase1_blink_times_set(ch, 10); // thrs/scale
|
|
ledc_phase2_blink_times_set(ch, 0);
|
|
|
|
//6
|
|
|
|
ledc_duty_cnt_sel(ch, DUTY_CNT_OWN);
|
|
ledc_thrs_set(ch, 1000); // 1000 -> 1hz
|
|
|
|
//7
|
|
ledc_phase_opt_sel(ch, DUTY_OPT_MODE_NEW);
|
|
|
|
ledc_phase_num_sel(ch, PHASE_NUM_ONE);
|
|
|
|
ledc_phase1_mode_sel(ch, PHASE_MODE_FIXED_DUTY);
|
|
ledc_phase2_mode_sel(ch, PHASE_MODE_FIXED_DUTY);
|
|
|
|
ledc_phase1_scale_set(ch, 0);
|
|
ledc_phase2_scale_set(ch, 0);
|
|
|
|
ledc_cycle_times_set(ch, 1);
|
|
ledc_loop_times_set(ch, 1);
|
|
|
|
ledc_nop_num_set(ch, 1);
|
|
|
|
}
|
|
|
|
|
|
iot_led_set_blink_interval(LED_SOFT_WHOLE_PERIOD);
|
|
iot_led_enable_blink(1);
|
|
|
|
#endif
|
|
return ERR_OK;
|
|
}
|
|
|