We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
I'm trying to find a typical communication protocol for transferring binary data by UART port. Basically, it should be detected according to the protocol when the input data is wrong.
The GPIB standard IEEE488.2 calls out a protocol that I have found also works for the serial port. the "ABPD" arbitrary binary ?? ?? is formatted as: the '#' character followed by a single digit that specifies how many characters that follow will specify the total transfer length.(for the stuff I was sending 99 bytes were plenty so I locked the code down to 2 to simplify the PC programmers and my lifes). Once the total byte count is known the rest is up to you. I followed it with a 2 byte checksum and then started in on the real data. /*example format== "#2ccSSwrd1wrd2wrd3...wrd16 cc = 10..40 in ascii. bytes count to follow SS = chksum if binary check enabled w1..w16 word data My interrupt routine looked like this: #pragma interrupt /* */ void Intr_SCI_unit(void) /* interrupt handler for the SCI module */ { WORD status, ch; int i,quote; // ... hardware functioning test ... removed */ /** break received when reset ALL buffers (break != null char) **/ if ((status & (RxBREAK | ANY_Rx_ERR)) == (RxBREAK | RxFR_ERR) ) { Rx_errch = memW(p + SCI_DATA); /* DUMMY rd to rst err flg */ clear_Rxbuf(); /* ie Fifo->in = Fifo->out = Fifo->count = 0; clear_Txbuf(); clear_BinRx(); Clr_parser_sys(); /* in main.c */ /* clr so "err" or 0 char not reported */ status &= ~(RxFR_ERR | RxBREAK| RxBUF_RDY); } /* end of if RxBREAK */ if (status & RxBUF_RDY) { /* Rx incoming char */ ch = get_the_char(); /* get char from hardware */ if (Rx.cnt >=(Rx_BUF_SIZE-MARGIN)) { /* if buffer is full ..*/ Stop_Rx(); /* if buffer full then try to Stop receiver */ } else do { quote = RS232.inquote; /* am I in a string */ if (!quote) { /* if i'm in the Binary transfer mode then ignore the value of the new character */ if (Bin_Rx.binary_mode) { Bin_Rx.ch = ch; Binary_Rx_code(); break; } if ('#'==ch) { /* may be a binary mode cmd */ Rx_buffer[Rx.in++] = ch; /* add char to fifo */ if (Rx.in >=Rx_BUF_SIZE) Rx.in = 0; /* test for raparound */ Rx.cnt++; /* inc char counter */ ZeroMemL(Bin_Rx); Bin_Rx.get_char_cnt = 1; Bin_Rx.binary_mode = TRUE; break; /* wait for the next char */ } if ( RS232.flow_cntr & RS232_FLOW_XON) { /* test for X.. chars */ if (ch == Xon_CHAR) { Tx_on_hold &= ~RS232_FLOW_XON; memW(p+ SCI_SCCR1) |= (TxON | ENA_Tx_INTR); /*make Tx on*/ break; /* goto Rx_read_exit; */ } if (ch == Xoff_CHAR) { Tx_on_hold |= RS232_FLOW_XON; /* set on_hold flag */ break; /* goto Rx_read_exit; */ } } /* end of if Xon flow control */ if (ch == BS_CHAR ) { /* if back space char */ if (Rx.cnt) { --Rx.cnt; if (--Rx.in < 0) Rx.in = Rx_BUF_SIZE; } break; } /* else not BS_CHAR */ } /* end of ! inside a quote string */ Rx_buffer[Rx.in++] = ch; /* add char to fifo */ if (Rx.in >=Rx_BUF_SIZE) Rx.in = 0; /* test for raparound */ Rx.cnt++; /* inc char counter */ if (quote) { if (ch==quote) RS232.inquote = 0; } else { if ((ch=='"') || (ch==39) ) RS232.inquote = ch; else if ((ch==';') || (ch < ' ')) { /* 13 || ch =='\n' */ SYS.Cmd.RS_command++; /* test for command term */ SYS.Cmd.new_cmd = TRUE; /* grab Parser's ear */ } } } while (0); /* end of incoming char,(0) for break commands */ } /* " " */ /*** ============== Error handing Control ========= ***/ .... /*** ============= Transmit Control ============== ***/ later ... void Binary_Rx_code(void) { BINARY_RX_TYPE *p = &Bin_Rx; char ch; long i,x,c; ch = p->ch; Rx_buffer[Rx.in++] = ch; /* add char to fifo */ if (Rx.in >=Rx_BUF_SIZE) Rx.in = 0; /* test for raparound */ Rx.cnt++; /* inc char counter */ if (p->bin_char_cnt) { /* char already added to buffer */ if (0 == (--p->bin_char_cnt)) { SYS.Cmd.RS_command++; /* test for command term */ SYS.Cmd.new_cmd = TRUE; /* grab Parser's ear */ ZeroMem( Bin_Rx ); /* clear for next time */ } return; } if (p->get_char_cnt) { if ((ch<'0') || (ch>'9')) { /* not a legel Bin_Rx cnt_er */ ZeroMemL(Bin_Rx); return; } i = ch -'0'; switch (p->get_char_cnt) { case 1: p->char_to_come_cnt = i; if ( p->char_to_come_cnt == 0) { ZeroMemL(Bin_Rx); /* RS232 does not support #0 type binary */ return; /* let ANSI take over */ } p->get_char_cnt = 2; /* for the next case code */ p->chars_to_come = 0; return; case 2: c = --p->char_to_come_cnt; x = 1; while (c--) x *= 10; p->chars_to_come += i * x; if (p->char_to_come_cnt) /* yet more to code */ return; p->get_char_cnt = 0; /* done w/ part 1*/ p->bin_char_cnt = p->chars_to_come; return; } /* end of switch */ return; } /* should not be able to get to here! */ }