123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885 |
- /*
- * File : rz.c
- * the core functions of implementing zmodem protocol
- * Change Logs:
- * Date Author Notes
- * 2011-03-29 itspy
- */
- #include <rtthread.h>
- #include <finsh.h>
- #include <shell.h>
- #include <rtdef.h>
- #include <dfs.h>
- #include <dfs_file.h>
- #include <dfs_posix.h>
- #include <stdio.h>
- #include "zdef.h"
- char ZF0_CMD; /* file conversion request */
- char ZF1_CMD; /* file management request */
- char ZF2_CMD; /* file transport request */
- char ZF3_CMD;
- rt_uint8_t Rxframeind; /* ZBIN ZBIN32, or ZHEX type of frame */
- rt_uint16_t Rxcount; /* received count*/
- char header_type; /* header type */
- rt_uint8_t rx_header[4]; /* received header */
- rt_uint8_t tx_header[4]; /* transmitted header */
- rt_uint32_t Rxpos; /* received file position */
- rt_uint32_t Txpos; /* transmitted file position */
- rt_uint8_t Txfcs32; /* TURE means send binary frames with 32 bit FCS */
- rt_uint8_t TxCRC; /* controls 32 bit CRC being sent */
- rt_uint8_t RxCRC; /* indicates/controls 32 bit CRC being received */
- /* 0 == CRC16, 1 == CRC32, 2 == CRC32 + RLE */
- char Attn[ZATTNLEN+1]; /* attention string rx sends to tx on err */
- void zinit_parameter(void);
- void zsend_bin_header(rt_uint8_t type, rt_uint8_t *hdr);
- void zsend_hex_header(rt_uint8_t type, rt_uint8_t *hdr);
- void zsend_bin_data(rt_uint8_t *buf, rt_int16_t len, rt_uint8_t frameend);
- static rt_int16_t zrec_data16(rt_uint8_t *buf, rt_uint16_t len);
- static rt_int16_t zrec_data32(rt_uint8_t *buf, rt_int16_t len);
- static rt_int16_t zrec_data32r(rt_uint8_t *buf, rt_int16_t len);
- rt_int16_t zget_data(rt_uint8_t *buf, rt_uint16_t len);
- rt_int16_t zget_header(rt_uint8_t *hdr);
- static rt_int16_t zget_bin_header(rt_uint8_t *hdr);
- static rt_int16_t zget_bin_fcs(rt_uint8_t *hdr);
- rt_int16_t zget_hex_header(rt_uint8_t *hdr);
- static void zsend_ascii(rt_uint8_t c);
- void zsend_zdle_char(rt_uint16_t ch);
- static rt_int16_t zget_hex(void);
- rt_int16_t zread_byte(void);
- rt_int16_t zxor_read(void);
- void zput_pos(rt_uint32_t pos);
- void zget_pos(rt_uint32_t pos);
- void zinit_parameter(void)
- {
- rt_uint8_t i;
- ZF0_CMD = CANFC32|CANFDX|CANOVIO; /* not chose CANFC32,CANRLE,although it have been supported */
- ZF1_CMD = 0; /* fix header length,not support CANVHDR */
- ZF2_CMD = 0;
- ZF3_CMD = 0;
- Rxframeind =0;
- header_type = 0;
- Rxcount = 0;
- for (i=0;i<4;i++) rx_header[i] = tx_header[i] = 0;
- Rxpos = Txpos = 0;
- RxCRC = 0;
- Txfcs32 = 0;
- return ;
- }
- /* send binary header */
- void zsend_bin_header(rt_uint8_t type, rt_uint8_t *hdr)
- {
- rt_uint8_t i;
- rt_uint32_t crc;
- zsend_byte(ZPAD);
- zsend_byte(ZDLE);
- TxCRC = Txfcs32;
- if (TxCRC == 0)
- {
- zsend_byte(ZBIN);
- zsend_zdle_char(type);
- /* add 16bits crc */
- crc = 0L;
- crc = updcrc16(type, 0);
- for (i=0;i<4;i++)
- {
- zsend_zdle_char(*hdr);
- crc = updcrc16((0377 & *hdr++),crc);
- }
- crc = updcrc16(0,updcrc16(0,crc));
- zsend_zdle_char(((int)(crc>>8)));
- zsend_zdle_char(crc);
- }
- else if(TxCRC == 1)
- {
- zsend_byte(ZBIN32);
- zsend_zdle_char(type);
- /* add 32bits crc */
- crc = 0xffffffffL;
- crc = updcrc32(type, crc);
- for (i=0;i<4;i++)
- {
- zsend_zdle_char(*hdr);
- crc = updcrc32((0377 & *hdr++), crc);
- }
- crc = ~crc;
- for (i=0; i<4;i++)
- {
- zsend_zdle_char(crc);
- crc >>= 8;
- }
- }
- else if (TxCRC == 2)
- {
- zsend_byte(ZBINR32);
- zsend_zdle_char(type);
- /* add 32bits crc */
- crc = 0xffffffffL;
- crc = updcrc32(type, crc);
- for (i=0;i<4;i++)
- {
- zsend_zdle_char(*hdr);
- crc = updcrc32((0377 & *hdr++), crc);
- }
- crc = ~crc;
- for (i=0; i<4;i++)
- {
- zsend_zdle_char(crc);
- crc >>= 8;
- }
- }
- return;
- }
- /* send hex header */
- void zsend_hex_header(rt_uint8_t type, rt_uint8_t *hdr)
- {
- rt_uint8_t i;
- rt_uint16_t crc;
- zsend_line(ZPAD); zsend_line(ZPAD); zsend_line(ZDLE);
- zsend_line(ZHEX);
- zsend_ascii(type);
- crc = updcrc16(type, 0);
- for (i=0; i<4; i++)
- {
- zsend_ascii(*hdr);
- crc = updcrc16((0377 & *hdr++), crc);
- }
- crc = updcrc16(0,updcrc16(0,crc));
- zsend_ascii(crc>>8);
- zsend_ascii(crc);
- /* send display control cmd */
- zsend_line(015); zsend_line(0212);
- if (type != ZFIN && type != ZACK)
- zsend_line(021);
- TxCRC = 0; /* clear tx crc type */
- return;
- }
- /* send binary data,with frameend */
- void zsend_bin_data(rt_uint8_t *buf, rt_int16_t len, rt_uint8_t frameend)
- {
- rt_int16_t i,c,tmp;
- rt_uint32_t crc;
- if (TxCRC == 0) /* send binary data with 16bits crc check */
- {
- crc = 0x0L;
- for (i=0;i<len;i++)
- {
- zsend_zdle_char(*buf);
- crc = updcrc16((0377 & *buf++), crc);
- }
- zsend_byte(ZDLE); zsend_byte(frameend);
- crc = updcrc16(frameend, crc);
- crc = updcrc16(0,updcrc16(0,crc));
- zsend_zdle_char(crc>>8);
- zsend_zdle_char(crc);
- }
- else if (TxCRC == 1) /* send binary data with 32 bits crc check */
- {
- crc = 0xffffffffL;
- for (i=0;i<len;i++)
- {
- c = *buf++ & 0377;
- zsend_zdle_char(c);
- crc = updcrc32(c, crc);
- }
- zsend_byte(ZDLE); zsend_byte(frameend);
- crc = updcrc32(frameend, crc);
- crc = ~crc;
- for (i=0;i<4;i++)
- {
- zsend_zdle_char((int)crc); crc >>= 8;
- }
- }
- else if (TxCRC == 2) /* send binary data with 32bits crc check,RLE encode */
- {
- crc = 0xffffffffL;
- tmp = *buf++ & 0377;
- for (i = 0; --len >= 0; ++buf)
- {
- if ((c = *buf & 0377) == tmp && i < 126 && len>0)
- {
- ++i; continue;
- }
- if (i==0)
- {
- zsend_zdle_char(tmp);
- crc = updcrc32(tmp, crc);
- if (tmp == ZRESC)
- {
- zsend_zdle_char(0100); crc = updcrc32(0100, crc);
- }
- tmp = c;
- }
- else if (i == 1)
- {
- if (tmp != ZRESC)
- {
- zsend_zdle_char(tmp); zsend_zdle_char(tmp);
- crc = updcrc32(tmp, crc);
- crc = updcrc32(tmp, crc);
- i = 0; tmp = c;
- }
- }
- else
- {
- zsend_zdle_char(ZRESC); crc = updcrc32(ZRESC, crc);
- if (tmp == 040 && i < 34)
- {
- i += 036;
- zsend_zdle_char(i);
- crc = updcrc32(i, crc);
- }
- else
- {
- i += 0101;
- zsend_zdle_char(i); crc = updcrc32(i, crc);
- zsend_zdle_char(tmp); crc = updcrc32(tmp, crc);
- }
- i = 0; tmp = c;
- }
- }
- zsend_byte(ZDLE); zsend_byte(frameend);
- crc = updcrc32(frameend, crc);
- crc = ~crc;
- for (i=0;i<4;i++)
- {
- zsend_zdle_char(crc);
- crc >>= 8;
- }
- }
- if (frameend == ZCRCW)
- zsend_byte(XON);
- return;
- }
- /* receive data,with 16bits CRC check */
- static rt_int16_t zrec_data16(rt_uint8_t *buf, rt_uint16_t len)
- {
- rt_int16_t c,crc_cnt;
- rt_uint16_t crc;
- rt_err_t res = -RT_ERROR;
- rt_uint8_t *p,flag = 0;
- p = buf;
- crc_cnt = 0; crc = 0L;
- Rxcount = 0;
- while(buf <= p+len)
- {
- if ((res = zread_byte()) & ~0377)
- {
- if (res == GOTCRCE || res == GOTCRCG ||
- res == GOTCRCQ || res == GOTCRCW)
- {
- c = res;
- c = res;
- crc = updcrc16(res&0377, crc);
- flag = 1;
- continue;
- }
- else if (res == GOTCAN) return ZCAN;
- else if (res == TIMEOUT) return TIMEOUT;
- else return res;
- }
- else
- {
- if (flag)
- {
- crc = updcrc16(res, crc);
- crc_cnt++;
- if (crc_cnt < 2) continue;
- if ((crc & 0xffff))
- {
- #ifdef ZDEBUG
- rt_kprintf("error code: CRC16 error \r\n");
- #endif
- return -RT_ERROR;
- }
- return c;
- }
- else
- {
- *buf++ = res;
- Rxcount++;
- crc = updcrc16(res, crc);
- }
- }
- }
- return -RT_ERROR;
- }
- /* receive data,with 32bits CRC check */
- static rt_int16_t zrec_data32(rt_uint8_t *buf, rt_int16_t len)
- {
- rt_int16_t c,crc_cnt;
- rt_uint32_t crc;
- rt_err_t res = -RT_ERROR;
- rt_uint8_t *p,flag = 0;
- crc_cnt = 0; crc = 0xffffffffL;
- Rxcount = 0;
- while (buf <= p+len)
- {
- if ((res = zread_byte()) & ~0377)
- {
- if (res == GOTCRCE || res == GOTCRCG ||
- res == GOTCRCQ || res == GOTCRCW)
- {
- c = res;
- crc = updcrc32(res&0377, crc);
- flag = 1;
- continue;
- }
- else if (res == GOTCAN) return ZCAN;
- else if (res == TIMEOUT) return TIMEOUT;
- else return res;
- }
- else
- {
- if (flag)
- {
- crc = updcrc32(res, crc);
- crc_cnt++;
- if (crc_cnt < 4) continue;
- if ((crc & 0xDEBB20E3))
- {
- #ifdef ZDEBUG
- rt_kprintf("error code: CRC32 error \r\n");
- #endif
- return -RT_ERROR;
- }
- return c;
- }
- else
- {
- *buf++ = res;
- Rxcount++;
- crc = updcrc32(res, crc);
- }
- }
- }
- return -RT_ERROR;
- }
- /* receive data,with RLE encoded,32bits CRC check */
- static rt_int16_t zrec_data32r(rt_uint8_t *buf, rt_int16_t len)
- {
- rt_int16_t c,crc_cnt;
- rt_uint32_t crc;
- rt_err_t res = -RT_ERROR;
- rt_uint8_t *p,flag = 0;
- crc_cnt = 0; crc = 0xffffffffL;
- Rxcount = 0;
- p = buf;
- while (buf <= p+len)
- {
- if ((res = zread_byte()) & ~0377)
- {
- if (res == GOTCRCE || res == GOTCRCG ||
- res == GOTCRCQ || res == GOTCRCW)
- {
- c = res;
- crc = updcrc32(res&0377, crc);
- flag = 1;
- continue;
- }
- else if (res == GOTCAN) return ZCAN;
- else if (res == TIMEOUT) return TIMEOUT;
- else return res;
- }
- else
- {
- if (flag)
- {
- crc = updcrc32(res, crc);
- crc_cnt++;
- if (crc_cnt < 4) continue;
- if ((crc & 0xDEBB20E3))
- {
- #ifdef ZDEBUG
- rt_kprintf("error code: CRC32 error \r\n");
- #endif
- return -RT_ERROR;
- }
- return c;
- }
- else
- {
- crc = updcrc32(res, crc);
- switch (c)
- {
- case 0:
- if (res == ZRESC)
- {
- c = -1; continue;
- }
- *buf++ = res;
- Rxcount++;
- continue;
- case -1:
- if (res >= 040 && res < 0100)
- {
- c = res - 035; res = 040;
- goto spaces;
- }
- if (res == 0100)
- {
- c = 0;
- *buf++ = ZRESC;
- Rxcount++;
- continue;
- }
- c = res; continue;
- default:
- c -= 0100;
- if (c < 1)
- goto end;
- spaces:
- if ((buf + c) > p+len)
- goto end;
- while ( --res >= 0)
- {
- *buf++ = res;
- Rxcount++;
- }
- c = 0; continue;
- }
- }
- } // if -else
- }
- end:
- return -RT_ERROR;
- }
- rt_int16_t zget_data(rt_uint8_t *buf, rt_uint16_t len)
- {
- rt_int16_t res = -RT_ERROR;
- if (RxCRC == 0)
- {
- res = zrec_data16(buf,len);
- }
- else if (RxCRC == 1)
- {
- res = zrec_data32(buf, len);
- }
- else if (RxCRC == 2)
- {
- res = zrec_data32r(buf, len);
- }
- return res;
- }
- /* get type and cmd of header, fix lenght */
- rt_int16_t zget_header(rt_uint8_t *hdr)
- {
- rt_int16_t c,prev_char;
- rt_uint32_t bit;
- rt_uint16_t get_can,step_out;
- bit = get_device_baud(); /* get console baud rate */
- Rxframeind = header_type = 0;
- step_out = 0;
- prev_char = 0xff;
- for (;;)
- {
- c = zread_line(100);
- switch(c)
- {
- case 021:
- case 0221:
- if (prev_char == CAN) break;
- if (prev_char == ZCRCW) goto start_again;
- break;
- case RCDO:
- goto end;
- case TIMEOUT:
- if (prev_char == CAN) break;
- if (prev_char == ZCRCW)
- {
- c = -RT_ERROR; goto end;
- }
- goto end;
- case ZCRCW:
- if (prev_char == CAN) goto start_again;
- break;
- case CAN:
- get_can:
- if (++get_can > 5)
- {
- c = ZCAN; goto end;
- }
- break;
- case ZPAD:
- if (prev_char == CAN) break;
- if (prev_char == ZCRCW) goto start_again;
- step_out = 1;
- break;
- default:
- if (prev_char == CAN) break;
- if (prev_char == ZCRCW) goto start_again;
- start_again:
- if (--bit == 0)
- {
- c = GCOUNT; goto end;
- }
- get_can = 0;
- break;
- }
- prev_char = c;
- if (step_out) break; /* exit loop */
- }
- step_out = get_can = 0;
- for (;;)
- {
- c = zxor_read();
- switch(c)
- {
- case ZPAD:
- break;
- case RCDO:
- case TIMEOUT:
- goto end;
- case ZDLE:
- step_out = 1;
- break;
- default:
- goto start_again;
- }
- if (step_out) break;
- }
- Rxframeind = c = zxor_read();
- switch (c)
- {
- case ZBIN32:
- RxCRC = 1; c = zget_bin_fcs(hdr); break;
- case ZBINR32:
- RxCRC = 2; c = zget_bin_fcs(hdr); break;
- case ZBIN:
- RxCRC = 0; c = zget_bin_header(hdr); break;
- case ZHEX:
- RxCRC = 0; c = zget_hex_header(hdr); break;
- case CAN:
- goto get_can;
- case RCDO:
- case TIMEOUT:
- goto end;
- default:
- goto start_again;
- }
- end:
- return c;
- }
- /* receive a binary header */
- static rt_int16_t zget_bin_header(rt_uint8_t *hdr)
- {
- rt_int16_t res, i;
- rt_uint16_t crc;
- if ((res = zread_byte()) & ~0377)
- return res;
- header_type = res;
- crc = updcrc16(res, 0);
- for (i=0;i<4;i++)
- {
- if ((res = zread_byte()) & ~0377)
- return res;
- crc = updcrc16(res, crc);
- *hdr++ = res;
- }
- if ((res = zread_byte()) & ~0377)
- return res;
- crc = updcrc16(res, crc);
- if ((res = zread_byte()) & ~0377)
- return res;
- crc = updcrc16(res, crc);
- if (crc & 0xFFFF)
- {
- rt_kprintf("CRC error\n");
- return -RT_ERROR;
- }
- return header_type;
- }
- /* receive a binary header,with 32bits FCS */
- static rt_int16_t zget_bin_fcs(rt_uint8_t *hdr)
- {
- rt_int16_t res, i;
- rt_uint32_t crc;
- if ((res = zread_byte()) & ~0377)
- return res;
- header_type = res;
- crc = 0xFFFFFFFFL;
- crc = updcrc32(res, crc);
- for (i=0;i<4;i++) /* 4headers */
- {
- if ((res = zread_byte()) & ~0377)
- return res;
- crc = updcrc32(res, crc);
- *hdr++ = res;
- }
- for (i=0;i<4;i++) /* 4bytes crc */
- {
- if ((res = zread_byte()) & ~0377)
- return res;
- crc = updcrc32(res, crc);
- }
- if (crc != 0xDEBB20E3)
- {
- #ifdef ZDEBUG
- rt_kprintf("CRC error\n");
- #endif
- return -RT_ERROR;
- }
- return header_type;
- }
- /* receive a hex style header (type and position) */
- rt_int16_t zget_hex_header(rt_uint8_t *hdr)
- {
- rt_int16_t res,i;
- rt_uint16_t crc;
- if ((res = zget_hex()) < 0)
- return res;
- header_type = res;
- crc = updcrc16(res, 0);
- for (i=0;i<4;i++)
- {
- if ((res = zget_hex()) < 0)
- return res;
- crc = updcrc16(res, crc);
- *hdr++ = res;
- }
- if ((res = zget_hex()) < 0)
- return res;
- crc = updcrc16(res, crc);
- if ((res = zget_hex()) < 0)
- return res;
- crc = updcrc16(res, crc);
- if (crc & 0xFFFF)
- {
- #ifdef ZDEBUG
- rt_kprintf("error code : CRC error\r\n");
- #endif
- return -RT_ERROR;
- }
- res = zread_line(100);
- if (res < 0)
- return res;
- res = zread_line(100);
- if (res < 0)
- return res;
- return header_type;
- }
- /* convert to ascii */
- static void zsend_ascii(rt_uint8_t c)
- {
- const char hex[] = "0123456789abcdef";
- zsend_line(hex[(c&0xF0)>>4]);
- zsend_line(hex[(c)&0xF]);
- return;
- }
- /*
- * aend character c with ZMODEM escape sequence encoding.
- */
- void zsend_zdle_char(rt_uint16_t ch)
- {
- rt_uint16_t res;
- res = ch & 0377;
- switch (res)
- {
- case 0377:
- zsend_byte(res);
- break;
- case ZDLE:
- zsend_byte(ZDLE);
- res ^= 0100;
- zsend_byte(res);
- break;
- case 021:
- case 023:
- case 0221:
- case 0223:
- zsend_byte(ZDLE);
- res ^= 0100;
- zsend_byte(res);
- break;
- default:
- zsend_byte(res);
- }
- }
- /* decode two lower case hex digits into an 8 bit byte value */
- static rt_int16_t zget_hex(void)
- {
- rt_int16_t res,n;
- if ((res = zxor_read()) < 0)
- return res;
- n = res - '0';
- if (n > 9)
- n -= ('a' - ':');
- if (n & ~0x0f)
- return -RT_ERROR;
- if ((res = zxor_read()) < 0)
- return res;
- res -= '0';
- if (res > 9)
- res -= ('a' - ':');
- if (res & ~0x0f)
- return -RT_ERROR;
- res += (n<<4);
- return res;
- }
- /*
- * read a byte, checking for ZMODEM escape encoding
- * including CAN*5 which represents a quick abort
- */
- rt_int16_t zread_byte(void)
- {
- register int res;
- again:
- /* Quick check for non control characters */
- if ((res = zread_line(100)) & 0140)
- return res;
- switch (res)
- {
- case ZDLE:
- break;
- case 023:
- case 0223:
- case 021:
- case 0221:
- goto again;
- default:
- return res;
- }
- again2:
- if ((res = zread_line(100)) < 0)
- return res;
- if (res == CAN && (res = zread_line(100)) < 0)
- return res;
- if (res == CAN && (res = zread_line(100)) < 0)
- return res;
- if (res == CAN && (res = zread_line(100)) < 0)
- return res;
- switch (res)
- {
- case CAN:
- return GOTCAN;
- case ZCRCE:
- case ZCRCG:
- case ZCRCQ:
- case ZCRCW:
- return (res | GOTOR);
- case ZRUB0:
- return 0177;
- case ZRUB1:
- return 0377;
- case 023:
- case 0223:
- case 021:
- case 0221:
- goto again2;
- default:
- if ((res & 0140) == 0100)
- return (res ^ 0100);
- break;
- }
- return -RT_ERROR;
- }
- /*
- * @read a character from the modem line with timeout.
- * @eat parity, XON and XOFF characters.
- */
- rt_int16_t zxor_read(void)
- {
- rt_int16_t res;
- for (;;)
- {
- if ((res = zread_line(100)) < 0)
- return res;
- switch (res &= 0177) {
- case XON:
- case XOFF:
- continue;
- case '\r':
- case '\n':
- case ZDLE:
- default:
- return res;
- }
- }
- }
- /* put file posistion into the header*/
- void zput_pos(rt_uint32_t pos)
- {
- tx_header[ZP0] = pos;
- tx_header[ZP1] = pos>>8;
- tx_header[ZP2] = pos>>16;
- tx_header[ZP3] = pos>>24;
- return;
- }
- /* Recover a long integer from a header */
- void zget_pos(rt_uint32_t pos)
- {
- Rxpos = (rx_header[ZP3] & 0377);
- Rxpos = (Rxpos << 8) | (rx_header[ZP2] & 0377);
- Rxpos = (Rxpos << 8) | (rx_header[ZP1] & 0377);
- Rxpos = (Rxpos << 8) | (rx_header[ZP0] & 0377);
- return;
- }
- /* end of zcore.c */
|