.. _topics-betfx: ======================================== BETFX 简化版通信原理 Release:2020.12.24 ======================================== 描述: =============== :: 不论哪种传输方式,都是采用一问一答方式进行的, 外部设备作为主机,BETFX是从机, 读取BETFX时,BETFX会在接收完数据后的5ms内作出回应; 写数据时, BETFX同样在收完数据 后的5ms内回复固定字符串”OK\r\n”, 数据帧最长256 Byte. UART 数据帧格式: =================== 读取数据格式: +--------+--------+------------------------------------+------------------------------------+--------+-----------+ | 说明 | 起始符 | 数据长度[LEN] | 内容[CMD+首地址addr+读取数据长度n] | 校验位 | 结束符 | +========+========+====================================+====================================+========+===========+ | | | | CMD:0x81读取系统信息 | | | + + + +------------------------------------+--------+-----------+ | | | | CMD:0x82读取系统配置 | | | + + + +------------------------------------+--------+-----------+ | | | | CMD:0x83读取当前效果器寄存器 | | | + + + +------------------------------------+--------+-----------+ | 读命令 | 0x24 | 0x03 | CMD:0x84读取效果器默认参数 | CS | 0x0d+0x0a | + + + +------------------------------------+--------+-----------+ | | | CMD(1bytes)+addr(1bytes)+n(1bytes) | CMD:0x85读取当前EQ参数 | | | + + + +------------------------------------+--------+-----------+ | | | | CMD:0x86读取EQ默认参数 | | | + + + +------------------------------------+--------+-----------+ | | | | 首地址:1bytes 查数据结构表 | | | + + + +------------------------------------+--------+-----------+ | | | | 读取数据长度:1bytes 查数据结构表 | | | +--------+--------+------------------------------------+------------------------------------+--------+-----------+ | 回复 | 0x24 | n | para1+para2...paran | CS | 0x0d+0x0a | +--------+--------+------------------------------------+------------------------------------+--------+-----------+ 写数据格式 +--------+----------+---------------+------------------------------------------------------+--------+-----------+ | 说明 | 起始符 | 数据长度[LEN] | 内容[CMD+首地址addr+写数据长度n+para1+para2...paran] | 校验位 | 结束符 | +========+==========+===============+======================================================+========+===========+ | | | | CMD:0x01 保留 | | | + + + +------------------------------------------------------+ + + | | | | CMD:0x02 设置系统配置 | | | + + + +------------------------------------------------------+ + + | | | | CMD:0x03 设置效果器寄存器 | | | + + + +------------------------------------------------------+ + + | 写命令 | 0x24 | 0x03+n | CMD:0x05 设置EQ寄存器 | CS | 0x0d+0x0a | + + + +------------------------------------------------------+ + + | | | | addr:1bytes 查数据结构表 | | | + + + +------------------------------------------------------+ + + | | | | n:1bytes 查数据结构表 | | | + + + +------------------------------------------------------+ + + | | | | para1+para2...para3:nbytes 设置参数值 | | | +--------+----------+---------------+------------------------------------------------------+--------+-----------+ | 回复 | OK\\r\\n | | | | | +--------+----------+---------------+------------------------------------------------------+--------+-----------+ 说明: 数据长度+内容 数据必须转义成2个字符 分别转换成16进制 高4位 跟地4位的ASSCII码 例如 0x81 --> 0x38+0x31 CS:是起始符+LEN+内容所有值累加和低8位转换成2个字符 :: 例如: 读取系统信息:制造商名称 占用0x20个字节 地址为0 $03810020B2\\r\\n 起始符:$ LEN:03 CMD:81 addr:00 n:20 CS:B2 (0x24+0x30+0x38+0x31+0x30+0x30+0x32+0x30)%0xFF=0xB2 结束符:\\r\\n 注意事项 =================== A. UART 物理格式: 115200-8-N-1, 从机响应时间<5mS; B. 为了将来扩展应用, 不要对所有保留字段进行写操作; C. 传输采用ASCII, 允许的字符仅有字符0-9, A-Z, $, 以及\r\n, 其他所有字符都是不合法的. D. 传输中多字节字段,高字节在前. 数据结构 =================== ------------------------------ 系统信息(只读, 读): CMD:0x81 ------------------------------ +--------+------------+-----------------------------------------------------------------------------+ | 首地址 | 长度[字节] | 内容 | +========+============+=============================================================================+ | 0x00 | 0x08 | H','A','N','M','U','S', 0x00, 0x00// 技术供应商名称 | +--------+------------+-----------------------------------------------------------------------------+ | 0x08 | 0x08 | 'D','E','1','0','0',0x00, 0x00, 0x00 // 主控型号 | +--------+------------+-----------------------------------------------------------------------------+ | 0x10 | 0x04 | 软件发布日期, BCD格式, YYMMDDxx, xx代表当天发布序号 | +--------+------------+-----------------------------------------------------------------------------+ | 0x14 | 0x0C | 保留 | +--------+------------+-----------------------------------------------------------------------------+ | 0x20 | 0x02 | DELAY最长时间,高字节在前;//应用程序首先要读取当前字段,以确认DELAY数据范围 | +--------+------------+-----------------------------------------------------------------------------+ | | | BIT0=1 支持REVERB, 否则不支持; | + + + + | | | BIT1=1 支持CHORUS, 否则不支持; | + + + + | | | BIT2=1 支持哇音,否则不支持; | + + + + | | | BIT3=1 支持颤音, 否则不支持; | + + + + | 0x22 | 0x01 | BIT4=1 支持DELAY, 否则不支持; | + + + + | | | BIT5=1 支持FBC, 否则不支持; | + + + + | | | BIT6=1 支持IN EQ, 否则不支持; | + + + + | | | BIT7=1 支持DRY VOL, 否则不支持; | +--------+------------+-----------------------------------------------------------------------------+ | 0x23 | 0x01 | EQ 支持最大段数, 一般为6,代表1个HPF, 一个LPF, 4个参量均衡 | +--------+------------+-----------------------------------------------------------------------------+ | 0x24 | 0x02 | 保留 | +--------+------------+-----------------------------------------------------------------------------+ :: 例子:读取技术供应商信息 +---------+------+--------+------------------------+ | PageLen | CMD | 首地址 | 读取长度 | +=========+======+========+========================+ | 0x03 | 0x81 | 0x00 | 0x08[读取全部数据长度] | +---------+------+--------+------------------------+ 起始符 PageLen cmd 首地址 读取长度 校验位 结束符 编码格式如下:字符: $03810008B8\\r\\n 十六进制: 0x24 + 0x30+0x33 + 0x38+0x31 + 0x30+0x30 + 0x30+0x38 + 0x42+0x38 + 0x0D+0x0A CS:=(0x24+0x30+0x33+0x38+0x31+0x30+030+0x+0x38)%255 =0xB8 转义2位 0x42+0x38 回复:$0848414E4D55530000E0\\r\\n 返回 HANMUS 08: 数据长度为8 48414E4D55530000 数据内容 E0: CS :: 读取主控型号:DE100 Send:$03810808C0\\r\\n REV :$084445313030000000A7\r\n :: 读取发布日期:20120801 2020年12月8号01版本 Send:$03811004B5\r\n REV :$042012080116\r\n :: 读取系统DELAY TIME最大值 0x1F4 Send:$03812002B4 REV :$0201F461 :: 读取系统支持配置项 Send:$03812201B5 REV :$01D3FC :读取值为0xD3 : :: 读取EQ支持最大段数 Send:$03812301B6 REV :$0106EB 读取值为 0x06 .. image:: ../images/sysInfor.jpg ------------------------------------------ 系统配置(可读写): CMD: 0x82[读]/ 0x02[写] ------------------------------------------ +--------+------------+--------------------------------------------------------------------------------+ | 首地址 | 长度[字节] | 内容 | +========+============+================================================================================+ | | | 'H',0x00,'A',0x00,'N',0x00,'M',0x00,'U',0x00,'S',0x00, 0x00,0x00, 0x00,0x00, | + + +--------------------------------------------------------------------------------+ | 0x00 | 0x20 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | + + +--------------------------------------------------------------------------------+ | | | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00// 制造商名称, 例如: BMW [unicode编码] | +--------+------------+--------------------------------------------------------------------------------+ | | | 'A',0x00,'F',0x00,'-',0x00,'I',0x00,'I',0x00,’R’,0x00,‘C’,0x00, 0x00,0x00, | + + +--------------------------------------------------------------------------------+ | 0x20 | 0x20 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | + + +--------------------------------------------------------------------------------+ | | | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 // 产品型号, 例如: 740Li [unicode编码] | +--------+------------+--------------------------------------------------------------------------------+ | 0x40 | 0x04 | 生产日期, BCD格式, YYMMDDxx, xx代表当天发布序号 | +--------+------------+--------------------------------------------------------------------------------+ | 0x44 | 0x04 | 产品序列号, HEX格式 | +--------+------------+--------------------------------------------------------------------------------+ | | | 0x55h: 不锁定, 解锁定后, 效果器参数将自动恢复为HANMUS提供的默认参数, | + + +--------------------------------------------------------------------------------+ | 0x48 | 0x01 | 0xAA 锁定, 锁定后, 效果器参数将不可读出, | + + +--------------------------------------------------------------------------------+ | | | 其他数据忽略; | +--------+------------+--------------------------------------------------------------------------------+ | 0x49 | 0x36 | 保留 | +--------+------------+--------------------------------------------------------------------------------+ :: 读取制造商信息: Send:$03820020B3\\r\\n REV :$20480041004E004D00550053000000000000000000000000000000000000000000DA\\r\\n :: 读取产品型号 Send:$03822020B5\\r\\n REV :$20410046002D00490049002D005200430044000000000000000000000000000000F1\\r\\n :: 读取生产日期:20120801 Send:$03824004B9 REV :$042012080116 :: 读取产品序列号 Send:$03824404BD REV :$040000000008 :: 读取锁定参数 Send:$03824801BE REV :$0100E5 : 写入制造商信息为: 声天下科技有限公司 Send:$23020020F05829590B4ED1798062096750966C51F8530000000000000000000000000000B8 REV :OK\r\n .. image:: ../images/config.jpg ---------------------------------------------------------------- 效果器参数(可读写): CMD:0x83[读]/0x03[写] / 0x84[读取默认值] ---------------------------------------------------------------- +--------+------------+----------------------------------------------------------------------------------------------+ | 首地址 | 长度[字节] | 内容 | +========+============+==============================================================================================+ | 0x00 | 0x01 | 保留 | +--------+------------+----------------------------------------------------------------------------------------------+ | 0x01 | 0x01 | [Delay Volume],Type: UINT8, 200: 0dB, 最小值: 0(负无穷大); 最大值:200(0dB), 步进0.5dB | +--------+------------+----------------------------------------------------------------------------------------------+ | 0x02 | 0x01 | [Delay Repeat], Type: UINT8, 0-20, Def: 7 | +--------+------------+----------------------------------------------------------------------------------------------+ | 0x03 | 0x02 | [Delay Time], Type: UINT16, DEF: 220mS, 高字节在前. | +--------+------------+----------------------------------------------------------------------------------------------+ | 0x05 | 0x02 | 保留 | +--------+------------+----------------------------------------------------------------------------------------------+ | 0x07 | 0x01 | [Reverb Volume], Type: UINT8, 200: 0dB, 最小值: 0(负无穷大); 最大值:200(0dB), 步进0.5dB | +--------+------------+----------------------------------------------------------------------------------------------+ | 0x08 | 0x01 | 保留 | +--------+------------+----------------------------------------------------------------------------------------------+ | 0x09 | 0x01 | [Decay time], Type: UINT8, 0-100, 单位 :% | +--------+------------+----------------------------------------------------------------------------------------------+ | 0x0A | 0x01 | [Room Size], Type: UINT8, 0-100, 单位 :% | +--------+------------+----------------------------------------------------------------------------------------------+ | 0x0B | 0x01 | [Dramp], Type: UINT8, 0-100, 单位 :% | +--------+------------+----------------------------------------------------------------------------------------------+ | 0x0C | 0x01 | [CHORUS Volume], Type: UINT8, 200: 0dB, 最小值: 0(负无穷大); 最大值:200(0dB), 步进0.5dB | +--------+------------+----------------------------------------------------------------------------------------------+ | 0x0D | 0x01 | [Chorus speed], Type: UINT8, 0-10HZ, 单位 :0.1HZ | +--------+------------+----------------------------------------------------------------------------------------------+ | 0x0E | 0x01 | [Chorus Depth], Type: UINT8, 0-100, 单位 :% | +--------+------------+----------------------------------------------------------------------------------------------+ | 0x0F | 0x01 | [Chorus Feedback],Type: UINT8, 0-100, 单位 :% | +--------+------------+----------------------------------------------------------------------------------------------+ | 0x10 | 0x01 | [FX volume],总音量, Type: UINT8, 200: 0dB, 最小值: 0(负无穷大); 最大值:200(0dB), 步进0.5dB | +--------+------------+----------------------------------------------------------------------------------------------+ | 0x11 | 0x02 | [REVERB HPF FREQ], Type: UINT16, DEF: 20HZ, 范围: 20HZ-20KHZ, 高字节在前. | +--------+------------+----------------------------------------------------------------------------------------------+ | 0x13 | 0x02 | [REVERB LPF FREQ], Type: UINT16, DEF: 20000HZ, 范围: 20HZ-20KHZ, 高字节在前. | +--------+------------+----------------------------------------------------------------------------------------------+ | 0x15 | 0x02 | [REVERB PEAK FREQ], Type: UINT16, DEF: 20000HZ, 范围: 20HZ-20KHZ, 高字节在前. | +--------+------------+----------------------------------------------------------------------------------------------+ | 0x17 | 0x01 | [REVERB PEAK GAIN], Type: UINT8, DEF: 0dB, 范围: 100 +-12dB, 100代表0dB. | +--------+------------+----------------------------------------------------------------------------------------------+ | 0x18 | 0x01 | [FBC ENABLE],0: DISABLE, 1:ENABLE | +--------+------------+----------------------------------------------------------------------------------------------+ | 0x19 | 0x01 | [DRY volume],总音量, Type: UINT8, 200: 0dB, 最小值: 0(负无穷大); 最大值:200(0dB), 步进0.5dB | +--------+------------+----------------------------------------------------------------------------------------------+ | 0x1A | 0x02 | 保留 | +--------+------------+----------------------------------------------------------------------------------------------+ :: 读取效果器参数默认值 Send:$0384001CC7\\r\\n REV :$1C08C80700DC0000C800265D63C8043200C801181F4003E86400C8000057\\r\\n :: 读取效果器参数 地址0开始到0x1B的值 Send:$0383001CC6\\r\\n REV :$1C08C80700DC0000C800265D63C8043200A501181F4003E864E8A800006D\\r\\n :: 设置Delay Volume 音量为-20.5db 设置值为 200-41=159 =0x9F Send:$040301019F2C\\r\\n REV :OK\\r\\n :: 设置Delay time 为200ms 设置值为 0x00C8 $0503030200C88C|\r|\n REV :OK\r\n :: 设置混响高通频率 HPF = 1000hz =0x03E8 $0503110203E890\r\n REV :OK\r\n ----------------------------------------------------------- EQ寄存器(可读写):CMD :0x85[读]/0x05[写]/0x86[读取默认值] ----------------------------------------------------------- +--------+------+-----------------------------------------------------------------------------------------------------+ | 首地址 | 长度 | 内容 | +========+======+=====================================================================================================+ | 0x00 | 0x02 | 高通滤波器中心频率, Type: UINT16, DEF: 20HZ, 范围: 20HZ-20KHZ, 高字节在前; 例如:1000hz:0x03E4 | +--------+------+-----------------------------------------------------------------------------------------------------+ | 0x02 | 0x02 | 低通滤波器中心频率, Type: UINT16, DEF: 20HZ, 范围: 20HZ-20KHZ, 高字节在前; | +--------+------+-----------------------------------------------------------------------------------------------------+ | 0x04 | 0x02 | 参量均衡1 中心频率, Type: UINT16, DEF: 20HZ, 范围: 20HZ-20KHZ, 高字节在前; | +--------+------+-----------------------------------------------------------------------------------------------------+ | 0x06 | 0x01 | 参量均衡1 增益,Type: UINT8, DEF:100, 数值100代表0dB, 最小值: 88(-12dB); 最大值:112(12dB), 步进1dB; | +--------+------+-----------------------------------------------------------------------------------------------------+ | 0x07 | 0x01 | 参量均衡1 Q值,Type: UINT8, DEF:10, 最小值: 1(0.1); 最大值:255(25.5), 步进1 | + + +-----------------------------------------------------------------------------------------------------+ | | | 实际Q值等于该值除以10, 例如数值10代表滤波器Q值为1, 数值50代表Q值为5; | +--------+------+-----------------------------------------------------------------------------------------------------+ | 0x08 | 0x02 | 参量均衡2 中心频率,Type: UINT16, DEF: 20HZ, 范围: 20HZ-20KHZ, 高字节在前; | +--------+------+-----------------------------------------------------------------------------------------------------+ | 0x0A | 0x02 | 参量均衡2 增益,Type: UINT8, DEF:100, 数值100代表0dB, 最小值: 88(-12dB); 最大值:112(12dB), 步进1dB; | +--------+------+-----------------------------------------------------------------------------------------------------+ | 0x0B | 0x01 | 参量均衡2 Q值,Type: UINT8, DEF:10, 最小值: 1(0.1); 最大值:255(25.5), 步进1 | +--------+------+-----------------------------------------------------------------------------------------------------+ | 0x0C | 0x02 | 参量均衡3 中心频率, Type: UINT16, DEF: 20HZ, 范围: 20HZ-20KHZ, 高字节在前; | +--------+------+-----------------------------------------------------------------------------------------------------+ | 0x0E | 0x01 | 参量均衡3 增益,Type: UINT8, DEF:100, 数值100代表0dB, 最小值: 88(-12dB); 最大值:112(12dB), 步进1dB; | +--------+------+-----------------------------------------------------------------------------------------------------+ | 0x0F | 0x01 | 参量均衡3 Q值,Type: UINT8, DEF:10, 最小值: 1(0.1); 最大值:255(25.5), 步进1 | + + +-----------------------------------------------------------------------------------------------------+ | | | 实际Q值等于该值除以10, 例如数值10代表滤波器Q值为1, 数值50代表Q值为5; | +--------+------+-----------------------------------------------------------------------------------------------------+ | 0x10 | 0x02 | 参量均衡4 中心频率, Type: UINT16, DEF: 20HZ, 范围: 20HZ-20KHZ, 高字节在前; | +--------+------+-----------------------------------------------------------------------------------------------------+ | 0x12 | 0x01 | 参量均衡4 增益,Type: UINT8, DEF:100, 数值100代表0dB, 最小值: 88(-12dB); 最大值:112(12dB), 步进1dB; | +--------+------+-----------------------------------------------------------------------------------------------------+ | 0x13 | 0x01 | 参量均衡4 Q值,Type: UINT8, DEF:10, 最小值: 1(0.1); 最大值:255(25.5), 步进1 | + + +-----------------------------------------------------------------------------------------------------+ | | | 实际Q值等于该值除以10, 例如数值10代表滤波器Q值为1, 数值50代表Q值为5; | +--------+------+-----------------------------------------------------------------------------------------------------+ | 0x14 | 0x0C | 保留 | +--------+------+-----------------------------------------------------------------------------------------------------+ :: 读取EQ寄存器所有参赛的默认值 Send:$0386001ECB\\r\\n REV :$1E00144E2001F4640A03E8640A0BB8640A1F40640A00000000000000000000E8\\r\\n :: 读取EQ寄存器所有值 Send:$03850020B6\\r\\n REV :$2000144E2001F4640A03E8640A0BB8640A1F40640A00000000000000000000000094\\r\\n :: 设置EQ低通滤波器频率为100 = 0x0064 $0505020200647C\\r\\n REV :OK\\r\\n :: 设置均衡2中心频率 为2000 = 0x7D0 $0505080207D093\\r\\n REV :OK\\r\\n :: 设置均衡4增益为-5db 设置值为 100-5=95 =0x5F $050512025F3091\\r\\n REV :OK\\r\\n :: 设置均衡1的Q值为 0.9 设置值为 0.9*10 = 0x09 $04050701091E\\r\\n REV :OK\\r\\n 编解码参考 =================== .. code-block:: c #define RPC_BUF_MAX 256 #define RPC_BUF_MASK (RPC_BUF_MAX-1) //RPC 命令集 #define RPC_RESERVE 0x01 #define RPC_WRITE_STSTEM_CONFIG 0x02 #define RPC_WRITE_FX_REG 0x03 #define RPC_WRITE_INEQ_REG 0x05 #define RPC_READ_SYSTEM_INFOR 0x81 #define RPC_READ_SYSTEM_CONFIG 0x82 #define RPC_READ_FX_REG 0x83 #define RPC_READ_FX_DEFAULT_REG 0x84 #define RPC_READ_INEQ_REG 0x85 #define RPC_READ_DEFAULT_INEQ_REG 0x86 typedef struct { unsigned char rpcPackageLen; unsigned char cmd,add,len; unsigned char buf[RPC_BUF_MAX]; }frame_ctrl; typedef struct { int fi, fo; unsigned char buf[RPC_BUF_MAX]; }fifo_t; unsigned char hex2Assci(unsigned char hc) { hc = hc & 0x0f; if ((hc >= 0) && (hc <= 9))return (hc + '0'); return ((hc - 10) + 'A'); } unsigned char assci2hex(unsigned char a, unsigned char b) { if (a >= '0' && a <= '9')a = a - '0'; else if (a >= 'a' && a <= 'f') a = a - 'a' + 10; else if (a >= 'A' && a <= 'F') a = a - 'A' + 10; if (b >= '0' && b <= '9')b = b - '0'; else if (b >= 'a' && b <= 'f') b = b - 'a' + 10; else if (b >= 'A' && b <= 'F') b = b - 'A' + 10; return a * 16 + b; } void pushFifo(fifo_t *pfifo, unsigned char *pBuf, int len) { while (len-- > 0) { pfifo->buf[pfifo->fi++] = *pBuf++; pfifo->fi &= RPC_BUF_MASK; } /* 编码函数:返回值 pBufOut 发送数据的长度 cmd: 命令 addr :首地址 len:读写数据长度 *pBufIn: 写数据的内容首地址 /读模式为NULL *PBufOut: 编码后保持数据的首地址 write: false 读 true 写 */ int encode(unsigned char cmd, unsigned char addr, unsigned char len, unsigned char *pBufIn, unsigned char *pBufOut, bool write) { int i; unsigned char cs, d, d1, d2; int offset = 0; pBufOut[offset++&RPC_BUF_MASK] = 0x24; cs = 0x24; // pageageLen d1 = hex2Assci((unsigned char)((write?(len+3):3)>> 4)); pBufOut[offset++&RPC_BUF_MASK] = d1; cs += d1; d1 = hex2Assci((unsigned char)((write ? (len + 3) : 3) >>0)); pBufOut[offset++&RPC_BUF_MASK] = d1; cs += d1; // cmd d1 = hex2Assci((unsigned char)(cmd >> 4)); pBufOut[offset++&RPC_BUF_MASK] = d1; cs += d1; d1 = hex2Assci((unsigned char)(cmd >> 0)); pBufOut[offset++&RPC_BUF_MASK] = d1; cs += d1; // addr d1 = hex2Assci((unsigned char)(addr >> 4)); pBufOut[offset++&RPC_BUF_MASK] = d1; cs += d1; d1 = hex2Assci((unsigned char)(addr >> 0)); pBufOut[offset++&RPC_BUF_MASK] = d1; cs += d1; //len d1 = hex2Assci((unsigned char)(len >> 4)); pBufOut[offset++&RPC_BUF_MASK] = d1; cs += d1; d1 = hex2Assci((unsigned char)(len >> 0)); pBufOut[offset++&RPC_BUF_MASK] = d1; cs += d1; // date for (i = 0; i< (write ? len:0); i++) { d = pBufIn[i]; d1 = hex2Assci((unsigned char)(d >> 4)); d2 = hex2Assci(d); pBufOut[offset++&RPC_BUF_MASK] = d1; pBufOut[offset++&RPC_BUF_MASK] = d2; cs += (d1 + d2); } pBufOut[offset++&RPC_BUF_MASK] = hex2Assci((cs >> 4)); pBufOut[offset++&RPC_BUF_MASK] = hex2Assci(cs); pBufOut[offset++&RPC_BUF_MASK] = 0x0d; pBufOut[offset++&RPC_BUF_MASK] = 0x0a; pBufOut[offset&RPC_BUF_MASK] = 0x00; // only for printf. //pfifo->fi = offset&RPC_BUF_MASK; return write?(len*2 + 13):13; } /* 解码函数:返回值 0:解码成功 -1: -2:没有新的数据 -3:数据长度不足 fifo_t *pfifo: 接收数据缓存 frame_ctrl *pRpc:解码结构体 */ int decode(fifo_t *pfifo, frame_ctrl *pRpc) { int i, len; unsigned char d1, d2; unsigned short d; unsigned char rpcPackageLen; int offset; unsigned char cs; int ofs1=0; if (pfifo->fo == pfifo->fi)return -2; while (pfifo->fo != pfifo->fi) { if (pfifo->buf[pfifo->fo] == 0x24) { ofs1 = pfifo->fo; break; } pfifo->fo++; pfifo->fo &= RPC_BUF_MASK; } if (pfifo->buf[pfifo->fo] == 0x24) { len = ((pfifo->fi + RPC_BUF_MAX) - ofs1)&RPC_BUF_MASK; if (len<9)return -3;// must wait for "\r\n". d1 = pfifo->buf[(ofs1 + 1)&RPC_BUF_MASK]; d2 = pfifo->buf[(ofs1 + 2)&RPC_BUF_MASK]; rpcPackageLen = assci2hex(d1, d2); if (len<(rpcPackageLen * 2 + 7)) return -4; cs = 0x24 + d1 + d2; pRpc->len = rpcPackageLen; offset = (ofs1 + 3)&RPC_BUF_MASK; for (i = 0; ibuf[offset++&RPC_BUF_MASK]; d2 = pfifo->buf[offset++&RPC_BUF_MASK]; pRpc->buf[i&RPC_BUF_MASK] = assci2hex(d1, d2); cs += (d1 + d2); } pfifo->buf[ofs1] |= 0x80; d1 = pfifo->buf[offset++&RPC_BUF_MASK]; d2 = pfifo->buf[offset++&RPC_BUF_MASK]; if (cs == assci2hex(d1, d2)) { d1 = pfifo->buf[offset++&RPC_BUF_MASK]; d2 = pfifo->buf[offset++&RPC_BUF_MASK]; if ((d1 == 0x0d) && (d2 == 0x0a)) { pRpc->len = rpcPackageLen; return 0; } }else { printf("CS check error:%x,%x", cs, assci2hex(d1, d2))); } return -1; }