ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

mydodo协议

2021-09-20 13:02:07  阅读:177  来源: 互联网

标签:协议 M2W CFG W2M eUart mydodo eCmd recv



wifi_串口协议v1.0.0

目录


帧结构

没帧数据由帧头+长度+载荷+校验和组成。

帧头1 帧头2 设备号 数据长度 数据 校验和
0x4D 0x59 xxx nByte xxxx BBC(异或校验)

例子:A5 5A 01 00 00,MCU上电初始化命令。

操作码 长度 载荷
1Byte 1Byte nBytes(0~130)

当一包数据最大只能20Bytes时,一帧数据可能会有拆包传输的情况,收到首包数据,需要根据长度字段判断该数据包是否接受完成,若长度字段大于18,则载荷部分拆包传输;若长度为0,则载荷部分为空。

命令

enum {
    eCmd_M2W_Init      = 0x00,    // MCU上电初始化
    eCmd_W2M_Init      = 0x01,    // WIFI上电初始化
    eCmd_W2M_WIFI_Conn = 0x02,    // wifi联网
    eCmd_M2W_Reset     = 0x03,    // 复位
    eCmd_M2W_Factory   = 0x04,    // 出厂模式

    eCmd_W2M_Update_Time    = 0x10,    // 更新时间
    eCmd_W2M_Update_Lunar   = 0x11,    // 更新农历
    eCmd_W2M_Update_Weather = 0x12,    // 更新天气
    eCmd_W2M_Sync_Time      = 0x13,    // 同步时间
    eCmd_W2M_Sync_Lunar     = 0x14,    // 同步农历
    eCmd_M2W_Sync_Weather   = 0x15,    // 同步天气

    eCmd_W2M_CFG_ALarm  = 0x20,    // 配置闹钟
    eCmd_W2M_Crtl_ALarm = 0x21,    // 控制闹钟
    eCmd_W2M_Play_Music = 0x22,    // 播放铃声

    eCmd_W2M_CFG_Sleep      = 0x30,    // 配置睡眠
    eCmd_W2M_Preview_SLight = 0x31,    // 预览睡眠亮度

    eCmd_W2M_CFG_HourMode       = 0x40,    // 配置时钟模式
    eCmd_M2W_CFG_HourMode       = 0x40,    // 配置时钟模式
    eCmd_W2M_CFG_TempMode       = 0x41,    // 配置温度模式
    eCmd_M2W_CFG_TempMode       = 0x41,    // 配置温度模式
    eCmd_W2M_CFG_DateMode       = 0x42,    // 配置日月模式
    eCmd_W2M_CFG_Scroll_Weather = 0x43,    // 配置天气切换
    eCmd_M2W_CFG_Scroll_Weather = 0x43,    // 配置天气切换
    eCmd_W2M_CFG_Content        = 0x44,    // 配置显示内容
    eCmd_W2M_CFG_Screen_SW      = 0x45,    // 配置屏幕关闭切换
    eCmd_W2M_CFG_Light          = 0x46,    // 配置屏幕亮度
    eCmd_M2W_CFG_Light          = 0x46,    // 配置屏幕亮度

    eCmd_W2M_Test_Init   = 0xF0,    // 产测开始
    eCmd_W2M_Test_RISS   = 0xF1,    // 产测信号强度
    eCmd_W2M_Test_Finish = 0xF2,    // 产测完成
    eCmd_W2M_Test_Failed = 0xF3,    // 产测失败
};

命令中,W2M类型命令属于是WIFI发往MCU指令;M2W类型命令属于MCU发往WIFI指令。

协议

代码样例

enum {
    eUart_Head0 = 0x00,
    eUart_Head1,
    eUart_Len,
    eUart_Body,
    eUart_CheckSum,
};

static uint8_t uart_protocol_state = eUart_Head0;
static uint8_t recv_timeout_cnt    = 0;

os_timer_t recv_timeout_timer;

/**
 * @brief  校验和
 * @note
 * @param  *source:
 * @param  len:
 * @retval
 */
uint8_t BCC_Check(uint8_t *dat, uint8_t dsize)
{
	uint8_t i=0;
        uint8_t check_sum = dat[0];

	for(i=1; i<dsize; i++)
		check_sum ^= dat[i];
	return check_sum;
}

/**
 * @brief  串口数据发送
 * @note
 * @param  *payload:
 * @param  payload_len:
 * @retval None
 */
void user_uart1_protocol_send(uint8_t *payload, uint8_t payload_len) {
    uint8_t buff[128] = {0};
    uint8_t checksum  = 0;
    uint8_t buff_len  = 0;

    buff[0] = UART_PROTOCOL_HEAD0;
    buff[1] = UART_PROTOCOL_HEAD1;
    buff[2] = payload_len;
    memcpy(&buff[3], payload, payload_len);
    checksum              = user_protocol_checksum(payload, payload_len);
    buff[3 + payload_len] = checksum;
    buff_len              = 4 + payload_len;

    uart_write(UART1, buff, buff_len);
}

/**
 * @brief  串口接收协议处理
 * @note
 * @retval None
 */
void user_uart1_recv_protocol_process(void) {
    static uint8_t byte_buf      = 0;
    static uint8_t payload_index = 0;

    while (fifo_get_cnt(&fifo_uart_recv) > 0) {
        fifo_getone(&fifo_uart_recv, &byte_buf);
        // LOG_INFO("byte_buf:%02X \r\n", byte_buf);

        switch (uart_protocol_state) {
        case eUart_Head0: {
            if (UART_PROTOCOL_HEAD0 == byte_buf) {
                uart_protocol_state++;
                os_timer_start(&recv_timeout_timer, 10, 1);
                recv_timeout_cnt = 0;
            }
            break;
        }
        case eUart_Head1: {
            if (UART_PROTOCOL_HEAD1 == byte_buf) {
                uart_protocol_state++;
                recv_timeout_cnt = 0;
            } else {
                if (UART_PROTOCOL_HEAD0 == byte_buf) {
                    recv_timeout_cnt = 0;
                } else {
                    uart_protocol_state--;
                    os_timer_stop(&recv_timeout_timer);
                }
            }

            break;
        }
        case eUart_Len: {
            payload_len = byte_buf;
            if (payload_len <= sizeof(payload_buff)) {
                payload_index = 0;
                uart_protocol_state++;
                recv_timeout_cnt = 0;
            } else {
                uart_protocol_state = eUart_Head0;
                os_timer_stop(&recv_timeout_timer);
            }
            break;
        }
        case eUart_Body: {
            payload_buff[payload_index] = byte_buf;
            payload_index++;
            if (payload_index == payload_len) {
                uart_protocol_state++;
            }
            recv_timeout_cnt = 0;
            break;
        }
        case eUart_CheckSum: {
            uint8_t check_sum     = byte_buf;
            uint8_t clc_check_sum = 0;

            os_timer_stop(&recv_timeout_timer);

            clc_check_sum = user_protocol_checksum(payload_buff, payload_len);
            if (clc_check_sum == check_sum) {
                // TODO: 解析协议
                user_protocol_recv_process(payload_buff, payload_len);
            }
            uart_protocol_state = eUart_Head0;
            break;
        }
        }
    }
}

/**
 * @brief  接收超时处理
 * @note
 * @param  *arg:
 * @retval None
 */
static void timer_recv_timeout_func(void *arg) {
    recv_timeout_cnt++;
    if (recv_timeout_cnt == 3) {
        uart_protocol_state = eUart_Head0;
        os_timer_stop(&recv_timeout_timer);
        LOG_ERR("uart recv timeout\r\n");
    }
}


/**
 * @brief  接收协议处理
 * @note
 * @param  *data:
 * @param  len:
 * @retval None
 */
void user_protocol_recv_process(uint8_t *data, uint8_t len) {
    if ((data == NULL) || (len == 0)) {
        return;
    }

    uint8_t *ptr  = data;
    uint8_t  len_ = len - 1;

    switch (*ptr++) {
    case eCmd_W2M_Init: {
        LOG_INFO("eCmd_W2M_Init\r\n");
        break;
    }
    case eCmd_W2M_WIFI_Conn: {
         // TODO: wifi连接处理
        break;
    }
    case eCmd_W2M_Update_Time: {
        // TODO: 更新时间
        break;
    }
    case eCmd_W2M_Update_Lunar: {
        // TODO: 更新农历时间
        break;
    }
    case eCmd_W2M_Update_Weather: {
        // TODO: 更新天气
        break;
    }
    case eCmd_W2M_CFG_ALarm: {
        // TODO: 配置闹钟
        break;
    }
    case eCmd_W2M_Crtl_ALarm: {
        // TODO: 控制闹钟
        break;
    }
    case eCmd_W2M_Play_Music: {
        // TODO: 播放铃声
        break;
    }
    case eCmd_W2M_CFG_Sleep: {
        // TODO: 配置睡眠
        break;
    }
    case eCmd_W2M_Preview_SLight: {
        // TODO: 预览睡眠亮度
        break;
    }
    case eCmd_W2M_CFG_HourMode: {
        // TODO: 配置小时制
    }
    case eCmd_W2M_CFG_Scroll_Weather: {
        // TODO: 配置天气滚动
        break;
    }
    case eCmd_W2M_CFG_Light: {
        // TODO: 配置亮度
        break;
    }
    }
}

标签:协议,M2W,CFG,W2M,eUart,mydodo,eCmd,recv
来源: https://www.cnblogs.com/taury/p/15314105.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有