/*!
 * \file jfet_commandLine.c
 *
 * \brief Command Line Interface (CLI) functions and commands
 *
 * \copyright  J Factor Embedded Technologies LLC. 2020
 * \copyright  TJM Embedded Software LLC. 2020
 * \author  T. J. Mulrooney
 */
/*
 * All Rights Reserved
 * UNPUBLISHED, LICENSED SOFTWARE.
 *
 * CONFIDENTIAL AND PROPRIETARY INFORMATION
 * WHICH IS THE PROPERTY OF J-Factor Embedded Technologies.
 *
 */

// #include <event_manager.h>
// #include <drivers/uart.h>
#include "jfet_files/jfet_common.h"
#include "jfet_files/w25q64jv_Driver.h"
#include <zephyr/drivers/i2c.h>
// #include "cloud/cloud_codec/cloud_codec.h"
#include "HDC2080.h"
////#include <net/aws_iot.h>
// #include "time.h"
// #include <date_time.h>
//
///* prottypes */
// uint8_t getLine(void);
// float  float_bits(uint32_t u);
void executeCmd(char *line);
int8_t getCLICmd(char *line);
void cliADC();
void cliBatMon();
void cliBME688CS();
void cliDeviceID();
void cliFlashErase();
void cliFlashEraseSector();
void cliFlashFillPage();
void cliFlashID();
void cliFlashNSS();
void cliFlashReadPage();
void cliFlashStatus();
void cliFlashWritePage();
void cliHelp();
void cliHumidity();
void cliI2CRead();
void cliI2CWrite();
void cliPublishNow();
void cliReset();
void cliResetCause();
void cliSensors();
void cliTemperature();
void cliVersion();
void displayHelp(char c);
// uint8_t myGetChar(void);
// int myGetChar1(void);
// void displayTouchHandler(unsigned char *ptrBuf, int cnt);
////int aws_iot_disconnect(void);
// int time_NTP_server_get(void);
//
///* external */
////extern struct cloud_data_cfg current_cfg;
// extern struct time_aux {
//	int64_t date_time_utc;
//	int64_t last_date_time_update;
// } time_aux;
//
////#include <strings.h>
// enum at_cmd_state cmd_state;     //!<state of AT command executed from command line
//
///* globals */
// uint8_t escapeSeen = 0;      //!<escape sequence seen

/* enums */
enum COMMANDS //!< vaild command indexes
{
    ADCX,
    //    ALARMSENABLED,
    BATMON,
    BME688CS,
    DEVICEID,
    //    CUSTOMER,
    //    DISTRIBUTOR,
    //    DUTYCYCLE,
    FLASHERASE,
    FLASHERASESECTOR,
    FLASHFILLPAGE,
    FLASHID,
    FLASHNSS,
    FLASHREADPAGE,
    FLASHSTATUS,
    FLASHWRITEPAGE,
    FLASHPARAMETERS,
    //	GROUP,
    HELP,
    HUMIDITY,
    I2CREAD,
    I2CWRITE,
    //	LOCATION,
    PUBLISHNOW,
    RESCAN,
    RESETX,
    RESETCAUSE,
    //    SAVED,
    //    SENSORID,
    //    SENSORNAME,
    SENSORS,
    TEMP,
    VERSIONX,
};

#define LINE_SIZE 80 //!< maximum number of characters on a CLI line
#define NUM_LINES 10 //!< maximum number of lines in saved history

/* Prototypes */

/* externs */
// extern UART_HandleTypeDef UartHandle;

/* Locals */
// static char line[LINE_SIZE];                           //!< character array read
////char lineDownlink[200];                   //!< character array downlink
////char downlinkIMEI[30];                          //<! character array fro downlink IMEI
static char lineTmp[LINE_SIZE]; //!< tempory line saved
// static char lastLine[NUM_LINES][LINE_SIZE];            //!< array of previous command lines
// static int8_t indexNextLineIn = 0;                     //!< index of next position to save current command line
// static int8_t indexNextLineOut = 0;                    //!< index of next position to read out saved command lines
// static int8_t linesInBuffer = 0;                       //!< number of lines in  command line buffer
// static int8_t charCount;                               //!< number of characters in the current command line
// static int8_t cursorPosition;                          //!< current cursor position in the current command line
//
//
/* sensor types and state (present = 1) */

char *sensorTypeNames[] = //!< sensor types and state (present = 1)
    {
        "HDC2080 - temperature/Humidty Sensor(I2C 0x40)",
        "W25Q64JV - 64MB Flash memory(SPI)",
        "Unknown",
};

char const *validCLICmds[] = //!< array of valid commands - case insensitive
    {
        "adc",
        //	"alarmsenabled",
        "batmon",
        "bme688cs",
        "deviceid",
        //    "customer",
        //	"distributor",
        //    "dutycycle",
        "flasherase",
        "flasherasesector",
        "flashfillpage",
        "flashid",
        "flashnss",
        "flashreadpage",
        "flashstatus",
        "flashwritepage",
        "flashparameters",
        //	"group",
        "help",
        "humidity",
        "i2cread",
        "i2cwrite",
        //	"location",
        "publishnow",
        "rescan",
        "reset",
        "resetcause",
        //    "saved",
        //    "sensorid",
        //    "sensorname",
        "sensors",
        "temp",
        "version",
};

char const *helpMessages[] =
    {
        "adc - display Battery voltage AIN0",
        //    "alarmsenabled [0/1/t/T/f/F]- display/set alarms enabled",
        "batmon - [0/1] enable or disable Battery monitor",
        "bme688cs [0/1] - display/set BME688 CS",
        "deviceid - display Device ID",
        //    "customer [X]- display/set customer",
        //    "distributor [X]- display/set distributor",
        //    "dutycycle [seconds] - number of seconds between Cellular messages sent",
        "flasherase -  erase entire memory",
        "flasherasesector - [sector] erase 256K Byte sector X (default 0) range ( 0 -> 31)",
        "flashfillpage [page data length] - fill length pages with data starting at page",
        "flashid - display serial flash ID",
        "flashnss 0/1 - set SPI NSS",
        "flashparameters - list the saved flash parameters",
        "flashreadpage [page length] - read length pages starting at page",
        "flashstatus - display serial flash status registers",
        "flashwritepage page address data - write data to address in page",
        ////    "gps - display cirrent GPS location",
        ////    "gpsenable - [0/1] enable or disable gps",
        ////    "gpsfixcheck - [n] display/set GPS fix check time",
        ////    "gpsexternal - [0/1] external or internal gps",
        //    "group [X]- display/set group",
        "help [c] - display list of valid commands starting with c",
        "humidity- display humidity",
        "i2cread [add reg length] - read length bytes from I2C address starting at r",
        "i2cwrite add reg data length - write byte to I2C address at reg",
        //    "location [X]- display/set location",
        "publishnow- publish a BLE payload now",
        "rescan - rescan for connected devices",
        "reset [x]- reset the board any paramter causes a WDT reset",
        "resetCause - display reason for last reset ",
        //    "saved [clear/n] - display/clear saved flash JSON packets",
        //    "sensorid [X]- display/set sensor ID",
        //    "sensorname - display/set sensor name",
        "sensors - display available sensors",
        "temp- display sensor temperatures ",
        "version - display version information",
        "END",
}; //!< array of help messages

///*!
// * \fn float  float_bits(uint32_t u)
// *
// * \brief converts 32 bit unsigned integer to a floating point
// *
// * \param u integer to convert to floating point
//  *
// * \return float floating point conversion of input integer
// */
// float  float_bits(uint32_t u)
//{
//    union
//    {
//        uint32_t  u;
//        float     f;
//    } temp;
//
//    temp.u = u;
//    return temp.f;
//}
//
/*!
 * \fn void executeCmd(char *line)
 *
 * \brief executes the command in line array.
 *
 * \return none
 */
void executeCmd(char *line)
{
    int8_t cmd;
    //    uint32_t i;
    //    int ret;
    //    uint32_t length;
    //    char str[80];
    ////    uint32_t pageAddress;
    //    uint8_t write_buffer[DATA_LENGTH];
    ////    struct tm time;
    //    int j;
    //    int k;
    ////    int l,m;
    //    float temp, tempMin, tempMax;
    //    float tempHum;
    //    //float uva,uvb,uvi;
    //    double testd = 1.23;
    //    enum at_cmd_state state;
    //    char *ceregState[] =
    //    {
    //      "Not registered. User Equipment (UE) is not currently searching for an operator to register to",
    //      "Registered, home network",
    //      "Not registered, but UE is currently trying to attach or searching an operator to register to",
    //      "Registration denied",
    //      "Unknown (e.g. out of E-UTRAN coverage)",
    //      "Registered, roaming",
    //      "Not registered due to Universal Integrated Circuit Card (UICC) failure",
    //    };
    strcpy(lineTmp, line); /* save command line */
    cmd = getCLICmd(line);
    //    printk("cmd: %d numParameters: %d\r\n",cmd,numParameters);

    /* execute command */
    switch (cmd)
    {
    case ADCX:
        cliADC();
        break; /* read and display ADC voltage */
    case BATMON:
        cliBatMon();
        break; /* set Battery Monitor GPIO */
    case BME688CS:
        cliBME688CS();
        break; /* set BME688 CS GPIO */
    case DEVICEID:
        cliDeviceID();
        break; /* display Device ID*/
    case FLASHERASE:
        cliFlashErase();
        break; /* erase Flash entire device */
    case FLASHERASESECTOR:
        cliFlashEraseSector();
        break; /* erase Flash sector */
    case FLASHFILLPAGE:
        cliFlashFillPage();
        break; /* fill flash page */
    case FLASHID:
        cliFlashID();
        break; /* display Flash ID */
    case FLASHNSS:
        cliFlashNSS();
        break; /* set/clear Flash NSS */
    case FLASHPARAMETERS:
        displayFlashxParameters();
        break; /* display all Flash Parameters */
    case FLASHREADPAGE:
        cliFlashReadPage();
        break; /* read n pages of Flash */
    case FLASHSTATUS:
        cliFlashStatus();
        break; /* display Flash Status Info */
    case FLASHWRITEPAGE:
        cliFlashWritePage();
        break; /* write a byte to a page */
    case HELP:
        cliHelp();
        break; /* display help message */
    case HUMIDITY:
        cliHumidity();
        break; /* display Humidity */
    case I2CREAD:
        cliI2CRead();
        break; /* I2C read */
    case I2CWRITE:
        cliI2CWrite();
        break; /* I2C Write */
    case PUBLISHNOW:
        cliPublishNow();
        break; /* Publish BLE data immediately */
    case RESCAN:
        rescan();
        break; /* rescan for connected devices */
    case RESETX:
        cliReset();
        break; /* software reset processor */
    case RESETCAUSE:
        cliResetCause();
        break; /* processor reset cause */
    case SENSORS:
        cliSensors();
        break; /* display connected sensors */
    case TEMP:
        cliTemperature();
        break; /* display temperature */
    case VERSIONX:
        cliVersion();
        break; /* display Version Info */
               //
               //
               //        case SW1X:
               //            if(numParameters > 2)
               //            {
               //                printk("format sw1 [0/1]\r\n");
               //                break;
               //            }
               //            if(numParameters == 2)
               //            {
               //                i = atoi(cmdLineParameter[1]);
               //                if(i == 0)
               //                {
               //                    jfet_dk_set_led(SW1, 0x0);
               //                    flashParameters.sw1 = false;
               //                }
               //                else
               //                {
               //                    jfet_dk_set_led(SW1, 0x1);
               //                    flashParameters.sw1 = true;
               //                }
               //           }
               //            printk("sw1: %d\r\n",flashParameters.sw1);
               //            break;
               //
               //        case SW2X:
               //            if(numParameters > 2)
               //            {
               //                printk("format sw2 [0/1]\r\n");
               //                break;
               //            }
               //            if(numParameters == 2)
               //            {
               //                i = atoi(cmdLineParameter[1]);
               //                if(i == 0)
               //                {
               //                    jfet_dk_set_led(SW2, 0x0);
               //                    flashParameters.sw2 = false;
               //                }
               //                else
               //                {
               //                    jfet_dk_set_led(SW2, 0x1);
               //                    flashParameters.sw2 = true;
               //                }
               //            }
               //            printk("sw2: %d\r\n",flashParameters.sw2);
               //            break;
               //
               //        case DUTYCYCLE:
               //            if(numParameters > 2)
               //            {
               //                printk("format dutycycle [seconds]\r\n");
               //                break;
               //            }
               //            if(numParameters == 2)
               //            {
               //                data = atoi(cmdLineParameter[1]);
               //             	flashParameters.dutyCycle = data;
               //           }
               //            break;
               //
               //        case SENSORID:
               //            if (numParameters > 1)
               //            {
               //                for(i=0; i < sizeof(flashParameters.sensorID); i++)
               //                    flashParameters.sensorID[i] = '\0';
               //                strncpy(flashParameters.sensorID,&lineTmp[9],6);
               //            }
               //            printk("Sensor ID: %s\r\n",flashParameters.sensorID);
               //            break;
               //
               //        case SENSORNAME:
               //            if (numParameters > 1)
               //            {
               //                for(i=0; i < sizeof(flashParameters.sensorName); i++)
               //                    flashParameters.sensorName[i] = '\0';
               //                strncpy(flashParameters.sensorName,&lineTmp[11],38);
               //            }
               //            printk("Sensor Name: %s\r\n",flashParameters.sensorName);
               //            break;
               //
               //       case CUSTOMER:
               //            if (numParameters > 1)
               //            {
               //                for(i=0; i < sizeof(flashParameters.customer); i++)
               //                    flashParameters.customer[i] = '\0';
               //                strncpy(flashParameters.customer,&lineTmp[9],38);
               //            }
               //            printk("Customer: %s\r\n",flashParameters.customer);
               //            break;
               //
               //        case LOCATION:
               //            if (numParameters > 1)
               //            {
               //                for(i=0; i < sizeof(flashParameters.location); i++)
               //                    flashParameters.location[i] = '\0';
               //                strncpy(flashParameters.location,&lineTmp[9],38);
               //            }
               //            printk("Location: %s\r\n",flashParameters.location);
               //            break;
               //
               //        case GROUP:
               //           if (numParameters > 1)
               //            {
               //                for(i=0; i < sizeof(flashParameters.group); i++)
               //                    flashParameters.group[i] = '\0';
               //                strncpy(flashParameters.group,&lineTmp[6],38);
               //            }
               //            printk("Group: %s\r\n",flashParameters.group);
               //            break;
               //
               //        case DISTRIBUTOR:
               //            if (numParameters > 1)
               //            {
               //                for(i=0; i < sizeof(flashParameters.distributor); i++)
               //                    flashParameters.distributor[i] = '\0';
               //                strncpy(flashParameters.distributor,&lineTmp[12],38);
               //            }
               //            printk("Distributor: %s\r\n",flashParameters.distributor);
               //            break;
               //
               //		case ALARMSENABLED:
               //			  if(numParameters > 2)
               //			  {
               //				  printk("format alarmsenabled [0/1/t/T/f/F]\r\n");
               //				  break;
               //			  }
               //			  if(numParameters == 2)
               //			  {
               //				  if( (cmdLineParameter[1][0] == 't') || (cmdLineParameter[1][0] == 'T') || (cmdLineParameter[1][0] == '1'))
               //					  address = 1;
               //				  else if( (cmdLineParameter[1][0] == 'f') || (cmdLineParameter[1][0] == 'F') || (cmdLineParameter[1][0] == '0'))
               //					  address = 0;
               //				  else
               //					  address = 0;
               //				  flashParameters.alarmsEnabled = address;
               //			  }
               //			  printk("alarms Enabled: %s\r\n",flashParameters.alarmsEnabled?"True":"False");
               //			  break;
               //
               //       case SAVED:
               //            if(numParameters > 3)
               //            {
               //                printk("format saved [clear/n] [len]\r\n");
               //                break;
               //            }
               //            else if (numParameters == 2)
               //            {
               //                if( (cmdLineParameter[1][0] == 'c') || (cmdLineParameter[1][0] == 'C') )
               //                {
               //                    flashParameters.nextSavedRead = 0;
               //                    flashParameters.nextSavedWrite = 0;
               //                    flashParameters.savedCount = 0;
               //                    sprintf(str,"Saved JSON Packets Cleared CLI\r\n");
               //                    myPrintkI(str);
               //                    break;
               //                }
               //                else
               //                {
               //                    data = atoi(cmdLineParameter[1]);       /* get packet to read */
               //                    if(data < flashParameters.savedCount)
               //                    {
               //                        flashxReadPage((data * 0x10) + FLASHJSONSTART + 0,flashReadIn);
               //                        flashxReadPage((data * 0x10) + FLASHJSONSTART + 1,flashReadIn + 256);
               //                        flashxReadPage((data * 0x10) + FLASHJSONSTART + 2,flashReadIn + 512);
               //                        flashxReadPage((data * 0x10) + FLASHJSONSTART + 3,flashReadIn + 768);
               //                        flashxReadPage((data * 0x10) + FLASHJSONSTART + 4,flashReadIn + 1024);
               //                        length = (flashReadIn[0] << 24) | (flashReadIn[1] << 16) |(flashReadIn[2] << 8) | flashReadIn[3];
               //                        sprintf(str,"\r\nJSON: %d length: %d address: (0x%X)\r\n",data,length, (data * 0x10) + FLASHJSONSTART );
               //                        myPrintkI(str);
               //                        myPrintkI(flashReadIn+4);
               //                        printk("\r\n");
               //                    }
               //                    else
               //                    {
               //                        sprintf(str,"%d >= %d packets saved\r\n",data,flashParameters.savedCount);
               //                        myPrintkW(str);
               //                    }
               //                    break;
               //                }
               //            }
               //           else if (numParameters == 3)
               //            {
               //                data = atoi(cmdLineParameter[1]);     /* get starting packet */
               //                if(data >= flashParameters.savedCount)
               //                {
               //                    sprintf(str,"%d >= %d packets saved\r\n",(data + i),flashParameters.savedCount);
               //                    myPrintkW(str);
               //                    return;
               //                }
               //                j = atoi(cmdLineParameter[2]);        /* get number of packets to display*/
               //                for(i = 0;i < j;i++)
               //                {
               ////                    printk("%d %d\r\n",i, data+i);
               //                     if((data + i) >= flashParameters.savedCount)
               //                    {
               //                        sprintf(str,"%d >= %d packets saved\r\n",(data + i),flashParameters.savedCount);
               //                        myPrintkW(str);
               //                        break;
               //                    }
               //                   flashxReadPage(((data + i) * 0x10) + FLASHJSONSTART + 0,flashReadIn);
               //                    flashxReadPage(((data + i) * 0x10) + FLASHJSONSTART + 1,flashReadIn + 256);
               //                    flashxReadPage(((data + i) * 0x10) + FLASHJSONSTART + 2,flashReadIn + 512);
               //                    flashxReadPage(((data + i) * 0x10) + FLASHJSONSTART + 3,flashReadIn + 768);
               //                    flashxReadPage(((data + i) * 0x10) + FLASHJSONSTART + 4,flashReadIn + 1024);
               //                    length = (flashReadIn[0] << 24) | (flashReadIn[1] << 16) |(flashReadIn[2] << 8) | flashReadIn[3];
               //                    sprintf(str,"\r\nJSON: %d length: %d address: (0x%X)\r\n",data + i,length, ((data + i) * 0x10) + FLASHJSONSTART );
               //                    myPrintkI(str);
               //                    myPrintkI(flashReadIn+4);
               //                    printk("\r\n");
               //                }
               //            }
               //            else if (numParameters == 1)
               //            {
               //                printk("Saved JSON Packets: %d\r\n",flashParameters.savedCount);
               //            }
               //          break;
               //
               //
    default:
        if (((line[0] == 'a') || (line[0] == 'A')) && ((line[1] == 't') || (line[1] == 'T')))
            break;
        if (strlen(line) != 0)
        {
            printk("Unknown cmd: %s\r\nType help for list of valid commands\r\n", line);
            //                linesInBuffer--;
            //                indexNextLineIn--;
            //                if(linesInBuffer == NUM_LINES)
            //                    indexNextLineIn = NUM_LINES -1;
        }
        break;
    }
}

/*!
 * \fn int8_t getCLICmd(char *line)
 *
 * \brief parses command line to find position of command in validCLICmds array.
 *
 * goes through line array separated by spaces. cmdLineParameter[numParameters]\n
 * is an array of pointers to the various parameters in the line until the end of line then\n
 * searches cmd array for a match in validCLICmds array.
 *
 * \return int8 - position of command in command array if found. -1 if not found\n
 */
int8_t getCLICmd(char *line)
{
    uint8_t i;
    int len = strlen(line);

    /* parse all parameters on the command line into cmdLineparameter array */
    numParameters = 0; /* no parameters seen yet */

    cmdLineParameter[numParameters++] = &line[0];
    for (i = 0; i < len; i++)
    {
        //    printk("%d %c\r\n",i,line[i]);
        if (line[i] == ' ')
        {
            line[i] = '\0';
            cmdLineParameter[numParameters++] = &line[i + 1];
        }
    }
    line[i] = '\0';

#if 0
  for(i=0;i<len+1;i++)
  {
      printk("%d %c %02X\r\n",i,line[i],line[i]);
  }
  for(i=0;i<numParameters;i++)
  {
      printk("i: %d Param: %s\r\n",i,cmdLineParameter[i]);
  }
#endif

    for (i = 0; i < sizeof(validCLICmds) / sizeof(validCLICmds[0]); i++)
    {
        if (strcmp(validCLICmds[i], cmdLineParameter[0]) == 0)
        {
            return i;
        }
    }
    return -1;
}

/*!
 * \fn void displayHelp(char c)
 *
 * \brief displays a list of all available CLI commands
 *
 * \param c check for only help messages beginning with c
 *
 * \return none
 */
void displayHelp(char c)
{
// #ifndef MEMORYSAVE
#if 1
    int i;

    printk("Valid Commands (%c)\r\n", c);
    for (i = 0; 1; i++)
    {
        if (strstr(helpMessages[i], "END") != NULL)
        {
            break;
        }
        if ((helpMessages[i][0] == c) || (c == 'z'))
        {
            printk("%s\r\n", helpMessages[i]);
        }
    }
#endif
}
//
/////*!
//// * \fn char * replace_char(char* str, char find, char replace)
//// *
//// * \brief replace characters in a string
//// *
//// * \param str pointer to string to search
//// * \param find character to look for
//// * \param replace character to replace found character with
//// *
//// * \return char * pointer to new string with replaced characters
//// */
////char * replace_char(char* str, char find, char replace)
////{
////    char *current_pos = strchr(str,find);
////    while (current_pos)
////    {
////        *current_pos = replace;
////        current_pos = strchr(current_pos,find);
////    }
////    return str;
////}
//
///*!
// * \fn uint8_t myGetChar(void)
// *
// * \brief function to get a character from the UART0
// *
// * \return uint8_t 0 if no character available otherwise the character received
// */
// uint8_t myGetChar(void)
//{
//    int status;
//     unsigned char ch;
//
//    status = uart_poll_in(uart0,&ch);
////    printk("status: %d\r\n",status);
//    if(status == 0)            /* check if character available */
//    {
////        printk("Char: 0x%02X %c\r\n",ch,ch);
//        return(ch);
//    }
//    return(0);      /* no character available */
//}
//
///*!
// * \fn int myGetChar1(void)
// *
// * \brief function to get a character from the UART1
// *
// * \return int -1 if no character available otherwise the character received
// */
// int myGetChar1(void)
//{
//
////     return uart1Get();
//
// #if 1
//    int status;
//     unsigned char ch;
//
//    status = uart_poll_in(uart1,&ch);
////    printk("status: %d\r\n",status);
//    if(status == 0)            /* check if character available */
//    {
////        printk("Char: 0x%02X %c\r\n",ch,ch);
//        return(ch);
//    }
//    return(-1);      /* no character available */
// #endif
//}

void cliADC()
{
    int err;

    err = adc_sample();
    if (err)
    {
        printk("Error in adc sampling: %d\n", err);
    }
    printf("ADC: %3.2f\r\n", adc_voltage[0]);
    return;
}

void cliBatMon()
{
    int i;

    i = 0;
    if (numParameters != 2)
    {
        printk("format batmon [0/1]\r\n");
        return;
    }
    i = atoi(cmdLineParameter[1]);
    gpio_pin_set(baten.port, baten.pin, i);
    printk("Battery Monitor: %s\r\n", i ? "Enabled" : "Disabled");
    return;
}

void cliBME688CS()
{
    int i;
    int bme688cs = 0;
    ;

    if (numParameters != 2)
    {
        printk("format bme688cs 0/1\r\n");
        return;
    }
    if (numParameters == 2)
    {
        i = atoi(cmdLineParameter[1]);
        if (i == 0)
        {
            gpio_pin_set(spics2n.port, spics2n.pin, 1); /* active low so turn on */
            bme688cs = 0;
        }
        else
        {
            gpio_pin_set(spics2n.port, spics2n.pin, 0); /* active low so turn off */
            bme688cs = 1;
        }
    }
    printk("BME688CS: %d\r\n", bme688cs);
    return;
}

void cliDeviceID()
{
    char str[50];
    sprintf(str, "Device ID: %s\r\n", devIDStr);
    myPrintkS(str);
}

void cliFlashErase()
{
    flashxErase();
    printk("Flash Erase complete\r\n");
    flashxClearParameters();
    return;
}
void cliFlashEraseSector()
{
    uint32_t address;
    char *end;

    if (numParameters == 1)
    {
        address = FLASHPARAMETERSTART;
    }
    else if (numParameters == 2)
    {
        address = strtoul(cmdLineParameter[1], &end, 16);
    }
    else
    {
        printk("format flasherasesector [sector]");
        return;
    }
    if (address >= 32)
    {
        printk("Sector address %d >= 32\r\n", address);
        return;
    }
    flashxEraseSector(address);
    printk("Flash Sector %d Erase complete\r\n", address);
    if (address == FLASHPARAMETERSTART)
    {
        flashxClearParameters(); /* clear all flash parameter if starting sector erased */
    }
}

void cliFlashFillPage()
{
    int address = 0;
    int length = 1;
    int32_t data;
    int i;
    char *end;

    address = 0;
    data = 0;
    length = 1;
    if (numParameters == 2)
    {
        address = strtoul(cmdLineParameter[1], &end, 16);
    }
    else if (numParameters == 3)
    {
        address = strtoul(cmdLineParameter[1], &end, 16);
        data = strtoul(cmdLineParameter[2], &end, 16);
    }
    else if (numParameters == 4)
    {
        address = strtoul(cmdLineParameter[1], &end, 16);
        data = strtoul(cmdLineParameter[2], &end, 16);
        length = atoi(cmdLineParameter[3]);
    }
    else if (numParameters > 4)
    {
        printk("format flashFill [address][data] [length]");
        return;
    }
    if (address >= 32768)
    {
        printk("Page address %d >= 32768\r\n", address);
        return;
    }
    for (i = 0; i < length; i++, address++)
    {
        printk("flashFill page: 0x%X data: 0x%02X\r\n", address, data);
        flashxFillPage(address, data);
        printk("flashFill complete\r\n");
    }
    return;
    ;
}

void cliFlashID()
{
    uint8_t flashIDIn[5];

    readNVFlashxID(flashIDIn);
    printk("Flash ID: 0x%02X 0x%02X 0x%02X\r\n", flashIDIn[0], flashIDIn[1], flashIDIn[2]);
}

void cliFlashNSS()
{
    int i;
    int flashNSS = 0;
    ;

    if (numParameters != 2)
    {
        printk("format flashnss 0/1\r\n");
        return;
    }
    if (numParameters == 2)
    {
        i = atoi(cmdLineParameter[1]);
        if (i == 0)
        {
            gpio_pin_set(spics1n.port, spics1n.pin, 1); /* active low so turn on */
            flashNSS = 0;
        }
        else
        {
            gpio_pin_set(spics1n.port, spics1n.pin, 0); /* active low so turn off */
            flashNSS = 1;
        }
    }
    printk("flashnss: %d\r\n", flashNSS);
    return;
}

void cliFlashReadPage()
{
    int address = 0;
    int length = 1;
    int i, j, k;
    char *end;
    char ascii[17];
    char str[80];

    if (numParameters == 2)
    {
        address = strtoul(cmdLineParameter[1], &end, 16);
    }
    else if (numParameters == 3)
    {
        address = strtoul(cmdLineParameter[1], &end, 16);
        length = atoi(cmdLineParameter[2]);
    }
    if (address >= 32768)
    {
        printk("Page address %d >= 32768\r\n", address);
        return;
    }

    /* read in the flash pages requested */
    for (k = 0; k < length; k++, address++)
    {
        flashxReadPage(address, flashReadIn);
        printk("Read Page 0x%X\r\n", address);
        ascii[0x10] = '\0';
        for (i = 0; i < 256; i++)
        {
            if ((i % 0x10) == 0)
            {
                if (i == 0)
                {
                    sprintf(str, "0x%06X ", (unsigned int)(address * 256) + i);
                }
                else
                {
                    sprintf(str, " %s\r\n0x%06X ", ascii, (unsigned int)(address * 256) + i);
                    for (j = 0; j < sizeof(ascii); j++)
                    {
                        ascii[j] = '\0';
                    }
                }
                printk("%s", str);
            }
            if ((flashReadIn[i] < 0x20) || (flashReadIn[i] > 0x7E))
            {
                ascii[i % 0x10] = '.';
            }
            else
            {
                ascii[i % 0x10] = flashReadIn[i];
            }
            printk("%02X ", flashReadIn[i]);
        }
        printk(" %s\r\n", ascii);
    }
    return;
}

void cliFlashStatus()
{
    uint8_t flashStatusIn[3];

    readNVFlashxStatus(flashStatusIn);
    printk("Flash Status 0x%02X 0x%02X 0x%02X\r\n", flashStatusIn[0], flashStatusIn[1], flashStatusIn[2]);
    printk("Status register 1\r\n");
    printk("%sBusy\r\n", flashStatusIn[0] & 0x01 ? "" : "Not ");
    printk("Write %sabled\r\n", flashStatusIn[0] & 0x02 ? "en" : "dis");
    printk("Block Protect %d\r\n", (flashStatusIn[0] & 0x1C) >> 2);
    printk("%s Protect\r\n", flashStatusIn[0] & 0x20 ? "Bottom" : "Top");
    printk("%sK Blocks\r\n", flashStatusIn[0] & 0x40 ? "4" : "64");
    printk("Status Register%s Protected\r\n", flashStatusIn[0] & 0x80 ? "" : " Not");
    printk("\r\nStatus register 2\r\n");
    printk("Status Register %sLocked\r\n", flashStatusIn[1] & 0x01 ? "" : "Not ");
    printk("QSPI %sEnabled\r\n", flashStatusIn[1] & 0x02 ? "" : "Not ");
    printk("Lock Bits %d\r\n", (flashStatusIn[1] & 0x38) >> 3);
    printk("Complement Protect %d\r\n", flashStatusIn[1] & 0x40);
    printk("Suspend Status %d\r\n", flashStatusIn[1] & 0x80);
    printk("\r\nStatus register 3\r\n");
    printk("Write protect Selection %d\r\n", flashStatusIn[2] & 0x04);
    printk("Drive Stength %d\r\n", (flashStatusIn[2] & 0x60) >> 5);
}

void cliFlashWritePage()
{
    uint32_t page;
    int32_t data;
    int address = 0;
    char *end;
    uint8_t dataArray[2];

    if (numParameters != 4)
    {
        printk("format flashWrite page address data\r\n");
        return;
    }
    page = strtoul(cmdLineParameter[1], &end, 16);
    address = strtoul(cmdLineParameter[2], &end, 16);
    data = strtoul(cmdLineParameter[3], &end, 16);
    if (page >= 32768)
    {
        printk("Page %d >= 32768\r\n", page);
        return;
    }
    if (address >= 256)
    {
        printk("Address %d >= 256\r\n", address);
        return;
    }
    dataArray[0] = data;
    printk("flashwrite page: 0x%X address: 0x%02X data: 0x%02X\r\n", page, address, dataArray[0]);
    flashxWritePage(page, address, dataArray, 1);
    printk("flashwrite complete\r\n");
    return;
}

void cliHelp()
{
    /* display command formats */
    //            printk("numParameters %d\r\n",numParameters);
    if (numParameters != 1)
    {
        displayHelp(cmdLineParameter[1][0]);
    }
    else
    {
        displayHelp('z');
    }
    return;
}

void cliHumidity()
{
    int i;

    i = 0;
    printk("Humidity (%%)\r\nDevice\tCurrent\tLow\tHigh\r\n");

    if ((sensorTypePresentAll & (1 << SENSORTYPEHDC2080)))
    {
        i++;
        hdcHumidity = readHumidity();
        printk("HDC2080\t%3.2f\t%3.2f\t%3.2f\r\n", hdcHumidity, readLowHumidityThreshold(), readHighHumidityThreshold());
    }
    if (i == 0)
        printk("No Humidity sensor connected\r\n");
    return;
}

void cliI2CRead()
{
    int i2cAddress, i2cRegister, length, i;
    char *end;
    uint8_t datas[DATA_LENGTH];

    i2cAddress = 0x00;
    i2cRegister = 0x00;
    length = 1; /* set to default address and length */
    if (numParameters == 2)
    {
        i2cAddress = strtoul(cmdLineParameter[1], &end, 16);
    }
    else if (numParameters == 3)
    {
        i2cAddress = strtoul(cmdLineParameter[1], &end, 16);
        i2cRegister = strtoul(cmdLineParameter[2], &end, 16);
    }
    else if (numParameters == 4)
    {
        i2cAddress = strtoul(cmdLineParameter[1], &end, 16);
        i2cRegister = strtoul(cmdLineParameter[2], &end, 16);
        length = atoi(cmdLineParameter[3]);
    }
    datas[0] = i2cRegister;
    i2c_write(i2c_dev, datas, 1, i2cAddress);

    i2c_read(i2c_dev, datas, length, 0x40);
    printk("I2C Read Address: 0x%02X Reg: 0x%02X Length: %d\r\n", (unsigned int)i2cAddress, (int)i2cRegister, (int)length);
    for (i = 0; i < length; i++)
    {
        printk("0x%02X 0x%02X\r\n", (unsigned int)(i2cRegister + i), datas[i]);
    }
    return;
}

void cliI2CWrite()
{
    int i2cAddress, i2cRegister, data;
    char *end;
    uint8_t dataArray[4];

    i2cAddress = 0x00;
    i2cRegister = 0x00;
    data = 1; /* set to default address and data */
    if (numParameters == 2)
    {
        i2cAddress = strtoul(cmdLineParameter[1], &end, 16);
    }
    else if (numParameters == 3)
    {
        i2cAddress = strtoul(cmdLineParameter[1], &end, 16);
        i2cRegister = strtoul(cmdLineParameter[2], &end, 16);
    }
    //           else if(numParameters == 5)
    else if (numParameters == 4)
    {
        i2cAddress = strtoul(cmdLineParameter[1], &end, 16);
        i2cRegister = strtoul(cmdLineParameter[2], &end, 16);
        data = strtoul(cmdLineParameter[3], &end, 16);
    }
    dataArray[0] = i2cRegister;
    dataArray[1] = data;
    i2c_write(i2c_dev, dataArray, 2, i2cAddress);
    printk("I2C write Address: 0x%02X Reg: 0x%02X data: 0x%02X\r\n", (unsigned int)i2cAddress, (int)i2cRegister, (int)data);
    return;
}

void cliPublishNow()
{
    printk("Send BLE data immediately\r\n");
    /* show RX received */
    k_sem_give(&hdc_rdy_seen); /* indicate HDC2080 RDY seen */
    return;
}

void cliReset()
{
    if (numParameters == 1)
    {
        printk("Software Reset the board\r\n");
#if defined(CONFIG_REBOOT)
        //              sys_reboot(SYS_REBOOT_COLD);
        NVIC_SystemReset();
#endif
    }
    //            else
    //            {
    //                printk("Forced WDT reset of the processor\r\n");
    //                stopWDTFeed = 1;
    //            }
    return;
}

void cliResetCause()
{
    printk("resetCause: %s\r\n", resetCause);
    return;
}

void cliSensors()
{
    char str[80];
    int i;

    printk("sensorTypePresentAll %08X\r\n", sensorTypePresentAll);
    for (i = 0; 1; i++)
    {
        if ((i & 0x3) == 0)
            myPrintf("\r\n");
        if (strcmp(sensorTypeNames[i], "Unknown") == 0)
            break;
        if ((sensorTypePresentAll & (1 << i)) == 0)
        {
            sprintf(str, "%s %s\r\n", sensorTypeNames[i], "Not Present");
            myPrintkW(str);
        }
        else
        {
            sprintf(str, "%s %s\r\n", sensorTypeNames[i], "Present");
            myPrintkI(str);
        }
    }
    return;
}

void cliTemperature()
{
    int i;

    i = 0;
    printk("Temperature (%%)\r\nDevice\tCurrent\tLow\tHigh\r\n");

    if ((sensorTypePresentAll & (1 << SENSORTYPEHDC2080)))
    {
        i++;
        hdcTemp = readTemp();
        ;
        printf("HDC2080\t%3.2f\t%3.2f\t%3.2f\r\n", hdcTemp, readLowTempThreshold(), readHighTempThreshold());
    }
    if (i == 0)
        printk("No Temperature sensor connected\r\n");
    return;
}

void cliVersion()
{
    /* display version and build information */
    printk("Board: %s%s\r\nFW VERSION: V %d.%02d %s%s\r\n", BOARD_NAME, BOARD_NAME_EXT, VERSION_MAJOR, VERSION_MINOR, VERSION_DATE, VERSION_DATE_EXT);
    printk("Built:%s %s\r\n", __DATE__, __TIME__);
    if (IS_ENABLED(CONFIG_LTE_NETWORK_MODE_LTE_M))
    {
        printk("GPS not available!\r\n");
    }
    if (IS_ENABLED(CONFIG_LTE_NETWORK_MODE_LTE_M_GPS))
    {
        printk("GPS available!\r\n");
    }
    return;
}
