Fri, 16 Oct 2020 22:08:47 +0200
compile for nucleo f446re & f303re with mbed 6
#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); void startup(void); void send(const uint8_t *buf, uint8_t size); void sendkey(uint8_t keycode); private: void pushCmd(uint8_t cmd, uint8_t size, char *payload); void rxIrq(void); void timeout(void); void set_timer(float v=0.0) { timeouter.detach(); if (v > 0.0) timeouter.attach(callback(this, &HPSerial::timeout), v); } private: UnbufferedSerial serial; uint8_t buf[BUF_SIZE]; uint8_t head; CircularBuffer<CMD, 32> cmdbuf; unsigned long ncmd; unsigned int errs[MAX_ERRS]; Ticker timeouter; public: // global state machine typedef enum { GSTATE_STARTING, GSTATE_IDLE, GSTATE_TX, GSTATE_RX, NUM_GSTATES} gstate_t; gstate_t gstate() {return cur_gstate;}; /* gstate_t do_start(); */ /* gstate_t do_send(); */ /* gstate_t do_receive(); */ /* typedef gstate_t(HPSerial::*gstatemethod)(); */ /* statemethod const gstate_table[NUM_GSTATES] = { */ /* &HPSerial::do_start, */ /* &HPSerial::do_send, */ /* &HPSerial::do_receive, */ /* }; */ /* gstate_t run_gstate(gstate_t cur_state); */ private: gstate_t cur_gstate; public: // transmission state machine typedef enum { STATE_IDLE, STATE_COMMAND, STATE_PAYLOAD_SIZE, STATE_PAYLOAD, STATE_SENDING, STATE_EOT, NUM_STATES} state_t; state_t state() {return cur_state;}; private: typedef struct state_data { uint8_t cmd; uint8_t size; uint8_t pos; char payload[MAX_BUFF]; } state_data_t; void _startup(void); state_t do_state_initial(uint8_t c=0x00); state_t do_state_command(uint8_t c); state_t do_state_payload_size(uint8_t c); state_t do_state_payload(uint8_t c); state_t do_state_sending(uint8_t c=0x00); state_t do_state_eot(uint8_t c=0x55); void send_ack(uint8_t c); typedef state_t(HPSerial::*statemethod)(uint8_t c); static statemethod state_table[NUM_STATES]; state_t run_state(state_t cur_state, uint8_t c); state_t cur_state; state_data_t tr_data; }; #endif