This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Find a Safe and Fast Protocol Based on UART

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! */
    }