Files
kunlun/dtest/flash_cmd/dtest_ftm_command.c
2024-09-28 14:24:04 +08:00

367 lines
9.8 KiB
C

/****************************************************************************
Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
be copied by any method or incorporated into another program without
the express written consent of Aerospace C.Power. This Information or any portion
thereof remains the property of Aerospace C.Power. The Information contained herein
is believed to be accurate and Aerospace C.Power assumes no responsibility or
liability for its use in any way and conveys no license or title under
any patent or copyright and makes no representation or warranty that this
Information is free from patent or copyright infringement.
****************************************************************************/
#include "chip_reg_base.h"
#include "hw_reg_api.h"
#include "iot_bitops.h"
#include "os_lock.h"
#include "iot_config.h"
#include "iot_io.h"
#include "iot_img_hdr.h"
#include "os_mem.h"
#include "dbg_io.h"
#include "os_utils.h"
#include "iot_ftm_internal.h"
#include "uart.h"
#include "iot_mtd.h"
#include "ahb.h"
#include "os_task.h"
#include "iot_clock.h"
#include "iot_uart.h"
#include "mtd.h"
#include "iot_mtd.h"
#include "iot_led.h"
#include "platform.h"
#include "flash.h"
#include "clk.h"
#include "dtest_ftm_command.h"
typedef struct _dtest_ftm_command_table_t_ {
uint32_t cid;
iot_ftm_cmd_func_t handler;
}dtest_ftm_cmd_table_t;
#define DTEST_FTM_DATA_UART 0
#define DTEST_FTM_PRINT_UART 1
#define DTEST_FTM_DATA_UART_TX_MAX 100
#define DTEST_FTM_CMD_MAX 50
dtest_ftm_cmd_table_t dtest_ftm_cmd_table[DTEST_FTM_CMD_MAX];
uint32_t dtest_ftm_cmd_table_index = 0;
iot_ftm_dtest_global_t *p_ftm_glb;
uint8_t buf_ftm_glb[sizeof(*p_ftm_glb)];
extern struct uart_ctrl uart_e_ctrl;
#define DTEST_FTM_HEAD_LEN 26
#define DTEST_FTM_POST_LEN 2
#define DTEST_FTM_CMD_LEN 6
#define DTEST_FTM_CMD_MIN_LEN (DTEST_FTM_HEAD_LEN + DTEST_FTM_POST_LEN + DTEST_FTM_CMD_LEN)
#define DTEST_FTM_PRECODE 0x2323
#define DTEST_FTM_PSTCODE 0x4040
#define dtest_ftm_set_pre(c) do{c[0] = c[1] = 0x23;}while(0)
#define dtest_ftm_set_dst_mac(c) do{c[2] = c[3] = c[4] = c[5] = c[6]= c[7] = 0;}while(0)
#define dtest_ftm_set_src_mac(c) do{c[8] = c[9] = c[10] = c[11] = c[12]= c[13] = 0;}while(0)
#define dtest_ftm_set_module_id(c, id) do{c[14] = id & 0xFF; c[15] = (id >> 8) & 0xFF;}while(0)
#define dtest_ftm_set_crc16(c, crc) do{c[16] = crc & 0xFF; c[17] = (crc >> 8) & 0xFF;}while(0)
#define dtest_ftm_set_message_id(c, id) do{c[18] = id & 0xFF; c[19] = (id >> 8) & 0xFF;\
c[20] = (id >> 16) & 0xFF; c[21] = (id >> 24) & 0xFF;}while(0)
#define dtest_ftm_set_length(c, len) do{c[22] = len & 0xFF; c[23] = (len >> 8) & 0xFF;\
c[24] = (len >> 16) & 0xFF; c[25] = (len >> 24) & 0xFF;}while(0)
#define dtest_ftm_set_tail(c) do{c[0] = c[1] = 0x40;}while(0)
#define dtest_ftm_get_pre(c) ((c[1] << 8) | c[0])
#define dtest_ftm_get_lenth(c) ((c[25] << 24) | (c[24] << 16) | (c[23] << 8) | c[22])
#define dtest_ftm_get_sub_lenth(c) ((c[31] << 8) | c[30])
#define dtest_ftm_get_cmd(c) ((c[27] << 8) | c[26])
#define dtest_ftm_get_len(c) ((c[29] << 8) | c[28])
#define dtest_ftm_get_post(c, l) ((c[33 + l] << 8) | c[32 + l])
void dtest_ftm_command_uart_send(uint8_t *buffer, uint32_t bufferlen)
{
uint8_t *p = buffer, *e = p + bufferlen;
iot_printf("\r\nSEND FRAME : ");
for (int len = 0; len < bufferlen; len++) {
iot_printf("%02x ", buffer[len]);
}
while (p < e) {
if (uart_e_ctrl.tx_fifo_cnt(DTEST_FTM_DATA_UART) < DTEST_FTM_DATA_UART_TX_MAX) {
uart_e_ctrl.putc(DTEST_FTM_DATA_UART, *p++);
}
}
return;
}
void dtest_ftm_command_uart_receive(void)
{
int cnt, ch;
while ((cnt = uart_e_ctrl.rx_fifo_cnt(DTEST_FTM_DATA_UART)) > 0){
while((cnt > 0) && (p_ftm_glb->cmd_buf_index < IOT_DTEST_COMMAND_BUFFER_LEN)) {
ch = uart_e_ctrl.getc(DTEST_FTM_DATA_UART);
p_ftm_glb->cmd_buf[p_ftm_glb->cmd_buf_index++] = ch & 0xFF;
cnt--;
}
if (p_ftm_glb->cmd_buf_index >= IOT_DTEST_COMMAND_BUFFER_LEN) {
break;
}
}
return;
}
void dtest_ftm_command_uart_init(void)
{
//iot_uart_open();
return;
}
void dtest_ftm_command_response(uint32_t moduleid, uint32_t msgid,
uint8_t *buffer, uint32_t bufferlen)
{
uint8_t *p_header = p_ftm_glb->event_buf, *p_tail = buffer + bufferlen;
dtest_ftm_set_pre(p_header);
dtest_ftm_set_dst_mac(p_header);
dtest_ftm_set_src_mac(p_header);
dtest_ftm_set_crc16(p_header, 0x0000);
dtest_ftm_set_module_id(p_header, moduleid);
dtest_ftm_set_message_id(p_header, msgid);
dtest_ftm_set_length(p_header, bufferlen);
dtest_ftm_set_tail(p_tail);
bufferlen += DTEST_FTM_HEAD_LEN + DTEST_FTM_POST_LEN;
dtest_ftm_command_uart_send(p_header, bufferlen);
return;
}
uint32_t dtest_ftm_command_take_handler(void)
{
uint8_t *p_header = p_ftm_glb->cmd_buf;
uint16_t length, i;
uint32_t cid;
iot_ftm_cmd_func_t handler = NULL;
cid = dtest_ftm_get_cmd(p_header) & 0xFFFF;
for (i = 0; i < dtest_ftm_cmd_table_index; i++)
{
if (cid == dtest_ftm_cmd_table[i].cid) {
handler = dtest_ftm_cmd_table[i].handler;
break;
}
}
length = dtest_ftm_get_sub_lenth(p_header);
if (NULL != handler) {
iot_printf("\r\n%s fn=0x%08x, cid=%04x.\r\n", __FUNCTION__,
handler, cid);
handler(p_ftm_glb->cmd_buf + DTEST_FTM_HEAD_LEN + DTEST_FTM_CMD_LEN, length);
return 1;
} else {
iot_printf("\r\n%s fn=0x%08x, cid=%04x not found.\r\n", __FUNCTION__,
handler, cid);
}
return 0;
}
uint32_t dtest_ftm_command_current_frame_len(uint16_t *data_len)
{
uint8_t *p = p_ftm_glb->cmd_buf, *e = p + p_ftm_glb->cmd_buf_index;
uint32_t sub_len, len, ptn;
if (p_ftm_glb->cmd_buf_index < DTEST_FTM_CMD_MIN_LEN) {
return 0;
}
/* Search 0x2323 */
do {
ptn = dtest_ftm_get_pre(p) & 0xFFFF;
if (DTEST_FTM_PRECODE == ptn) {
break;
}
p++;
} while(p < e);
if ((p < e) && (p > p_ftm_glb->cmd_buf)) {
/* Get pre-code, move data ahead. */
os_mem_cpy(p_ftm_glb->cmd_buf, p,
p_ftm_glb->cmd_buf_index - (p - p_ftm_glb->cmd_buf));
return 0;
} else if (p >= e) {
/* No pre-code in buffer. */
p_ftm_glb->cmd_buf_index = 0;
return 0;
}
sub_len = dtest_ftm_get_sub_lenth(p) & 0xFFFF;
len = dtest_ftm_get_lenth(p);
if ((DTEST_FTM_CMD_MIN_LEN + len > IOT_DTEST_COMMAND_BUFFER_LEN)
|| (len != sub_len + DTEST_FTM_CMD_LEN)){
/* invalid length, break the pre-code, then search again. */
p[0] = 0xFF;
return 0;
} else if (DTEST_FTM_CMD_MIN_LEN + sub_len > p_ftm_glb->cmd_buf_index) {
/* No whole frame received. */
return 0;
}
ptn = dtest_ftm_get_post(p, sub_len) & 0xFFFF;
if (DTEST_FTM_PSTCODE != ptn) {
/* invalid post-code, break the pre-code, then search again. */
p[0] = 0xFF;
return 0;
}
/* Get whole frame, feadback the length of user-data. */
*data_len = sub_len;
iot_printf("\r\nRCVD FRAME : ");
for (len = 0; len < sub_len + DTEST_FTM_CMD_MIN_LEN; len++) {
iot_printf("%02x ", p_ftm_glb->cmd_buf[len]);
}
return 1;
}
uint32_t dtest_ftm_command_add(uint32_t cid, void *handler)
{
if ((dtest_ftm_cmd_table_index >= DTEST_FTM_CMD_MAX)
|| (NULL == handler)){
return 1;
}
dtest_ftm_cmd_table[dtest_ftm_cmd_table_index].cid = cid;
dtest_ftm_cmd_table[dtest_ftm_cmd_table_index].handler = handler;
dtest_ftm_cmd_table_index++;
return 0;
}
void iot_ftm_cmd_command_list_add();
void dtest_ftm_main_task(void *arg)
{
uint16_t sub_len;
(void)arg;
p_ftm_glb = (iot_ftm_dtest_global_t *)buf_ftm_glb;
p_ftm_glb->cmd_buf_index = 0;
p_ftm_glb->cmd = p_ftm_glb->cmd_buf + DTEST_FTM_HEAD_LEN + DTEST_FTM_CMD_LEN;
p_ftm_glb->event = p_ftm_glb->event_buf + DTEST_FTM_HEAD_LEN;
iot_ftm_cmd_command_list_add();
while (1) {
if (dtest_ftm_command_current_frame_len(&sub_len)) {
dtest_ftm_command_take_handler();
/* Cover this frame with following data. */
sub_len += DTEST_FTM_CMD_MIN_LEN;
os_mem_cpy(p_ftm_glb->cmd_buf, p_ftm_glb->cmd_buf + sub_len, sub_len);
p_ftm_glb->cmd_buf_index -= sub_len;
sub_len = 0;
}
dtest_ftm_command_uart_receive();
}
return;
}
int32_t dtest_ftm_task_start()
{
//start the tasks;
os_start_kernel();
return 0;
}
int32_t dtest_ftm_task_init()
{
os_task_h handle;
/* start plc lib task */
handle = os_create_task(dtest_ftm_main_task, NULL, 6);
//create the tasks;
if(handle != NULL) {
iot_printf("task 1 init successfully...\r\n");
}
return 0;
}
static int32_t dtest_ftm_platform_init()
{
clk_core_freq_set(CPU_FREQ_150M);
mtd_device_init(1);
ahb_cache_disable();
ahb_cache_enable();
ahb_cache_fill_valid_space();
/*platform intialization*/
platform_init();
//resource initializations;
system_clock_init();
system_uart_init();
dbg_uart_init_port(1, 1);
dbg_uart_stage1_init();
return 0;
}
int32_t dtest_ftm_module_init(void)
{
//platform intialization;
dtest_ftm_platform_init();
//create all the tasks;
dtest_ftm_task_init();
iot_printf("\r\nstarting...\r\n");
return 0;
}
int32_t dtest_ftm_module_start(void)
{
int32_t res = 0;
res = dtest_ftm_task_start();
return res;
}
int main(void)
{
//module init;
dtest_ftm_module_init();
//module start;
dtest_ftm_module_start();
return 0;
}