iR58/bk_aidk/projects/lock_lfvx/.svn/pristine/f9/f90c762ae0ee8641909af2d1cc19128b2aebe825.svn-base
2025-05-10 11:44:51 +08:00

1010 lines
30 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <components/log.h>
#include <components/system.h>
#include <os/os.h>
#include <components/shell_task.h>
#include <common/bk_include.h>
#include "gpio_map.h"
#include "gpio_driver.h"
#include <driver/gpio.h>
#include <common/bk_kernel_err.h>
//#include "bk_wifi_netif.h"
#include "bk_wifi.h"
#include <os/str.h>
#include "bk_uart.h"
#include <os/mem.h>
#include <os/os.h>
#include <common/bk_kernel_err.h>
#include <string.h>
//#include "wlan_ui_pub.h"
//#include <lwip/inet.h>
#include <driver/uart.h>
#include "ilock_client.h"
#define TAG "iLock"
#define LOGI(...) BK_LOGI(TAG, ##__VA_ARGS__)
#define LOGE(...) BK_LOGE(TAG, ##__VA_ARGS__)
#define LOGW(...) BK_LOGW(TAG, ##__VA_ARGS__)
#define LOGD(...) BK_LOGD(TAG, ##__VA_ARGS__)
#define SET_BIT(x, bit) (x |= (1 << bit)) /* 置1第bit位 */
#define GET_BIT(x, bit) ((x & (1 << bit)) >> bit) /* 获取第bit位 */
#define CLEAR_BIT(x, bit) (x &= ~(1 << bit)) /* 清零第bit位 */
static const int RX_BUF_SIZE = 128;
//static const char *ILOCK_TAG = "ILOCK_CLIENT";
static uart_id_t uart_id = UART_ID_1;
//static uart_id_t uart_id = UART_ID_2;
static beken_thread_t ilock_thread_hdl = NULL;
ilock_dev dev_info_lasted;
static int serial_num = 0;
static char ilock_device_id[32] = {0};
static beken_queue_t uart1_msg_q = NULL;
static beken_queue_t lock_command_q = NULL;
//static lock_package_t lock_pack;
static lock_command_t lock_command;
static beken_semaphore_t uart_rx_semaphore = NULL;
static int rx_start = 0;
typedef enum
{
NULL_MSG = 0,
UART_TX_MSG,
UART_RX_MSG,
} UartMessageType;
typedef struct
{
UartMessageType type;
int len;
uint8_t *msg;
} UartMessage;
#define CMD_LOCK_START 0xAA
#define CMD_LOCK_END 0xAA
#define CMD_PACKAGE_LEN_MAX 128
#define UART_BAUDRATE 9600
/**
* 0x1:请求包,都需要回复
0x2:响应包,回复执行结果
0x3:回执包,仅通知收到(高 4BIT)
*/
#define CMD_TYPE_REQ 0x01
#define CMD_TYPE_RET 0x02
#define CMD_TYPE_REC 0x03//receipt
typedef enum
{
STATUS_IDLE =0,
STATUS_HEAD,/*获取标志头*/
STATUS_LEN, /*获取长度*/
STATUS_DATA,/*获取数据*/
STATUS_CRC1,/*获取CRC1*/
STATUS_CRC2,/*获取CRC2*/
} ilock_recv_t;
static unsigned char recv_buff[CMD_PACKAGE_LEN_MAX];
static int data_len;
static int recv_len;
static ilock_recv_t recv_state = STATUS_IDLE;
static ilock_client_cb_ops_t *event_cb;
void ilock_set_callback(ilock_client_cb_ops_t *cb_ops){
event_cb = cb_ops;
}
static void uart_example_rx_isr(uart_id_t id, void *param)
{
BK_LOGE(TAG, "uart(%d) enter uart_example_rx_isr\r\n", id);
int ret;
ret = rtos_set_semaphore(&uart_rx_semaphore);
if(kNoErr !=ret){
os_printf("rx_isr: set sema failed\r\n");
}
}
void ilock_uart_init(void) {
uart_config_t config = {0};
os_memset(&config, 0, sizeof(uart_config_t));
config.baud_rate = UART_BAUDRATE; //115200 8130 38400
config.data_bits = UART_DATA_8_BITS;
config.parity = UART_PARITY_NONE;
config.stop_bits = UART_STOP_BITS_1;
config.flow_ctrl = UART_FLOWCTRL_DISABLE;
//config.src_clk = UART_SCLK_XTAL_26M;
int ret = bk_uart_is_in_used(uart_id);
warning_prf("bk_uart_is_in_used : %d \r\n",ret);
BK_LOG_ON_ERR(bk_uart_init(uart_id, &config));
//CLI_LOGI("uart init, uart_id=%d\n", uart_id);
BK_LOG_ON_ERR(bk_uart_set_baud_rate(uart_id, UART_BAUDRATE));
//bk_uart_disable_sw_fifo(uart_id);
//bk_uart_register_rx_isr(uart_id, (uart_isr_t)uart_example_rx_isr, NULL);
bk_uart_enable_rx_interrupt(uart_id);
//BK_LOG_ON_ERR(bk_uart_enable_rx_interrupt(uart_id));
//BK_LOG_ON_ERR(bk_uart_register_rx_isr(uart_id, uart_example_rx_isr, NULL));
}
void ilock_uart_deinit(){
bk_uart_deinit(uart_id);
}
char * ilock_client_get_device_id(){
return ilock_device_id;
}
int ilock_crc16_modbus(uint8_t *CRC_buf, int len)
{ // x16+x15+x2+1
int CRC_ReturnValue = 0xffff;
int i, j, temp;
for (i = 0; i < len; i++)
{
//BK_LOGE(TAG, "+++%02x\r\n", CRC_buf[i]);
temp = CRC_buf[i] & 0xff;
CRC_ReturnValue ^= temp;
j = 8;
while (j != 0)
{
if ((CRC_ReturnValue & 0x01) != 0)
CRC_ReturnValue = (CRC_ReturnValue >> 1) ^ 0xA001;
else
CRC_ReturnValue = CRC_ReturnValue >> 1;
j--;
}
}
return CRC_ReturnValue;
}
int ilock_sendData(char* data,int len)
{
bk_uart_write_bytes(uart_id, data, len);
return -1;
}
int ilock_send_package(uint8_t cmd_type,uint8_t cmd,uint8_t*cmd_data,int data_len){
//AA packlen 0x01(4bit-serial 4bit-cmdtype) cmd body 0x010x02(crc)
uint8_t cmds[data_len+6];
os_memset(&cmds, 0, sizeof(cmds));
cmds[0] = 0xAA;
cmds[1] = (data_len+4)&0xFF;
//serial
if(serial_num > 0xF){
serial_num = 0;
}else{
serial_num++;
}
//cmd_type
switch (cmd_type)
{
case CMD_TYPE_REQ:
cmds[2]= 0x11;
break;
case CMD_TYPE_RET:
cmds[2]= 0xD2;
break;
case CMD_TYPE_REC:
cmds[2]= 0xD3;
break;
default:
break;
}
cmds[2] = cmds[2]&0xF;// 0000xyzu 高位0000
//serialno
int bit0 = GET_BIT(serial_num,0);
int bit1 = GET_BIT(serial_num,1);
int bit2 = GET_BIT(serial_num,2);
int bit3 = GET_BIT(serial_num,3);
if(bit0){
SET_BIT(cmds[2],4);
}
if(bit1){
SET_BIT(cmds[2],5);
}
if(bit2){
SET_BIT(cmds[2],6);
}
if(bit3){
SET_BIT(cmds[2],7);
}
//BK_LOGE(TAG, "serial-->%d\r\n", cmds[2]>>4 );
cmds[3]= cmd;
if(cmd_data!=NULL && data_len != 0){
os_memcpy(&cmds[4], cmd_data, data_len);
}
int crc = ilock_crc16_modbus(&cmds[2],data_len+2);
int cmd_len = sizeof(cmds);
cmds[cmd_len-2] = (crc >> 8);
cmds[cmd_len-1] = (crc & 0xff);
BK_LOG_ON_ERR(bk_uart_set_baud_rate(uart_id, UART_BAUDRATE));
bk_uart_write_bytes(uart_id, cmds, cmd_len);
#if 0
//lock_command
int count = 0;
while(1){
rtos_delay_milliseconds(300);
if(count>10){
BK_LOGE(TAG, "cmd-->FAILED!!!\r\n", cmds[2]>>4 );
break;
}
if(lock_command.cmd_type == cmd_type ){
BK_LOGE(TAG, "$$$$$$$$$$$$$\r\n");
break;
}else{
BK_LOGE(TAG, "@@@@@@@@@@@@@ type:%02X resp_state:%02X \r\n",lock_command.cmd_type ,lock_command.resp_state);
}
count++;
}
BK_LOGE(TAG, "FINISH!!!!!!!!!\r\n");
for (int i = 0; i < sizeof(cmds); i++) {
BK_LOGE(TAG, "-->%02x\r\n", cmds[i]);
}
#endif
return 1;
}
int ilock_cmds(char*cmds,int cmd, char* playload,int playload_len){
//char cmds[10] = {0xAA, 0x08, 0x11, 0x41, 0x0B, 0x00, 0x00, 0x00, 0xB1, 0x00};
//bk_uart_write_bytes(uart_id, cmds, sizeof(cmds));
return 1;
}
int ilock_read_state(){
BK_LOGE(TAG, "ilock_read_state\n");
ilock_send_package(CMD_TYPE_REQ,0x44,NULL,0);
return 1;
}
int ilock_set_utc(long utc){
BK_LOGE(TAG, "ilock_set_utc:%lld\n",utc);
uint8_t data[4] = {0x00};
data[0] = (utc >> 24) &0xff;
data[1] = (utc >> 16) &0xff;
data[2] = (utc >> 8) &0xff;
data[3] = utc&0xff;
//BK_LOGE(TAG, "utc:%02X%02X%02X%02X\n",data[0],data[2],data[2],data[3]);
ilock_send_package(CMD_TYPE_REQ,0x12,(uint8_t*)&data,sizeof(data));
return 1;
}
int ilock_ping(){
BK_LOGE(TAG, "ilock_ping");
//ilock_send_package(CMD_TYPE_REQ,0xE4,NULL,0);
uint8_t data[1] = {0x01};
ilock_send_package(CMD_TYPE_REQ,0x49,(uint8_t*)&data,sizeof(data));
return 1;
}
int ilock_read_version(){
ilock_send_package(CMD_TYPE_REQ,0x21,NULL,0);
return 1;
}
int ilock_read_serialno(){
ilock_send_package(CMD_TYPE_REQ,0x20,NULL,0);
return 1;
}
//*
//1 or 3
int ilock_play_voice(int voice_index){
uint8_t data[1] = {voice_index};
ilock_send_package(CMD_TYPE_REQ,0x48,(uint8_t*)&data,sizeof(data));
return 1;
}
int ilock_factory_reset(){
BK_LOGE(TAG, "ilock_factory_reset");
uint8_t data[5] = {0};
ilock_send_package(CMD_TYPE_REQ,0x24,(uint8_t*)&data,sizeof(data));
return 1;
}
int ilock_open_lock(){
//aa 0b 81 40 06 43 bb 8b a6 1f 03 88 6d
//bk_uart_set_baud_rate(uart_id, 8130);
//unsigned char wakeup[4] = {0x0F,0xF0,0xFF,0xFF};
//bk_uart_write_bytes(uart_id, wakeup, sizeof(wakeup));
//rtos_delay_milliseconds(50);
//unsigned char cmds[6] = {0xAA,0x04,0xD1,0x44,0xD0,0x9D};
uint8_t data[5] = {0x0D,0x00,0x00,0x00,0x00};
BK_LOGE(TAG, "ilock_open_lock");
ilock_send_package(CMD_TYPE_REQ,0x40,(uint8_t*)&data,sizeof(data));
return 0;
}
int ilock_open_lock_sos(){
BK_LOGE(TAG, "ilock_open_lock_sos");
uint8_t data[5] = {0x0D,0x00,0x00,0x00,0x00};
ilock_send_package(CMD_TYPE_REQ,0x4A,(uint8_t*)&data,sizeof(data));
return 0;
}
int ilock_open_camera(){
BK_LOGE(TAG, "ilock_open_camera");
uint8_t data[1] = {0x01};
ilock_send_package(CMD_TYPE_REQ,0x49,(uint8_t*)&data,sizeof(data));
return 0;
}
int ilock_close_camera(){
BK_LOGE(TAG, "\n\nilock_close_camera\n\n");
uint8_t data[1] = {0x00};
ilock_send_package(CMD_TYPE_REQ,0x49,(uint8_t*)&data,sizeof(data));
return 0;
}
int ilock_close_lock(){
BK_LOGE(TAG, "ilock_close_lock");
uint8_t data[5] = {0x0D,0x00,0x00,0x00,0x00};
ilock_send_package(CMD_TYPE_REQ,0x41,(uint8_t*)&data,sizeof(data));
return 0;
}
/*
*获取锁体参数
*/
int ilock_read_lock_params(){
ilock_send_package(CMD_TYPE_REQ,0x23,NULL,0);
return 0;
}
static void ilock_parser_data(uint8_t *recv, int len){
if(recv == NULL || len == 0) return;
if(recv[0]!= 0xAA && len < 2) return;
uint8_t data_len = recv[1];
//LOGE("data len: %d \n", data_len);
LOGE("\n");
LOGE("data len: %d \n", data_len);
//命令序号
uint8_t serial_no = (recv[2]&0xF0)>>4;
LOGE("serial_no: %d \n", serial_no);
//判断数据类型
uint8_t type = (recv[2]&0xF);
switch (type)
{
case 1://req
LOGE("data type: req\n");
break;
case 2://resp
LOGE("data type: resp\n");
break;
case 3://receipt
LOGE("data type: receipt\n");
break;
default:
break;
}
LOGE("cmd: %2x\n", recv[3]);
if(type == 1){
switch (recv[3])
{
case 0x47:{
LOGE("event: %d\n",recv[4]);
char str_state[32] = {0};
sprintf(str_state,"%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X",recv[5],recv[6],recv[7],recv[8],
recv[9],recv[10],recv[11],recv[12],recv[13],recv[14],recv[15],recv[16],recv[17],recv[18]);
LOGE("state: %s\n",str_state);
//获取状态数据体长度(去标志头尾等)
int status_len = data_len - 5 -2 ;
//循环判断key 和 value
ilock_dev dev_info;
for(int i = 0 ;i<status_len ;i++){
int index = 5+i;
int key = recv[index];
//LOGE("key: %02X\n",key);
switch(key){
case 0x01:
dev_info.lock_lock_state= recv[index+1];
i++;
break;
case 0x02:
dev_info.lock_door_state = recv[index+1];
i++;
break;
case 0x03:
dev_info.lock_lockedin_state = recv[index+1];
i++;
break;
case 0x04:
dev_info.lock_power_supply = recv[index+1];
i++;
break;
case 0x05:
dev_info.lock_batt_value = recv[index+1];
i++;
break;
case 0x06:
dev_info.lock_batt_state = recv[index+1];
i++;
break;
case 0x07:
dev_info.lock_disable_lock_state = recv[index+1];
i++;
break;
case 0xF0:
i = i+2; //F0 的值为2个字节
break;
case 0xF1:
i = i+4; //F1 的值为4个字节
break;
}
//LOGE("value: %02X\n",recv[5+i+1]);
//i++;
}
//LOGE(" batt_value> %d \r\n,",dev_info.lock_batt_value);
//LOGE(" lock_door_state> %d \r\n,",dev_info.lock_door_state);
//LOGE(" lock_lock_state> %d \r\n,",dev_info.lock_lock_state);
if (event_cb != NULL)
event_cb->event_lock_state(&dev_info);
break;
}
case 0x48:
if (event_cb != NULL)
event_cb->event_doorbell(0,0);
break;
case 0x49:
if (event_cb != NULL)
event_cb->event_network_boarding();
break;
}
}
if(type == 2){ //resp
switch (recv[3])
{
//获取版本号回复
case 0x21:
if(recv[4] == 0){
LOGE("read version: succ\n");
LOGE("%02X%02X%02X%02X\n",recv[5],recv[6],recv[7],recv[8]);
char str_version[8] = {0};
sprintf(str_version,"%02X%02x%02X%02X",recv[5],recv[6],recv[7],recv[8]);
if (event_cb != NULL)
event_cb->event_lock_version(str_version,strlen(str_version));
}
break;
//获取锁体状态回复
case 0x23:
if(recv[4] == 0){
LOGE("read param: succ\n");
int body_len = data_len - 3 - 2;
LOGE("body_len: %d\n",body_len);
char str_params[body_len];
os_memcpy(&str_params[0], &recv[5], body_len);
#if 0
for (int i = 0; i < body_len; i++) {
BK_LOGE(TAG, "%02X\r\n", str_params[i]);
}
#endif
if (event_cb != NULL)
event_cb->event_lock_params(str_params,body_len);
}
else{
LOGE("read param: fail\n");
}
break;
case 0x40:
if(recv[4] == 0){
LOGE("unlock: succ\n");
if (event_cb != NULL)
event_cb->event_lock_unlock(1);
}
else{
LOGE("unlock: fail\n");
if (event_cb != NULL)
event_cb->event_lock_unlock(0);
}
break;
case 0x4A:
LOGE("sos unlock: succ lock_command.cmd_type%02X\n",lock_command.cmd_type);
if(recv[4] == 0){
if(lock_command.cmd_type == 0x4A){
lock_command.resp_state=1;
lock_command.cmd_result = 1;
}
LOGE("sos unlock: succ\n");
if (event_cb != NULL)
event_cb->event_lock_unlock_sos(1);
}
else{
if(lock_command.cmd_type == 0x4A){
lock_command.resp_state=1;
lock_command.cmd_result = 0;
}
LOGE("sos unlock: fail\n");
if (event_cb != NULL)
event_cb->event_lock_unlock_sos(0);
}
break;
case 0x41:
if(recv[4] == 0){
LOGE("lock: succ\n");
if (event_cb != NULL)
event_cb->event_lock_lock(1);
}
else{
LOGE("lock: fail\n");
if (event_cb != NULL)
event_cb->event_lock_lock(0);
}
break;
case 0x44:{
LOGE("event: %d\n",recv[4]);
char str_state[32] = {0};
sprintf(str_state,"%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X",recv[5],recv[6],recv[7],recv[8],
recv[9],recv[10],recv[11],recv[12],recv[13],recv[14],recv[15],recv[16],recv[17],recv[18]);
LOGE("state: %s\n",str_state);
//获取状态数据体长度(去标志头尾等)
int status_len = data_len - 5 -2 ;
//循环判断key 和 value
ilock_dev dev_info;
for(int i = 0 ;i<status_len ;i++){
int index = 5+i;
int key = recv[index];
//LOGE("key: %02X\n",key);
switch(key){
case 0x01:
dev_info.lock_lock_state= recv[index+1];
i++;
break;
case 0x02:
dev_info.lock_door_state = recv[index+1];
i++;
break;
case 0x03:
dev_info.lock_lockedin_state = recv[index+1];
i++;
break;
case 0x04:
dev_info.lock_power_supply = recv[index+1];
i++;
break;
case 0x05:
dev_info.lock_batt_value = recv[index+1];
i++;
break;
case 0x06:
dev_info.lock_batt_state = recv[index+1];
i++;
break;
case 0x07:
dev_info.lock_disable_lock_state = recv[index+1];
i++;
break;
case 0xF0:
i = i+2; //F0 的值为2个字节
break;
case 0xF1:
i = i+4; //F1 的值为4个字节
break;
}
//LOGE("value: %02X\n",recv[5+i+1]);
//i++;
}
//LOGE(" batt_value> %d \r\n,",dev_info.lock_batt_value);
//LOGE(" lock_door_state> %d \r\n,",dev_info.lock_door_state);
//LOGE(" lock_lock_state> %d \r\n,",dev_info.lock_lock_state);
if (event_cb != NULL)
event_cb->event_lock_state(&dev_info);
break;
}
case 0x47:
break;
default:
break;
}
}
LOGE("\n");
if (event_cb != NULL)
event_cb->event_lock_recv_data(recv,len);
}
static void ilock_rx_task(void *arg)
{
uint8_t *data = (uint8_t *)os_malloc(RX_BUF_SIZE+1);
#if 0
//char *msg = NULL;
int ret = -1;
int cnt = 0;
uint8_t rx_data;
while (1) {
ret = rtos_get_semaphore(&uart_rx_semaphore, BEKEN_WAIT_FOREVER);
if(kNoErr == ret) {
while(1) /* read all data from rx-FIFO. */
{
ret = uart_read_byte_ex(uart_id, &rx_data);
if (ret == -1)
break;
data[cnt] = (char)rx_data;
cnt++;
if(cnt >= RX_BUF_SIZE)
break;
}
//bkreg_run_command1(data, cnt);
if(cnt > 0){
uint8_t *buff = (uint8_t *)os_malloc(cnt);
if(buff)
{
os_memcpy(buff, data, cnt);
UartMessage uMsg;
uMsg.len = cnt;
uMsg.msg = buff;
uMsg.type = UART_RX_MSG;
bk_err_t ret = rtos_push_to_queue(&uart1_msg_q, &uMsg, BEKEN_NEVER_TIMEOUT);
if(kNoErr != ret)
{
os_printf("rtos_push_to_queue failed\r\n");
os_free(buff);
}
}
memset(data,0,RX_BUF_SIZE+1);
cnt = 0;
}
}
}
#else
while (rx_start) {
//ilock_sendData("hello world!!",3);
int rxBytes = bk_uart_read_bytes(uart_id, data, RX_BUF_SIZE, BEKEN_WAIT_FOREVER);//ms BEKEN_WAIT_FOREVER 200
if (rxBytes > 0) {
data[rxBytes] = 0;
uint8_t *buff = (uint8_t *)os_malloc(rxBytes);
if(buff)
{
os_memcpy(buff, data, rxBytes);
UartMessage uMsg;
uMsg.len = rxBytes;
uMsg.msg = buff;
uMsg.type = UART_RX_MSG;
bk_err_t ret = rtos_push_to_queue(&uart1_msg_q, &uMsg, BEKEN_NEVER_TIMEOUT);
if(kNoErr != ret)
{
os_printf("rtos_push_to_queue failed\r\n");
os_free(buff);
}
}
//BK_LOGE(TAG, "uart recv data:\r\n");
//bk_uart_write_bytes(uart_id, data, rxBytes);
//for (int i = 0; i < rxBytes; i++) {
// BK_LOGE(TAG, "%02X\r\n", data[i]);
//}
//warning_prf("Read %d bytes: %s \r\n",rxBytes,data);
}else{
//warning_prf("Read ..\r\n");
}
}
#endif
if(data) {
os_free(data);
}
data = NULL;
BK_LOGE(TAG, "lock_rx_task finish \r\n");
}
/**
* 处理命令
* 1.判断命令类型
* 2.组装命令
* 3.发送命令
* 4.while命令结果
* 5.命令是否超时 重复一次
* 6.回调结果
*/
void lock_command_handle_thread( beken_thread_arg_t arg )
{
while(1)
{
bk_err_t ret = rtos_pop_from_queue(&lock_command_q, &lock_command, BEKEN_WAIT_FOREVER);
if(kNoErr != ret)
{
}
BK_LOGE(TAG, "handle_thread:%02X\r\n",lock_command.cmd_type);
//rtos_delay_milliseconds(1000);
switch(lock_command.cmd_type)
{
case CMD_OPEN_LOCK:
break;
case CMD_OPEN_LOCK_SOS:
BK_LOGE(TAG, "lock_command_q -> CMD_OPEN_LOCK_SOS\r\n");
ilock_open_lock_sos();
break;
case CMD_CLOSE_LOCK:
break;
default:
os_printf("unknown msg\r\n");
break;
}
}
}
int ilock_send_lock_commond(char *message_id,int cmd_type,int param){
BK_LOGE(TAG, "ilock_send_lock_commond:%02x",cmd_type);
lock_command_t command;
command.cmd_type = cmd_type;
memset(command.message_id,0,sizeof(command.message_id));
strcpy((char *)command.message_id,message_id);
BK_LOGE(TAG, "ilock_send_lock_commond:%s",command.message_id);
bk_err_t ret = rtos_push_to_queue(&lock_command_q, &command, BEKEN_NEVER_TIMEOUT);
if(kNoErr != ret)
{
os_printf("rtos_push_to_queue failed\r\n");
}
BK_LOGE(TAG, "ilock_send_lock_commond: succ");
return 1;
}
/**
* 对接收到的串口数据进行分包解析处理
*/
static ilock_recv_t parser_data(unsigned char data){
//BK_LOGE(TAG,"%02X ", data&0xFF);
if(recv_len == CMD_PACKAGE_LEN_MAX){
recv_len = 0;
recv_state = STATUS_IDLE;
}
switch(recv_state){
case STATUS_IDLE:
case STATUS_HEAD://接收0xAA头
if(data == CMD_LOCK_START){
recv_len = 0;
recv_buff[recv_len++] = data;
recv_state = STATUS_LEN;
}
break;
case STATUS_LEN://接收LEN
data_len = data;
recv_buff[recv_len++] = data;
recv_state = STATUS_DATA;
break;
case STATUS_DATA://接收DATA
recv_buff[recv_len++] = data;
if(recv_len== data_len) {
//DATA接收到缓冲区完成
recv_state = STATUS_CRC1;
}
break;
case STATUS_CRC1://接收CRC1
recv_buff[recv_len++] = data;
recv_state = STATUS_CRC2;
break;
case STATUS_CRC2://接收CRC2
recv_buff[recv_len++] = data;
int crc = ilock_crc16_modbus(&recv_buff[2],recv_len-4);
unsigned char crc1 = recv_buff[recv_len-2]&0xFF;
unsigned char crc2 = recv_buff[recv_len-1]&0xFF;
int crcData =crc1 << 8|crc2;
//printf("CRC1 %02X \r\n", crc1);
//printf("CRC2 %02X \r\n", crc2);
//printf("crcData %d \r\n", crcData);
if(crcData != crc) {
BK_LOGE(TAG,"CRC ERROR!\r\n");
recv_len = 0;
recv_state = STATUS_IDLE;
}else {
BK_LOGE(TAG,"CRC OK!\r\n");
//处理一包完整的数据包
ilock_parser_data(recv_buff,recv_len);
recv_len = 0;
data_len = 0;
}
recv_state = STATUS_IDLE;
break;
default: break;;
}
return recv_state;
}
void uart_tx_rx_handle_thread( beken_thread_arg_t arg )
{
UartMessage uMsg;
while(1)
{
bk_err_t ret = rtos_pop_from_queue(&uart1_msg_q, &uMsg, BEKEN_WAIT_FOREVER);
if(kNoErr != ret)
{
}
switch(uMsg.type)
{
case UART_RX_MSG:
os_printf("UART_RX_MSG \r\n");
//对接收到的数据逐个传入解析器 解析出完整的通信协议包
for(int i = 0; i< uMsg.len; i++){
parser_data(uMsg.msg[i]);
}
if(uMsg.msg)
{
os_free(uMsg.msg);
}
break;
case UART_TX_MSG:
//uart1_txdata_handler(u1msg);
os_printf("UART_TX_MSG \r\n");
break;
default:
os_printf("unknown msg\r\n");
break;
}
}
}
void ilock_init(void)
{
bk_uart_driver_init();
ilock_uart_init();
bk_err_t ret = BK_OK;
if(NULL == uart_rx_semaphore)
{
ret = rtos_init_semaphore(&uart_rx_semaphore, 1);
if (kNoErr != ret)
os_printf("ilock_init: create background sema failed\r\n");
}
ret = rtos_init_queue(&uart1_msg_q,
"UartQueue",
sizeof(UartMessage),
12);
ret = rtos_init_queue(&lock_command_q,
"LockCommand",
sizeof(lock_command_t),
5);
ret = rtos_create_thread( NULL, BEKEN_APPLICATION_PRIORITY,
"UART1_TxRx_Handle",
uart_tx_rx_handle_thread,
0x2048,
0 );
ret = rtos_create_thread( NULL, BEKEN_APPLICATION_PRIORITY,
"LockCommand_Handle ",
lock_command_handle_thread,
0x2048,
0 );
if (ret != kNoErr) {
warning_prf("ilock_init fail \r\n");
ilock_thread_hdl = NULL;
}
}
void ilock_rx_start(){
bk_err_t ret = BK_OK;
rx_start = 1;
ret = rtos_create_thread(&ilock_thread_hdl,
BEKEN_APPLICATION_PRIORITY,
"ilock",
(beken_thread_function_t)ilock_rx_task,
1024*2,
NULL);
if (ret != kNoErr) {
warning_prf("create ilock_rx_task fail \r\n");
ilock_thread_hdl = NULL;
}
}
void ilock_rx_stop(){
rx_start = 0;
}
void ilock_deinit(void){
rtos_deinit_queue(&uart1_msg_q);
uart1_msg_q = NULL;
ilock_rx_stop();
bk_uart_driver_deinit();
}