/*
 * serial.h
 *
 *  Created on: Nov 30, 2022
 *      Author: thom maughan
 *
 *      Note: command line changed to incorporate merge of ISUS / MSC1 / CF2 code  Feb 2024
 */

#include <stdint.h>

#ifndef SERIAL_H_
#define SERIAL_H_



#define M2M_DELIM_MS_TIMEOUT        250     //was 250         // CF2 / MSC1 timeout is tbd (need to look at ljc code)
#define H2M_DELIM_MS_TIMEOUT        50000        // 50000 was 2500, was 1000, changed 7 Mar 2025  50sec

// used in main.c
#define SERIAL_INACTIVITY_TIMEOUT_M2M_SEC 30            //was 17, now 30 per UW Spec Aug 2024   //Was 10, now 17 per Yui's measurement of MSC1
#define SERIAL_INACTIVITY_TIMEOUT_H2M_SEC 180


// sensor type, as defined by sys_sensor_mode is defd in apf.h
//#define UNSELECTED_MODE         0
//#define ISUS_SENSOR_MODE        1
//#define DURA_SENSOR_MODE        2

#define M2M_GOTO_SLEEP          -1          //retval for handle_m2m_code, that causes sleep
#define M2M_RESET_TIMEOUT       -2          //time was set, need to reset elapse time timer

#define CTRL_A                  0x01
#define CTRL_C                  0x03
#define CTRL_D                  0x04
#define ESC                     0x1B



#define ERRBUFSIZE              256

// safegets()
#define RECL                    30
#define MAXINBUFF               RECL+14
#define MAXREAD                 MAXINBUFF-2

// SyncNextSample()
#define SYNC_FROM_CURRENT_TIME  1
#define SYNC_FROM_LAST_SAMPLE   2

// OpenApfLogFile()
#define ISUS_DATA_FILE          1
#define DURA_DATA_FILE          2

// SendRecords() and CalcRecsPending()
#define DATSPOOL_FILE           0
#define ERRORLOG_FILE           1

#define FNULL                   ((FILE *)NULL)


#define M2M_RX_PREAMBLE_HACK    0xAA        //'U'
#define M2M_RX_PREAMBLE_TXT     0xAA        //was '<'     // was U
#define M2M_RX_PREAMBLE         0xAA


void m2m_statemachine_init(void);
int handle_m2m_comm(void);
int parse_rx0_buf(void);
void save_apf_vars_fram(void);
void save_sys_data_eeprom(void);
void print_NAK(void);
void print_prompt(void);
void print_pwron_msg(void);

void print_prompt(void);
void print_NAK(void);

void save(void);

// handle_m2m_comm returns 0 for no rxByte, 1 for rxByte, and CMD_XXX if command is executed
// start numbering CMD_xxx at 3
#define CMD_NOTDEFD             0       //
#define CMD_SPARE1              1
#define CMD_SPARE2              2
#define CMD_TAKESAMPLE          3       // TS Takesample
#define CMD_STARTSAMPLE         4       // SS Silent Sample
#define CMD_SENDLAST            5       // SL Send Last (from FRAM)
#define CMD_GETCAL              6       //
#define CMD_EXPORTCAL           7       //
#define CMD_GETHEADER           8       // GH Get Header
#define CMD_GETMETADATA         9       // GM Get Metadata
#define CMD_SLEEP               10      // SLP ZZ sleep
#define CMD_GETTIME             11      // CFG_TIMESTAMP
#define CMD_SETTIME             12      //
#define CMD_HELP                13      //
#define CMD_GETPERIOD           14      //
#define CMD_SETPERIOD           15      //
#define CMD_GETDATAFIELD        16
#define CMD_SETDATAFIELD        17
#define CMD_GETFILENAME         18      //
#define CMD_SETFILENAME         19      //
#define CMD_GETALIGN            20
#define CMD_SETALIGN            21
#define CMD_GETCFG_SAMPNUM      22      //
#define CMD_SETCFG_SAMPNUM      23      //
#define CMD_GETCFG_TIMESTAMP    24      //
#define CMD_SETCFG_TIMESTAMP    25      //
#define CMD_GETCFG_BIASNEG      26
#define CMD_SETCFG_BIASNEG      27      //CFG_BIAS_BAT_NEG
#define CMD_TEST_BIASNEG        28
#define CMD_GETCFG_BIASPOS      29      //CFG_BIAS_BAT_POS  biaspos
#define CMD_SETCFG_BIASPOS      30
#define CMD_TEST_BIASPOS        31
#define CMD_GETCFG_IB           32      //
#define CMD_SETCFG_IB           33      //
#define CMD_TEST_IB             34
#define CMD_GETCFG_IK           35      //
#define CMD_SETCFG_IK           36      //
#define CMD_TEST_IK             37      // ik
#define CMD_GETCFG_SPARE        38      // NOT
#define CMD_SETCFG_SPARE        39      // NOT
#define CMD_GETCFG_VK           40      // CFG_V_COUNTER_ELECT
#define CMD_SETCFG_VK           41      //
#define CMD_TEST_VK             42      // vk
#define CMD_GETCFG_VK_STD       43      //
#define CMD_SETCFG_VK_STD       44      //
#define CMD_GETCFG_VTHERM       45      //
#define CMD_SETCFG_VTHERM       46      //
#define CMD_TEST_VTHERM         47      // CFG_V_THERMISTOR
#define CMD_GETCFG_VTHERM_STD   48
#define CMD_SETCFG_VTHERM_STD   49
#define CMD_GETCFG_TEMPC        50      // CFG_CALC_TEMP
#define CMD_SETCFG_TEMPC        51
#define CMD_TEST_TEMPC          52
#define CMD_GETCFG_VRSI         53      // CFG_VRSI
#define CMD_SETCFG_VRSI         54      //
#define CMD_TEST_VRSI           55
#define CMD_GETCFG_VRSI_STD     56      //
#define CMD_SETCFG_VRSI_STD     57      //
#define CMD_GETCFG_PHINT        58      // CFG_CALC_PH_VRSI
#define CMD_SETCFG_PHINT        59
#define CMD_TEST_PHINT          60
#define CMD_GETCFG_VRSE         61      //
#define CMD_SETCFG_VRSE         62      //
#define CMD_TEST_VRSE           63
#define CMD_GETCFG_VRSE_STD     64      //
#define CMD_SETCFG_VRSE_STD     65      //
#define CMD_GETCFG_PHEXT        66
#define CMD_SETCFG_PHEXT        67
#define CMD_TEST_PHEXT          68
#define CMD_GETCFG_VBAT         69      // CFG_VIN_BAT_VOLT
#define CMD_SETCFG_VBAT         70      //
#define CMD_TEST_VBAT           71
#define CMD_GETCFG_BRDTEMP      72      // CFG_BRD_TEMP
#define CMD_SETCFG_BRDTEMP      73
#define CMD_GETCFG_HUMID        74      // CFG_BRD_HUMIDITY
#define CMD_SETCFG_HUMID        75
#define CMD_TEST_ENV            76
#define CMD_HELPCONFIG          77
#define CMD_HELPTEST            78
#define CMD_HELPDEPLOY          79
#define CMD_GETVERSION          80
#define CMD_GETCFG_CONFIG       81
#define CMD_SETCFG_CONFIG       82
#define CMD_MAINMENU            83
#define CMD_GETSTORE            84      // MICROSD Enable
#define CMD_SETSTORE            85
#define CMD_FILESYSTEM          86      // FatFS
#define CMD_TEST_VRSI_STD       87
#define CMD_TEST_VRSE_STD       88
#define CMD_TEST_TIMESTAMP      89
#define CMD_TEST_SAMPNUM        90
#define CMD_TEST_VK_STD         91
#define CMD_TEST_VTHERM_STD     92
#define CMD_SAMP_DATABARF       93

#define CMD_APF_BAKE             100      // BAKE
#define CMD_APF_CFG              101      //
#define CMD_APF_CFG_DURA         102
#define CMD_APF_CFG_ISUS         103
#define CMD_APF_CAL              104      //
#define CMD_APF_CTD_SET          105      //
#define CMD_APF_CTD_GET          106      //
#define CMD_APF_GET_ERR          107      // ERR print errors
#define CMD_APF_SET_FIT          108      //
#define CMD_APF_GET_FIT          109      //
#define CMD_APF_INIT             110      //
#define CMD_APF_SET_MODE         111      //
#define CMD_APF_GET_MODE         112      //
#define CMD_APF_OFF              113      // Sleep
#define CMD_APF_GET_PC           114      // PC Print Counters
#define CMD_APF_Q_SENSORCFG      115      // Sensor type (ISUS, DURAFET)  would like to deprecate this
#define CMD_APF_SET_RTC          116      //
#define CMD_APF_GET_RTC          117      //
#define CMD_APF_GET_SC           118      // S  SC Sample Counters
#define CMD_APF_XFER_SE          119      // Transfer error log
#define CMD_APF_GET_SE           120      // Calc Recs pending
#define CMD_APF_SLP              121      // Flush RX buf, then suspend (sleep)
#define CMD_APF_SPECTRA_SET         122      //
#define CMD_APF_SPECTRA_GET         123      //
#define CMD_APF_GET_TA           124      // TA Time of sample Acq
#define CMD_APF_SET_TINT         125      // TINT Set integration time
#define CMD_APF_GET_TINT         126      // TINT,? Get integration time
#define CMD_APF_PING             127      //d WW
#define CMD_APF_ISUS_T1          128      // Take ISUS sample (like ts)
#define CMD_APF_DURA_T2          129      // Take Dura pH sample
#define CMD_APF_CIH              130      // Isus Header
#define CMD_APF_CDH              131      // Durafet header

//#define CMD_APF_SL                          // Send Last (already have a send last)
//#define CMD_APF_TS                        // Take Sample (already have a take sample)

#define CMD_APF_H2M              132      //  changes timing and command termination, try for measuring the character timing, using 'H' so h2m is not needed (to hard to type 3 letters)
#define CMD_APF_M2M              133      //  restores timing termination

#define CMD_APF_GET_SYSINFO      134
#define CMD_FILEIO_HELP          135
#define CMD_FILEIO_LS            136
#define CMD_FILEIO_MKDIR         137
#define CMD_FILEIO_CD            138
#define CMD_FILEIO_PWD           139
#define CMD_FILEIO_CAT           140
#define CMD_FILEIO_RM            141
#define CMD_FILEIO_MV            142
#define CMD_YMODEM_SEND          143
#define CMD_YMODEM_RECEIVE       144
#define CMD_TAKESAMPLE_T0        145  // Same effect as CMD_TAKESAMPLE, but sets mode=0
#define CMD_APF_WDOG             146  // display watchdog debug info
#define CMD_THOMZ_TEST           147
#define CMD_APF_DEVSTATUS        148
#define CMD_BIG_HELP             149
#define CMD_APF_SET_TYPE         150
#define CMD_APF_DBG              151  //toggle dbg printfs on/off  mmsDbg flag
#define CMD_APF_ISUS_S1          152      // start sample ISUS sample (like ss with mode=1)
#define CMD_APF_DURA_S2          153      // silent sample Dura pH sample (like ss with mode=2)

#define CMD_GETHEADER_ISUS       154    //GH1
#define CMD_GETHEADER_DURA       155    //GH2

#define CMD_ACK                  156    // Useless ACK command
#define CMD_ECHO                 157    // echo,on  echo,off

#define CMD_SET_PROFILECNT       158
#define CMD_GET_PROFILECNT       159
#define CMD_APF_FILETEST         160     // TEMPORARY testing file commands, long filename support, etc.
#define CMD_APF_TEST_SENSOR      161     // test,isus  test,dura

#define CMD_FILEIO_CHKDSK        162
#define CMD_FILEIO_FORMAT        163
#define CMD_FILEIO_TOUCH         164
#define CMD_FILEIO_CP            165

#define CMD_ZMODEM_RECEIVE       166
#define CMD_ZMODEM_SEND          167
#define CMD_APF_READZCOEF        168
#define CMD_APF_ZCOEF            169
#define CMD_APF_READECOEF        170
#define CMD_APF_ECOEF            171
#define CMD_APF_DEFAULTS         172
#define CMD_WISD                 173
#define CMD_YOOSTER              174
#define CMD_APF_DIAG             175

#define CMD_APF_NITRATE          176
#define CMD_APF_PH               177

#define CMD_APF_BAUD             178
#define CMD_APF_SERNUM           179
#define CMD_APF_SYS_STATUS       180
#define CMD_APF_VINMIN           181

#define CMD_APF_ERROR            182
#define CMD_APF_SCANSPECTRA      183
#define CMD_PH_CAL               184
#define CMD_QA                   185
#define CMD_APF_CALDATE          186
#define CMD_SETTINGS             187


#define MAX_SIZE_RX0_BUF    768
struct rxStateMach
{
    unsigned int  state;
    unsigned int  indx;
    unsigned int  cnt;
    unsigned int  cr_cnt;
    unsigned int  cmd;
    unsigned long tick_ms_start;      // for timeout
    unsigned long tick_ms_now;
    unsigned long tick_ms_delta;      // not really needed, but useful for dev
    unsigned long tick_ms_delim;        // time based delimiter

    uint8_t     byte;
    uint8_t     buf[MAX_SIZE_RX0_BUF];
};

// Max number of tokens
#define CMD_TOKENS_MAX_ARGC 8
typedef struct
{
    char cmd_buf[MAX_SIZE_RX0_BUF + 1]; // cache incoming command line here, strtok will null fill it
    int argc;
    char* argv[CMD_TOKENS_MAX_ARGC+1];  // extra spot beyond CMD_TOKENS_MAX_ARGC, because argv[argc] must be NULLable if argc==CMD_TOKENS_MAX_ARGC
} CMD_Tokens;

// Tokenizes on ascii space input str of up to length MAX_SIZE_RX0_BUF up to a max of CMD_TOKENS_MAX_ARGC tokens
// returns 1 on success, <=0 on failure
// This function is non-reentrant due to use of strtok - and is non-reentrant with any other users of strtok.
// TI CCS does not ship a strtok_r (which is a POSIX extension and not part of the standard).
// This will matter in an eventual RTOS world where other threads are also parsing text, hopefully that toolchain has a strtok_r.
// Probably can just re-implement a simple parsing function when its needed.
int build_argc_argv(const char* str, CMD_Tokens* const out_tokens);

#endif /* SERIAL_H_ */
