demo工程暂存 优化菜单界面UI和功能

This commit is contained in:
2024-04-29 16:32:24 +08:00
commit 330cd25cf1
3310 changed files with 2163318 additions and 0 deletions

View File

@ -0,0 +1,679 @@
#include <stdint.h>
#include <stddef.h>
#include "driver_gpio.h"
#include "fr30xx.h"
#include "app_task.h"
#include "fr_device_pmu_io.h"
#include "fr_device_button.h"
#include "app_lvgl.h"
/* FreeRTOS kernel includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "timers.h"
#define BUTTON_IDX_MAX 1
#define BUTTON_SHORT_DURING 0x08 // x10ms
#define BUTTON_LONG_DURING 0x14 // x100ms
#define BUTTON_LONG_LONG_DURING 0x28 // x100ms
#define BUTTON_MULTI_INTERVAL 0x14 // x10ms
#define BUTTON_LONG_PRESSING_INTERVAL 0x1e // x10ms
uint8_t current_state = BUTTON_WORKING_STATE_IDLE;
uint16_t button_task_id;
xTimerHandle button_anti_shake_timer;
xTimerHandle button_pressing_timer;
xTimerHandle button_state_timer;
xTimerHandle moto_mode_button_state_timer;
xTimerHandle moto_set_button_state_timer;
/* which io is enabled for button function */
uint32_t button_io_mask = 0;
uint32_t curr_button_before_anti_shake = 0;
uint32_t current_pressed_button = 0;
uint32_t last_saved_button = 0;
uint32_t button_to_be_send = 0; //for multi click
uint8_t pressed_cnt = 0; //for multi click
void button_toggle_detected(uint32_t curr_button)
{
if(button_io_mask != 0) {
curr_button_before_anti_shake = curr_button & button_io_mask;
if(xPortIsInsideInterrupt())
xTimerStartFromISR( button_anti_shake_timer, NULL );
else
xTimerStart(button_anti_shake_timer, 0);
}
}
void button_int_isr(uint32_t changed_button)
{
uint32_t curr_button;
curr_button = current_pressed_button ^ changed_button;
struct app_task_event *event;
event = app_task_event_alloc(APP_TASK_EVENT_BTN_TOGGLE, sizeof(uint32_t), false);
if(event)
{
memcpy(event->param, (void *)&curr_button, sizeof(uint32_t));
event->param_len = sizeof(uint32_t);
app_task_event_post(event, false);
}
}
void button_send_event(uint8_t event, uint32_t button, uint8_t cnt)
{
struct button_msg_t msg;
msg.button_index = button;
msg.button_type = event;
msg.button_cnt = cnt;
struct app_task_event *toggle_event;
toggle_event = app_task_event_alloc(APP_TASK_EVENT_BTN_OUTPUT, sizeof(msg), false);
if(toggle_event)
{
memcpy(toggle_event->param, (void *)&msg, sizeof(msg));
toggle_event->param_len = sizeof(msg);
app_task_event_post(toggle_event, false);
}
pressed_cnt = 0;
}
static void button_idle(uint8_t event)
{
if(event == BUTTON_WORKING_EVENT_SINGLE_PRESSED)
{
current_state = BUTTON_WORKING_STATE_JUST_PRESSED;
xTimerChangePeriod(button_state_timer, BUTTON_SHORT_DURING*10,0);
xTimerStart(button_state_timer,0);
button_send_event(BUTTON_PRESSED, current_pressed_button, pressed_cnt);
}
else if(event == BUTTON_WORKING_EVENT_COMB_PRESSED)
{
current_state = BUTTON_WORKING_STATE_COMB_JUST_PRESSED;
xTimerChangePeriod(button_state_timer, BUTTON_SHORT_DURING*10,0);
xTimerStart(button_state_timer,0);
button_send_event(BUTTON_COMB_PRESSED, current_pressed_button, pressed_cnt);
}
}
static void button_just_pressed(uint8_t event)
{
if(event == BUTTON_WORKING_EVENT_RELEASED)
{
current_state = BUTTON_WORKING_STATE_IDLE;
xTimerStop(button_state_timer,0);
button_send_event(BUTTON_RELEASED, last_saved_button, pressed_cnt);
}
else if(event == BUTTON_WORKING_EVENT_COMB_PRESSED)
{
current_state = BUTTON_WORKING_STATE_COMB_JUST_PRESSED;
xTimerChangePeriod(button_state_timer, BUTTON_SHORT_DURING*10,0);
xTimerStart(button_state_timer,0);
button_send_event(BUTTON_COMB_PRESSED, current_pressed_button, pressed_cnt);
}
else if(event == BUTTON_WORKING_EVENT_TIME_OUT)
{
current_state = BUTTON_WORKING_STATE_PRESSED;
xTimerChangePeriod(button_state_timer, (BUTTON_LONG_DURING*10-BUTTON_SHORT_DURING)*10,0);
xTimerStart(button_state_timer,0);
}
}
static void button_pressed(uint8_t event)
{
if(event == BUTTON_WORKING_EVENT_RELEASED)
{
if(0/*__jump_table.button_disable_multi_click*/ & last_saved_button)
{
current_state = BUTTON_WORKING_STATE_IDLE;
button_send_event(BUTTON_SHORT_PRESSED, last_saved_button, 0);
}
else
{
//TBD<42><44><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
current_state = BUTTON_WORKING_STATE_WAIT_MULTI;
button_to_be_send = last_saved_button;
pressed_cnt++;
xTimerChangePeriod(button_state_timer,BUTTON_MULTI_INTERVAL*10,0);
xTimerStart(button_state_timer,0);
}
}
else if(event == BUTTON_WORKING_EVENT_COMB_PRESSED)
{
current_state = BUTTON_WORKING_STATE_COMB_JUST_PRESSED;
xTimerChangePeriod(button_state_timer, BUTTON_SHORT_DURING*10,0);
xTimerStart(button_state_timer,0);
button_send_event(BUTTON_COMB_PRESSED, current_pressed_button, pressed_cnt);
}
else if(event == BUTTON_WORKING_EVENT_TIME_OUT)
{
current_state = BUTTON_WORKING_STATE_LONG_PRESSED;
xTimerChangePeriod(button_state_timer, ((BUTTON_LONG_LONG_DURING-BUTTON_LONG_DURING)*10)*10,0);
xTimerStart(button_state_timer,0);
xTimerChangePeriod(button_pressing_timer, BUTTON_LONG_PRESSING_INTERVAL*10,0);
xTimerStart(button_pressing_timer,0);
button_send_event(BUTTON_LONG_PRESSED, current_pressed_button, pressed_cnt);
}
}
static void button_wait_multi(uint8_t event)
{
if(event == BUTTON_WORKING_EVENT_SINGLE_PRESSED)
{
if(current_pressed_button != button_to_be_send)
{
if(pressed_cnt > 1)
{
button_send_event(BUTTON_MULTI_PRESSED, button_to_be_send, pressed_cnt);
}
else
{
button_send_event(BUTTON_SHORT_PRESSED, button_to_be_send, pressed_cnt);
}
button_send_event(BUTTON_PRESSED, current_pressed_button, pressed_cnt);
}
current_state = BUTTON_WORKING_STATE_JUST_PRESSED;
xTimerChangePeriod(button_state_timer, BUTTON_SHORT_DURING*10,0);
xTimerStart(button_state_timer,0);
}
else if(event == BUTTON_WORKING_EVENT_COMB_PRESSED)
{
current_state = BUTTON_WORKING_STATE_COMB_JUST_PRESSED;
xTimerChangePeriod(button_state_timer, BUTTON_SHORT_DURING*10,0);
xTimerStart(button_state_timer,0);
button_send_event(BUTTON_COMB_PRESSED, current_pressed_button, pressed_cnt);
button_send_event(BUTTON_SHORT_PRESSED, button_to_be_send, pressed_cnt);
}
else if(event == BUTTON_WORKING_EVENT_TIME_OUT)
{
current_state = BUTTON_WORKING_STATE_IDLE;
if(pressed_cnt > 1)
{
button_send_event(BUTTON_MULTI_PRESSED, button_to_be_send, pressed_cnt);
}
else
{
button_send_event(BUTTON_SHORT_PRESSED, button_to_be_send, pressed_cnt);
}
}
}
static void button_long_pressed(uint8_t event)
{
if(event == BUTTON_WORKING_EVENT_RELEASED)
{
current_state = BUTTON_WORKING_STATE_IDLE;
xTimerStop(button_state_timer,0);
xTimerStop(button_pressing_timer,0);
button_send_event(BUTTON_LONG_RELEASED, last_saved_button, pressed_cnt);
}
else if(event == BUTTON_WORKING_EVENT_COMB_PRESSED)
{
current_state = BUTTON_WORKING_STATE_COMB_JUST_PRESSED;
xTimerChangePeriod(button_state_timer, BUTTON_SHORT_DURING*10,0);
xTimerStart(button_state_timer,0);
xTimerStop(button_pressing_timer,0);
button_send_event(BUTTON_COMB_PRESSED, current_pressed_button, pressed_cnt);
button_send_event(BUTTON_LONG_RELEASED, last_saved_button, pressed_cnt);
}
else if(event == BUTTON_WORKING_EVENT_TIME_OUT)
{
current_state = BUTTON_WORKING_STATE_LONG_LONG_PRESSED;
button_send_event(BUTTON_LONG_LONG_PRESSED, current_pressed_button, pressed_cnt);
}
}
static void button_long_long_pressed(uint8_t event)
{
if(event == BUTTON_WORKING_EVENT_RELEASED)
{
xTimerStop(button_pressing_timer,0);
current_state = BUTTON_WORKING_STATE_IDLE;
button_send_event(BUTTON_LONG_LONG_RELEASED, last_saved_button, pressed_cnt);
}
else if(event == BUTTON_WORKING_EVENT_COMB_PRESSED)
{
current_state = BUTTON_WORKING_STATE_COMB_JUST_PRESSED;
xTimerChangePeriod(button_state_timer, BUTTON_SHORT_DURING*10,0);
xTimerStart(button_state_timer,0);
xTimerStop(button_pressing_timer,0);
button_send_event(BUTTON_COMB_PRESSED, current_pressed_button, pressed_cnt);
button_send_event(BUTTON_LONG_LONG_RELEASED, last_saved_button, pressed_cnt);
}
}
static void button_comb_just_pressed(uint8_t event)
{
if(event == BUTTON_WORKING_EVENT_RELEASED)
{
current_state = BUTTON_WORKING_STATE_IDLE;
xTimerStop(button_state_timer,0);
button_send_event(BUTTON_COMB_RELEASED, last_saved_button, pressed_cnt);
}
else if(event == BUTTON_WORKING_EVENT_SINGLE_PRESSED)
{
current_state = BUTTON_WORKING_STATE_JUST_PRESSED;
xTimerChangePeriod(button_state_timer, BUTTON_SHORT_DURING*10,0);
xTimerStart(button_state_timer,0);
button_send_event(BUTTON_COMB_RELEASED, last_saved_button, pressed_cnt);
button_send_event(BUTTON_PRESSED, current_pressed_button, pressed_cnt);
}
else if(event == BUTTON_WORKING_EVENT_COMB_PRESSED)
{
current_state = BUTTON_WORKING_STATE_JUST_PRESSED;
xTimerChangePeriod(button_state_timer, BUTTON_SHORT_DURING*10,0);
xTimerStart(button_state_timer,0);
button_send_event(BUTTON_COMB_PRESSED, current_pressed_button, pressed_cnt);
}
else if(event == BUTTON_WORKING_EVENT_TIME_OUT)
{
current_state = BUTTON_WORKING_STATE_COMB_PRESSED;
xTimerChangePeriod(button_state_timer, (BUTTON_LONG_DURING*10-BUTTON_SHORT_DURING)*10,0);
xTimerStart(button_state_timer,0);
}
}
static void button_comb_pressed(uint8_t event)
{
if(event == BUTTON_WORKING_EVENT_RELEASED)
{
current_state = BUTTON_WORKING_STATE_IDLE;
xTimerStop(button_state_timer,0);
button_send_event(BUTTON_COMB_SHORT_PRESSED, last_saved_button, pressed_cnt);
}
else if(event == BUTTON_WORKING_EVENT_SINGLE_PRESSED)
{
current_state = BUTTON_WORKING_STATE_JUST_PRESSED;
xTimerChangePeriod(button_state_timer, BUTTON_SHORT_DURING*10,0);
xTimerStart(button_state_timer,0);
button_send_event(BUTTON_COMB_SHORT_PRESSED, last_saved_button, pressed_cnt);
button_send_event(BUTTON_PRESSED, current_pressed_button, pressed_cnt);
}
else if(event == BUTTON_WORKING_EVENT_COMB_PRESSED)
{
current_state = BUTTON_WORKING_STATE_COMB_JUST_PRESSED;
xTimerChangePeriod(button_state_timer, BUTTON_SHORT_DURING*10,0);
xTimerStart(button_state_timer,0);
button_send_event(BUTTON_COMB_SHORT_PRESSED, last_saved_button, pressed_cnt);
button_send_event(BUTTON_COMB_PRESSED, current_pressed_button, pressed_cnt);
}
else if(event == BUTTON_WORKING_EVENT_TIME_OUT)
{
current_state = BUTTON_WORKING_STATE_COMB_LONG_PRESSED;
xTimerChangePeriod(button_state_timer, ((BUTTON_LONG_LONG_DURING-BUTTON_LONG_DURING)*10)*10,0);
xTimerStart(button_state_timer,0);
xTimerChangePeriod(button_pressing_timer, BUTTON_LONG_PRESSING_INTERVAL*10,0);
xTimerStart(button_pressing_timer,0);
button_send_event(BUTTON_COMB_LONG_PRESSED, current_pressed_button, pressed_cnt);
}
}
static void button_comb_long_pressed(uint8_t event)
{
if(event == BUTTON_WORKING_EVENT_RELEASED)
{
current_state = BUTTON_WORKING_STATE_IDLE;
xTimerStop(button_state_timer,0);
xTimerStop(button_pressing_timer,0);
button_send_event(BUTTON_COMB_LONG_RELEASED, last_saved_button, pressed_cnt);
}
else if(event == BUTTON_WORKING_EVENT_SINGLE_PRESSED)
{
current_state = BUTTON_WORKING_STATE_JUST_PRESSED;
xTimerChangePeriod(button_state_timer, BUTTON_SHORT_DURING*10,0);
xTimerStart(button_state_timer,0);
xTimerStop(button_pressing_timer,0);
button_send_event(BUTTON_COMB_LONG_RELEASED, last_saved_button, pressed_cnt);
button_send_event(BUTTON_PRESSED, current_pressed_button, pressed_cnt);
}
else if(event == BUTTON_WORKING_EVENT_COMB_PRESSED)
{
current_state = BUTTON_WORKING_STATE_COMB_JUST_PRESSED;
xTimerChangePeriod(button_state_timer, BUTTON_SHORT_DURING*10,0);
xTimerStart(button_state_timer,0);
xTimerStop(button_pressing_timer,0);
button_send_event(BUTTON_COMB_LONG_RELEASED, last_saved_button, pressed_cnt);
button_send_event(BUTTON_COMB_PRESSED, current_pressed_button, pressed_cnt);
}
else if(event == BUTTON_WORKING_EVENT_TIME_OUT)
{
current_state = BUTTON_WORKING_STATE_COMB_LONG_LONG_PRESSED;
button_send_event(BUTTON_COMB_LONG_LONG_PRESSED, current_pressed_button, pressed_cnt);
}
}
static void button_comb_long_long_pressed(uint8_t event)
{
if(event == BUTTON_WORKING_EVENT_RELEASED)
{
current_state = BUTTON_WORKING_STATE_IDLE;
xTimerStop(button_pressing_timer,0);
button_send_event(BUTTON_COMB_LONG_LONG_RELEASED, last_saved_button, pressed_cnt);
}
else if(event == BUTTON_WORKING_EVENT_SINGLE_PRESSED)
{
current_state = BUTTON_WORKING_STATE_JUST_PRESSED;
xTimerChangePeriod(button_state_timer, BUTTON_SHORT_DURING*10,0);
xTimerStart(button_state_timer,0);
xTimerStop(button_pressing_timer,0);
button_send_event(BUTTON_COMB_LONG_LONG_RELEASED, last_saved_button, pressed_cnt);
button_send_event(BUTTON_PRESSED, current_pressed_button, pressed_cnt);
}
else if(event == BUTTON_WORKING_EVENT_COMB_PRESSED)
{
current_state = BUTTON_WORKING_STATE_COMB_JUST_PRESSED;
xTimerChangePeriod(button_state_timer, BUTTON_SHORT_DURING*10,0);
xTimerStart(button_state_timer,0);
xTimerStop(button_pressing_timer,0);
button_send_event(BUTTON_COMB_LONG_LONG_RELEASED, last_saved_button, pressed_cnt);
button_send_event(BUTTON_COMB_PRESSED, current_pressed_button, pressed_cnt);
}
}
void (*const button_statemachines[BUTTON_WORKING_STATE_MAX])(uint8_t) =
{
button_idle,
button_just_pressed,
button_pressed,
button_wait_multi,
button_long_pressed,
button_long_long_pressed,
button_comb_just_pressed,
button_comb_pressed,
button_comb_long_pressed,
button_comb_long_long_pressed,
};
//one or more button is released or pressed
int button_toggle_handler(uint32_t curr_button)
{
enum button_working_event_t event;
current_pressed_button = curr_button;
if(last_saved_button != current_pressed_button)
{
if(current_pressed_button == 0)
{
event = BUTTON_WORKING_EVENT_RELEASED;
}
else
{
if((current_pressed_button & (current_pressed_button-1)) == 0)
{
event = BUTTON_WORKING_EVENT_SINGLE_PRESSED;
}
else
{
event = BUTTON_WORKING_EVENT_COMB_PRESSED;
}
}
button_statemachines[current_state](event);
last_saved_button = current_pressed_button;
}
return 0;
}
static void button_timeout_handler( TimerHandle_t xTimer)
{
button_statemachines[current_state](BUTTON_WORKING_EVENT_TIME_OUT);
}
static void button_pressing_timeout_handler( TimerHandle_t xTimer )
{
enum button_type_t event;
if((current_pressed_button & (current_pressed_button - 1)) == 0)
{
event = BUTTON_LONG_PRESSING;
}
else
{
event = BUTTON_COMB_LONG_PRESSING;
}
button_send_event(event, current_pressed_button, pressed_cnt);
xTimerChangePeriod(button_pressing_timer, BUTTON_LONG_PRESSING_INTERVAL*10,0);
xTimerStart(button_pressing_timer,0);
}
static void button_anti_shake_timeout_handler( TimerHandle_t xTimer )
{
uint32_t curr_button;
curr_button = ool_read16(PMU_REG_PIN_DATA);
curr_button &= button_io_mask;
if(curr_button == curr_button_before_anti_shake)
{
curr_button ^= button_io_mask;
struct app_task_event *event;
event = app_task_event_alloc(APP_TASK_EVENT_BTN_TOGGLE, sizeof(uint32_t), false);
if(event)
{
memcpy(event->param, (void *)&curr_button, sizeof(uint32_t));
event->param_len = sizeof(uint32_t);
app_task_event_post(event, false);
}
}
}
void button_event_handler(void * param)
{
struct button_msg_t *button_msg;
const char *button_type_str[] = {
"BUTTON_PRESSED",
"BUTTON_RELEASED",
"BUTTON_SHORT_PRESSED",
"BUTTON_MULTI_PRESSED",
"BUTTON_LONG_PRESSED",
"BUTTON_LONG_PRESSING",
"BUTTON_LONG_RELEASED",
"BUTTON_LONG_LONG_PRESSED",
"BUTTON_LONG_LONG_RELEASED",
"BUTTON_COMB_PRESSED",
"BUTTON_COMB_RELEASED",
"BUTTON_COMB_SHORT_PRESSED",
"BUTTON_COMB_LONG_PRESSED",
"BUTTON_COMB_LONG_PRESSING",
"BUTTON_COMB_LONG_RELEASED",
"BUTTON_COMB_LONG_LONG_PRESSED",
"BUTTON_COMB_LONG_LONG_RELEASED",
};
button_msg = (struct button_msg_t *)param;
uint8_t encode_bit_code = 0;
printf("KEY 0x%08x, TYPE %s. %d\r\n", button_msg->button_index, button_type_str[button_msg->button_type],button_msg->button_type);
if(button_msg->button_type == BUTTON_PRESSED) //short button
{
if(button_msg->button_index == 113)
{
if(!gui_task_resume()){
encode_bit_code = 113;
//gui_task_msg_send(BUTTON_KEY_EVT,NULL,0,NULL,0,NULL);
gui_task_msg_send(ENCODE_KEY_EVT,(void *)&encode_bit_code,1,NULL,0,NULL);
encode_bit_code = 0x0;
gui_task_msg_send(ENCODE_KEY_EVT,(void *)&encode_bit_code,1,NULL,0,NULL);
}
}
else if(button_msg->button_index == 119)
{
if(!gui_task_resume())
{
encode_bit_code = 119;
// gui_task_msg_send(BUTTON_KEY2_EVT,NULL,0,NULL,0,NULL);
gui_task_msg_send(ENCODE_KEY_EVT,(void *)&encode_bit_code,1,NULL,0,NULL);\
encode_bit_code = 0x0;
gui_task_msg_send(ENCODE_KEY_EVT,(void *)&encode_bit_code,1,NULL,0,NULL);
}
}
}
else if(button_msg->button_type == BUTTON_LONG_PRESSED)//long
{
if(button_msg->button_index == 113)
{
if(!gui_task_resume())
gui_task_msg_send(BUTTON_KEY_EVT,NULL,0,NULL,0,NULL);
}
else if(button_msg->button_index == 119)
{
if(!gui_task_resume())
{
gui_task_msg_send(BUTTON_KEY2_EVT,NULL,0,NULL,0,NULL);
}
}
}
}
void button_init(uint32_t enable_io)
{
button_io_mask = enable_io;
button_anti_shake_timer = xTimerCreate("button_anti_shake_timer", 10, pdFALSE, NULL, button_anti_shake_timeout_handler);
button_pressing_timer = xTimerCreate("button_pressing_timer", BUTTON_LONG_PRESSING_INTERVAL * 10, pdFALSE, NULL, button_pressing_timeout_handler);
button_state_timer = xTimerCreate("button_state_timer", 10 , pdFALSE, NULL, button_timeout_handler);
}
#define BUTTON_SET 0X00
#define BUTTON_MODE 0X01
#define BUTTON_LONG_SET 0X02
#define BUTTON_LONG_MODE 0X03
enum
{
LV_KEY_RESET = 0, // 0x11
LV_KEY_SET = 10, // 0x71
LV_KEY_MODE = 119, // 0x77
LV_KEY_LONG_SET = 114, // 0x72
LV_KEY_LONG_MODE = 120, // 0x78
};
#define SHORT_PRESS_THRESHOLD 200
static bool button_set_status(void){
bool status ;
status = gpio_read_pin(GPIOB, GPIO_PIN_10);
return status;
}
static bool button_mode_status(void){
bool status ;
status = gpio_read_pin(GPIOB, GPIO_PIN_11);
return status;
}
extern uint8_t key_code;
extern uint32_t encode_release_last_time;
extern uint8_t lvgl_start;
static void button_task(void *arg)
{
bool set_status = 1;
bool mode_status = 1;
uint16_t set_endTime = 0;
uint16_t mode_endTime = 0;
bool set_flag_Pressed = false; //按下为true
bool mode_flag_Pressed = false; //按下为true
uint8_t encode_bit_code = 0;
for(;;){
vTaskDelay(10);
set_status = button_set_status();
mode_status = button_mode_status();
if(lvgl_start!=1)
continue;
if (!set_status && !set_flag_Pressed)
set_flag_Pressed = true;
if(!set_status && set_flag_Pressed)
set_endTime++;
if (set_status && set_flag_Pressed) {
set_flag_Pressed = false;
if (set_endTime < SHORT_PRESS_THRESHOLD) {
//printf("set BUTTON_KEY_EVT============== set_endTime = %d \r\n",set_endTime);
encode_release_last_time = set_endTime;//portGET_RUN_TIME_COUNTER_VALUE();
encode_bit_code = LV_KEY_SET;
gui_task_msg_send(ENCODE_KEY_EVT,(void *)&encode_bit_code,1,NULL,0,NULL);
vTaskDelay(80);
encode_bit_code = LV_KEY_RESET;
gui_task_msg_send(ENCODE_KEY_EVT,(void *)&encode_bit_code,1,NULL,0,NULL);
} else{
//printf("set long press ENCODE_KEY_EVT============== set_endTime %d\r\n",set_endTime);
encode_bit_code = LV_KEY_LONG_SET;
gui_task_msg_send(ENCODE_KEY_EVT,(void *)&encode_bit_code,1,NULL,0,NULL);
vTaskDelay(80);
encode_bit_code = LV_KEY_RESET;
gui_task_msg_send(ENCODE_KEY_EVT,(void *)&encode_bit_code,1,NULL,0,NULL);
}
set_endTime =0;
}
if (!mode_status && !mode_flag_Pressed)
mode_flag_Pressed = true;
if(!mode_status && mode_flag_Pressed)
mode_endTime++;
if(mode_status && mode_flag_Pressed) {
mode_flag_Pressed = false;
if (mode_endTime < SHORT_PRESS_THRESHOLD) {//短按
//printf("mode BUTTON_KEY2_EVT============== mode_endTime =%d\r\n",mode_endTime);
encode_bit_code = LV_KEY_MODE;
gui_task_msg_send(ENCODE_KEY_EVT,(void *)&encode_bit_code,1,NULL,0,NULL);
vTaskDelay(80);
encode_bit_code = LV_KEY_RESET;
gui_task_msg_send(ENCODE_KEY_EVT,(void *)&encode_bit_code,1,NULL,0,NULL);
} else{
//printf("mode long press BUTTON_KEY2_EVT============== mode_endTime =%d\r\n",mode_endTime);
encode_bit_code = LV_KEY_LONG_MODE;
gui_task_msg_send(ENCODE_KEY_EVT,(void *)&encode_bit_code,1,NULL,0,NULL);
vTaskDelay(80);
encode_bit_code = LV_KEY_RESET;
gui_task_msg_send(ENCODE_KEY_EVT,(void *)&encode_bit_code,1,NULL,0,NULL);
}
mode_endTime =0;
}
}
}
void button_gpio_config(void)
{
GPIO_InitTypeDef gpio_config;
__SYSTEM_GPIOB_CLK_ENABLE();
gpio_config.Pin = GPIO_PIN_10 | GPIO_PIN_11;
gpio_config.Mode = GPIO_MODE_INPUT;
gpio_config.Pull = GPIO_PULLUP;
gpio_config.Alternate = GPIO_FUNCTION_0;
gpio_init(GPIOB, &gpio_config);
xTaskCreate(button_task, "buttontask", RPMSG_TASK_STACK_SIZE, NULL, RPMSG_TASK_PRIORITY, NULL);
}

View File

@ -0,0 +1,82 @@
#ifndef _BUTTON_H
#define _BUTTON_H
#include <stdint.h>
enum button_event_t
{
BUTTON_TOGGLE,
BUTTON_PRESSED_EVENT,
BUTTON_TIMER_TO_TIMER,
BUTTON_PRESSING_TO_TIMER,
BUTTON_ANTI_SHAKE_TO_TIMER,
};
enum button_type_t
{
BUTTON_PRESSED,
BUTTON_RELEASED,
BUTTON_SHORT_PRESSED,
BUTTON_MULTI_PRESSED,
BUTTON_LONG_PRESSED,
BUTTON_LONG_PRESSING,
BUTTON_LONG_RELEASED,
BUTTON_LONG_LONG_PRESSED,
BUTTON_LONG_LONG_RELEASED,
BUTTON_COMB_PRESSED,
BUTTON_COMB_RELEASED,
BUTTON_COMB_SHORT_PRESSED,
BUTTON_COMB_LONG_PRESSED,
BUTTON_COMB_LONG_PRESSING,
BUTTON_COMB_LONG_RELEASED,
BUTTON_COMB_LONG_LONG_PRESSED,
BUTTON_COMB_LONG_LONG_RELEASED,
};
enum button_working_state_t
{
BUTTON_WORKING_STATE_IDLE,
BUTTON_WORKING_STATE_JUST_PRESSED,
BUTTON_WORKING_STATE_PRESSED,
BUTTON_WORKING_STATE_WAIT_MULTI,
BUTTON_WORKING_STATE_LONG_PRESSED,
BUTTON_WORKING_STATE_LONG_LONG_PRESSED,
BUTTON_WORKING_STATE_COMB_JUST_PRESSED,
BUTTON_WORKING_STATE_COMB_PRESSED,
BUTTON_WORKING_STATE_COMB_LONG_PRESSED,
BUTTON_WORKING_STATE_COMB_LONG_LONG_PRESSED,
BUTTON_WORKING_STATE_MAX,
};
enum button_working_event_t
{
BUTTON_WORKING_EVENT_RELEASED,
BUTTON_WORKING_EVENT_SINGLE_PRESSED,
BUTTON_WORKING_EVENT_COMB_PRESSED,
BUTTON_WORKING_EVENT_TIME_OUT,
};
struct button_toggle_param_t
{
uint32_t curr_button;
uint32_t timestamp;
};
struct button_msg_t
{
uint32_t button_index;
uint8_t button_type;
uint8_t button_cnt; // only for multi click
};
void button_toggle_detected(uint32_t curr_button);
void button_int_isr(uint32_t changed_button);
void button_init(uint32_t enable_io);
void button_gpio_config(void);
int button_toggle_handler(uint32_t curr_button);
void button_event_handler(void *param);
#endif //_BUTTON_H

View File

@ -0,0 +1,188 @@
#include "fr_device_charge.h"
#include "app_lvgl.h"
static uint8_t charge_status = CHARGING_IDLE;
/************************************************************************************
* @fn charge init
*
* @brief charge init
*/
void device_charge_init(void)
{
uint32_t timeout_count = 10;
/* enable charge function, and set charge current & voltage. */
pmu_charge_enable(PMU_CHG_CUR_88mA, PMU_CHG_END_VOL_4_1);
#if 1
while(timeout_count)
{
/* Check that the charger is connected */
if (read_analog_status() & PMU_CHG_ACOK_STATUS_BIT)
{ /* filter */
//system_delay_us(100);
if (read_analog_status() & PMU_CHG_ACOK_STATUS_BIT)
{ /* The charger is connected. Check out action */
pmu_charge_monitor_en(PMU_CHARGING_OUT);
/* Check that the battery is full */
pmu_battery_full_monitor_en(PMU_BATTERY_FULL);
printf("charge config 1 \r\n");
charge_status = CHARGING_IN;
charge_vbat_toggle_detected(charge_status);
break;
}
}
else
{ /* filter */
//system_delay_us(100);
if ((read_analog_status() & PMU_CHG_ACOK_STATUS_BIT) == 0)
{ /* The charger not connected. Check in action */
pmu_charge_monitor_en(PMU_CHARGING_IN);
printf("charge config 2 \r\n");
charge_status = CHARGING_IDLE;
charge_vbat_toggle_detected(charge_status);
break;
}
}
timeout_count--;
if (timeout_count == 0)
printf("ACOK status timeout");
}
NVIC_EnableIRQ(PMU_IRQn);
#endif
//while(1);
}
void PMU_Charge_Monitor_IRQHandler(void)
{
if (read_analog_status() & PMU_CHG_ACOK_STATUS_BIT)
{
//printf("charge in...\r\n");
/* The charger is connected. Check out action */
pmu_charge_monitor_en(PMU_CHARGING_OUT);
/* Check that the battery is full */
pmu_battery_full_monitor_en(PMU_BATTERY_FULL);
charge_status = CHARGING_IN;
}
else
{
//printf("charge out...\r\n");
/* The charger not connected. Check in action */
pmu_charge_monitor_en(PMU_CHARGING_IN);
charge_status = CHARGING_OUT;
}
charge_vbat_toggle_detected(charge_status);
}
void PMU_Battery_Full_IRQHandler(void)
{
if (read_analog_status() & PMU_BATFULL_STATUS_BIT)
{
//printf("full...\r\n");
/* The battery is full. Check that the battery not full */
pmu_battery_full_monitor_en(PMU_BATTERY_NOT_FULL);
charge_status = CHARGING_FULL;
}
else
{
//printf("not full\r\n");
/* The battery not full. Check that the battery is full */
pmu_battery_full_monitor_en(PMU_BATTERY_FULL);
charge_status = CHARGING_NOT_FULL;
}
charge_vbat_toggle_detected(charge_status);
}
/*
send vbat charge status
*/
void charge_vbat_toggle_detected(uint8_t sat)
{
struct app_task_event *event;
event = app_task_event_alloc(APP_TASK_EVENT_CHARGE_OUTPUT, sizeof(uint8_t), false);
if(event)
{
memcpy(event->param, (void *)&sat, sizeof(uint8_t));
event->param_len = sizeof(uint8_t);
app_task_event_post(event, false);
}
}
void charge_event_handle(uint8_t param)
{
printf("%s param=%d \r\n",__func__,param);
switch(param)
{
case CHARGING_IDLE:
printf("---> CHARGING_IDLE \r\n");
break;
case CHARGING_IN:
printf("---> CHARGING_IN \r\n");
if(gui_task_handle_is_active() == NULL)
return;
gui_task_resume();
gui_task_msg_send(POWER_CHARGE_IN_EVT,NULL,0,NULL,0,NULL);
break;
case CHARGING_OUT:
printf("---> CHARGING_OUT \r\n");
if(gui_task_handle_is_active() == NULL)
return;
gui_task_resume();
gui_task_msg_send(POWER_CHARGE_OUT_EVT,NULL,0,NULL,0,NULL);
break;
case CHARGING_FULL:
printf("---> CHARGING_FULL \r\n");
break;
case CHARGING_NOT_FULL:
printf("---> CHARGING_NOT_FULL \r\n");
break;
}
}
uint8_t get_charge_status(void)
{
return charge_status;
}

View File

@ -0,0 +1,33 @@
#ifndef __FR_DEVICE_CHARGE__
#define __FR_DEVICE_CHARGE__
#ifdef __cplusplus
extern "C" {
#endif
#include "fr30xx.h"
#include "app_task.h"
#define read_analog_status() ool_read(PMU_REG_ANA_STATUS)
typedef enum
{
CHARGING_IDLE = 0,
CHARGING_IN,
CHARGING_OUT,
CHARGING_FULL,
CHARGING_NOT_FULL,
}enum_charge_type_t;
extern void device_charge_init(void);
extern void charge_vbat_toggle_detected(uint8_t sat);
extern void charge_event_handle(uint8_t param);
extern uint8_t get_charge_status(void);
#ifdef __cplusplus
}
#endif
#endif /* __FR_DEVICE_CHARGE__ */

View File

@ -0,0 +1,264 @@
#include <stdint.h>
#include <stddef.h>
#include "driver_gpio.h"
#include "fr30xx.h"
#include "app_task.h"
#include "fr_device_pmu_io.h"
#include "fr_device_encode.h"
#include "app_lvgl.h"
/* FreeRTOS kernel includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "timers.h"
extern uint8_t key_code;
#define ENCODE_FILO_LEN 16
static uint8_t encode_bit_status = 0;
static uint8_t encode_bit_code = 0;
encode_type_t encode_table_filo[ENCODE_FILO_LEN];
uint8_t encode_table_key[ENCODE_FILO_LEN];
uint8_t key_release_flag = 0;
const uint8_t encode_table_value[8][5] =
{
{0x01, 0x00, 0x02, 0x03, 0x01},
{0x02, 0x03, 0x01, 0x00, 0x01},
{0x03, 0x01, 0x00, 0x02, 0x01},
{0x00, 0x02, 0x03, 0x01, 0x01},
{0x02, 0x00, 0x01, 0x03, 0x02},
{0x01, 0x03, 0x02, 0x00, 0x02},
{0x03, 0x02, 0x00, 0x01, 0x02},
{0x00, 0x01, 0x03, 0x02, 0x02},
};
uint32_t encode_last_time;
static uint32_t get_encode_basetime(void)
{
uint32_t cur_base_time = portGET_RUN_TIME_COUNTER_VALUE();
uint32_t diff;
if(cur_base_time >= encode_last_time)
diff = cur_base_time - encode_last_time;
else
diff = (((uint32_t)0xFFFFFFFF) - encode_last_time) + cur_base_time + 1;
encode_last_time = cur_base_time;
return diff;
}
uint32_t encode_release_last_time;
static uint32_t get_encode_release_basetime(void)
{
uint32_t cur_base_time = portGET_RUN_TIME_COUNTER_VALUE();
uint32_t diff;
if(cur_base_time >= encode_release_last_time)
diff = cur_base_time - encode_release_last_time;
else
diff = (((uint32_t)0xFFFFFFFF) - encode_release_last_time) + cur_base_time + 1;
return diff;
}
void clear_encode_fifo(void)
{
encode_last_time = portGET_RUN_TIME_COUNTER_VALUE();
memset(encode_table_filo,0,ENCODE_FILO_LEN*2);
}
void encode_push_key(uint8_t key_value)
{
uint8_t i;
uint32_t time;
time = get_encode_basetime();
if(time <= 3)
{
time += encode_table_filo[0].time;
if(time > 0xff)
time = 0xff;
encode_table_filo[0].time = time;
encode_table_filo[0].keyvalue = key_value;
// printf("fiter");
}
else
{
for(i = ENCODE_FILO_LEN - 1; i > 0; i -- )
{
encode_table_filo[i] = encode_table_filo[i - 1];
}
encode_table_filo[0].keyvalue = key_value;
if(time > 255)
{
encode_table_filo[0].time = 0xff;
// printf("\n");
// printf("\n");
// printf("\n");
// printf("\n");
// printf("\n");
// printf("\n");
}
else
encode_table_filo[0].time = time;
}
// printf("keyvlue:");
// for(i = 0; i < 15; i ++ )
// {
// printf("%d/", encode_table_filo[i].keyvalue);
// printf("%d ", encode_table_filo[i].time);
// }
// printf("\n");
}
uint8_t get_encode_start(void)
{
uint8_t i = 0;
while(i < ENCODE_FILO_LEN)
{
if(encode_table_filo[i].time == 0xff)
{
i ++;
break;
}
i ++;
}
return i;
}
void encode_event_handle(uint8_t key_value)
{
uint8_t len;
uint8_t start;
uint8_t i,j;
// if (get_charte_state())
// return;
// if (system_enter_music_flag)
// return;
//printf("value %d\n", key_value);
start = get_encode_start();
len = start;
for(i = 0; i < len; i++)
{
encode_table_key[i] = encode_table_filo[start - 1].keyvalue;
start --;
}
if(len > 4)
{
j = 0;
while(j < (len-4))
{
i = 0;
while(i < 8)
{
if(memcmp(&encode_table_value[i][0],encode_table_key+j,4) == 0)
{
//if(!key_release_flag)
{
//os_timer_stop(&encode_release_timer);
encode_bit_code = encode_table_value[i][4];
//printf("code %d \n",encode_bit_code);
key_release_flag = 1;
if(!gui_task_resume())
{
encode_release_last_time = portGET_RUN_TIME_COUNTER_VALUE();
encode_bit_code |= 0x80;
gui_task_msg_send(ENCODE_KEY_EVT,(void *)&encode_bit_code,1,NULL,0,NULL);
}
return;
}
}
i ++;
}
j++;
}
}
else if((len >= 2) && (len <= 4))
{
i = 0;
while(i < 8)
{
if(memcmp(&encode_table_value[i][0],encode_table_key,len) == 0)
{
//if(!key_release_flag)
{
//os_timer_stop(&encode_release_timer);
encode_bit_code = encode_table_value[i][4];
//printf("code %d \n",encode_bit_code);
key_release_flag = 1;
if(!gui_task_resume())
{
encode_release_last_time = portGET_RUN_TIME_COUNTER_VALUE();
encode_bit_code |= 0x80;
gui_task_msg_send(ENCODE_KEY_EVT,(void *)&encode_bit_code,1,NULL,0,NULL);
}
return;
}
}
i ++;
}
}
}
bool encode_key_release(void)
{
if(get_encode_release_basetime() > 10)
{
key_code = 0;
return true;
}
return false;
}
void encode_toggle_detected(uint8_t curr_encode)
{
//printf("encode %d \n",curr_encode);
if(encode_bit_status != curr_encode)
{
encode_bit_status = curr_encode;
encode_push_key(curr_encode);
struct app_task_event *event;
event = app_task_event_alloc(APP_TASK_EVENT_ENCODE_TOGGLE, sizeof(uint8_t), false);
if(event)
{
memcpy(event->param, (void *)&curr_encode, sizeof(uint8_t));
event->param_len = sizeof(uint8_t);
app_task_event_post(event, false);
}
}
}

View File

@ -0,0 +1,21 @@
#ifndef __FR_DEVICE_ENCODE_H__
#define __FR_DEVICE_ENCODE_H__
#include <stdint.h>
typedef struct
{
uint8_t keyvalue;
uint8_t time; //1 ms as unit
}encode_type_t;
bool encode_key_release(void);
void encode_toggle_detected(uint8_t curr_encode);
void encode_event_handle(uint8_t key_value);
#endif //__FR_DEVICE_ENCODE_H__

View File

@ -0,0 +1,38 @@
#include "fr_device_pa.h"
bool pa_enable_flag = false;
void device_pa_init(void)
{
GPIO_InitTypeDef gpio_config;
__SYSTEM_GPIOA_CLK_ENABLE();
gpio_config.Pin = GPIO_PIN_6;
gpio_config.Mode = GPIO_MODE_OUTPUT_PP;
gpio_config.Pull = GPIO_PULLDOWN;
gpio_config.Alternate = GPIO_FUNCTION_0;
gpio_init(GPIOA, &gpio_config);
pa_enable_flag = false;
gpio_write_pin(GPIOA, GPIO_PIN_6, GPIO_PIN_CLEAR); //defaultoutput low
}
void device_pa_enable(void)
{
if(pa_enable_flag == false){
printf("PA enable\r\n");
pa_enable_flag = true;
gpio_write_pin(GPIOA, GPIO_PIN_6, GPIO_PIN_SET); //output high
}
}
void device_pa_disable(void)
{
if(pa_enable_flag == true){
printf("PA disable\r\n");
pa_enable_flag = false;
gpio_write_pin(GPIOA, GPIO_PIN_6, GPIO_PIN_CLEAR); //output low
}
}

View File

@ -0,0 +1,21 @@
#ifndef __FR_DEVICE_PA__
#define __FR_DEVICE_PA__
#ifdef __cplusplus
extern "C" {
#endif
#include "fr30xx.h"
#include "app_task.h"
extern void device_pa_init(void);
extern void device_pa_enable(void);
extern void device_pa_disable(void);
#ifdef __cplusplus
}
#endif
#endif /* __FR_DEVICE_PA__ */

View File

@ -0,0 +1,118 @@
/*********************
* INCLUDES
*********************/
#include "driver_gpio.h"
#include "fr30xx.h"
#include "app_lvgl.h"
#include "fr_device_pmu_io.h"
#include "fr_device_button.h"
#include "fr_device_encode.h"
/*********************
* DEFINES
*********************/
#define BUTTON_DEBUG(fmt,arg...) printf("[BUTTON]"fmt,##arg)
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
/**********************
* STATIC VARIABLES
**********************/
/**********************
* VARIABLES
**********************/
/**********************
* MACROS
**********************/
/**********************
* EXTERN FUNCTIONS
**********************/
/**********************
* FUNCTIONS
**********************/
void device_pmu_io_init(void)
{
pmu_gpio_int_init(BUTTON_PIN_NUM, PMU_GPIO_PULL_UP, 1);
pmu_gpio_int_init(SOS_KEY_PIN_NUM, PMU_GPIO_PULL_UP, 1);
pmu_gpio_int_init(KEY1_PIN_NUM, PMU_GPIO_PULL_UP, 1);
pmu_gpio_int_init(ENCONDED_A_PIN_NUM, PMU_GPIO_PULL_UP, 1);
pmu_gpio_int_init(ENCONDED_B_PIN_NUM, PMU_GPIO_PULL_UP, 1);
pmu_enable_isr(PMU_GPIO_PMU_INT_MSK_BIT);
NVIC_SetPriority(PMU_IRQn, 4);
NVIC_EnableIRQ(PMU_IRQn);
}
void PMU_GPIO_PMU_IRQHandler(void)
{
uint16_t data = ool_read16(PMU_REG_PIN_DATA);
uint16_t result = ool_read16(PMU_REG_PIN_XOR_RESULT);
/* update last value with latest data */
ool_write16(PMU_REG_PIN_LAST_V, data);
/* clear last XOR result */
ool_write16(PMU_REG_PIN_XOR_CLR, result);
// printf("PMU IO: 0x%04x, 0x%04x\r\n", data, result);
if (data & PMU_PIN_9) {
system_prevent_sleep_clear(SYSTEM_PREVENT_SLEEP_TYPE_HCI_RX);
}
else {
system_prevent_sleep_set(SYSTEM_PREVENT_SLEEP_TYPE_HCI_RX);
}
if (result & (ENCONDED_A_PIN_NUM | ENCONDED_B_PIN_NUM)) {
uint8_t encode_bit_status;
if (!(data & ENCONDED_A_PIN_NUM))
{
encode_bit_status |= 0x02;
}
else
{
encode_bit_status &= 0xFD;
}
if (!(data & ENCONDED_B_PIN_NUM))
{
encode_bit_status |= 0x01;
}
else
{
encode_bit_status &= 0xFE;
}
encode_toggle_detected(encode_bit_status);
}
if (result & (BUTTON_PIN_NUM | SOS_KEY_PIN_NUM | KEY1_PIN_NUM)) {
button_toggle_detected(data);
}
}

View File

@ -0,0 +1,108 @@
#ifndef __FR_DEVICE_PMU_IO_H__
#define __FR_DEVICE_PMU_IO_H__
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "app_config.h"
/*********************
* DEFINES
*********************/
#if BOARD_SEL == BOARD_EVB_FR5090
#define BUTTON_PIN_NUM PMU_PIN_7
#define SOS_KEY_PIN_NUM PMU_PIN_5
#define KEY1_PIN_NUM PMU_PIN_4
#define ENCONDED_A_PIN_NUM PMU_PIN_2
#define ENCONDED_B_PIN_NUM PMU_PIN_3
#define PMU_IO_INTTERUPT_DEFAULT (BUTTON_PIN_NUM|SOS_KEY_PIN_NUM|KEY1_PIN_NUM|ENCONDED_A_PIN_NUM|ENCONDED_B_PIN_NUM)
#elif BOARD_SEL == BOARD_EVB_FR3092E
#define BUTTON_PIN_NUM PMU_PIN_7
#define SOS_KEY_PIN_NUM PMU_PIN_5
#define KEY1_PIN_NUM PMU_PIN_4
#define ENCONDED_A_PIN_NUM PMU_PIN_2
#define ENCONDED_B_PIN_NUM PMU_PIN_3
#define PMU_IO_INTTERUPT_DEFAULT (BUTTON_PIN_NUM|SOS_KEY_PIN_NUM|ENCONDED_A_PIN_NUM|ENCONDED_B_PIN_NUM)
#elif BOARD_SEL == BOARD_EVB_FR3092E_CM
#define BUTTON_PIN_NUM PMU_PIN_4
#define SOS_KEY_PIN_NUM PMU_PIN_5
#define KEY1_PIN_NUM PMU_PIN_3
#define ENCONDED_A_PIN_NUM PMU_PIN_7
#define ENCONDED_B_PIN_NUM PMU_PIN_6
#define PMU_IO_INTTERUPT_DEFAULT (BUTTON_PIN_NUM|SOS_KEY_PIN_NUM|KEY1_PIN_NUM|ENCONDED_A_PIN_NUM|ENCONDED_B_PIN_NUM)
#elif BOARD_SEL == BOARD_EVB_FR3092E_RGB
#define BUTTON_PIN_NUM PMU_PIN_7
#define SOS_KEY_PIN_NUM PMU_PIN_5
#define KEY1_PIN_NUM PMU_PIN_4
#define ENCONDED_A_PIN_NUM PMU_PIN_2
#define ENCONDED_B_PIN_NUM PMU_PIN_3
#define PMU_IO_INTTERUPT_DEFAULT (BUTTON_PIN_NUM|SOS_KEY_PIN_NUM|ENCONDED_A_PIN_NUM|ENCONDED_B_PIN_NUM)
#else
#error "choose correct board"
#endif
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
/**********************
* STATIC VARIABLES
**********************/
/**********************
* VARIABLES
**********************/
/**********************
* MACROS
**********************/
//default Time zone
/**********************
* EXTERN FUNCTIONS
**********************/
void device_pmu_io_init(void);
/**********************
* FUNCTIONS
**********************/
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif

View File

@ -0,0 +1,396 @@
/**
* @file fr_device_rtc.c
*
* @author tangzheng
*/
/*********************
* INCLUDES
*********************/
/* Standard includes. */
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "fr30xx.h"
#include "FreeRTOS.h"
#include "lvgl.h"
#include "fr_device_rtc.h"
#include "fr_watch.h"
/*********************
* DEFINES
*********************/
#define RTC_DEBUG(fmt,arg...) printf("[RTC]"fmt,##arg)
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
/**********************
* STATIC VARIABLES
**********************/
#define BLE_BASETIMECNT_MASK ((uint32_t)0xFFFFFFFF) //((uint32_t)0x4FFFFFF)
uint32_t system_rtc_tick = 0;
uint32_t last_ke_time;
/**********************
* VARIABLES
**********************/
const unsigned char g_day_per_mon[MONTH_PER_YEAR] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
time_rtc_t rtc_time = {
.ucYear = 2023,
.ucMonth = 10,
.ucDate = 1,
.ucHour = 12,
.ucMinute = 0,
.ucSecond = 0,
};
time_zone_t gSysTimeZone = {
.h = 8,
.m = 0,
};
static uint32_t sys_utc_time;
/**********************
* MACROS
**********************/
/**********************
* EXTERN FUNCTIONS
**********************/
/**********************
* FUNCTIONS
**********************/
unsigned char applib_dt_is_leap_year(unsigned short year)
{
if((year % 400) == 0)
{
return 1;
}
else if((year % 100) == 0)
{
return 0;
}
else if((year % 4) == 0)
{
return 1;
}
else
{
return 0;
}
}
unsigned char applib_dt_last_day_of_mon(unsigned char month, unsigned short year)
{
if((month == 0) || (month > 12))
{
return g_day_per_mon[1] + applib_dt_is_leap_year(year);
}
if(month != 2)
{
return g_day_per_mon[month - 1];
}
else
{
return g_day_per_mon[1] + applib_dt_is_leap_year(year);
}
}
unsigned int CalcWeekday(time_rtc_t time)
{
char century_code, year_code, month_code, day_code;
int week = 0;
century_code = year_code = month_code = day_code = 0;
if(time.ucMonth == 1 || time.ucMonth == 2)
{
century_code = (time.ucYear - 1) / 100;
year_code = (time.ucYear - 1) % 100;
month_code = time.ucMonth + 12;
day_code = time.ucDate;
}
else
{
century_code = time.ucYear / 100;
year_code = time.ucYear % 100;
month_code = time.ucMonth;
day_code = time.ucDate;
}
week = year_code + year_code / 4 + century_code / 4 - 2 * century_code + 26 * (month_code + 1) / 10 + day_code - 1;
week = week > 0 ? (week % 7) : ((week % 7) + 7);
return week;
}
unsigned int utc_time_to_sec(time_rtc_t* currTime)
{
unsigned short i;
unsigned int no_of_days = 0;
int utc_time;
if(currTime->ucYear < UTC_BASE_YEAR)
{
return 0;
}
/* year */
for(i = UTC_BASE_YEAR; i < currTime->ucYear; i++)
{
no_of_days += (DAY_PER_YEAR + applib_dt_is_leap_year(i));
}
/* month */
for(i = 1; i < currTime->ucMonth; i++)
{
no_of_days += applib_dt_last_day_of_mon((unsigned char) i, currTime->ucYear);
}
/* day */
no_of_days += (currTime->ucDate - 1);
#if 0
/* sec */
//utc_time = (unsigned int) no_of_days * SEC_PER_DAY + (unsigned int)(currTime->ucHour * SEC_PER_HOUR +
// currTime->ucMinute * SEC_PER_MIN + currTime->ucSecond);
utc_time = (unsigned int) no_of_days * SEC_PER_DAY + (unsigned int)((currTime->ucHour-8) * SEC_PER_HOUR +
currTime->ucMinute * SEC_PER_MIN + currTime->ucSecond);
#else
utc_time = (unsigned int) no_of_days * SEC_PER_DAY + (unsigned int)(currTime->ucHour * SEC_PER_HOUR +
currTime->ucMinute * SEC_PER_MIN + currTime->ucSecond);
utc_time -= (gSysTimeZone.h * 3600 + gSysTimeZone.m * 60);
#endif
return utc_time;
}
void utc_sec_to_time(unsigned int utc_sec, time_rtc_t* result)
{
int sec, day;
unsigned short y;
unsigned char m;
unsigned short d;
//unsigned char dst;
#if 0
if(daylightSaving)
{
utc_sec += SEC_PER_HOUR;
}
#endif
utc_sec = utc_sec + gSysTimeZone.h * 3600 + gSysTimeZone.m * 60;
/* hour, min, sec */
/* hour */
sec = utc_sec % SEC_PER_DAY;
result->ucHour = sec / SEC_PER_HOUR;
/* min */
sec %= SEC_PER_HOUR;
result->ucMinute = sec / SEC_PER_MIN;
/* sec */
result->ucSecond = sec % SEC_PER_MIN;
/* year, month, day */
/* year */
/* year */
day = utc_sec / SEC_PER_DAY;
for(y = UTC_BASE_YEAR; day > 0; y++)
{
d = (DAY_PER_YEAR + applib_dt_is_leap_year(y));
if(day >= d)
{
day -= d;
}
else
{
break;
}
}
result->ucYear = y;
for(m = 1; m < MONTH_PER_YEAR; m++)
{
d = applib_dt_last_day_of_mon(m, y);
if(day >= d)
{
day -= d;
}
else
{
break;
}
}
result->ucMonth = m;
result->ucDate = (unsigned char)(day + 1);
//result->DayIndex = applib_dt_dayindex(result->ncYear, result->ucMonth, result->ucDate);
}
unsigned char system_time_set_time_zone(time_zone_t set)
{
if(gSysTimeZone.h == set.h && gSysTimeZone.m == set.m)
{
return 0;
}
gSysTimeZone = set;
return 1;
}
void system_time_set(time_rtc_t set)
{
rtc_time = set;
}
time_rtc_t *system_time_get(void)
{
return &rtc_time;
}
time_zone_t *system_time_get_timeZone(void)
{
return &gSysTimeZone;
}
//date & time
bool CalcDoYear(uint16_t ucYear)
{
if((ucYear % 400 == 0)
||((ucYear % 4 == 0) && (ucYear % 100 != 0)))
{
return 1; //run nian
}
return 0;
}
uint8_t CalcMaxDate(time_rtc_t time)
{
uint8_t dates;
switch(time.ucMonth)
{
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
dates = 31;
break;
case 2:
if(CalcDoYear(time.ucYear))
dates = 29; //run nian
else
dates = 28;
break;
case 4:
case 6:
case 9:
case 11:
dates = 30;
break;
}
return dates;
}
uint32_t system_get_curr_time(void)
{
return portGET_RUN_TIME_COUNTER_VALUE();
//return system_rtc_tick;
}
static uint32_t get_sys_ke_basetime(void)
{
uint32_t cur_base_time = system_get_curr_time();
uint32_t diff;
if(cur_base_time >= last_ke_time)
diff = cur_base_time - last_ke_time;
else
diff = (BLE_BASETIMECNT_MASK - last_ke_time) + cur_base_time + 1;
return diff;
}
void dev_rtc_time_init(void)
{
sys_utc_time = utc_time_to_sec(&rtc_time);
last_ke_time = system_get_curr_time();
}
unsigned int get_sys_utc_time(void)
{
return sys_utc_time;
}
void fr_system_update_utc_time(time_rtc_t *cur_time)
{
sys_utc_time = utc_time_to_sec(cur_time);
}
void rtc_running(void)
{
uint32_t diff = get_sys_ke_basetime();
if( diff > 1000 )
{
uint32_t temp_time_value=0;
temp_time_value = diff / 1000;
last_ke_time += temp_time_value*1000;
//if( last_ke_time > BLE_BASETIMECNT_MASK)
// last_ke_time -= (BLE_BASETIMECNT_MASK+1);
sys_utc_time += temp_time_value;
utc_sec_to_time(sys_utc_time,&sync_cm3_data.time);
}
}

View File

@ -0,0 +1,83 @@
/**
* @file fr_device_rtc.h
*
* @author tangzheng
*/
#ifndef __FR_DEVICE_RTC_H__
#define __FR_DEVICE_RTC_H__
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
typedef struct {
signed char h;
signed char m;
}time_zone_t;
/**********************
* STATIC PROTOTYPES
**********************/
/**********************
* STATIC VARIABLES
**********************/
/**********************
* VARIABLES
**********************/
/**********************
* MACROS
**********************/
#define UTC_BASE_YEAR 1970
#define MONTH_PER_YEAR 12
#define DAY_PER_YEAR 365
#define SEC_PER_DAY 86400
#define SEC_PER_HOUR 3600
#define SEC_PER_MIN 60
//default Time zone
#define DEFAULT_TIME_ZONE {8, 00}
/**********************
* EXTERN FUNCTIONS
**********************/
extern void rtc_running(void);
extern void dev_rtc_time_init(void);
extern unsigned int get_sys_utc_time(void);
/**********************
* FUNCTIONS
**********************/
#ifdef __cplusplus
} /*extern "C"*/
#endif
#endif

View File

@ -0,0 +1,386 @@
#include "fr_device_vbat.h"
#include "fr_device_charge.h"
#include "fr_watch.h"
uint16_t CH_Data[10];
uint8_t Bat_voltage = 0;
bool bat_filo_init_flag = false;
/************************************************************************************
* @fn adc vbat start
*
* @brief adc vbat start
*/
void device_vbat_init(enum_ADC_Demo_t fe_demo)
{
adc_InitConfig_t ADC_Config;
__SYSTEM_ADC_CLK_ENABLE();
pmu_adc_power_ctrl(true);
pmu_vbe_power_ctrl(true);
switch(0)
{
case ADC_SOFTWARE_TRIGGER_MODE:
{
ADC_Config.ADC_Reference = ADC_REF_IOLDO;
ADC_Config.ADC_TriggerMode = ADC_SOFTWARE_TRIGGER;
#if 0
adc_set_channel_maping(0, ADC_CHANNEL_MAP_PMU_P4);
adc_set_channel_maping(1, ADC_CHANNEL_MAP_PMU_P5);
adc_set_channel_maping(2, ADC_CHANNEL_MAP_PMU_P6);
adc_set_channel_maping(3, ADC_CHANNEL_MAP_PMU_P7);
adc_set_channel_maping(4, ADC_CHANNEL_MAP_VABT);
adc_set_channel_maping(5, ADC_CHANNEL_MAP_VBE);
#else
adc_set_channel_maping(4, ADC_CHANNEL_MAP_VBAT);
#endif
adc_init(ADC_Config);
adc_soft_trigger_convert(4);
while(!adc_get_channel_valid_status(4));
uint16_t adc_result = adc_get_channel_data(4);
uint16_t vbat_vol = adc_result * 4 * 3300 / 1023;
//init filo
if(!bat_filo_init_flag)
{
battery_value_fifo_init(vbat_vol);
bat_filo_init_flag = true;
}
//transform to precentage
//Bat_voltage = transform_battery(vbat_vol);
Bat_voltage = battery_value_fifo_inc(transform_battery(vbat_vol));
sync_cm3_data.battery.battery_value = Bat_voltage;
printf("adc %d vol %d prec %d \r\n",adc_result,vbat_vol,Bat_voltage);
}
break;
#if 0
case ADC_HARDWARE_TRIGGER_LOOP_MODE:
{
ADC_Config.ADC_Reference = ADC_REF_IOLDO;
ADC_Config.ADC_TriggerMode = ADC_HARDWARE_TRIGGER;
ADC_Config.HardTriggerConfig.ADC_Channel_Max = 6;
ADC_Config.HardTriggerConfig.ADC_Convert_Mode = ADC_LOOP_MODE;
adc_init(ADC_Config);
adc_set_channel_maping(0, ADC_CHANNEL_MAP_PMU_P4);
adc_set_channel_maping(1, ADC_CHANNEL_MAP_PMU_P5);
adc_set_channel_maping(2, ADC_CHANNEL_MAP_PMU_P6);
adc_set_channel_maping(3, ADC_CHANNEL_MAP_PMU_P7);
adc_set_channel_maping(4, ADC_CHANNEL_MAP_VABT);
adc_set_channel_maping(5, ADC_CHANNEL_MAP_VBE);
adc_convert_start();
while(1)
{
for (int i = 0; i < 6; i++)
{
if (adc_get_channel_valid_status(i))
{
CH_Data[i] = adc_get_channel_data(i);
printf("Channel:%d, DATA:%d\r\n", i, CH_Data[i]);
}
}
}
}break;
case ADC_HARDWARE_TRIGGER_IT_MODE:
{
ADC_Config.ADC_Reference = ADC_REF_IOLDO;
ADC_Config.ADC_TriggerMode = ADC_HARDWARE_TRIGGER;
ADC_Config.HardTriggerConfig.ADC_Channel_Max = 6;
ADC_Config.HardTriggerConfig.ADC_Convert_Mode = ADC_LOOP_MODE;
adc_init(ADC_Config);
adc_set_channel_maping(0, ADC_CHANNEL_MAP_PMU_P4);
adc_set_channel_maping(1, ADC_CHANNEL_MAP_PMU_P5);
adc_set_channel_maping(2, ADC_CHANNEL_MAP_PMU_P6);
adc_set_channel_maping(3, ADC_CHANNEL_MAP_PMU_P7);
adc_set_channel_maping(4, ADC_CHANNEL_MAP_VABT);
adc_set_channel_maping(5, ADC_CHANNEL_MAP_VBE);
adc_convert_start_IT();
NVIC_EnableIRQ(ADC_IRQn);
while(1);
}break;
#endif
}
}
/*
get vbat voltage
*/
uint16_t device_get_vbat(void)
{
return Bat_voltage;
}
/*
adc vbat event handle
*/
void adc_vbat_event_handle(void)
{
device_vbat_init(ADC_SOFTWARE_TRIGGER_MODE);
}
/*
adc vbat start detect
*/
void adc_vbat_start_detect(void)
{
struct app_task_event *event;
event = app_task_event_alloc(APP_TASK_EVENT_ADC_VBAT_DETECT, 0, false);
if(event)
{
//memcpy(event->param, (void *)&curr_button, sizeof(uint32_t));
//event->param_len = sizeof(uint32_t);
app_task_event_post(event, false);
}
}
/*
adc isr
*/
void adc_irq(void)
{
for (int i = 0; i < 6; i++)
{
if (adc_get_channel_valid_status(i))
{
//printf("int channel: %d, DATA:%d\r\n", i, adc_get_channel_data(i));
}
}
}
const uint16_t g_battery_table[] =
{
//0-10 //3405
3405,
3410,
3415,
3420,
3425,
3430,
3435,
3440,
3446,
3452,
//10-20 //3458
3458,
3464,
3470,
3476,
3482,
3488,
3494,
3500,
3506,
3512,
//20-30 //3519
3516,
3520,
3524,
3528,
3532,
3536,
3540,
3544,
3548,
3552,
//30-40 //3555
3556,
3560,
3564,
3568,
3572,
3576,
3579,
3582,
3585,
3588,
//40-50 //3590
3591,
3594,
3597,
3602,
3605,
3608,
3611,
3614,
3617,
3620,
// 3800 --> 50% //3623
//50-60
3623,
3627,
3631,
3635,
3639,
3643,
3647,
3652,
3657,
3662,
// 3844
//60-70 //3667
3667,
3673,
3679,
3685,
3691,
3697,
3703,
3710,
3717,
3724,
// 3920
//70-80 //3731
3731,
3739,
3747,
3755,
3763,
3771,
3779,
3787,
3795,
3803,
//3980
//80-90 //3812
3811,
3819,
3827,
3835,
3843,
3851,
3859,
3867,
3875,
3883,
//4040
//90-100 //3830
3900,
3915,
3930,
3945,
3960,
3975,
3990,
4005,
4020,
4050,
};
uint8_t transform_battery(uint16_t battery_value)
{
uint8_t i = 100;
while(i > 0)
{
if(battery_value >= g_battery_table[i - 1])
{
break;
}
i --;
}
return i;
}
#define BATTERY_FIFO_MAX 20
uint8_t battery_detect_fifo[BATTERY_FIFO_MAX];
void battery_value_fifo_init(uint16_t value)
{
uint8_t voltage = transform_battery(value);
for(uint8_t i = 0; i < BATTERY_FIFO_MAX; i ++ )
{
battery_detect_fifo[i] = voltage;
}
Bat_voltage = voltage;
}
uint8_t battery_value_fifo_inc(uint8_t value)
{
for(uint8_t i = 0; i < (BATTERY_FIFO_MAX - 1); i ++ )
{
battery_detect_fifo[(BATTERY_FIFO_MAX - 1) - i] = battery_detect_fifo[(BATTERY_FIFO_MAX - 2) - i];
}
battery_detect_fifo[0] = value;
uint32_t battery_total = 0;
for(uint8_t i = 0; i < BATTERY_FIFO_MAX; i ++ )
{
battery_total += battery_detect_fifo[i];
}
uint8_t averages = battery_total / BATTERY_FIFO_MAX;
if(get_charge_status() == CHARGING_IN)
{
return averages;
}
else
{
if(averages > Bat_voltage)
{
return Bat_voltage;
}
else
{
return averages;
}
}
}

View File

@ -0,0 +1,32 @@
#ifndef __FR_DEVICE_BATTERY__
#define __FR_DEVICE_BATTERY__
#ifdef __cplusplus
extern "C" {
#endif
#include "fr30xx.h"
#include "app_task.h"
/* ADC demo select */
typedef enum
{
ADC_SOFTWARE_TRIGGER_MODE,
ADC_HARDWARE_TRIGGER_LOOP_MODE,
ADC_HARDWARE_TRIGGER_IT_MODE,
}enum_ADC_Demo_t;
/* Exported functions --------------------------------------------------------*/
extern void device_vbat_init(enum_ADC_Demo_t fe_demo);
extern void adc_vbat_event_handle(void);
extern void adc_vbat_start_detect(void);
extern uint8_t transform_battery(uint16_t battery_value);
extern uint8_t battery_value_fifo_inc(uint8_t value);
extern void battery_value_fifo_init(uint16_t value);
#ifdef __cplusplus
}
#endif
#endif /* __FR_DEVICE_BATTERY__ */