/*
 * Copyright (c) 2016, Freescale Semiconductor, Inc.
 * Copyright (c) 2016-2021, NXP
 * All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#ifndef LDC_H
#define LDC_H
#include "common.h"

/*******************************************************************************
 * Definitions
 ******************************************************************************/
#define LCD_NO_OF_BACK_PLANES    8           //1-8
#define LCD_NO_OF_FRONT_PLANES  15  
#define LCD_CLOCK LCD_CLOCK_EXT            // LCD_CLOCK_EXT: OSCOUT (external clock reference) as the LCD clock source
// LCD_CLOCK_ALT: alternate clock as the LCD clock source

#define LCD_VSUPPLY LCD_VLL3_FROM_VDD       //LCD_VLL2_FROM_VDD  :  drives VLL2 internally from VDD
//LCD_VLL3_FROM_VDD  :  drives VLL3 internally from VDD
//LCD_VLL1_FROM_VLCD :  drives VLL1 internally from VLCD
//LCD_VLL3_FROM_EXT  :  drives VLL3 externally or V(IREG)

#define LCD_CLOCK_PRESCALER  0

#define LCD_CHARGE_PUMP_SELECT LCD_CHARGE_PUMP_ENABLE   //LCD_CHARGE_PUMP_ENABLE: charge pump is enabled
//LCD_CHARGE_PUMP_DISABLE: resistor network enabled

#define LCD_LOAD_ADJUST  3

#define LCD_CLOCK_EXT 0
#define LCD_CLOCK_ALT 1

#define LCD_CHARGE_PUMP_ENABLE      1      //charge pump is enabled
#define LCD_CHARGE_PUMP_DISABLE     0      //resistor network enabled

#define LCD_VLL2_FROM_VDD           0      //drives VLL2 internally from VDD
#define LCD_VLL3_FROM_VDD           1      //drives VLL3 internally from VDD
#define LCD_VLL1_FROM_VLCD          2      //drives VLL1 internally from VLCD
#define LCD_VLL3_FROM_EXT           3      //drives VLL3 externally or V(IREG)

typedef enum
{
  LCD_CHAR_SPACE,                // ' ' (Space)
  LCD_CHAR_DASH,                 // '-' (Minus Sign)
  LCD_CHAR_0,                    // '0'
  LCD_CHAR_1,                    // '1'
  LCD_CHAR_2,                    // '2'
  LCD_CHAR_3,                    // '3'
  LCD_CHAR_4,                    // '4'
  LCD_CHAR_5,                    // '5'
  LCD_CHAR_6,                    // '6'
  LCD_CHAR_7,                    // '7'
  LCD_CHAR_8,                    // '8'
  LCD_CHAR_9,                    // '9'
  LCD_CHAR_A,                    // 'A'
  LCD_CHAR_B,                    // 'B'
  LCD_CHAR_C,                    // 'C'
  LCD_CHAR_D,                    // 'D'
  LCD_CHAR_E,                    // 'E'
  LCD_CHAR_F,                    // 'F'
  LCD_CHAR_G,                    // 'G'
  LCD_CHAR_H,                    // 'H'
  LCD_CHAR_I,                    // 'I'
  LCD_CHAR_J,                    // 'J'
  LCD_CHAR_K,                    // 'K'
  LCD_CHAR_L,                    // 'L'
  LCD_CHAR_M,                    // 'M'
  LCD_CHAR_N,                    // 'N'
  LCD_CHAR_O,                    // 'O'
  LCD_CHAR_P,                    // 'P'
  LCD_CHAR_Q,                    // 'Q'
  LCD_CHAR_R,                    // 'R'
  LCD_CHAR_S,                    // 'S'
  LCD_CHAR_T,                    // 'T'
  LCD_CHAR_U,                    // 'U'
  LCD_CHAR_V,                    // 'V'
  LCD_CHAR_W,                    // 'W'
  LCD_CHAR_X,                    // 'X'
  LCD_CHAR_Y,                    // 'Y'
  LCD_CHAR_Z,                    // 'Z'
} LCD_CHARS;

#define LCD_SEG_NONE            0x00    //no segment is selected

#define LCD_SEG_SP1                 0x80
#define LCD_SEG_SP2                 0x40
#define LCD_SEG_SP3                 0x20
#define LCD_SEG_SP4                 0x10
#define LCD_SEG_SP5                 0x08
#define LCD_SEG_SP6                 0x04
#define LCD_SEG_SP7                 0x02
#define LCD_SEG_SP8                 0x01

#define LCD_SEG_D                   LCD_SEG_SP2
#define LCD_SEG_E                   LCD_SEG_SP3
#define LCD_SEG_C                   LCD_SEG_SP4
#define LCD_SEG_G                   LCD_SEG_SP5
#define LCD_SEG_F                   LCD_SEG_SP6
#define LCD_SEG_B                   LCD_SEG_SP7
#define LCD_SEG_A                   LCD_SEG_SP8

#define NUM_DIGITS              10
#define NUM_FRONTPLANEPINS      15

extern  uint8 FrontPlanePins[];
extern  uint8 BackPlanePins[];
extern  char  disp_string[NUM_DIGITS];
extern  uint8 LCDArray[NUM_FRONTPLANEPINS];

//Front Plane Pins
#define LCDPIN9   LCD->WF8B[16]
#define LCDPIN10  LCD->WF8B[17]
#define LCDPIN11  LCD->WF8B[18]
#define LCDPIN12  LCD->WF8B[19]
#define LCDPIN13  LCD->WF8B[20]
#define LCDPIN14  LCD->WF8B[23]
#define LCDPIN15  LCD->WF8B[24]
#define LCDPIN16  LCD->WF8B[25]
#define LCDPIN17  LCD->WF8B[26]
#define LCDPIN18  LCD->WF8B[27]
#define LCDPIN19  LCD->WF8B[28]
#define LCDPIN20  LCD->WF8B[34]
#define LCDPIN21  LCD->WF8B[30]
#define LCDPIN22  LCD->WF8B[31]
#define LCDPIN23  LCD->WF8B[33]


// Back plane pins
#define LCDPIN1   LCD->WF8B[0] 
#define LCDPIN2   LCD->WF8B[1] 
#define LCDPIN3   LCD->WF8B[6]
#define LCDPIN4   LCD->WF8B[7]
#define LCDPIN5   LCD->WF8B[8]
#define LCDPIN6   LCD->WF8B[13]
#define LCDPIN7   LCD->WF8B[14]
#define LCDPIN8   LCD->WF8B[15]


#define CONFIG_LCD_ONE_MODE   config_lcd_mode();

/* all the segments are OFF by writing 0 to all the frontplane pin registers*/
#define LCD_ALLFP_OFF   {\
  LCDPIN9  = 0x0;\
  LCDPIN10 = 0x0;\
  LCDPIN11 = 0x0;\
  LCDPIN12 = 0x0;\
  LCDPIN13 = 0x0;\
  LCDPIN14 = 0x0;\
  LCDPIN15 = 0x0;\
  LCDPIN16 = 0x0;\
  LCDPIN17 = 0x0;\
  LCDPIN18 = 0x0;\
  LCDPIN19 = 0x0;\
  LCDPIN20 = 0x0;\
  LCDPIN21 = 0x0;\
  LCDPIN22 = 0x0;\
  LCDPIN23 = 0x0;\
}

/* all the segments are ON  by writing 0xFF to all the frontplane pin registers*/
#define LCD_ALLFP_ON   {\
  LCDPIN9 = 0xFF;\
  LCDPIN10 = 0xFF;\
  LCDPIN11 = 0xFF;\
  LCDPIN12 = 0xFF;\
  LCDPIN13 = 0xFF;\
  LCDPIN14 = 0xFF;\
  LCDPIN15 = 0xFF;\
  LCDPIN16 = 0xFF;\
  LCDPIN17 = 0xFF;\
  LCDPIN18 = 0xFF;\
  LCDPIN19 = 0xFF;\
  LCDPIN20 = 0xFF;\
  LCDPIN21 = 0xFF;\
  LCDPIN22 = 0xFF;\
  LCDPIN23 = 0xFF;\
}

#define ON_RS()            (LCDArray[0] |= LCD_SEG_SP1)
#define ON_EARTH()         (LCDArray[0] |= LCD_SEG_SP2)
#define ON_NM()            (LCDArray[0] |= LCD_SEG_SP3)
#define ON_REV()           (LCDArray[0] |= LCD_SEG_SP4)
#define ON_ND()            (LCDArray[0] |= LCD_SEG_SP5)
#define ON_MD()            (LCDArray[0] |= LCD_SEG_SP6)

#define ON_DATE()          (LCDArray[1] |= LCD_SEG_SP1)
#define ON_TIME()          (LCDArray[1] |= LCD_SEG_SP2)
#define ON_IMPORT()        (LCDArray[1] |= LCD_SEG_SP3)
#define ON_EXPORT()        (LCDArray[1] |= LCD_SEG_SP4)
#define ON_LEFTARROW()     (LCDArray[1] |= LCD_SEG_SP5)
#define ON_RIGHTARROW()    (LCDArray[1] |= LCD_SEG_SP6)
#define ON_BP()            (LCDArray[1] |= LCD_SEG_SP7)
#define ON_AV()            (LCDArray[1] |= LCD_SEG_SP8)

#define ON_COL2()          (LCDArray[2] |= LCD_SEG_SP1)
#define ON_COL1()          (LCDArray[3] |= LCD_SEG_SP1)
#define ON_DP1()           (LCDArray[4] |= LCD_SEG_SP1)
#define ON_DP2()           (LCDArray[5] |= LCD_SEG_SP1)
#define ON_DP3()           (LCDArray[6] |= LCD_SEG_SP1)
#define ON_DP4()           (LCDArray[7] |= LCD_SEG_SP1)
#define ON_DP5()           (LCDArray[8] |= LCD_SEG_SP1)

#define ON_CUM()           (LCDArray[11] |= LCD_SEG_SP1)

#define ON_ON()            (LCDArray[12] |= LCD_SEG_SP1)
#define ON_BAT()           (LCDArray[12] |= LCD_SEG_SP7)
#define ON_MAG()           (LCDArray[12] |= LCD_SEG_SP8)
#define ON_PHASER()        (LCDArray[12] |= LCD_SEG_SP6)                       
#define ON_PHASEY()        (LCDArray[12] |= LCD_SEG_SP5)        
#define ON_PHASEB()        (LCDArray[12] |= LCD_SEG_SP2)

#define ON_LOCK()          (LCDArray[13] |= LCD_SEG_SP1)
#define ON_k()             (LCDArray[13] |= LCD_SEG_SP2)
#define ON_V()             (LCDArray[13] |= LCD_SEG_SP3)
#define ON_V1()            (LCDArray[13] |= LCD_SEG_SP4)
#define ON_A()             (LCDArray[13] |= LCD_SEG_SP5)
#define ON_R()             (LCDArray[13] |= LCD_SEG_SP6)
#define ON_h()             (LCDArray[13] |= LCD_SEG_SP7)
#define ON_z()             (LCDArray[13] |= LCD_SEG_SP8)

#define ON_POSTPAID()      (LCDArray[14] |= LCD_SEG_SP3)
#define ON_PREPAID()       (LCDArray[14] |= LCD_SEG_SP4)
#define C_OPEN()           (LCDArray[14] |= LCD_SEG_SP5)
#define ON_PF()            (LCDArray[14] |= LCD_SEG_SP7)
#define ON_TOD()           (LCDArray[14] |= LCD_SEG_SP8)

#define ON_SIG1()          (LCDArray[10] |= LCD_SEG_SP1)
#define ON_PR()            (LCDArray[12] |= LCD_SEG_SP6)
#define ON_PY()            (LCDArray[12] |= LCD_SEG_SP5)
#define ON_PB()            (LCDArray[12] |= LCD_SEG_SP2)

#define ON_W()       { \
  ON_V();              \
  ON_V1();             \
}

#define ON_Wh()      { \
  ON_W();              \
  ON_h();             \
}

#define ON_kW()      { \
  ON_k();              \
  ON_W();              \
}

#define ON_kWh()     { \
  ON_kW();             \
  ON_h();              \
}

#define ON_kV()      { \
  ON_k();              \
  ON_V();              \
}

#define ON_kVA()     { \
  ON_kV();             \
  ON_A();              \
}

#define ON_kVAr()     { \
  ON_kV();             \
  ON_A();              \
  ON_R();              \
}

#define ON_kVAh()    { \
  ON_kVA();            \
  ON_h();              \
}

#define ON_kVArh()    { \
  ON_kVA();            \
  ON_R();              \
  ON_h();              \
}

#define ON_VA()       { \
  ON_V();              \
  ON_A();              \
}

#define ON_VAh()     { \
  ON_V();              \
  ON_A();              \
  ON_h();              \
}

#define ON_VAR()     { \
  ON_V();              \
  ON_A();              \
  ON_R();              \
}

#define ON_VArh()     { \
  ON_V();              \
  ON_A();              \
  ON_R();              \
  ON_h();              \
}

#define ON_HZ()     { \
  ON_h();              \
  ON_z();              \
} 
#define ON_COL2_3() { \
  ON_COL1();          \
  ON_COL2();          \
}

#if 0
#define ON_SIG_25()     { \
  ON_SIG4();             \
}
#define ON_SIG_50()     { \
  ON_SIG4();             \
  ON_SIG3();             \
}
#define ON_SIG_75()     { \
  ON_SIG4();             \
  ON_SIG3();             \
  ON_SIG2();             \
}
#define ON_SIG_100()    { \
  ON_SIG4();             \
  ON_SIG3();             \
  ON_SIG2();             \
  ON_SIG1();             \
}
#endif
      
/** Enable 'BATTERY' on LCD */
#define ON_BATT()          (LCDArray[12] |= LCD_SEG_SP7)                               

/** Enable 'unlock' on LCD */
#define ON_UNLOCK()        (LCDArray[14] |= LCD_SEG_SP1)
                               
#define ON_P1()         (LCDArray[4] |= LCD_SEG_SP1)                       
#define ON_P2()         (LCDArray[5] |= LCD_SEG_SP1)                       
#define ON_P3()         (LCDArray[6] |= LCD_SEG_SP1)                              
#define ON_P4()         (LCDArray[7] |= LCD_SEG_SP1)                                 
#define ON_P5()         (LCDArray[8] |= LCD_SEG_SP1)                      

/*******************************************************************************
* Prototypes
******************************************************************************/
/* Data */
extern const uint8 lcd_char_table[];

/*functions*/
extern void LCDInit();
extern void LCDClear(void);
extern uint8 LCDFindChar(uint8 character);
extern void config_lcd_mode(void);
extern void lcd_PrintString(void);
#endif  /* LDC_H */
