--- a/src/hp34comm.cpp Wed Oct 26 22:41:16 2016 +0200 +++ b/src/hp34comm.cpp Sat Oct 29 23:44:31 2016 +0200 @@ -15,19 +15,15 @@ #endif DigitalOut lled(LED1); - -HPSerial::HPSerial(PinName rx): - serial_rx(NC, rx), - ncmd(0) { - - //pc.printf("HPSerial init\n"); + + - for(uint8_t i=0; i<MAX_ERRS; i++) - errs[i] = 0; - reset(); - - serial_rx.baud(187500); - serial_rx.attach(this, &HPSerial::rxIrq, Serial::RxIrq); +HPSerial::HPSerial(PinName tx, PinName rx): + serial(tx, rx) +{ + cur_state = do_state_initial(&rx_data, 0x00); + serial.baud(187500); + serial.attach(this, &HPSerial::rxIrq, Serial::RxIrq); } bool HPSerial::cmd_available(void) { @@ -45,63 +41,11 @@ unsigned int HPSerial::nerrors(uint8_t errorno) { return errs[errorno]; } - - - -void HPSerial::reset(uint8_t errorno) { - timeouter.detach(); - head = 0; - tx_state = Idle; - setstatedbg(); - tx_cmd = 0xFF; - tx_ack = false; - tx_len = 0xFF; - memset(buf, 0, BUF_SIZE); - if (errorno != 0xFF){ - errs[errorno]++; - } - -} -void HPSerial::handleAck(uint8_t val) { - if ((tx_state == Rx) & (tx_cmd == 0xFF) & (tx_ack == false) & (val == 0x66)) { - // special case: keypad does not acknwledge and takes precedence - // on the "bus" - tx_state = Tx; - setstatedbg(); - } else - if (tx_cmd == 0xFF) // beginning of a packet, expect 0x99 as ack - if (val == 0x99) - { - tx_ack = true; -#ifdef DEBUG2 - ack = 1; - wait_us(2); - ack = 0; -#endif - } - else - reset(1); - - else // expect 0x00 as ack - if (val == 0x00) - { - tx_ack = true; -#ifdef DEBUG2 - ack = 1; - wait_us(2); - ack = 0; -#endif - } - else - reset(2); -} - -void HPSerial::pushCmd(TrState direction, uint8_t cmd, uint8_t size, char *payload) { +void HPSerial::pushCmd(uint8_t cmd, uint8_t size, char *payload) { CMD val; uint8_t i; val.id = ncmd++; - val.direction = direction; val.cmd = cmd; val.size = size; for(i=0; i<size; i++) @@ -110,114 +54,92 @@ cmdbuf.push(val); } -void HPSerial::handleChar(uint8_t val) { - if (tx_ack == false) - reset(3); - else // remaining of the state machine - if (tx_cmd == 0xFF) { - // begin of transmission, expect a cmd - tx_cmd = val; - tx_ack = false; - tx_len = 0xFF; - } - else if (tx_len == 0xFF) { - if (val == 0x55) { - // packet was in fact a keystroke, tx_cmd is in fact the key - // stroke and no payload is expected -#ifdef DEBUG2 - statetx = 1; -#endif - pushCmd((TrState)Tx, tx_cmd, 0, (char*)buf); -#ifdef DEBUG2 - wait_us(2); - statetx = 0; -#endif - reset(); - } else { - // got a cmd, expect a payload size - tx_len = val; - tx_ack = false; - } - } - else if (tx_len == 0x55) { - // packet was in fact a keystroke, tx_cmd is in fact the key - // stroke and no payload is expected -#ifdef DEBUG2 - statetx = 1; -#endif - pushCmd((TrState)Tx, tx_cmd, 0, (char*)buf); -#ifdef DEBUG2 - wait_us(2); - statetx = 0; -#endif - reset(); - } - else if (tx_len > 0) { - // a payload char - buf[head++] = val; - tx_len--; - tx_ack = false; - } - else { // end of payload, manage sent content - uint8_t cur_state = tx_state; - pushCmd((TrState)tx_state, tx_cmd, head, (char*)buf); - - switch(val) { - case 0x66: // a new transmisson - reset(); - tx_state = cur_state; - setstatedbg(); - break; - case 0x55: - reset(); - break; - default: - reset(6); - break; - } - } +void HPSerial::send_ack(uint8_t c) { + timeouter.attach(this, &HPSerial::timeout, 0.001); // if nothing else happen in the next ms, reset + serial.putc(c); +} + +HPSerial::state_t HPSerial::do_state_initial(HPSerial::instance_data_t *data, + uint8_t c) +{ + // go back to initial state + data->cmd = 0xFF; + data->size = 0; + data->received = 0; + timeouter.detach(); + return HPSerial::STATE_IDLE; +} + +HPSerial::state_t HPSerial::do_state_handcheck(HPSerial::instance_data_t *data, + uint8_t c) +{ + // we are idle, incoming char is a handcheck + // knwon handcheck values are 0x66 and 0x33 + switch (c) { + case 0x33: + send_ack(0xCC); + return HPSerial::STATE_PAYLOAD_SIZE; + break; + case 0x66: + send_ack(0x99); + return HPSerial::STATE_COMMAND; + break; + default: + return do_state_initial(data, 0x00); + } } +HPSerial::state_t HPSerial::do_state_command(HPSerial::instance_data_t *data, + uint8_t c) +{ + if (c == 0x55) { // EoT + return do_state_initial(data, 0x00); + } + data->cmd = c; + data->size = 0; + send_ack(0x00); + return HPSerial::STATE_PAYLOAD_SIZE; +} -void HPSerial::setstatedbg(void) { -#ifdef DEBUG2 - if (tx_state == Rx) - staterx = 1; - else - staterx = 0; - if (tx_state == Tx) - statetx = 1; - else - statetx = 0; -#endif +HPSerial::state_t HPSerial::do_state_payload_size(HPSerial::instance_data_t *data, + uint8_t c) +{ + data->size = c; + data->received = 0; + send_ack(0x00); + return HPSerial::STATE_PAYLOAD; } +HPSerial::state_t HPSerial::do_state_payload(HPSerial::instance_data_t *data, + uint8_t c) +{ + data->payload[data->received++] = c; + send_ack(0x00); + if (data->received >= data->size) { + pushCmd(data->cmd, data->size, data->payload); + return HPSerial::STATE_COMMAND; + } + return HPSerial::STATE_PAYLOAD; +} + +HPSerial::state_t HPSerial::run_state(HPSerial::state_t cur_state, + HPSerial::instance_data_t *data, + uint8_t c) +{ + return (this->*(HPSerial::state_table[cur_state]))(data, c); +}; + void HPSerial::rxIrq(void) { uint8_t val; - if(serial_rx.readable()) { // no reason why we would end here without this condition, but hey + if(serial.readable()) { // no reason why we would end here without + // this condition, but hey #ifdef DEBUG2 inrx=1; #endif lled = 1; - val = serial_rx.getc(); - - timeouter.attach(this, &HPSerial::timeout, 0.001); // if nothing else happen in the next ms, reset - - if (tx_state == Idle) - if (val == 0x66) { - // no transmission in progress, expect a start of transmission - tx_state = Rx; - tx_ack = false; - setstatedbg(); - } - else { - reset(4); - } - else if (tx_ack == false) // manage the acks - handleAck(val); - else - handleChar(val); + val = serial.getc(); + cur_state = run_state(cur_state, &rx_data, val); lled = 0; #ifdef DEBUG2 inrx=0; @@ -227,7 +149,5 @@ void HPSerial::timeout(void) { - if (tx_state != Idle) { - reset(7); - } + cur_state = do_state_initial(&rx_data, 0x00); }