/*
 * ph_base.h
 * base definitions for pH structures and protocols for comms between pH receiver and sender
 * also shared functions
 * lots of protocol copied from ADV
 *
 *  Created on: Nov 19, 2021
 *      Author: Irene Hu
 */

#ifndef PH_BASE_H_
#define PH_BASE_H_

#include "stdint.h" // uintxx
#include "inttypes.h" // print specific width integer types
// https://stackoverflow.com/questions/3168275/printf-format-specifiers-for-uint32-t-and-size-t
// https://stackoverflow.com/questions/29112878/how-do-i-printf-a-uint16-t
// getting some whack numbers outputted that are too large for my int types
#include "system.h" // timers - also includes time.h
#include "user_io.h" // uprintf, getUserInput
#include "uartstdio.h" // UARTwrite etc for writing buffer to screen
#include "fatfs/src/ff.h" // output to file
#include "microsd.h" // some more file output stuff

//#define PRINT_PH_TIMING
// need to put this flag here so it gets to both phb and phf too
// since moved print function here (3/1/22) so phf can use it too

#define PH_BAUD 115200

#ifndef ADV_H_ // figure out later where i want to define these timeouts - maybe some file shared by both
#define ACK_TIMEOUT_MS 1500 // amount of time to wait for an Ack or Nack
#define CMD_TIMEOUT_MS 5000 // WiringSerial used to block for up to 10s waiting for a byte on the port
#endif

#define PHGETMEAS_TIMEOUT_MS 25 // has to be fast, skip pH meas if not received in time and still get ADV data

#define PH_ACK 0x06
#define PH_NACK 0x15
#define PH_SYNCBYTE 0xa5
#define PH_IDPTD 0xb5

#define PH_CHECKSUM_BASE 0xb58c // might as well steal the ADV's random number

#define PH_ADCFREQ_VRS 20
#define PH_ADCFREQ_VTHERM 80

// commands
#define PH_MEASCONT "MC" // back tells front to turn on adc and start measuring
#define PH_STOPMEAS "SM" // back tells front to turn off adc and exit function
#define PH_GETMEAS "GM" // poll command for a measurement, after sending MC
#define PH_MEASONCE "MO" // encapsulated single measurement

// for aborting
//#define CTRL_X 24 // as in system.h

// used in menu for phb and phc
#define TIMESTAMP_FMT "%Y/%m/%d %H:%M:%S"


// basic pH+thermistor unit
struct __attribute__((__packed__)) pH_ptdata {
    // unlike ADV struct, but sync and id bytes here, make it easier for checksum iterator
    unsigned char sync;
    unsigned char id;
    uint16_t count; // counter - makes sure both sides are on same page, checked for skipped counts etc
    // also use to calculate timing on front end
    // timing needs to be calc'd across multiple samples (not sample to sample) bc stuck with 1ms resolution
    int32_t Vrs; // Vrse or Vrsi determined by sender
    int32_t Vtherm;
    // ADC outputs are 24, and we're only reading once.  but still use int32 to simplify things
    int16_t checksum; // store checksum for front end (to be sent), and a flag for back end (0 for succeed, 1 for fail)
};
// 1/20/22: just read into sizeof(struct) to try to send struct in once piece using uart write, and learned
// the members need to be aligned
// https://stackoverflow.com/questions/119123/why-isnt-sizeof-for-a-struct-equal-to-the-sum-of-sizeof-of-each-member
// miraculously, this struct is already aligned lol.
// as long as the struct itself starts on a 4-byte-aligned address
// 1/25/22: make it packed, to avoid any system-dependent behavior
// https://riptutorial.com/c/example/31059/packing-structures

// shared functions
int16_t ph_calcChecksum(struct pH_ptdata *pHDatStruct);
int ph_printpHDataHdr(FIL* ofs, int txFlg);
int ph_printpHData(struct pH_ptdata *pHDatStruct, FIL* ofs, int txFlg);
void ph_printHexData(struct pH_ptdata *pHDatStruct);


#endif /* PH_BASE_H_ */
