P0功能已实现,按键、LED、过零检测、配网、OTA都已正常实现

This commit is contained in:
2026-09-04 18:49:07 +08:00
parent 2fb61a6458
commit 0de88083ba
47 changed files with 5184 additions and 26 deletions
+107
View File
@@ -0,0 +1,107 @@
#include "asm/mcpwm.h"
#include "asm/clock.h"
#include "asm/gpio.h"
/******************************* 外部GPIO引脚中断参考代码 ***************************/
void (*io_isr_cbfun)(u8 index) = NULL;
void set_io_ext_interrupt_cbfun(void (*cbfun)(u8 index))
{
io_isr_cbfun = cbfun;
}
___interrupt
void io_interrupt(void)
{
u32 io_index = -1;
if (JL_MCPWM->CH0_CON1 & BIT(15)) {
JL_MCPWM->CH0_CON1 |= BIT(14);
io_index = 0;
} else if (JL_MCPWM->CH1_CON1 & BIT(15)) {
JL_MCPWM->CH1_CON1 |= BIT(14);
io_index = 1;
} else if (JL_MCPWM->CH2_CON1 & BIT(15)) {
JL_MCPWM->CH2_CON1 |= BIT(14);
io_index = 2;
} else if (JL_MCPWM->CH3_CON1 & BIT(15)) {
JL_MCPWM->CH3_CON1 |= BIT(14);
io_index = 3;
} else {
return;
}
if (io_isr_cbfun) {
io_isr_cbfun(io_index);
}
}
void io_ext_interrupt_init(u8 index, u8 port, u8 trigger_mode)
{
if (port > IO_PORT_MAX) {
return;
}
gpio_set_die(port, 1);
gpio_set_direction(port, 1);
if (trigger_mode) {
gpio_set_pull_up(port, 1);
gpio_set_pull_down(port, 0);
JL_MCPWM->FPIN_CON &= ~BIT(16 + index);//下降沿触发
} else {
gpio_set_pull_up(port, 0);
gpio_set_pull_down(port, 1);
JL_MCPWM->FPIN_CON |= BIT(16 + index);//上升沿触发
}
JL_MCPWM->FPIN_CON |= BIT(8 + index);//开启滤波
JL_MCPWM->FPIN_CON |= (0b111111 << 0); //滤波时间 = 16 * 64 / hsb_clk (单位:s)
gpio_ich_sel_iutput_signal(port, INPUT_CH_SIGNAL_MC_FPIN0 + index, INPUT_CH_TYPE_GP_ICH);
request_irq(IRQ_MCPWM_CHX_IDX, 3, io_interrupt, 0); //注册中断函数
PWM_CH_REG *pwm_reg = get_pwm_ch_reg(index);
pwm_reg->ch_con1 = BIT(14) | BIT(11) | BIT(4) | (index << 0);
JL_MCPWM->MCPWM_CON0 |= BIT(index);
#if 0
printf("JL_MCPWM->CH%d_CON1 = 0x%x\n", index, pwm_reg->ch_con1);
printf("JL_MCPWM->FPIN_CON = 0x%x\n", JL_MCPWM->FPIN_CON);
printf("JL_MCPWM->MCPWM_CON0 = 0x%x\n", JL_MCPWM->MCPWM_CON0);
printf("JL_IOMAP->ICH_CON0 = 0x%x\n", JL_IOMAP->ICH_CON0);
printf("JL_IOMAP->ICH_CON1 = 0x%x\n", JL_IOMAP->ICH_CON1);
printf("JL_IOMAP->ICH_CON2 = 0x%x\n", JL_IOMAP->ICH_CON2);
printf("JL_IOMAP->ICH_CON3 = 0x%x\n", JL_IOMAP->ICH_CON3);
printf("JL_IMAP->FI_GP_ICH0 = %d\n", JL_IMAP->FI_GP_ICH0);
printf("JL_IMAP->FI_GP_ICH1 = %d\n", JL_IMAP->FI_GP_ICH1);
printf("JL_IMAP->FI_GP_ICH2 = %d\n", JL_IMAP->FI_GP_ICH2);
printf("JL_IMAP->FI_GP_ICH3 = %d\n", JL_IMAP->FI_GP_ICH3);
printf("JL_IMAP->FI_GP_ICH4 = %d\n", JL_IMAP->FI_GP_ICH4);
printf("JL_IMAP->FI_GP_ICH5 = %d\n", JL_IMAP->FI_GP_ICH5);
printf("JL_IMAP->FI_GP_ICH6 = %d\n", JL_IMAP->FI_GP_ICH6);
printf("JL_IMAP->FI_GP_ICH7 = %d\n", JL_IMAP->FI_GP_ICH7);
printf("JL_IMAP->FI_GP_ICH8 = %d\n", JL_IMAP->FI_GP_ICH8);
printf("JL_IMAP->FI_GP_ICH9 = %d\n", JL_IMAP->FI_GP_ICH9);
#endif // 0
}
void io_ext_interrupt_close(u8 index, u8 port)
{
if (port > IO_PORT_MAX) {
return;
}
gpio_set_die(port, 0);
gpio_set_direction(port, 1);
gpio_set_pull_up(port, 0);
gpio_set_pull_down(port, 0);
gpio_ich_disable_iutput_signal(port, INPUT_CH_SIGNAL_MC_FPIN0 + index, INPUT_CH_TYPE_GP_ICH);
PWM_CH_REG *pwm_reg = get_pwm_ch_reg(index);
pwm_reg->ch_con1 = BIT(14);
}
///////////// 使用举例如下 //////////////////
void my_io_isr_cbfun(u8 index)
{
printf("io index --> %d Hello world !\n", index);
}
void io_ext_interrupt_test(void)
{
set_io_ext_interrupt_cbfun(my_io_isr_cbfun);
io_ext_interrupt_init(0, IO_PORTA_04, 1);
io_ext_interrupt_init(1, IO_PORTB_01, 1);
io_ext_interrupt_init(2, IO_PORTC_02, 1);
io_ext_interrupt_init(3, IO_PORTG_01, 1);
}
+405
View File
@@ -0,0 +1,405 @@
#include "asm/mcpwm.h"
#include "asm/clock.h"
#include "asm/gpio.h"
#define MCPWM_DEBUG_ENABLE 1
#if MCPWM_DEBUG_ENABLE
#define mcpwm_debug(fmt, ...) printf("[MCPWM] "fmt, ##__VA_ARGS__)
#else
#define mcpwm_debug(...)
#endif
#define MCPWM_CLK clk_get("mcpwm")
/********************************硬件PWM相关函数**************************/
PWM_TIMER_REG *get_pwm_timer_reg(pwm_ch_num_type index)
{
PWM_TIMER_REG *reg = NULL;
switch (index) {
case pwm_ch0:
reg = (PWM_TIMER_REG *)(&(JL_MCPWM->TMR0_CON));
break;
case pwm_ch1:
reg = (PWM_TIMER_REG *)(&(JL_MCPWM->TMR1_CON));
break;
case pwm_ch2:
reg = (PWM_TIMER_REG *)(&(JL_MCPWM->TMR2_CON));
break;
case pwm_ch3:
reg = (PWM_TIMER_REG *)(&(JL_MCPWM->TMR3_CON));
break;
default:
break;
}
return reg;
}
PWM_CH_REG *get_pwm_ch_reg(pwm_ch_num_type index)
{
PWM_CH_REG *reg = NULL;
switch (index) {
case pwm_ch0:
reg = (PWM_CH_REG *)(&(JL_MCPWM->CH0_CON0));
break;
case pwm_ch1:
reg = (PWM_CH_REG *)(&(JL_MCPWM->CH1_CON0));
break;
case pwm_ch2:
reg = (PWM_CH_REG *)(&(JL_MCPWM->CH2_CON0));
break;
case pwm_ch3:
reg = (PWM_CH_REG *)(&(JL_MCPWM->CH3_CON0));
break;
default:
break;
}
return reg;
}
static u8 clk_in_io = IO_PORTC_02;
/*
* @brief 更改MCPWM的频率
* @parm frequency 频率
*/
void mcpwm_set_frequency(pwm_ch_num_type ch, pwm_aligned_mode_type align, u32 frequency)
{
PWM_TIMER_REG *reg = get_pwm_timer_reg(ch);
if (reg == NULL) {
return;
}
reg->tmr_con = 0;
reg->tmr_cnt = 0;
reg->tmr_pr = 0;
u32 i = 0;
u32 mcpwm_div_clk = 0;
u32 mcpwm_tmr_pr = 0;
u32 mcpwm_fre_min = 0;
u32 clk = MCPWM_CLK;
for (i = 0; i < 16; i++) {
mcpwm_fre_min = clk / (65536 * (1 << i));
if ((frequency >= mcpwm_fre_min) || (i == 15)) {
break;
}
}
reg->tmr_con |= (i << 3); //div 2^i
mcpwm_div_clk = clk / (1 << i);
if (frequency == 0) {
mcpwm_tmr_pr = 0;
} else {
if (align == pwm_center_aligned) { //中心对齐
mcpwm_tmr_pr = mcpwm_div_clk / (frequency * 2) - 1;
} else {
mcpwm_tmr_pr = mcpwm_div_clk / frequency - 1;
}
}
reg->tmr_pr = mcpwm_tmr_pr;
//timer mode
if (align == pwm_center_aligned) { //中心对齐
reg->tmr_con |= 0b10;
} else {
reg->tmr_con |= 0b01;
}
}
static u32 old_mcpwm_clk = 0;
static void clock_critical_enter(void)
{
old_mcpwm_clk = clk_get("mcpwm");
}
static void clock_critical_exit(void)
{
u32 new_mcpwm_clk = clk_get("mcpwm");
if (new_mcpwm_clk == old_mcpwm_clk) {
return;
}
PWM_CH_REG *pwm_reg = NULL;
PWM_TIMER_REG *timer_reg = NULL;
for (u8 ch = 0; ch < 4; ch++) {
if (JL_MCPWM->MCPWM_CON0 & BIT(ch + 8)) {
pwm_reg = get_pwm_ch_reg(ch);
timer_reg = get_pwm_timer_reg(ch);
if (new_mcpwm_clk > old_mcpwm_clk) {
timer_reg->tmr_pr = timer_reg->tmr_pr * (new_mcpwm_clk / old_mcpwm_clk);
pwm_reg->ch_cmpl = pwm_reg->ch_cmpl * (new_mcpwm_clk / old_mcpwm_clk);
} else {
timer_reg->tmr_pr = timer_reg->tmr_pr / (old_mcpwm_clk / new_mcpwm_clk);
pwm_reg->ch_cmpl = pwm_reg->ch_cmpl / (old_mcpwm_clk / new_mcpwm_clk);
}
pwm_reg->ch_cmph = pwm_reg->ch_cmpl;
}
}
}
CLOCK_CRITICAL_HANDLE_REG(mcpwm, clock_critical_enter, clock_critical_exit)
/*
* @brief 设置一个通道的占空比
* @parm pwm_ch_num 通道号:pwm_ch0pwm_ch1pwm_ch2
* @parm duty 占空比:0 ~ 10000 对应 0% ~ 100%
*/
void mcpwm_set_duty(pwm_ch_num_type pwm_ch, u16 duty)
{
PWM_TIMER_REG *timer_reg = get_pwm_timer_reg(pwm_ch);
PWM_CH_REG *pwm_reg = get_pwm_ch_reg(pwm_ch);
if (pwm_reg && timer_reg) {
pwm_reg->ch_cmpl = timer_reg->tmr_pr * duty / 10000;
pwm_reg->ch_cmph = pwm_reg->ch_cmpl;
timer_reg->tmr_cnt = 0;
timer_reg->tmr_con |= 0b01;
if (duty == 10000) {
timer_reg->tmr_cnt = 0;
timer_reg->tmr_con &= ~(0b11);
} else if (duty == 0) {
timer_reg->tmr_cnt = pwm_reg->ch_cmpl;
timer_reg->tmr_con &= ~(0b11);
}
}
}
/*
* @brief 打开或者关闭一个时基
* @parm pwm_ch_num 通道号:pwm_ch0pwm_ch1pwm_ch2
* @parm enable 1:打开 0:关闭
*/
void mctimer_ch_open_or_close(pwm_ch_num_type pwm_ch, u8 enable)
{
if (pwm_ch > pwm_ch_max) {
return;
}
if (enable) {
JL_MCPWM->MCPWM_CON0 |= BIT(pwm_ch + 8); //TnEN
} else {
JL_MCPWM->MCPWM_CON0 &= (~BIT(pwm_ch + 8)); //TnDIS
}
}
/*
* @brief 打开或者关闭一个通道
* @parm pwm_ch_num 通道号:pwm_ch0pwm_ch1pwm_ch2
* @parm enable 1:打开 0:关闭
*/
void mcpwm_ch_open_or_close(pwm_ch_num_type pwm_ch, u8 enable)
{
if (pwm_ch >= pwm_ch_max) {
return;
}
if (enable) {
JL_MCPWM->MCPWM_CON0 |= BIT(pwm_ch); //PWMnEN
} else {
JL_MCPWM->MCPWM_CON0 &= (~BIT(pwm_ch)); //PWMnDIS
}
}
/*
* @brief 关闭MCPWM模块
*/
void mcpwm_open(pwm_ch_num_type pwm_ch)
{
if (pwm_ch >= pwm_ch_max) {
return;
}
PWM_CH_REG *pwm_reg = get_pwm_ch_reg(pwm_ch);
pwm_reg->ch_con1 &= ~(0b111 << 8);
pwm_reg->ch_con1 |= (pwm_ch << 8); //sel mctmr
mcpwm_ch_open_or_close(pwm_ch, 1);
mctimer_ch_open_or_close(pwm_ch, 1);
}
/*
* @brief 关闭MCPWM模块
*/
void mcpwm_close(pwm_ch_num_type pwm_ch)
{
mctimer_ch_open_or_close(pwm_ch, 0);
mcpwm_ch_open_or_close(pwm_ch, 0);
}
void log_pwm_info(pwm_ch_num_type pwm_ch)
{
PWM_CH_REG *pwm_reg = get_pwm_ch_reg(pwm_ch);
PWM_TIMER_REG *timer_reg = get_pwm_timer_reg(pwm_ch);
mcpwm_debug("tmr%d con0 = 0x%x", pwm_ch, timer_reg->tmr_con);
mcpwm_debug("tmr%d pr = 0x%x", pwm_ch, timer_reg->tmr_pr);
mcpwm_debug("pwm ch%d_con0 = 0x%x", pwm_ch, pwm_reg->ch_con0);
mcpwm_debug("pwm ch%d_con1 = 0x%x", pwm_ch, pwm_reg->ch_con1);
mcpwm_debug("pwm ch%d_cmph = 0x%x, pwm ch%d_cmpl = 0x%x", pwm_ch, pwm_reg->ch_cmph, pwm_ch, pwm_reg->ch_cmpl);
mcpwm_debug("MCPWM_CON0 = 0x%x", JL_MCPWM->MCPWM_CON0);
mcpwm_debug("mcpwm clk = %d", MCPWM_CLK);
}
void mcpwm_init(struct pwm_platform_data *arg)
{
//set output IO
PWM_CH_REG *pwm_reg = get_pwm_ch_reg(arg->pwm_ch_num);
if (pwm_reg == NULL) {
return;
}
//set mctimer frequency
mcpwm_set_frequency(arg->pwm_ch_num, arg->pwm_aligned_mode, arg->frequency);
pwm_reg->ch_con0 = 0;
if (arg->complementary_en) { //是否互补
pwm_reg->ch_con0 &= ~(BIT(5) | BIT(4));
pwm_reg->ch_con0 |= BIT(5); //L_INV
} else {
pwm_reg->ch_con0 &= ~(BIT(5) | BIT(4));
}
mcpwm_open(arg->pwm_ch_num); //mcpwm enable
//set duty
mcpwm_set_duty(arg->pwm_ch_num, arg->duty);
//H:
if (arg->h_pin < IO_MAX_NUM) { //任意引脚
pwm_reg->ch_con0 |= BIT(2); //H_EN
gpio_och_sel_output_signal(arg->h_pin, OUTPUT_CH_SIGNAL_MC_PWM0_H + 2 * arg->pwm_ch_num);
gpio_set_direction(arg->h_pin, 0); //DIR output
}
//L:
if (arg->l_pin < IO_MAX_NUM) { //任意引脚
pwm_reg->ch_con0 |= BIT(3); //L_EN
gpio_och_sel_output_signal(arg->l_pin, OUTPUT_CH_SIGNAL_MC_PWM0_L + 2 * arg->pwm_ch_num);
gpio_set_direction(arg->l_pin, 0); //DIR output
}
log_pwm_info(arg->pwm_ch_num);
}
#define PWM_CH0_ENABLE 0
#define PWM_CH1_ENABLE 0
#define PWM_CH2_ENABLE 0
#define PWM_CH3_ENABLE 0
void usr_mcpwm_init(void)
{
struct pwm_platform_data pwm_p_data;
#if PWM_CH0_ENABLE
pwm_p_data.pwm_aligned_mode = pwm_edge_aligned; //边沿对齐
pwm_p_data.pwm_ch_num = pwm_ch0; //通道号
pwm_p_data.frequency = 500; //1KHz
pwm_p_data.duty = 0; //占空比50%
pwm_p_data.h_pin = IO_PORTA_06; //任意引脚
pwm_p_data.l_pin = -1; //任意引脚,不需要就填-1
pwm_p_data.complementary_en = 0; //两个引脚的波形, 0: 同步, 1: 互补,互补波形的占空比体现在H引脚上
mcpwm_init(&pwm_p_data);
#endif
#if PWM_CH1_ENABLE
pwm_p_data.pwm_aligned_mode = pwm_edge_aligned; //边沿对齐
pwm_p_data.pwm_ch_num = pwm_ch1; //通道号
pwm_p_data.frequency = 500; //1KHz
pwm_p_data.duty = 0; //占空比25%
pwm_p_data.h_pin = IO_PORTA_08; //任意引脚
pwm_p_data.l_pin = -1; //任意引脚,不需要就填-1
pwm_p_data.complementary_en = 0; //两个引脚的波形, 0: 同步, 1: 互补,互补波形的占空比体现在H引脚上
mcpwm_init(&pwm_p_data);
#endif
#if PWM_CH2_ENABLE
pwm_p_data.pwm_aligned_mode = pwm_edge_aligned; //边沿对齐
pwm_p_data.pwm_ch_num = pwm_ch2; //通道号
pwm_p_data.frequency = 10000; //10KHz
pwm_p_data.duty = 5000; //占空比50%
pwm_p_data.h_pin = IO_PORTA_03; //任意引脚
pwm_p_data.l_pin = -1; //任意引脚,不需要就填-1
mcpwm_init(&pwm_p_data);
#endif
#if PWM_CH3_ENABLE
pwm_p_data.pwm_aligned_mode = pwm_edge_aligned; //边沿对齐
pwm_p_data.pwm_ch_num = pwm_ch3; //通道号
pwm_p_data.frequency = 10000; //10KHz
pwm_p_data.duty = 7500; //占空比75%
pwm_p_data.h_pin = IO_PORTA_04; //任意引脚
pwm_p_data.l_pin = IO_PORTA_05; //任意引脚,不需要就填-1
pwm_p_data.complementary_en = 0; //两个引脚的波形, 0: 同步, 1: 互补,互补波形的占空比体现在H引脚上
mcpwm_init(&pwm_p_data);
#endif
}
/*
extern void clk_out(u8 gpio, enum CLK_OUT_SOURCE clk);
clk_out(IO_PORTA_07, LSB_CLK_OUT);
extern void wdt_clear();
*/
/******************************* 用timer做pwm的参考代码 ***************************/
/**
* @param JL_TIMERx : JL_TIMER0/1/2/3
* @param pwm_io : JL_PORTA_01, JL_PORTB_02,,,等等,支持任意普通IO
* @param fre : 频率,单位Hz
* @param duty : 初始占空比,0~10000对应0~100%
*/
void timer_pwm_init(JL_TIMER_TypeDef *JL_TIMERx, u32 pwm_io, u32 fre, u32 duty)
{
switch ((u32)JL_TIMERx) {
case (u32)JL_TIMER0 :
gpio_och_sel_output_signal(pwm_io, OUTPUT_CH_SIGNAL_TIMER0_PWM);
break;
case (u32)JL_TIMER1 :
gpio_och_sel_output_signal(pwm_io, OUTPUT_CH_SIGNAL_TIMER1_PWM);
break;
case (u32)JL_TIMER2 :
gpio_och_sel_output_signal(pwm_io, OUTPUT_CH_SIGNAL_TIMER2_PWM);
break;
case (u32)JL_TIMER3 :
bit_clr_ie(IRQ_TIME3_IDX);
gpio_och_sel_output_signal(pwm_io, OUTPUT_CH_SIGNAL_TIMER3_PWM);
break;
case (u32)JL_TIMER4 :
gpio_och_sel_output_signal(pwm_io, OUTPUT_CH_SIGNAL_TIMER4_PWM);
break;
case (u32)JL_TIMER5 :
gpio_och_sel_output_signal(pwm_io, OUTPUT_CH_SIGNAL_TIMER5_PWM);
break;
default:
return;
}
u32 u_clk = 24000000;
//初始化timer
JL_TIMERx->CON = 0;
JL_TIMERx->CON |= (0b110 << 10); //时钟源选择STD_24M时钟源
JL_TIMERx->CON |= (0b0001 << 4); //时钟源再4分频
JL_TIMERx->CNT = 0; //清计数值
JL_TIMERx->PRD = u_clk / (4 * fre); //设置周期
JL_TIMERx->PWM = (JL_TIMERx->PRD * duty) / 10000; //设置初始占空比,0~10000对应0~100%
JL_TIMERx->CON |= (0b01 << 0); //计数模式
JL_TIMERx->CON |= BIT(8); //PWM使能
//设置引脚状态
gpio_set_die(pwm_io, 1);
gpio_set_pull_up(pwm_io, 0);
gpio_set_pull_down(pwm_io, 0);
gpio_set_direction(pwm_io, 0);
printf("JL_TIMERx->PRD = 0x%x\n", JL_TIMERx->PRD);
printf("JL_TIMERx->CON = 0x%x\n", JL_TIMERx->CON);
}
void set_timer_pwm_duty(JL_TIMER_TypeDef *JL_TIMERx, u32 duty)
{
JL_TIMERx->PWM = (JL_TIMERx->PRD * duty) / 10000; //0~10000对应0~100%
}
void timer_pwm_test(void)///GPIO随意映射
{
timer_pwm_init(JL_TIMER2, IO_PORTC_03, 10000, 7000);
timer_pwm_init(JL_TIMER3, IO_PORTG_04, 1000, 2000);
}
+187
View File
@@ -0,0 +1,187 @@
#include "app_config.h"
#include "key_event_deal.h"
#include "system/includes.h"
#include "tone_player.h"
#include "app_task.h"
#include "tone_player.h"
#include "media/includes.h"
#include "system/sys_time.h"
//#include "alarm.h"
#include "clock_cfg.h"
#include "rtc_app.h"
/*************************************************************
此文件函数主要是rtc
**************************************************************/
#include "usr_jb_global.h"
#if TCFG_APP_RTC_EN
#define LOG_TAG_CONST APP_RTC
#define LOG_TAG "[APP_RTC]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
/* #define LOG_DUMP_ENABLE */
#define LOG_CLI_ENABLE
#include "debug.h"
struct rtc_opr {
void *dev_handle;
/*u8 rtc_set_mode;
u8 rtc_pos;
u8 alm_enable;
u8 alm_num;
struct sys_time set_time;*/
};
static struct rtc_opr *__this = NULL;
static void rtc_app_init()
{
if (!__this) {
__this = zalloc(sizeof(struct rtc_opr));
ASSERT(__this, "%s %di \n", __func__, __LINE__);
__this->dev_handle = dev_open("rtc", NULL);
if (!__this->dev_handle) {
ASSERT(0, "%s %d \n", __func__, __LINE__);
}
}
}
//*----------------------------------------------------------------------------*/
/**@brief rtc 退出
@param 无
@return
@note
*/
/*----------------------------------------------------------------------------*/
static void rtc_task_close()
{
if (__this) {
if (__this->dev_handle) {
dev_close(__this->dev_handle);
__this->dev_handle = NULL;
}
free(__this);
__this = NULL;
}
}
//*----------------------------------------------------------------------------*/
/**@brief rtc 启动
@param 无
@return
@note
*/
/*----------------------------------------------------------------------------*/
void rtc_task_start()
{
rtc_app_init();
}
//*----------------------------------------------------------------------------*/
/**@brief rtc 主任务
@param 无
@return 无
@note
*/
/*----------------------------------------------------------------------------*/
void usr_jb_rtc_init()
{
rtc_task_start();
}
struct sys_time usr_jb_current_time;
// 计算某年某月某日是星期几(返回1-7对应周一到周日)
uint8_t calculateWeekday(uint16_t year, uint8_t month, uint8_t day)
{
if (month < 3) {
month += 12;
year -= 1;
}
uint16_t century = year / 100;
uint16_t yearInCentury = year % 100;
uint16_t h = (day + (13 * (month + 1)) / 5 + yearInCentury + yearInCentury / 4 + century / 4 + 5 * century) % 7;
uint8_t weekday = (h + 5) % 7 + 1;
return weekday;
}
void usr_rtc_read_time()
{
static u8 cnt=0;
cnt++;
if(cnt>2)
{
cnt=0;
read_sys_time(&usr_jb_current_time);
if((usr_jb_current_time.year<2025)||(usr_jb_current_time.year>2098))
{
usr_var.usr_time_set_flag=0;
}
else
{
usr_var.usr_time_set_flag=1;
}
if(usr_var.usr_time_set_flag)
{
usr_var.usr_cureent_utc=convertToUtcTimestamp(usr_jb_current_time.year,usr_jb_current_time.month,usr_jb_current_time.day,usr_jb_current_time.hour,usr_jb_current_time.min,usr_jb_current_time.sec);
if(usr_var.usr_cureent_utc)
{
if(usr_var.usr_cureent_utc>usr_var.usr_timezoneOffset)usr_var.usr_cureent_utc=usr_var.usr_cureent_utc-usr_var.usr_timezoneOffset;
}
usr_var.usr_week_data=calculateWeekday(usr_jb_current_time.year,usr_jb_current_time.month,usr_jb_current_time.day);
usr_jb_ignore_alft();
}
/*printf("time: %d-%d-%d %d:%d:%d",
usr_jb_current_time.year,
usr_jb_current_time.month,
usr_jb_current_time.day,
usr_jb_current_time.hour,
usr_jb_current_time.min,
usr_jb_current_time.sec);*/
}
}
struct sys_time usr_set_time;
void usr_set_sys_time()//设置时间
{
//dev_ioctl(__this->dev_handle, IOCTL_SET_SYS_TIME, (u32)&usr_set_time);
write_sys_time(&usr_set_time);
usr_jb_current_time.year=usr_set_time.year;
usr_jb_current_time.month=usr_set_time.month;
usr_jb_current_time.day=usr_set_time.day;
usr_jb_current_time.hour=usr_set_time.hour;
usr_jb_current_time.min=usr_set_time.min;
usr_jb_current_time.sec=usr_set_time.sec;
usr_var.usr_cureent_utc=convertToUtcTimestamp(usr_jb_current_time.year,usr_jb_current_time.month,usr_jb_current_time.day,usr_jb_current_time.hour,usr_jb_current_time.min,usr_jb_current_time.sec);
if(usr_var.usr_cureent_utc)
{
if(usr_var.usr_cureent_utc>usr_var.usr_timezoneOffset)usr_var.usr_cureent_utc=usr_var.usr_cureent_utc-usr_var.usr_timezoneOffset;
}
printf("##### usr_var.usr_cureent_utc = %d\n",usr_var.usr_cureent_utc);
}
#else
void app_rtc_task()
{
}
#endif
+140
View File
@@ -0,0 +1,140 @@
#include "system/includes.h"
#include "app_config.h"
#include "asm/pwm_led.h"
#include "tone_player.h"
#include "ui_manage.h"
#include "app_main.h"
#include "app_task.h"
#include "asm/charge.h"
#include "app_power_manage.h"
#include "app_charge.h"
#include "user_cfg.h"
#include "audio.h"
#include "vm.h"
#include "sys_time.h"
/*
硬件定时器demo
*/
extern const int CONFIG_CPU_UNMASK_IRQ_ENABLE;//需要极准确的定时效果时开启不可屏蔽中断
static JL_TIMER_TypeDef *TIMER = NULL;
static int irq_id = -1;
#define TIMER_UNIT_US 1000//设置中断时间,单位us
#define MAX_TIME_CNT 0x7fff //分频准确范围,更具实际情况调整
#define MIN_TIME_CNT 0x0030
static const u16 timer_div[] = {
/*0000*/ 1,
/*0001*/ 4,
/*0010*/ 16,
/*0011*/ 64,
/*0100*/ 2,
/*0101*/ 8,
/*0110*/ 32,
/*0111*/ 128,
/*1000*/ 256,
/*1001*/ 4 * 256,
/*1010*/ 16 * 256,
/*1011*/ 64 * 256,
/*1100*/ 2 * 256,
/*1101*/ 8 * 256,
/*1110*/ 32 * 256,
/*1111*/ 128 * 256,
};
SET_INTERRUPT
static void user_timer_isr()
{
/*if(CONFIG_CPU_UNMASK_IRQ_ENABLE){
unmask_enter_critical();
}
else{
local_irq_disable();
}*/
TIMER->CON |= BIT(14); //清中断标志位
//用户自定义代码
//......
/*if(CONFIG_CPU_UNMASK_IRQ_ENABLE){
unmask_exit_critical();
}
else{
local_irq_enable();
}*/
}
int user_timer_uninit();
int user_timer_init(u16 usr_time_us)
{
u32 prd_cnt;
u8 index;
u32 app_timer_clk = 24000000;//时钟用STD24M
user_timer_uninit();
printf("------------%s :%d", __func__, __LINE__);
printf("%d %d %d %d %d %d\n", JL_TIMER0->CON, JL_TIMER1->CON, JL_TIMER2->CON,
JL_TIMER3->CON, JL_TIMER4->CON, JL_TIMER5->CON);
/*if((JL_TIMER0->CON & 0x3) == 0) {
TIMER = JL_TIMER0;
irq_id = IRQ_TIME0_IDX;
}
else */if((JL_TIMER1->CON & 0x3) == 0) {
TIMER = JL_TIMER1;
irq_id = IRQ_TIME1_IDX;
}
else if((JL_TIMER2->CON & 0x3) == 0) {
TIMER = JL_TIMER2;
irq_id = IRQ_TIME2_IDX;
}
else if((JL_TIMER3->CON & 0x3) == 0) {
TIMER = JL_TIMER3;
irq_id = IRQ_TIME3_IDX;
}
else if((JL_TIMER4->CON & 0x3) == 0) {
TIMER = JL_TIMER4;
irq_id = IRQ_TIME4_IDX;
}
else if((JL_TIMER5->CON & 0x3) == 0) {
TIMER = JL_TIMER5;
irq_id = IRQ_TIME5_IDX;
}
else{
return -1;
}
for (index = 0; index < (sizeof(timer_div) / sizeof(timer_div[0])); index++) {
prd_cnt = usr_time_us * (app_timer_clk / 1000000) / timer_div[index];
if (prd_cnt > MIN_TIME_CNT && prd_cnt < MAX_TIME_CNT) {
break;
}
}
printf("irq_id %d PRD : 0x%x / %d", irq_id, prd_cnt, app_timer_clk);
TIMER->CNT = 0;
TIMER->PRD = prd_cnt - 1;
request_irq(irq_id, 2, user_timer_isr, 0);
if(CONFIG_CPU_UNMASK_IRQ_ENABLE){
irq_unmask_set(irq_id, 1, 0);
}
TIMER->CON = (index << 4) | BIT(0) | BIT(11)| BIT(12);//BIT(11)| BIT(12):时钟用STD24M
printf("PRD : 0x%x / %d", prd_cnt, app_timer_clk);
return 0;
}
int user_timer_uninit()
{
if(TIMER == NULL){
return 0;
}
TIMER->CON = BIT(14);
unrequest_irq(irq_id);
TIMER = NULL;
return 0;
}
+103
View File
@@ -0,0 +1,103 @@
#include "system/includes.h"
#include "asm/uart_dev.h"
#include "system/event.h"
#include "key_event_deal.h"
#include "app_task.h"
#include "usr_jb_global.h"
/*
硬件uart demo
*/
#if USR_JB_UART_RX_PIN
/*
在打开sleep时使用UART接收,需要把UART RX引脚配置为唤醒脚
在休眠时,如果对端MCU需要发数据给蓝牙IC,则需要先发一个唤醒帧来唤醒蓝牙IC,
唤醒后对端MCU再发送协议数据,具体用法全局搜索 USR_JB_UART_RX_PIN 这个宏,本demo已经做好了
或者也可以单独使用一个GPIO,当对端有数据要过来时,拉低或者拉高GPIO,数据结束后再休眠
*/
const uart_bus_t *uart_bus;
static u8 uart_cbuf[512] __attribute__((aligned(4)));
static u8 uart_rxbuf[512] __attribute__((aligned(4)));
int uart_tr_send_data(u8 *data, u32 len)
{
if(uart_bus)
{
if(usr_var.usr_uart_recieve==0)
{
usr_var.usr_uart_recieve=1;
uart_bus->write(data,len);
usr_var.usr_uart_recieve=0;
}
else
{
uart_bus->write(data,len);
}
}
}
void usr_uart_send_test()
{
char* test_string="I am uart test\n";
uart_tr_send_data(test_string,strlen(test_string));
}
static void uart_u_task(void *arg)
{
int ret;
u32 uart_rxcnt = 0;
printf("uart_u_task start\n");
while (1)
{
//uart_bus->read()在尚未收到串口数据时会pend信号量,挂起task,直到UART_RX_PND或UART_RX_OT_PND中断发生,post信号量,唤醒task
uart_rxcnt = uart_bus->read(uart_rxbuf, sizeof(uart_rxbuf), 0);
if (uart_rxcnt)
{
usr_var.usr_uart_recieve=5;///不进入sleep
uart_tr_send_data(uart_rxbuf,uart_rxcnt);///收发回传测试
}
}
}
void uart_dev_init_main()
{
struct uart_platform_data_t u_arg = {0};
u_arg.tx_pin = USR_JB_UART_TX_PIN;
u_arg.rx_pin = USR_JB_UART_RX_PIN;
u_arg.rx_cbuf = uart_cbuf;
u_arg.rx_cbuf_size = 512;
u_arg.frame_length = 512;
u_arg.rx_timeout = 10;
u_arg.isr_cbfun = NULL;
u_arg.baud = 115200;
u_arg.is_9bit = 0;
uart_bus = uart_dev_open(&u_arg);
if (uart_bus != NULL)
{
printf("uart_dev_open() success\n");
os_task_create(uart_u_task, (void *)uart_bus, 31, 512, 0, "uart_u_task");
}
}
#endif