AVS/GD32F103C8T6/App/User/app.c

850 lines
23 KiB
C
Raw Normal View History

2023-10-18 17:36:51 +08:00
#include "app.h"
#include "can_parsing.h"
#define STROBE_LIGHT_MODE_SETTING_INDEX (0x00)
#define CAN_TYPE_SETTING_INDEX (0x01)
#define STROBE_LIGHT_ENABLE_SETTING_INDEX (0x02)
#define VOLUME_LEVEL_SETTING_INDEX (0x03)
static uint64_t led_rx_timestamp = 0, led_tx_timestamp = 0;
static uint8_t door_front_status = 1, door_front_status_temporary = 1;
static uint8_t door_back_status = 1, door_back_status_temporary = 1;
static uint8_t door_status = 1, door_status_temporary = 1;
static uint8_t turn_left_status = 1, turn_left_status_temporary = 1;
static uint8_t turn_left_parsing_count = 0; /* 转向接收次数 */
static uint8_t turn_right_status = 1, turn_right_status_temporary = 1;
static uint8_t turn_right_parsing_count = 0; /* 转向接收次数 */
static uint8_t emergency_flashers_status = 1, emergency_flashers_status_temporary = 1; /* 双闪 */
static uint8_t reversing_status = 1, reversing_status_temporary = 1;
static uint8_t diaodu_status = 0, diaodu_status_temporry = 0;
static uint8_t volume_1_status = 1, volume_1_status_temporary = 1;
static uint8_t volume_2_status = 1, volume_2_status_temporary = 1;
static uint8_t volume_3_status = 1, volume_3_status_temporary = 1;
static uint8_t volume_4_status = 1, volume_4_status_temporary = 1;
static uint8_t can_type = 0;
static uint8_t strobe_light_flashing_enable = 1; /* 0 关闭; 1 开启 */
static uint8_t strobe_light_flashing_mode = 1; /* 0 常亮; 1 频闪; 2 爆闪; */
static uint32_t strobe_light_flashing_count = 0;
static uint8_t strobe_light_task_uuid = 0; /* 频闪灯控制任务 ID */
static uint8_t emergency_flashers_operate_task_uuid = 0; /* 双闪状态下频闪灯控制任务 ID */
static uint8_t volume_level = 0; /* 音量默认级别 */
static uint8_t set_volume_count = 0;
/* 车辆状态上传状态, 0x00 不需要上传0x01 需要上传 */
static uint8_t door_front_upload_status = 0;
static uint8_t door_back_upload_status = 0;
static uint8_t turn_left_upload_status = 0;
static uint8_t turn_right_upload_status = 0;
static uint8_t reversing_upload_status = 0;
static uint8_t diaodu_upload_status = 0;
/* 频闪灯复位*/
static void strobe_light_reset(void);
#ifdef USE_LED
/* LED 指示灯分析任务 */
static void led_parsing_task(uint8_t uuid);
#endif
/* 设置音量级别 */
static void set_volume_level(uint8_t level);
/* 音量级别控制按钮 分析任务 */
static void volume_io_control_parsing_task(uint8_t uuid);
/* can 数据分析任务 */
static void can_parsing_task(uint8_t uuid);
/* 频闪灯控制任务 */
static void strobe_light_operate_task(uint8_t uuid);
/* 双闪状态下频闪灯控制任务 */
static void emergency_flashers_operate_task(uint8_t uuid);
/* 车辆状态 分析任务 */
static void vehicle_status_parsing_task(uint8_t uuid);
/* 车辆状态 上传任务 */
static void vehicle_status_upload_task(uint8_t uuid);
/* 发送状态灯更新 */
static void led_tx_update(void);
/* 接受状态灯更新 */
static void led_rx_update(void);
/**
* @brief
*/
void timer_interrupt_callback(uint32_t timer_periph)
{
}
/**
* @brief GPIO中断回调函数
*/
void gpio_interrupt_callback(uint32_t pin)
{
switch (pin)
{
case DOOR_FRONT_PIN:
door_front_status_temporary = gpio_input_bit_get(DOOR_FRONT_PERIPH, DOOR_FRONT_PIN);
door_front_upload_status = 0x01;
break;
case DOOR_BACK_PIN:
door_back_status_temporary = gpio_input_bit_get(DOOR_BACK_PERIPH, DOOR_BACK_PIN);
door_back_upload_status = 0x01;
break;
case TURN_LEFT_PIN:
turn_left_status_temporary = gpio_input_bit_get(TURN_LEFT_PERIPH, TURN_LEFT_PIN);
turn_left_upload_status = 0x01;
break;
case TURN_RIGHT_PIN:
turn_right_status_temporary = gpio_input_bit_get(TURN_RIGHT_PERIPH, TURN_RIGHT_PIN);
turn_right_upload_status = 0x01;
break;
case REVERSING_PIN:
reversing_status_temporary = gpio_input_bit_get(REVERSING_PERIPH, REVERSING_PIN);
reversing_upload_status = 0x01;
break;
}
}
/**
* @brief
*/
void usart_interrupt_callback(uint32_t usart_periph, uint8_t data)
{
switch (usart_periph)
{
case HOST_USART_PERIPH:
api_concat_byte(data);
break;
case RS485_USART_PERIPH:
diaodu_concat_byte(data);
break;
}
}
/**
* @brief
*/
void app_init(void)
{
/* 上位机通讯协议初始化 */
api_init();
/* 语音芯片初始化 */
v58_init();
m62429_init();
// ir_init();
/* 主动获取一次IO状态 */
door_front_status = door_front_status_temporary = gpio_input_bit_get(DOOR_FRONT_PERIPH, DOOR_FRONT_PIN);
door_back_status = door_back_status_temporary = gpio_input_bit_get(DOOR_BACK_PERIPH, DOOR_BACK_PIN);
turn_left_status = turn_left_status_temporary = gpio_input_bit_get(TURN_LEFT_PERIPH, TURN_LEFT_PIN);
turn_right_status = turn_right_status_temporary = gpio_input_bit_get(TURN_RIGHT_PERIPH, TURN_RIGHT_PIN);
reversing_status = reversing_status_temporary = gpio_input_bit_get(REVERSING_PERIPH, REVERSING_PIN);
can_type = setting_read_byte(CAN_TYPE_SETTING_INDEX, 0x00);
strobe_light_flashing_mode = setting_read_byte(STROBE_LIGHT_MODE_SETTING_INDEX, 0x01);
strobe_light_flashing_enable = setting_read_byte(STROBE_LIGHT_ENABLE_SETTING_INDEX, 0x01);
volume_level = setting_read_byte(VOLUME_LEVEL_SETTING_INDEX, 0x01); /* 默认中档 */
set_volume_level(volume_level);
/* 创建 上位机数据检测任务 */
task_create((task_func)api_process, 0);
/* 创建 红外遥控器数据检测任务 */
task_create((task_func)ir_process, 0);
/* 创建 调度数据检测任务 */
task_create((task_func)diaodu_process, 0);
/* 创建 心跳发送任务 */
task_create((task_func)api_upload_heart_beat, 3000);
#ifdef USE_LED
/* 创建 LED 指示灯分析任务 */
task_create(led_parsing_task, 30);
#endif
/* 创建 CAN数据分析任务 */
task_create(can_parsing_task, 0);
/* 创建 频闪灯控制任务, 并挂起 */
strobe_light_task_uuid = task_create(strobe_light_operate_task, 500);
task_suspend(strobe_light_task_uuid);
/* 创建 双闪状态下频闪灯控制任务 */
emergency_flashers_operate_task_uuid = task_create(emergency_flashers_operate_task, 500);
task_suspend(emergency_flashers_operate_task_uuid);
/* 创建 车辆状态分析任务 */
task_create(vehicle_status_parsing_task, 1000);
/* 创建 车辆状态 定时上传任务 */
task_create(vehicle_status_upload_task, 100);
/* 创建 音量按键 定时分析任务 */
task_create(volume_io_control_parsing_task, 100);
}
static void strobe_light_reset(void)
{
gpio_bit_write(LED_STROBE_PERIPH, LED_STROBE_PIN, RESET);
}
#ifdef USE_LED
static void led_parsing_task(uint8_t uuid)
{
/* 超过500ms钟未发送数据熄灭发送指示灯 */
if (timestamp - led_rx_timestamp > 500)
{
gpio_bit_write(LED_RX_PERIPH, LED_RX_PIN, RESET);
led_rx_timestamp = timestamp;
}
/* 超过500ms钟未接收到数据熄灭接收指示灯 */
if (timestamp - led_tx_timestamp > 500)
{
gpio_bit_write(LED_TX_PERIPH, LED_TX_PIN, RESET);
led_tx_timestamp = timestamp;
}
}
#endif
static void set_volume_level(uint8_t level)
{
switch (level)
{
case 0x00:
m62429_set_vol(0);
strobe_light_flashing_enable = 0x01;
break;
case 0x01:
m62429_set_vol(8);
strobe_light_flashing_enable = 0x01;
break;
case 0x02:
m62429_set_vol(9);
strobe_light_flashing_enable = 0x01;
break;
case 0x03:
m62429_set_vol(11);
strobe_light_flashing_enable = 0x00;
break;
default:
return;
}
if (level == 3)
gpio_bit_write(AMP_CTRL_PERIPH, AMP_CTRL_PIN, RESET); /* 停止功放 */
else
gpio_bit_write(AMP_CTRL_PERIPH, AMP_CTRL_PIN, SET); /* 开启功放 */
setting_write_byte(STROBE_LIGHT_ENABLE_SETTING_INDEX, strobe_light_flashing_enable);
setting_write_byte(VOLUME_LEVEL_SETTING_INDEX, volume_level = level);
setting_save();
}
static void volume_io_control_parsing_task(uint8_t uuid)
{
uint8_t level = 0xFF;
volume_1_status_temporary = gpio_input_bit_get(VOLUME_1_PERIPH, VOLUME_1_PIN);
volume_2_status_temporary = gpio_input_bit_get(VOLUME_2_PERIPH, VOLUME_2_PIN);
volume_3_status_temporary = gpio_input_bit_get(VOLUME_3_PERIPH, VOLUME_3_PIN);
volume_4_status_temporary = gpio_input_bit_get(VOLUME_4_PERIPH, VOLUME_4_PIN);
if (volume_1_status != volume_1_status_temporary)
{
volume_1_status = volume_1_status_temporary;
if (volume_1_status == 0)
level = 0;
}
if (volume_2_status != volume_2_status_temporary)
{
volume_2_status = volume_2_status_temporary;
if (volume_2_status == 0)
level = 1;
}
if (volume_3_status != volume_3_status_temporary)
{
volume_3_status = volume_3_status_temporary;
if (volume_3_status == 0)
level = 2;
}
if (volume_4_status != volume_4_status_temporary)
{
volume_4_status = volume_4_status_temporary;
if (volume_4_status == 0)
level = 3;
}
if (level != 0xFF)
{
set_volume_level(level);
api_upload_data_forwarding(0x06, level);
}
}
static void can_parsing_task(uint8_t uuid)
{
can_receive_message_struct receive_message = {0};
if (can_try_receive(CAN0, &receive_message))
{
/* CAN 解析 */
if (receive_message.rx_ff == CAN_FF_EXTENDED)
{
switch (can_type)
{
case 0x00:
can_byd_01_parsing(receive_message.rx_efid, receive_message.rx_data, &door_front_status_temporary, &door_back_status_temporary, &turn_left_status_temporary, &turn_right_status_temporary, &reversing_status_temporary);
break;
case 0x01:
can_byd_02_parsing(receive_message.rx_efid, receive_message.rx_data, &door_front_status_temporary, &door_back_status_temporary, &turn_left_status_temporary, &turn_right_status_temporary, &reversing_status_temporary);
break;
case 0x02:
can_byd_03_parsing(receive_message.rx_efid, receive_message.rx_data, &door_front_status_temporary, &door_back_status_temporary, &turn_left_status_temporary, &turn_right_status_temporary, &reversing_status_temporary);
break;
case 0x03:
can_yutong_parsing(receive_message.rx_efid, receive_message.rx_data, &door_front_status_temporary, &door_back_status_temporary, &turn_left_status_temporary, &turn_right_status_temporary, &reversing_status_temporary);
break;
case 0x04:
can_jinlong_parsing(receive_message.rx_efid, receive_message.rx_data, &door_front_status_temporary, &door_back_status_temporary, &turn_left_status_temporary, &turn_right_status_temporary, &reversing_status_temporary);
break;
case 0x05:
can_ankai_parsing(receive_message.rx_efid, receive_message.rx_data, &door_front_status_temporary, &door_back_status_temporary, &turn_left_status_temporary, &turn_right_status_temporary, &reversing_status_temporary);
break;
}
if (door_front_status_temporary != door_front_status)
door_front_upload_status = 0x01;
if (door_back_status_temporary != door_back_status)
door_back_upload_status = 0x01;
if (turn_left_status_temporary != turn_left_status)
turn_left_upload_status = 0x01;
if (turn_right_status_temporary != turn_right_status)
turn_right_upload_status = 0x01;
if (reversing_status_temporary != reversing_status)
reversing_upload_status = 0x01;
}
}
}
/* 频闪灯控制任务 */
static void strobe_light_operate_task(uint8_t uuid)
{
if (strobe_light_flashing_enable == 0)
{
/* 恢复频闪灯状态 */
strobe_light_reset();
strobe_light_flashing_count = 0;
return;
}
strobe_light_flashing_count += 1;
if (strobe_light_flashing_mode == 0)
{
/* 设置任务频率 1000 毫秒 */
task_set_frequency(uuid, 1000);
/* 常亮 */
gpio_bit_write(LED_STROBE_PERIPH, LED_STROBE_PIN, SET);
/* 计数归零 */
strobe_light_flashing_count = 0;
}
else if (strobe_light_flashing_mode == 1)
{
/* 频闪 */
gpio_bit_toggle(LED_STROBE_PERIPH, LED_STROBE_PIN);
if (strobe_light_flashing_count >= 4)
{
strobe_light_flashing_count = 0;
task_set_frequency(uuid, 1000);
}
else if (strobe_light_flashing_count == 2)
task_set_frequency(uuid, 500);
else
task_set_frequency(uuid, 50);
}
else if (strobe_light_flashing_mode == 2)
{
/* 爆闪 */
gpio_bit_toggle(LED_STROBE_PERIPH, LED_STROBE_PIN);
if (strobe_light_flashing_count >= 20)
{
strobe_light_flashing_count = 0;
task_set_frequency(uuid, 1000);
}
else
task_set_frequency(uuid, 50);
}
}
static void emergency_flashers_operate_task(uint8_t uuid)
{
strobe_light_flashing_count += 1;
/* 频闪 */
gpio_bit_toggle(LED_STROBE_PERIPH, LED_STROBE_PIN);
if (strobe_light_flashing_count >= 4)
{
strobe_light_flashing_count = 0;
task_set_frequency(uuid, 1000);
}
else if (strobe_light_flashing_count == 2)
task_set_frequency(uuid, 500);
else
task_set_frequency(uuid, 50);
}
static void vehicle_status_parsing_task(uint8_t uuid)
{
uint8_t status = 0xFF, status_type = 0xFF;
uint8_t door_change = 0;
/* 倒车状态判断 */
if (reversing_status != reversing_status_temporary)
{
reversing_status = reversing_status_temporary;
status_type = 3;
status = reversing_status;
/* 优先级最高, 如果状态为触发, 关闭语音 */
if (reversing_status == 0)
v58_stop();
goto EXECUTE;
}
/* 处于倒车状态时, 不继续检测 */
if (reversing_status == 0)
return;
/* 进出站状态判断 */
if (diaodu_status_temporry != 0 && diaodu_status != diaodu_status_temporry)
{
diaodu_status = diaodu_status_temporry;
/* 到站 */
if (diaodu_status == 1)
{
status_type = 4;
status = 0x00;
/* 优先级最高,关闭语音 */
v58_stop();
}
///* 出站 */
// else if(diaodu_status == 2)
// status_type = 5;
goto EXECUTE;
}
if (door_front_status_temporary != door_front_status)
door_front_status = door_front_status_temporary;
if (door_back_status_temporary != door_back_status)
door_back_status = door_back_status_temporary;
door_status_temporary = door_front_status_temporary | door_back_status_temporary;
if (door_status != door_status_temporary)
{
door_status = door_status_temporary;
status_type = 0;
status = door_status;
}
/* 进站状态, 不继续执行 */
if (diaodu_status == 1)
{
/* 当前后门开启后 */
if (door_status == 0)
{
/* 重置进站状态 */
diaodu_status = diaodu_status_temporry = 0;
/* 关闭语音 */
v58_stop();
goto EXECUTE;
}
return;
}
/* 当前后门开启后, 不处理其他数据 */
if (door_status == 0)
goto EXECUTE;
/* 左转弯状态判断 */
if (turn_left_status != turn_left_status_temporary)
{
/* 如果未触发状态, 需进行二次判断 */
if (turn_left_status_temporary == 1)
{
turn_left_parsing_count++;
if (turn_left_parsing_count < 3)
goto TURN_RIGHT_STATUS_TAG2;
}
turn_left_parsing_count = 0;
turn_left_status = turn_left_status_temporary;
status_type = 1;
status = turn_left_status;
/* 屏蔽此时左转弯数据 */
if (turn_left_status == 1 && turn_right_status == 0)
status_type = 0xFF;
}
TURN_RIGHT_STATUS_TAG2:
/* 右转弯状态判断 */
if (turn_right_status != turn_right_status_temporary)
{
/* 如果未触发状态, 需进行二次判断 */
if (turn_right_status_temporary == 1)
{
turn_right_parsing_count++;
if (turn_right_parsing_count < 3)
goto EXECUTE;
}
turn_right_parsing_count = 0;
turn_right_status = turn_right_status_temporary;
status_type = 2;
status = turn_right_status;
/* 屏蔽此时右转弯数据 */
if (turn_right_status == 1 && turn_left_status == 0)
status_type = 0xFF;
}
#if 0
/* 判断双闪状态 */
emergency_flashers_status_temporary = turn_left_status | turn_right_status;
if (emergency_flashers_status != emergency_flashers_status_temporary)
{
emergency_flashers_status = emergency_flashers_status_temporary;
if (emergency_flashers_status_temporary == 0)
{
/* 挂起 频闪灯控制任务 */
task_suspend(strobe_light_task_uuid);
/* 恢复频闪灯状态 */
strobe_light_reset();
/* 停止语音播报 */
v58_stop();
/* 恢复 双闪状态下频闪灯控制任务 */
task_resume(emergency_flashers_operate_task_uuid);
#if defined(USE_AK517)
ak517_please_note_that();
#elif defined(USE_QGEL50X)
qgel50x_please_note_that();
#endif
}
else if (emergency_flashers_status_temporary == 1)
{
/* 挂起 频闪灯控制任务 */
task_suspend(emergency_flashers_operate_task_uuid);
/* 恢复频闪灯状态 */
strobe_light_reset();
/* 停止语音播报 */
v58_stop();
}
}
#endif
EXECUTE:
if (status_type == 0xFF || emergency_flashers_status_temporary == 0)
return;
if (status == 0x01)
{
/* 挂起 频闪灯控制任务 */
task_suspend(strobe_light_task_uuid);
/* 恢复频闪灯状态 */
strobe_light_reset();
/* 停止语音播报 */
v58_stop();
}
else
{
/* 停止语音播报 */
v58_stop();
/* 播报语音 */
switch (status_type)
{
case 0:
v58_door_opening_warning();
break;
case 1:
v58_left_turn_warning();
break;
case 2:
v58_right_turn_warning();
break;
case 3:
v58_reverse_warning();
break;
case 4:
v58_arrival_warning();
break;
case 5:
return;
}
/* 恢复 频闪灯控制任务 */
task_resume(strobe_light_task_uuid);
}
}
/* IO 数据定时上传任务 */
static void vehicle_status_upload_task(uint8_t uuid)
{
if (door_front_upload_status == 0x01)
{
api_upload_vehicle_status(0x00, door_front_status_temporary);
api_upload_data_forwarding(0x00, door_front_status_temporary);
door_front_upload_status = 0x00;
}
if (door_back_upload_status == 0x01)
{
api_upload_vehicle_status(0x01, door_back_status_temporary);
api_upload_data_forwarding(0x01, door_back_status_temporary);
door_back_upload_status = 0x00;
}
if (turn_left_upload_status == 0x01)
{
api_upload_vehicle_status(0x02, turn_left_status_temporary);
api_upload_data_forwarding(0x02, turn_left_status_temporary);
turn_left_upload_status = 0x00;
}
if (turn_right_upload_status == 0x01)
{
api_upload_vehicle_status(0x03, turn_right_status_temporary);
api_upload_data_forwarding(0x03, turn_right_status_temporary);
turn_right_upload_status = 0x00;
}
if (reversing_upload_status == 0x01)
{
api_upload_vehicle_status(0x04, reversing_status_temporary);
api_upload_data_forwarding(0x04, reversing_status_temporary);
reversing_upload_status = 0x00;
}
if (diaodu_upload_status == 0x01)
{
api_upload_vehicle_status(0x05, diaodu_status_temporry);
api_upload_data_forwarding(0x05, diaodu_status_temporry);
diaodu_upload_status = 0x00;
}
}
static void led_tx_update(void)
{
#ifdef USE_LED
gpio_bit_toggle(LED_TX_PERIPH, LED_TX_PIN);
led_tx_timestamp = timestamp;
#endif
}
static void led_rx_update(void)
{
#ifdef USE_LED
gpio_bit_toggle(LED_RX_PERIPH, LED_RX_PIN);
led_rx_timestamp = timestamp;
#endif
}
void diaodu_arrival_or_departure_parsing(uint8_t status)
{
diaodu_status_temporry = status;
diaodu_upload_status = 0x01;
}
void ir_key_triggered(uint8_t key)
{
uint8_t level = 0x00;
if (key == 0x98) /* + */
level = volume_level - 1;
else if (key == 0x68) /* - */
level = volume_level + 1;
else
return;
set_volume_level(level);
api_upload_data_forwarding(0x06, level);
}
void api_notify_data_upload(uint8_t *buffer, uint16_t length)
{
led_tx_update();
usart_send_bytes(HOST_USART_PERIPH, buffer, length);
}
void api_notify_set_strobe_light_mode(uint8_t mode)
{
led_rx_update();
strobe_light_flashing_mode = mode;
setting_write_byte(STROBE_LIGHT_MODE_SETTING_INDEX, mode);
setting_save();
api_response_set_strobe_light_mode(API_SUCCESS);
}
void api_notify_get_strobe_light_mode(void)
{
led_rx_update();
api_response_get_strobe_light_mode(API_SUCCESS, strobe_light_flashing_mode);
}
void api_notify_set_volume_level(uint8_t level)
{
led_rx_update();
set_volume_level(level);
api_response_set_volume_level(API_SUCCESS);
api_upload_data_forwarding(0x06, level);
}
void api_notify_get_volume_level(void)
{
api_response_get_volume_level(API_SUCCESS, volume_level);
}
void api_notify_set_can_type(uint8_t type)
{
led_rx_update();
can_type = type;
setting_write_byte(CAN_TYPE_SETTING_INDEX, type);
setting_save();
api_response_set_can_type(API_SUCCESS);
}
void api_notify_get_can_type(void)
{
led_rx_update();
api_response_get_can_type(API_SUCCESS, can_type);
}
void api_notify_send_audio_pulse(uint8_t pulse_count)
{
v58_send_pulse(pulse_count);
api_response_send_audio_pulse(API_SUCCESS);
}
void api_notify_data_forwarding(uint8_t type, uint8_t value)
{
switch (type)
{
case 0x00:
door_front_status_temporary = value;
break;
case 0x01:
door_back_status_temporary = value;
break;
case 0x02:
turn_left_status_temporary = value;
break;
case 0x03:
turn_right_status_temporary = value;
break;
case 0x04:
reversing_status_temporary = value;
break;
case 0x05:
diaodu_status_temporry = value;
break;
case 0x06:
set_volume_level(value);
break;
}
}