351 lines
9.5 KiB
C
351 lines
9.5 KiB
C
/*
|
|
* @Author: shenghao.xu
|
|
* @Date: 2023-04-04 08:38:59
|
|
* @LastEditors: shenghao.xu
|
|
* @LastEditTime: 2023-04-04 11:31:35
|
|
* @Description:
|
|
* email:545403892@qq.com
|
|
* Copyright (c) 2023 by shenghao.xu, All Rights Reserved.
|
|
*/
|
|
|
|
#include <string.h>
|
|
#include "../inc/data_analysis.h"
|
|
#include "../inc/sqqueue.h"
|
|
#include "../inc/debug.h"
|
|
|
|
typedef uint8_t data_entry_t;
|
|
typedef void (*state_t)(uint8_t data_id, uint8_t sig, uint8_t ch);
|
|
|
|
typedef enum _event /* enumeration */
|
|
{
|
|
SD_SIG,
|
|
LD_SIG,
|
|
CHAR_SIG,
|
|
ED_SIG,
|
|
} sig_event;
|
|
|
|
typedef struct _fsm_t_
|
|
{
|
|
state_t current_state;
|
|
} fsm_t;
|
|
|
|
typedef struct _DATA_frm_t_
|
|
{
|
|
uint8_t sd_index;
|
|
|
|
struct
|
|
{
|
|
uint8_t data[DATA_LD_LEN_MAX];
|
|
uint8_t index;
|
|
uint16_t frm_len;
|
|
} ld; // length describe
|
|
|
|
uint16_t payload_len; // actually len of recvived data
|
|
uint8_t ed_index;
|
|
|
|
uint16_t last_enter_q_num; // record the num of frames has entered the queue
|
|
uint8_t locked;
|
|
uint8_t sig;
|
|
} data_frm_t;
|
|
|
|
#define TRAN(state) (fsm[data_id].current_state = (state_t)(state))
|
|
#define FSM_DISPATCH(data_id, sig, ch) (fsm[data_id].current_state((data_id), (sig), (ch)))
|
|
|
|
static fsm_t fsm[DATA_NUM] = {0};
|
|
|
|
static data_frm_t data_frm_array[DATA_NUM];
|
|
static data_reg_t data_reg_array[DATA_NUM];
|
|
|
|
static sqqueue_ctrl_t data_recv_sqq[DATA_NUM];
|
|
|
|
static void wait_sd_state(uint8_t data_id, uint8_t sig, uint8_t ch);
|
|
/************************************************************/
|
|
void lock_data(uint8_t data_id)
|
|
{
|
|
data_frm_array[data_id].locked = true;
|
|
for (uint8_t i = 0; i < data_frm_array[data_id].last_enter_q_num; i++)
|
|
{
|
|
data_recv_sqq[data_id].revoke(&data_recv_sqq[data_id]);
|
|
}
|
|
|
|
data_frm_array[data_id].last_enter_q_num = 0;
|
|
data_frm_array[data_id].sd_index = 0;
|
|
data_frm_array[data_id].ed_index = 0;
|
|
data_frm_array[data_id].ld.frm_len = 0;
|
|
data_frm_array[data_id].payload_len = 0;
|
|
|
|
TRAN(wait_sd_state);
|
|
}
|
|
|
|
void unlock_data(uint8_t data_id)
|
|
{
|
|
TRAN(wait_sd_state);
|
|
|
|
data_frm_array[data_id].last_enter_q_num = 0;
|
|
data_frm_array[data_id].sd_index = 0;
|
|
data_frm_array[data_id].ed_index = 0;
|
|
data_frm_array[data_id].ld.frm_len = 0;
|
|
data_frm_array[data_id].payload_len = 0;
|
|
|
|
data_frm_array[data_id].locked = false;
|
|
}
|
|
|
|
static void end_state_handle(uint8_t data_id, uint8_t sig, uint8_t ch)
|
|
{
|
|
TRAN(wait_sd_state);
|
|
data_frm_array[data_id].ld.frm_len = 0;
|
|
data_frm_array[data_id].payload_len = 0;
|
|
data_frm_array[data_id].last_enter_q_num = 0;
|
|
if (data_reg_array[data_id].func_ptr != NULL)
|
|
{
|
|
(*(data_reg_array[data_id].func_ptr))();
|
|
}
|
|
}
|
|
|
|
static void wait_end_state(uint8_t data_id, uint8_t sig, uint8_t ch)
|
|
{
|
|
if (!data_reg_array[data_id].ed.valid)
|
|
{
|
|
if (data_frm_array[data_id].ld.frm_len == 0)
|
|
{
|
|
TRAN(wait_sd_state);
|
|
|
|
end_state_handle(data_id, sig, ch);
|
|
|
|
for (uint8_t i = 0; i < data_frm_array[data_id].last_enter_q_num; i++)
|
|
{
|
|
data_recv_sqq[data_id].revoke(&data_recv_sqq[data_id]);
|
|
}
|
|
data_frm_array[data_id].last_enter_q_num = 0;
|
|
}
|
|
else
|
|
{
|
|
if (data_recv_sqq[data_id].enter(&data_recv_sqq[data_id], (void *)&ch))
|
|
{
|
|
data_frm_array[data_id].last_enter_q_num++;
|
|
if (++data_frm_array[data_id].payload_len ==
|
|
data_frm_array[data_id].ld.frm_len)
|
|
{
|
|
end_state_handle(data_id, sig, ch);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
lock_data(data_id);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (data_frm_array[data_id].ld.frm_len == 0)
|
|
{
|
|
if (data_recv_sqq[data_id].enter(&data_recv_sqq[data_id], (void *)&ch))
|
|
{
|
|
data_frm_array[data_id].last_enter_q_num++;
|
|
if (data_reg_array[data_id].ed.data[0] == ch)
|
|
{
|
|
end_state_handle(data_id, sig, ch);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
lock_data(data_id);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (data_recv_sqq[data_id].enter(&data_recv_sqq[data_id], (void *)&ch))
|
|
{
|
|
data_frm_array[data_id].last_enter_q_num++;
|
|
if (++data_frm_array[data_id].payload_len >=
|
|
data_frm_array[data_id].ld.frm_len - data_reg_array[data_id].ld.pos)
|
|
{
|
|
if (data_reg_array[data_id].ed.data[0] == ch)
|
|
{
|
|
end_state_handle(data_id, sig, ch);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
lock_data(data_id);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void wait_ld_state(uint8_t data_id, uint8_t sig, uint8_t ch)
|
|
{
|
|
if (!data_reg_array[data_id].ld.valid)
|
|
{
|
|
TRAN(wait_end_state);
|
|
FSM_DISPATCH(data_id, data_frm_array[data_id].sig, ch);
|
|
return;
|
|
}
|
|
data_frm_array[data_id].ld.data[data_frm_array[data_id].ld.index++] = ch;
|
|
if (data_recv_sqq[data_id].enter(&data_recv_sqq[data_id], (void *)&ch))
|
|
{
|
|
data_frm_array[data_id].last_enter_q_num++;
|
|
if (data_frm_array[data_id].ld.index == data_reg_array[data_id].ld.len)
|
|
{
|
|
if (data_reg_array[data_id].ld.little_endian == true)
|
|
{
|
|
data_frm_array[data_id].ld.frm_len =
|
|
data_frm_array[data_id].ld.data[DATA_LD_LEN_MAX - 1] * 256 +
|
|
data_frm_array[data_id].ld.data[DATA_LD_LEN_MAX - 2];
|
|
}
|
|
else
|
|
{
|
|
data_frm_array[data_id].ld.frm_len =
|
|
data_frm_array[data_id].ld.data[DATA_LD_LEN_MAX - 2] * 256 +
|
|
data_frm_array[data_id].ld.data[DATA_LD_LEN_MAX - 1];
|
|
}
|
|
|
|
if (data_reg_array[data_id].ld.len == 1) // 只有1个字节长度的数据
|
|
{
|
|
data_frm_array[data_id].ld.frm_len = data_frm_array[data_id].ld.data[0];
|
|
}
|
|
|
|
if ((data_frm_array[data_id].ld.frm_len > data_reg_array[data_id].argu.len_max) || (data_frm_array[data_id].ld.frm_len < data_reg_array[data_id].argu.len_min))
|
|
{
|
|
data_frm_array[data_id].ld.index = 0;
|
|
TRAN(wait_sd_state);
|
|
|
|
for (uint8_t i = 0; i < data_frm_array[data_id].last_enter_q_num; i++)
|
|
{
|
|
data_recv_sqq[data_id].revoke(&data_recv_sqq[data_id]);
|
|
}
|
|
|
|
data_frm_array[data_id].ld.frm_len = 0;
|
|
data_frm_array[data_id].last_enter_q_num = 0;
|
|
}
|
|
else
|
|
{
|
|
data_frm_array[data_id].ld.index = 0;
|
|
TRAN(wait_end_state);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
lock_data(data_id);
|
|
}
|
|
}
|
|
|
|
static void wait_sd_state(uint8_t data_id, uint8_t sig, uint8_t ch)
|
|
{
|
|
if (!data_reg_array[data_id].sd.valid)
|
|
{
|
|
TRAN(wait_ld_state);
|
|
FSM_DISPATCH(data_id, data_frm_array[data_id].sig, ch);
|
|
return;
|
|
}
|
|
if (data_reg_array[data_id].sd.data[data_frm_array[data_id].sd_index++] == ch)
|
|
{
|
|
if (data_recv_sqq[data_id].enter(&data_recv_sqq[data_id], (void *)&ch))
|
|
{
|
|
data_frm_array[data_id].last_enter_q_num++;
|
|
if (data_frm_array[data_id].sd_index == data_reg_array[data_id].sd.len)
|
|
{
|
|
data_frm_array[data_id].sd_index = 0;
|
|
TRAN(wait_ld_state);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
lock_data(data_id);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (uint8_t i = 0; i < data_frm_array[data_id].last_enter_q_num; i++)
|
|
{
|
|
data_recv_sqq[data_id].revoke(&data_recv_sqq[data_id]);
|
|
}
|
|
|
|
data_frm_array[data_id].sd_index = 0;
|
|
data_frm_array[data_id].last_enter_q_num = 0;
|
|
}
|
|
}
|
|
|
|
static void data_char_handle(uint8_t data_id, uint8_t ch)
|
|
{
|
|
if (data_reg_array[data_id].echo_en)
|
|
{
|
|
data_write(data_id, &ch, 1);
|
|
}
|
|
|
|
FSM_DISPATCH(data_id, data_frm_array[data_id].sig, ch);
|
|
}
|
|
|
|
data_interupt_cb_t data_fsm_init(uint8_t data_id)
|
|
{
|
|
TRAN(wait_sd_state);
|
|
data_reg_array[data_id].func_ptr = NULL;
|
|
memset(&data_frm_array[data_id], 0, sizeof(data_frm_t));
|
|
data_frm_array[data_id].sig = CHAR_SIG;
|
|
|
|
if (sqqueue_ctrl_init(&data_recv_sqq[data_id],
|
|
sizeof(data_entry_t),
|
|
DATA_BUF_RECV_SQQ_LEN) == false)
|
|
{
|
|
DBG_ASSERT(false __DBG_LINE);
|
|
}
|
|
|
|
return data_char_handle;
|
|
}
|
|
|
|
uint8_t data_read(uint8_t id, void *buffer, uint16_t len)
|
|
{
|
|
uint8_t i = 0;
|
|
data_entry_t e;
|
|
uint8_t *buf = (uint8_t *)buffer;
|
|
|
|
if (data_recv_sqq[id].get_len(&data_recv_sqq[id]) >= len)
|
|
{
|
|
for (i = 0; i < len; i++)
|
|
{
|
|
e = *((data_entry_t *)data_recv_sqq[id].del(&data_recv_sqq[id]));
|
|
buf[i] = e;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
while ((data_recv_sqq[id].get_len(&data_recv_sqq[id]) != 0) && (i < len))
|
|
{
|
|
e = *((data_entry_t *)data_recv_sqq[id].del(&data_recv_sqq[id]));
|
|
buf[i++] = e;
|
|
}
|
|
}
|
|
|
|
if (data_frm_array[id].locked)
|
|
{
|
|
unlock_data(id);
|
|
}
|
|
|
|
return i;
|
|
}
|
|
|
|
void data_write(uint8_t id, uint8_t *const string, uint16_t len)
|
|
{
|
|
}
|
|
|
|
bool data_reg(uint8_t id, data_reg_t reg)
|
|
{
|
|
if (data_reg_array[id].func_ptr == NULL)
|
|
{
|
|
memcpy((void *)&data_reg_array[id], (void *)®, sizeof(reg));
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
void data_unreg(uint8_t id)
|
|
{
|
|
memset((void *)&data_reg_array[id], 0, sizeof(data_reg_t));
|
|
data_reg_array[id].func_ptr = NULL;
|
|
}
|