/******************************************************************************
  * file    Inc/common.h
  * author  YuLiang
  * version 1.0.0
  * date    10-Jun-2022
  * brief   This file provides all the headers of the common functions.
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; COPYRIGHT(c) 2022 LandPower</center></h2>
  *
  * Redistribution and use in source and binary forms, with or without modification,
  * are permitted provided that the following conditions are met:
  *   1. Redistributions of source code must retain the above copyright notice,
  *      this list of conditions and the following disclaimer.
  *   2. Redistributions in binary form must reproduce the above copyright notice,
  *      this list of conditions and the following disclaimer in the documentation
  *      and/or other materials provided with the distribution.
  *   3. Neither the name of STMicroelectronics nor the names of its contributors
  *      may be used to endorse or promote products derived from this software
  *      without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  ******************************************************************************/

#ifndef __COMMON_H
#define __COMMON_H

/* Includes ------------------------------------------------------------------*/
#include <stdint.h>
#include "stm32l4xx_hal.h"

/* Define --------------------------------------------------------------------*/
#define VERSION_MAJOR 1
#define VERSION_MINOR 10
#define COMPILE_TIME (__DATE__" "__TIME__) 

#define NAME_LEN 32
#define DEV_COMPILE_TIME_LEN 32
#define DEV_VERSION_STR_LEN 32
#define NUM_LEN 11
#define DEV_CAPABILITY_LEN 16
#define DEV_RESET_INFO_NUM 10

/* 以下宏保证dev_info_t结构体大小是4096byte,正好占用1个扇区大小. */
#define DEV_INFO_SIZE 512

#define DEV_FLASH_REPETITION 3

#define IS_VERSION_CHG (strncmp((char*)dev_info.boot_compile_time, COMPILE_TIME, DEV_COMPILE_TIME_LEN - 1) != 0)

/* 配置串口进入IAP的等待时间(ENTRY_IAP_DELAY_COUNTER*ENTRY_IAP_RX_TIMEOUT)ms */
#define ENTRY_IAP_DELAY_COUNTER 30
#define ENTRY_IAP_RX_TIMEOUT 100

/* bin校验使用后 */
#define BIN_PKT_TYPE_LEN 4
#define BIN_PKT_HEAD_LEN 8

#define IS_CAP_LETTER(c)    (((c) >= 'A') && ((c) <= 'F'))
#define IS_LC_LETTER(c)     (((c) >= 'a') && ((c) <= 'f'))
#define IS_09(c)            (((c) >= '0') && ((c) <= '9'))
#define ISVALIDHEX(c)       (IS_CAP_LETTER(c) || IS_LC_LETTER(c) || IS_09(c))
#define ISVALIDDEC(c)       IS_09(c)
#define CONVERTDEC(c)       (c - '0')

#define CONVERTHEX_ALPHA(c) (IS_CAP_LETTER(c) ? ((c) - 'A'+10) : ((c) - 'a'+10))
#define CONVERTHEX(c)       (IS_09(c) ? ((c) - '0') : CONVERTHEX_ALPHA(c))

#define CONTROL(X) ((X) - '@')
#define PRINT_USART_BUF_LEN 128

#define MAC_LEN 6
#define MAC_STR_LEN 18
#define MAC_STR_BYTE_LEN 3
#define MAC_STR_HIGH_BIT 0
#define MAC_STR_LOWER_BIT 1
#define MAC_STR_SEQ_BIT 2

#define IP_STR_LEN 17
#define TYPE_STR_LEN 5
#define PORT_STR_LEN 7
#define ID_STR_LEN 9

#define FALSE 0
#define TRUE 1

/* Constants used by Serial Command Line Mode */
#define TX_TIMEOUT          ((uint32_t)100)
#define RX_TIMEOUT          HAL_MAX_DELAY

/* Exported types ---------------------------------------------------------------------*/
/* 重启类型号. */
typedef enum
{
    RESET_WATCHDOG = 0,
    RESET_CLI,
    RESET_IAP,
    RESET_RESET,
    RESET_UPDATE,
    RESET_SET_DEFAULT_CLI,
    RESET_SET_DEFAULT
} RESET_INFO_E;

/* bin报文头结构体. */
typedef struct
{
    uint8_t dev_type_m;
    uint8_t dev_type_s;
    uint8_t file_type;
    uint8_t version_m;
    uint16_t version_s;
    int8_t reserve[10];
    uint32_t crc32;
} bin_pkt_tail_t;

/* 时间信息.8byte. */
typedef struct
{
    uint16_t year;
    uint8_t mon;
    uint8_t day;
    uint8_t hour;
    uint8_t min;
    uint8_t sec;
    uint8_t state; /* 空开状态.用于断电报警,其他代码可做无效位. */
} dev_time_t;

/* 电源上闪光灯功率信息.4byte. */
typedef struct 
{
    uint16_t power;
    uint16_t noise;
} dev_light_power_t;

/* 记录补光灯功率计算值. */
typedef struct
{
    uint16_t max;
    uint16_t min;
    uint8_t conut_max;
    uint8_t conut_min;
    uint16_t time;
} dev_light_cal_t;

/* 信息记录保存. */
typedef struct
{
    /* UPDATE_MAGIC,INIT_DONE_MAGIC. 4byte */
    uint32_t magic;
    /* 重启信息保存. 84byte */
    dev_time_t reset_info[DEV_RESET_INFO_NUM];
    uint8_t reset_index;
    uint8_t reset_type;
    uint8_t reserve0[2];
    /* 保证配置区 512byte 的保留位. */
    uint8_t reserve[420]; 
    /* INIT_DONE_MAGIC. 4byte */
    uint32_t magic_bak;
} dev_record_t;

/* 器件信息保存. */
typedef struct
{
    /* INIT_DONE_MAGIC. 4byte */
    uint32_t magic;
    /* 设备信息. 36byte */
    uint8_t type_m;
    uint8_t type_s;
    uint8_t mac[6];
    uint8_t id[4];
    uint8_t ip[4];
    uint8_t ip_mask[4];
    uint8_t ip_gw[4];
    uint8_t server_ip[4];
    uint8_t wireless_server_ip[4];
    uint16_t server_port;
    uint16_t wireless_server_port;
    /* 版本信息. 224byte */
    uint8_t boot_version[DEV_VERSION_STR_LEN];
    uint8_t boot_compile_time[DEV_COMPILE_TIME_LEN];
    uint8_t img_version[DEV_VERSION_STR_LEN];
    uint8_t img_compile_time[DEV_COMPILE_TIME_LEN];
    uint8_t hardware_version[DEV_VERSION_STR_LEN];
    uint8_t FPGA_version[DEV_VERSION_STR_LEN];
    uint8_t factory_time[DEV_COMPILE_TIME_LEN];
    /* 内部flash和spi flash中img的大小. 32byte */
    uint32_t fireware_size;
    uint32_t spi_fireware_size;
    uint8_t update_ip_addr[4];
    uint16_t update_port;
    uint16_t csg_version;
    unsigned char capability_set[DEV_CAPABILITY_LEN];
    uint8_t csg_id[8];
    uint8_t csg_card[8];
    /* 保留空间,以便以后添加成员的时候不用再升级IAP程序. */
    uint8_t reserved[196];
    /* INIT_DONE_MAGIC. 4byte */
    uint32_t magic_bak;
} dev_info_t;

/* Exported macro ------------------------------------------------------------*/
/* 大小端网络序处理 */
#ifndef LITTLE_ENDIAN
    #define LITTLE_ENDIAN 1234
#endif

#ifndef BIG_ENDIAN
    #define BIG_ENDIAN 4321
#endif

#ifndef BYTE_ORDER
    #define BYTE_ORDER LITTLE_ENDIAN
#endif

#if BYTE_ORDER == BIG_ENDIAN
    #define iap_htons(x) (x)
    #define iap_ntohs(x) (x)
    #define iap_htonl(x) (x)
    #define iap_ntohl(x) (x)
    #define PP_HTONS(x) (x)
    #define PP_NTOHS(x) (x)
    #define PP_HTONL(x) (x)
    #define PP_NTOHL(x) (x)
#else /* BYTE_ORDER != BIG_ENDIAN */
    #ifndef iap_htons
        uint16_t iap_htons(uint16_t x);
    #endif
    #define iap_ntohs(x) iap_htons(x)

    #ifndef iap_htonl
        uint32_t iap_htonl(uint32_t x);
    #endif
    #define iap_ntohl(x) iap_htonl(x)

    /* These macros should be calculated by the preprocessor and are used
       with compile-time constants only (so that there is no little-endian
       overhead at runtime). */
    #define PP_HTONS(x) ((((x) & 0xff) << 8) | (((x) & 0xff00) >> 8))
    #define PP_NTOHS(x) PP_HTONS(x)
    #define PP_HTONL(x) ((((x) & 0xff) << 24) | \
                        (((x) & 0xff00) << 8) | \
                        (((x) & 0xff0000UL) >> 8) | \
                        (((x) & 0xff000000UL) >> 24))
    #define PP_NTOHL(x) PP_HTONL(x)
#endif /* BYTE_ORDER == BIG_ENDIAN */

#define HAL_E_RETURN(_f_) \
    do { \
        HAL_StatusTypeDef _rv_ = HAL_ERROR; \
        if ((_rv_ = _f_) != 0) \
        { \
            Serial_PutString("\r\nError return "__FILE__"("); \
            Int2Str(number_str, __LINE__); \
            Serial_PutString(number_str); \
            Serial_PutString(").\r\n"); \
            return _rv_; \
        } \
    } while(0)
    
/* Extern global variables ---------------------------------------------------*/
extern dev_info_t dev_info;
extern uint8_t number_str[NUM_LEN];

/* Exported functions ------------------------------------------------------- */
extern void Int2Str(uint8_t *p_str, uint32_t intnum);
extern uint32_t Str2Int(uint8_t *inputstr, uint32_t *intnum);
extern void Serial_PutString(uint8_t *p_string);
extern HAL_StatusTypeDef Serial_PutByte(uint8_t param);
extern HAL_StatusTypeDef Serial_PutBytes(uint8_t* buf, uint16_t len, uint32_t timeout);
extern void vty_print(char *format, ...);
extern void phy_reset(void);
extern void crc32_table_init(void);
extern uint32_t crc32_update(uint32_t crc, char* buf, uint32_t len);
extern HAL_StatusTypeDef dev_info_init(void);
extern HAL_StatusTypeDef dev_info_save(void);
extern HAL_StatusTypeDef dev_record_read(void);
extern void menu_entry(void);
extern void watchdog_refresh(void);

#endif  /* __COMMON_H */
/************************ (C) COPYRIGHT LandPower *****END OF FILE****/
