src/hp34comm.h

Sat, 29 Oct 2016 23:44:31 +0200

author
David Douard <david.douard@logilab.fr>
date
Sat, 29 Oct 2016 23:44:31 +0200
changeset 18
4fd621551d55
parent 10
01515349b30e
child 19
a52d60613cf7
permissions
-rw-r--r--

[full replacement] implement a state machine for Rx

#ifndef HP34COMM_H
#define HP34COMM_H

#include "mbed.h"
#include "CircularBuffer.h"

/***** HP 34970A communication class ***/

#define MAX_ERRS 10
#define MAX_BUFF 16
#define BUF_SIZE 16



class HPSerial {

public:
  typedef struct _CMD
  {
    uint8_t cmd;
    uint8_t size;
    char value[MAX_BUFF+1];
    unsigned long id;
  } CMD;


  
  HPSerial(PinName tx, PinName rx);
  
  bool cmd_available(void);
  bool pop(CMD& cmd);
  bool cmd_buf_full(void);
  unsigned int nerrors(uint8_t errorno);
		     
  
private:
  void pushCmd(uint8_t cmd, uint8_t size, char *payload);
  void rxIrq(void);
  void timeout(void);

 private:
  RawSerial serial;
  uint8_t buf[BUF_SIZE];
  uint8_t head;
  CircularBuffer<CMD, 32> cmdbuf;
  unsigned long ncmd;
  unsigned int errs[MAX_ERRS];
  Ticker timeouter;

  // state machine stuff
  typedef enum {STATE_IDLE,
		STATE_HANDCHEKED,
		STATE_COMMAND,
		STATE_PAYLOAD_SIZE,
		STATE_PAYLOAD,
		NUM_STATES} state_t;

  
  typedef struct instance_data {
    uint8_t cmd;
    uint8_t size;
    uint8_t received;
    char payload[MAX_BUFF];
  } instance_data_t;

  state_t do_state_initial(instance_data_t *data, uint8_t c);
  state_t do_state_handcheck(instance_data_t *data, uint8_t c);
  state_t do_state_command(instance_data_t *data, uint8_t c);
  state_t do_state_payload_size(instance_data_t *data, uint8_t c);
  state_t do_state_payload(instance_data_t *data, uint8_t c);

  void send_ack(uint8_t c);
  
  // pointer to "state method" (ie. one of the just above)
  typedef state_t(HPSerial::*statemethod)(instance_data_t *data, uint8_t c);
  statemethod const state_table[NUM_STATES] = {
      &HPSerial::do_state_initial,
      &HPSerial::do_state_handcheck,
      &HPSerial::do_state_command,
      &HPSerial::do_state_payload_size,
      &HPSerial::do_state_payload,
  };
  
  state_t run_state(state_t cur_state, instance_data_t *data, uint8_t c);

  state_t cur_state;
  instance_data rx_data;
};

#endif

mercurial