/*******************************************************************************
  MPLAB Harmony Application Header File

  Company:
    Microchip Technology Inc.

  File Name:
    weller.h

  Summary:
    This header file provides prototypes and definitions for the application.

 * V1.5 - slow current display filter change from 0.2 to 0.03
 * 
  Description:
    This header file provides function prototypes and data type definitions for
    the application.  Some of these are required by the system (such as the
    "APP_Initialize" and "APP_Tasks" prototypes) and some of them are only used
    internally by the application (such as the "APP_STATES" definition).  Both
    are defined here for convenience.
*******************************************************************************/

//DOM-IGNORE-BEGIN
/*******************************************************************************
Copyright (c) 2013-2014 released Microchip Technology Inc.  All rights reserved.

Microchip licenses to you the right to use, modify, copy and distribute
Software only when embedded on a Microchip microcontroller or digital signal
controller that is integrated into your product or third party product
(pursuant to the sublicense terms in the accompanying license agreement).

You should refer to the license agreement accompanying this Software for
additional information regarding your rights and obligations.

SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF
MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE.
IN NO EVENT SHALL MICROCHIP OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER
CONTRACT, NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR
OTHER LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR
CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF
SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
(INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
 *******************************************************************************/
//DOM-IGNORE-END

#define PIC32MZ_PCB 1

#ifndef _WELLER_H
#define _WELLER_H

// *****************************************************************************
// *****************************************************************************
// Section: Included Files
// *****************************************************************************
// *****************************************************************************

#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdlib.h>
#include "system_config.h"
#include "system_definitions.h"
#include "driver/tmr/drv_tmr.h"
#include "system/ports/sys_ports.h"
#include "system/system.h"
#include "peripheral/spi/plib_spi.h"
#include "peripheral/ports/plib_ports.h"
#include "peripheral/devcon/plib_devcon.h"
#include "system/devcon/sys_devcon.h"

   
// *****************************************************************************
// *****************************************************************************
//  SPI Stuff
// *****************************************************************************
// *****************************************************************************
#define BAUDRATE_100KHZ 100000
#define BAUDRATE_1000KHZ 1000000
    
    
    
// *****************************************************************************
// *****************************************************************************
// Section: Type Definitions
// Port B
// *****************************************************************************
// *****************************************************************************
/*         Implementation specific Definitions                                */


#ifdef PIC32MX_PCB
/* RB3  = LCD RS - Active Low (output) */
#define KS0108_LCD_RST 8
/* RB4  = LCD Enable (output) */
#define KS0108_LCD_E 16
/* RB5  = LCD Chip Select 1 (output) */
#define KS0108_LCD_CS1 32
#endif

#ifdef PIC32MZ_PCB
/* RB2  = Encoder_Select_1 */
#define Rotary_Encoder_Select_0 4

#define APP_PSU_ADC1_PORT PORT_CHANNEL_B
/* RB3 CS_ADC1 */
#define CS_ADC1 0x008
/* RB4 = LCD_RS (output)*/
#define KS0108_LCD_RS 16
/* RB5  = LCD Chip Select 1 (output) */
#define KS0108_LCD_CS1 32
/* RB6  = LCD Chip Select 2 (output) */
#define KS0108_LCD_CS0 64
/* RB7 = Encoder_Select_2 */
#define Rotary_Encoder_Select_1 128

/*****************************************************************************/
//    Pin identifications for rotary coder headers
//      - These define the coding behaviour
//      - you ought to document these better you lazy sod
//
//  OK here is a bit more.
//  On PIC32MZ
// - Pin 1 = RB2
// - Pin 6 = RB7
//
// PortB = 0b0XXXX0XX = OLD Encoder
// PortB = 0b1XXXX0XX = TYPE A Encoder
// PortB = 0b0XXXX1XX = TYPE B Encoder
// PortB = 0b1XXXX1XX = UNUSED
//
// Port B bits 1 and 6 have weak pullup set in the config file
// Jumper them to ground (pin 7 or 8) to set a "0"
/*****************************************************************************/
/* Old Rotary Encoder = 00XXXXXX*/
#define Old_Rotary_Encoder 0x0000
/* Type A rotary Encoder = 10XXXXXX*/
#define Type_A_Rotary_Encoder 0x0080
/* Type B Rotary Encoder = 01XXXXXX*/
#define Type_B_Rotary_Encoder 0x0004
#define Encoder_Select_Bits   (4+128)


#endif

 /****************************************************************************/   
 // The rest of port B   
 /****************************************************************************/   
/* RB8 - LCD0 (output) */
/* RB9 - LCD1 (output) */
/* RB10 - LCD2 (output) */
/* RB11 - LCD3 (output) */
/* RB12 - LCD4 (output) */
/* RB13 - LCD5 (output) */
/* RB14 - LCD6 (output) */
/* RB15 - LCD7 (output) */
#define KS0108_PortBits 0xFF00
   

#ifdef PIC32MZ_PCB
/*****************************************************************************/    
/*                                                                           */
/*  PSU Control Header goes to J2 on PIC32MZ board                           */
/*  Pin:   Port:    Function                                                 */
/*  1       D0      CS_DAC1 - To PSU                                         */
/*  2       D2      SDI_PSU - From PSU                                       */
/*  3       B3      CS_ADC1                                                  */
/*  4       D3      SDO_PSU - To PSU                                         */
/*  5       D10     CS_DAC2                                                  */
/*  6       D1      SCK_PSU - To PSU                                         */
/*  7       D9      CS_ADC2 - To PSU                                         */
/*  8       D4      Unused                                                   */
/*  9       --      GND                                                      */
/*  1       --      5V  - in or out configurable                             */
/*                                                                           */
/*****************************************************************************/    

// *****************************************************************************
// Port D
// you really do have the full set of ways of defining the bit masks for each 
//     port!  Tidy this up sometime!
// *****************************************************************************
#define APP_PSU_PORT PORT_CHANNEL_D
/* RD0 CS_DAC1 */
#define CS_DAC1 0x001
/* RD1 = SCK_PSU*/
#define SCK_PSU 0x002
/* RD2 = SDI_PSU*/
#define SDI_PSU 0x004
/* RD3 SDO_PSU*/
#define SDO_PSU 0x008
/* RD4 UNUSED*/
/* RD5 = LCD_RW (output)*/
#define KS0108_LCD_RW 32
/* RD6 - na */
/* RD7 - na */
/* RD8 - na */
/* RD9 CS_ADC2 */
#define CS_ADC2 0x200
/* RD10 CS_DAC2*/
#define CS_DAC2 0x400
#endif


#ifdef PIC32MX_PCB
/* RD6 = LCD_RS (output)*/
#define KS0108_LCD_RS 64
/* RD7 = LCD_CS (output)*/
#define KS0108_LCD_CS0 128
#endif

// *****************************************************************************
// Port E
// This is where the buttons live as the user interface    
// *****************************************************************************
/* RE0 = VDD Drive for UI*/
/* RE1 = EXIT (input)       Weak pulldown set in config file */
/* RE2 = SELECT (input)     Weak pulldown set in config file */
/* RE3 = PHASEA (input)     Weak pulldown set in config file */
/* RE4 = PHASEB (input)     Weak pulldown set in config file */
/* RE5 = ROT2_PHASEA (input)     Weak pulldown set in config file */
/* RE6 = ROT2_PHASEB (input)     Weak pulldown set in config file */
/* RE7 = SHUTDOWN (input)     Weak pulldown set in config file */
//#define Rotary_Encoder_Select_1 128

 
// *****************************************************************************
// Port F and G
// *****************************************************************************
/* RF0 EEPROM Chip Select_Active Low*/
#define EEPROM_Select 1
/* RF1 EEPROM Chip Hold_Active Low*/
#define EEPROM_Hold 2
/* RF1 SPARE (output)*/

#ifdef PIC32MZ_PCB
/* RF4  = LCD Reset - Active Low (output) */
#define KS0108_LCD_RST 16
/* RF5  = LCD Enable (output) */
#define KS0108_LCD_E 32
#endif

/* RG6 = SPI_SCK2 */
/* RG7 = SPI_SDI2 "0001" */
/* RG8 = SPI_SDO2 = "0110" */
/* RG9 = SPI_SS2 = "0110" */
    
#define APP_HEARTBEAT_PORT PORT_CHANNEL_B
/* test LED on 32MZ board = B8*/
#define APP_HEARTBEAT_PIN PORTS_BIT_POS_8
#define APP_WELLER_HEATER_PORT PORT_CHANNEL_B
#define APP_WELLER_HEATER_PIN 0x0007   

/* LCD Defines */ 
#ifdef PIC32MX_PCB
#define APP_LCD_PORT_CS0 PORT_CHANNEL_D
#define APP_LCD_PORT_CS1 PORT_CHANNEL_B
#define APP_LCD_PORT_RESET PORT_CHANNEL_B
#define APP_LCD_PORT_RW PORT_CHANNEL_D
#define APP_LCD_PORT_RS PORT_CHANNEL_D
#define APP_LCD_PORT_ENABLE PORT_CHANNEL_B
#define ADAU_SPI_Port SPI_ID_1           // EEPROM on SPI 1
#define EEPROM_SPI_Port SPI_ID_1       
#endif


#ifdef PIC32MZ_PCB
#define APP_DSP_RESET_L_PORT PORT_CHANNEL_B
#define APP_DSP_RESET_L_MASK 0x08
#define DSP_SET_RESET   SYS_PORTS_Clear(PORTS_ID_0, APP_DSP_RESET_L_PORT, APP_DSP_RESET_L_MASK)
#define DSP_CLEAR_RESET SYS_PORTS_Set(PORTS_ID_0,   APP_DSP_RESET_L_PORT, APP_DSP_RESET_L_MASK, APP_DSP_RESET_L_MASK)

#define APP_LCD_PORT_CS0 PORT_CHANNEL_B
#define APP_LCD_PORT_CS1 PORT_CHANNEL_B
#define APP_LCD_PORT_RESET PORT_CHANNEL_F
#define APP_LCD_PORT_RW PORT_CHANNEL_D
#define APP_LCD_PORT_RS PORT_CHANNEL_B
#define APP_LCD_PORT_ENABLE PORT_CHANNEL_F
#define ADAU_SPI_Port SPI_ID_2           // EEPROM on SPI 2
#define EEPROM_SPI_Port  SPI_ID_2  // EEPROM SPI port
#define PSU_SPI_Port SPI_ID_1  // ADC and DAC SPI port

#endif   

#define APP_LCD_PORT_DATA PORT_CHANNEL_B
    
// USER INTERFACE PORT STUFF
#define APP_UI_PORT PORT_CHANNEL_E
#define APP_UI_PORT_DRIVE 0x0001
#define APP_ENCODER_TYPE_PORT PORT_CHANNEL_B
#define APP_UI_COUNT_MAX 999     //This is arbitrary
#define APP_UI_TMR DRV_TMR_INDEX_1
#define APP_UI_TMR_PERIOD 0x01FF
#define APP_UI_TMR_IS_PERIODIC true


//SPI EEPROM Stuff
#define EEPROM_CHIPSEL_PORT PORT_CHANNEL_F
#define EEPROM_CHIPSEL_BIT 0x0001
#define EEPROM_HOLD_PORT PORT_CHANNEL_F
#define EEPROM_HOLD_BIT 0x0002
#define EEPROM_Disable_Hold SYS_PORTS_Set(PORTS_ID_0, EEPROM_HOLD_PORT, EEPROM_HOLD_BIT, EEPROM_HOLD_BIT)


/***************************************************/
/* Storage related in the hardware implementation  */
/* Stuff to allow memory bank in use to be tracked */
/***************************************************/
#define Mem_Banks_Do_Not_Erase      3
#define Mem_Banks_Erase             4
#define Max_Mem_Banks_With_Erase    4
#define Max_Mem_Banks               2
#define Default_Mem_Bank            0
#define Clear_Buffers_SPI_Time      3
/* How big is each set of data in ROM?*/
#define ParmSet_Array_Size          256
/* data locations */
#define V1_Offset_In_Mem            0
#define I1_Offset_In_Mem            4
#define V2_Offset_In_Mem            8
#define I2_Offset_In_Mem            12
#define V_Max_Offset                16
#define I_Max_Offset                20
#define Tracking_Offset             24
#define Num_Rails_Offset            28
#define Transformer_VA_Offset       32
#define V1_Offset_Offset            36
#define V2_Offset_Offset            40
#define V1_Output_Cal_Offset        44
#define V2_Output_Cal_Offset        48
#define I1_Offset_Offset            52
#define I2_Offset_Offset            56
#define I1_Cal_Offset               60
#define I2_Cal_Offset               64
#define V1_Read_Cal_Offset          68
#define V2_Read_Cal_Offset          72

/******************************************************************************/
// Hard Coded Defines
// Should not need user change 
/******************************************************************************/    
#define ADC_Max                     4095
#define DAC_Max                     4095
#define Vref_Nom_Mv                 5000
#define ISense_mV_Amp               250
#define VMax_Default_mV             30000
#define IMax_Default_mA             6000
#define V_Limit_mV                  25000
#define I_Limit_mA                  5000
#define V_Init                      10000        /* 10 volt */
#define I_Init                      100         /* 100mA */
#define V_Min                       0
#define V_Min_Setup                 12000      /* pretty well set by the prereg */
#define I_Min                       100
#define I_Lim_Default               1000        /*mA */
#define V_Offset_Min                -300        /* mV */
#define V_Offset_Default            0           /* mV */
#define V_Offset_Max                300         /* mV */
#define V_Scale_FSD                 50000       /* mV */
#define I_Offset_Min                -100        /* mA */
#define I_Offset_Default            0           /* mA */
#define I_Offset_Max                100         /* mA */
#define Cal_Init                    1000        /* Cal scale is mv/v */
#define I_Cal_Min                   500         /* mA per Amp */
#define I_Cal_Max                   2000        /* mA per Amp */
#define V_Cal_Min                   500         /* mV per Amp */
#define V_Cal_Max                   2000        /* mV per Amp */
#define Feedback_Voltage_Divider    (15.666)      /* 1.5K and 22k resistive*/
#define Current_Sense_Resistor_mOhms 10       /* milli Ohms */
#define Current_Sense_Amplifier_Gain 50         /* times */
#define Losses_in_Rect              7500        /* 2.2V diodes, 3.2V ripple, 1.5V SWM, 1V linear */
#define Loss_Margin                 1200        /* mV */
#define Voltage_Output_DAC_FSD_mV   5000        /* set by 3.3V rail (1.25*((390+220)/220)) */
#define Current_Output_DAC_FSD_mV   5000        /* set by 3.3V rail (1.25*((390+220)/220)) */
#define Measurement_ADC_FSD_mV      5000        /* set by 3.3V rail (1.25*((390+220)/220)) */
#define ADC_Resolution              4095        /* max scale */
#define DAC_Resolution              4095        /* max scale */

/******************************************************************************/
/* General "Stuff"                                                            */
/******************************************************************************/
#define Display_Start_Screen_ms     500         /*  display screen */
#define	Revert_To_Idle              300     /* Seems like a sensible number*/
#define Error_Msg_Time              2000    /* ms */
#define Num_Rails_Default           2       /* default to 2 rails */ 
#define Tracking_Default            1       /* start True */
#define	Current_Normal_Speed        1       /* Seems like a sensible number*/
#define	Current_Speed               10      /* Seems like a sensible number*/
#define Voltage_Normal_Speed        1       /* 10mV per click */
#define Voltage_Speed               25      /* 250mV per click */
#define Voltage_Setup_Normal_Speed  10      /* 10mV per click */
#define Voltage_Setup_Speed         20      /* 10mV per click */
#define VA_Normal_Speed             1       /* 10mV per click */
#define VA_Speed                    2      /* 250mV per click */
#define Slow_Start_Ramp_Time_mS     300     /* start with this.... */
#define Current_Step                10      /* milliamps per click */
#define Cal_Step                    1       /* milliamps / volt / click */
#define Cal_Speed_Step              50      /* milliamps / volt / click */
#define Current_Limit_Step          100     /* milliamps per click */
#define Voltage_Step                10      /* millivolts per click */
#define Voltage_Setup_Step          10      /* Multiplier = millivolts per click */
#define VA_Step                     5       /* VA click */
#define Transformer_VA_Min          30      /* VA per rail*/
#define Transformer_VA_Max          500     /* VA Per Rail */
#define Transformer_VA_To_DCOUT_Scale 1.2   /* 20% as loss for VA -> V*I */
#define Offset_Step                 1       /* mV or mA */
#define Offset_Normal_Speed         1       /* 10mV per click */
#define Offset_Speed                2       /* 250mV per click */
#define Assumed_Efficiency          0.8     /* 80% efficiency */
#define Voltage_Filter_Coeff        0.2     /* Filter measurements */
#define Current_Filter_Coeff        0.03     /* Filter measurements */
#define V_Bound_mV                  100     /* use this to sense voltage out of bounds */
#define V_Bound_Percent             5       /* use this to sense voltage out of bounds */
#define I_Bound                     90      /* percent... warn for current close / at limit */

/******************************************************************************/
// Display Graph Constants
/******************************************************************************/
#define Display_Origin_X    18 /* runs from 18 to 128 */
#define Display_Origin_Y    54 /* Runs 54 down to 0 */
#define Display_Scale_X     4  /* seconds per pixel */
#define Display_Scale_Y     5  /* degrees per pixel */

/******************************************************************************/
// Values and limits for the application  
// THESE WILL BE IN DEGREES CELSIUS FOR TEMP     
// THESE WILL BE IN SECONDS FOR TIME     
/******************************************************************************/    


/* Approx EEPROM write delay in mS */
#define EEPROM_WR_Delay             10   
/*****************************************************************************/
// EEPROM Hardware Related Definitions
/*****************************************************************************/
#define CselEEPROM DelayUs(1); SYS_PORTS_Set(PORTS_ID_0, APP_EEPROM_PORT, EEPROM_Select, EEPROM_Select); DelayUs(1);
#define CselClearEEPROM DelayUs(1); SYS_PORTS_Clear(PORTS_ID_0, APP_EEPROM_PORT, EEPROM_Select, EEPROM_Select); DelayUs(1);
#define HoldClearEEPROM DelayUs(1); SYS_PORTS_Set(PORTS_ID_0, APP_EEPROM_PORT, EEPROM_Hold, EEPROM_Hold); DelayUs(1);
#define HoldEEPROM DelayUs(1); SYS_PORTS_Clear(PORTS_ID_0, APP_EEPROM_PORT, EEPROM_Hold, EEPROM_Hold); DelayUs(1);
#define EEPROM_INIT_DELAY 10
#define EEPROM_Sel_Delay 2
    
/******************************************************************************/
/* Deal with SPI Write for Harmony which does not include a blocking write    */
/******************************************************************************/
#define PLIB_SPI_WRITE_C(_CHOSEN_SPI_Port, _CHOSEN_WREN) PLIB_SPI_BufferWrite(_CHOSEN_SPI_Port, _CHOSEN_WREN); while (!PLIB_SPI_ReceiverBufferIsFull(_CHOSEN_SPI_Port))


/******************************************************************************/
/*    PSU ADC and DAC Specific stuff                                          */
/******************************************************************************/
#define  PSU_CH1_DAC_ChipSelect_Assert SYS_PORTS_Clear(PORTS_ID_0, APP_PSU_PORT, CS_DAC1)
#define PSU_CH1_DAC_ChipSelect_DeAssert SYS_PORTS_Set(PORTS_ID_0, APP_PSU_PORT, CS_DAC1, CS_DAC1)
#define  PSU_CH2_DAC_ChipSelect_Assert SYS_PORTS_Clear(PORTS_ID_0, APP_PSU_PORT, CS_DAC2)
#define PSU_CH2_DAC_ChipSelect_DeAssert SYS_PORTS_Set(PORTS_ID_0, APP_PSU_PORT, CS_DAC2, CS_DAC2)
#define  PSU_CH1_ADC_ChipSelect_Assert SYS_PORTS_Clear(PORTS_ID_0, APP_PSU_ADC1_PORT,  CS_ADC1)
#define PSU_CH1_ADC_ChipSelect_DeAssert SYS_PORTS_Set(PORTS_ID_0, APP_PSU_ADC1_PORT, CS_ADC1, CS_ADC1)
#define  PSU_CH2_ADC_ChipSelect_Assert SYS_PORTS_Clear(PORTS_ID_0, APP_PSU_PORT,  CS_ADC2)
#define PSU_CH2_ADC_ChipSelect_DeAssert SYS_PORTS_Set(PORTS_ID_0, APP_PSU_PORT, CS_ADC2, CS_ADC2)
#define PSU_Ch_1 1
#define PSU_Ch_2 2
#define DAC_Voltage_Channel 0
#define DAC_Current_Channel 1
#define ADC_Voltage_Channel 0
#define ADC_Current_Channel 1
#define DAC_Tcsl 10      //minimum CS Low time before write (spec 40ns))
#define DAC_Tcsh 10      //minimum CS High time after write (Spec 15ns))


/***********************************************************************/
/* SPI DAC Stuff                                                       */
/* DAC target is MCP4922                                               */
/* LDAC is tied low, output is at CSEL going high                      */
/* /SHDN is tied high so this input is not used                        */
/* CSEL must go low first                                              */
/* The DAC expects 16 bits in a transaction                            */
/* Four config bits then 12 bits of data MSB first                     */
/***********************************************************************/
/* CS is active low                                                    */
#define DAC_CSel 0x0
#define DAC_NCSel 0x1
#define DAC_BitMask 0x00000FFF
/* CMD1 = four config bits followed by the 4MSB                        */
/* Bit 7 = DAC channel: 1 DAC B                                        */
/*                      0 DAC A                                        */
/* Bit 6 = Buffered Vref 1 = buffered                                  */
/* Bit 5 = GAin: 1 = Vout x1                                           */
/*               0 = Vref x2                                           */
/* Bit 4 = SHDN_L: 1 = output enabled                                 */
/*                  0 = output disabled                                 */
#define DAC1_Write_CMD 0x70
#define DAC2_Write_CMD 0xf0
/* Add 4 MSB of output to this word and then write LSB as second byte  */
/***********************************************************************/


/***********************************************************************/
/* SPI ADC Stuff                                                       */
/* ADC target is MCP3202                                               */
/* ADC_Read_CMD1 is an 8 bit word sent at the start of the transaction */
/* This along with ADC_Read_CMD2 and 3 send the following to the ADC   */
/* Read in the three bytes as each of he three CMD words are written   */
/* Ignore the first, and mask off the bottom 12 bits of the 2nd and 3rd*/
/***********************************************************************/
/* CMD1 = Seven zeroes than a high bit                                 */
/* The final 1 = START     The ADC ignores all zeroes                  */
#define ADC_Read_CMD1 0x01
/* CMD2 = 1?1X XXX or 0xA0  or 0xE0                                    */
/*     SGL = 1, single ended                                           */
/*     ODD = 0 reads channel 0                                         */
/*     ODD = 1 reads channel 1                                         */
#define ADC_Read_CMD2_CH0 0xA0   //A0
#define ADC_Read_CMD2_CH1 0xE0   //E0 
/* CMD3 = 0xXX                                                         */
#define ADC_Read_CMD3 0x00
/* CS is active low                                                    */
#define ADC_CSel 0x0
#define ADC_NCSel 0x1
#define ADC_Tsucs 10     //minimum CS Low time before write (spec 100ns))
#define ADC_Tcsh 10      //minimum CS High time after write (Spec 500ns))
#define ADC_Tsample 200 //minimum time for read after start = 1.5 clock cycles
#define ADC_Top_Bitmask 0x0f



/* more stuff Use this bitfield to watch what buttons are happening... */
#define HMI_Port SYS_PORTS_Read( PORTS_ID_0, APP_UI_PORT )
#define Encoder_Definition_Port SYS_PORTS_Read( PORTS_ID_0, ENC_DEF_PORT )
#define  Exit (unsigned char) 2         // bit 1 of port E
#define  Sel (unsigned char)  4         // bit 2 of port E
#define  Vals_0 (unsigned char) 8       // bit 3 of port E
#define  Vals_1 (unsigned char) 16      // bit 4 of port E
#define  Vals_0_RE2 (unsigned char) 32  // bit 5 of port E
#define  Vals_1_RE2 (unsigned char) 64  // bit 6 of port E
#define  Shutdown_Sw (unsigned char) 128// bit 7 of port E

/***************************************************/
//  User interface behaviour control
// These define how long before increments on the rotary encoder go from
// "slow increments" to fast increments
// then how lond before "fast" reverts to "slow" again
/***************************************************/
#define Speed_Init     1
#define Auto_Revert_Init_Val 400000
#define Key_Press_Delay_Us 150
#define Slow_Counter_Init 50000
#define Fast_Counter_Init 7
    
/***************************************************/
/* Behaviour of the Rotary Encoder                 */
/***************************************************/
/*    ENCODER One                                  */
/***************************************************/
#define Phase_0 (unsigned char) 0
#define Phase_1 Vals_0
#define Phase_2 Vals_0 + Vals_1
#define Phase_3 Vals_1
#define Rot_Up Vals_1
#define Rot_Down Vals_0 + Vals_1
/***************************************************/
/*    ENCODER Two                                  */
/***************************************************/
#define Phase_0_RE2 (unsigned char) 0
#define Phase_1_RE2 Vals_0_RE2
#define Phase_2_RE2 Vals_0_RE2 + Vals_1_RE2
#define Phase_3_RE2 Vals_1_RE2
#define Rot_Up_RE2 Vals_1_RE2
#define Rot_Down_RE2 Vals_0_RE2 + Vals_1_RE2


/* Old Rotary Encoder = 00XXXXXX*/
#define Encoder_Type_Is_Old (!(SYS_PORTS_Read( PORTS_ID_0, APP_ENCODER_TYPE_PORT ) & (Type_A_Rotary_Encoder )))
/* Type A rotary Encoder = 10XXXXXX*/
#define Encoder_Type_Is_TypeA (SYS_PORTS_Read( PORTS_ID_0, APP_ENCODER_TYPE_PORT ) & (Type_A_Rotary_Encoder + Type_B_Rotary_Encoder))
/* Type B Rotary Encoder = 01XXXXXX*/
#define Encoder_Type_Is_TypeB (SYS_PORTS_Read( PORTS_ID_0, APP_ENCODER_TYPE_PORT ) & Type_B_Rotary_Encoder)
#define Drive_PortE_Out SYS_PORTS_Set(PORTS_ID_0, APP_UI_PORT, APP_UI_PORT_DRIVE, APP_UI_PORT_DRIVE)

/***************************************************/
//  User input
/***************************************************/
#define Up_Keys (Keypress_Read == Vals_1)
#define Down_Keys (Keypress_Read == (Vals_0 + Vals_1))
#define Sel_Key (Keypress_Read == Sel)
#define Exit_Key (Keypress_Read == Exit)

    
// *****************************************************************************
// *****************************************************************************
/* Application states
  Summary:
   he first set are Application states enumeration
  Description:
    This enumeration defines the valid application states.  These states
    determine the behavior of the application at various times.
*/
// *****************************************************************************
// *****************************************************************************
typedef enum
{
	/* Application's state machine's initial state. */
	WELLER_STATE_INIT=0,
	WELLER_STATE_LCDINIT,
    WELLER_STATE_SLOW_START,
	WELLER_STATE_IDLE,
	WELLER_STATE_SETV,
	WELLER_STATE_SETI,            
    WELLER_STATE_SETUP,
    WELLER_STATE_TRACKING,
    WELLER_STATE_POWER_SETTINGS,
    WELLER_STATE_POWER_NUM_OUTPUTS,
    WELLER_STATE_POWER_MAX_CURRENT,
    WELLER_STATE_POWER_MAXIMUM_V,
    WELLER_STATE_POWER_TRANSFORMER_VA,
    WELLER_STATE_CAL_V1_OUTPUT_OFFSET,
    WELLER_STATE_CAL_V1_READ_SCALE,
    WELLER_STATE_CAL_V1_SET_SCALE,
    WELLER_STATE_CAL_I1_OFFSET,
    WELLER_STATE_CAL_I1_SCALE,
    WELLER_STATE_CAL_V2_OUTPUT_OFFSET,
    WELLER_STATE_CAL_V2_READ_SCALE,
    WELLER_STATE_CAL_V2_SET_SCALE,
    WELLER_STATE_CAL_I2_OFFSET,
    WELLER_STATE_CAL_I2_SCALE,
	WELLER_STATE_SERVICE_TASKS,
    WELLER_STATE_CAL_CHANGE
} WELLER_STATES;


typedef enum
{
	/* Application's state machine's initial state. */
	WELLER_ACTION_INIT=0,
	WELLER_ACTION_V1,
    WELLER_ACTION_I1,
    WELLER_ACTION_V2,
    WELLER_ACTION_I2,
    WELLER_ACTION_TRACKING,
    WELLER_ACTION_POWER,
    WELLER_ACTION_POWER_CHANGE,
    WELLER_ACTION_POWER_SINGLE_DUAL,
    WELLER_ACTION_POWER_TX_V,
    WELLER_ACTION_POWER_TX_VA,
    WELLER_ACTION_CAL,
    WELLER_ACTION_CAL_V1_OFFSET,
    WELLER_ACTION_CAL_V1_SCALE,
    WELLER_ACTION_CAL_I1_OFFSET,
    WELLER_ACTION_CAL_I1_SCALE,
    WELLER_ACTION_CAL_V2_OFFSET,
    WELLER_ACTION_CAL_V2_SCALE,
    WELLER_ACTION_CAL_I2_OFFSET,
    WELLER_ACTION_CAL_I2_SCALE,
    WELLER_ACTION_YES,
    WELLER_ACTION_NO
            
	/* TODO: Define states used by the application state machine. */
} WELLER_ACTIONS;


/*****************************************************************************/
/*****************************************************************************/
/*                     DISPLAY RELATED DATA                                  */
/*****************************************************************************/
/*****************************************************************************/
/* Display Strings */
#define UI_DIV 2500    // divider for UI ISR to display update
#define Update_UI_Timer (wellerData.UI_Update_Counter > UI_DIV)
#define Reset_UI_Timer wellerData.UI_Update_Counter = 0
#define Blank_Char_Init 	0x20
#define Line1_Init      	"Intelligent PSU "
#define Line2_Init          "   V1.5 2021    "
#define ClearScreen  GLCD_ClearScreen_buff(ScreenBuff);  Buffer_Refresh(ScreenBuff, 0, 0, 128, 64);
#define APP_LCD_DATA_LOC 0xFF00 
#define UI_Temp_Meas_Update_Threshold Temp_Scale
// Graphics Macros
#define Refresh_LCD GLCD_WriteBuf(ScreenBuff, 0, 0, KS0108_SCREEN_WIDTH, KS0108_SCREEN_HEIGHT);
#define UI_BootClr_X1   0
#define UI_BootClr_Y1   0 
#define UI_BootClr_X2   128
#define UI_BootClr_Y2   64
#define UI_BootVer_X    0
#define UI_BootVer_Y    13 
#define UI_BootMod_X    0
#define UI_BootMod_Y    35
#define UI_Idle_CH1x    70
#define UI_Idle_CH1x_Single    77
#define UI_Idle_CH2x    70
#define UI_Idle_Set_Meas_x 54
#define UI_Idle_Parms_x 88
#define UI_Idle_V1Measy  19
#define UI_Idle_V1_Single_Measy  21
#define UI_Idle_V2Measy  30
#define UI_Idle_I1Measy  42
#define UI_Idle_I1_Single_Measy  47
#define UI_Idle_I2Measy  55
#define UI_Idle_I1setx  0
#define UI_Idle_I2setx  0
#define UI_Idle_V1setx  0
#define UI_Idle_V2setx  0
#define Tracking_L1x    0
#define Tracking_L1y    0
#define Tracking_L2y    14
#define Tracking_L3y    28
#define Tracking_L4y    42
#define Tracking_L5y    55
#define SU_Tracking_L1x  8
#define SU_Tracking_L1y  53


// *****************************************************************************
// *****************************************************************************
/* Application Data

  Summary:
    Holds application data

  Description:
    This structure holds the application's data.

  Remarks:
    Application strings and buffers are be defined outside this structure.
 */
// *****************************************************************************
// *****************************************************************************

typedef struct
{
    /* The application's current state */
    WELLER_STATES       state;                 /* UI driver timer handle. */
    DRV_HANDLE          UI_Timer;               /* UI timer timeout count. */
    int                 UI_Count;               /* UI fast count. */
    int                 UI_Fast_Count;          /* UI slow count. */
    int                 UI_Slow_Count;          /* UI update count. */
    int                 UI_Update_Counter;      /* UI speed - change rate per click. */
    unsigned int        UI_Speed;               /* UI needs update */
    bool                UI_Update_Display;      /* UI needs update */
    bool                UI_Display_Lockout;     /* Flag to say a key has been pressed */
    bool                UI_Keypressed;          /* UI action */
    bool                UI_Keypressed_RE2;          /* UI action */
    WELLER_ACTIONS      UI_Action;              /* Heartbeat driver timer handle. */
    int                 V1;                     /* Channel 1 set voltage in mV */
    int                 I1;                     /* Channel 1 set current in mA */
    int                 V2;                     /* Channel 2 set voltage in mV */
    int                 I2;                     /* Channel 2 set current in mA */
    int                 Vout_Scale;             /* Channel 1 set voltage in uV per bit */
    int                 Iout_Scale;             /* Channel 1 set current in uA per bit */
    int                 Vmeas_Scale;            /* Channel 1 set voltage in mV */
    int                 Imeas_Scale;            /* Channel 1 set current in mA */
    int                 V1_Meas;                /* Channel 1 set voltage in mV */
    int                 I1_Meas;                /* Channel 1 set current in mA */
    int                 V2_Meas;                /* Channel 2 set voltage in mV */
    int                 I2_Meas;                /* Channel 2 set current in mA */
    int                 V_Max;                  /* Maximum voltage derived from transformer voltage spec*/
    int                 I_Max;                  /* Maximum Current derived from transformer voltage spec & Vout*/
    bool                Tracking;               /* if Tracking then V1 = V2 and I1 = I2 */
    int                 Num_Rails;              /* number of power rails, 1 or 2*/
    int                 Transformer_VA;         /* Transformer Power Rating per rail VA*/
    int                 V1_Offset;              /* mV offset when output set to zero */
    int                 V2_Offset;              /* mV offset when output set to zero */
    int                 V1_Output_Cal;          /* Voltage 1 Cal Correction */
    int                 V2_Output_Cal;          /* Voltage 2 Cal Correction */
    int                 V1_Read_Cal;            /* Voltage 1 Cal Correction */
    int                 V2_Read_Cal;            /* Voltage 2 Cal Correction */
    int                 I1_Offset;              /* mA offset ADC I1 read */
    int                 I2_Offset;              /* mA offset ADC I2 read */
    int                 I1_Cal;                 /* Current 1 Cal correction */
    int                 I2_Cal;                 /* Current 2 Cal correction */
    DRV_HANDLE          heartbeatTimer;         /* Heartbeat timer timeout count. */
    unsigned int        heartbeatCount;         /* Heartbeat LED toggle flag. */
    bool                heartbeatToggle;
    unsigned int        MemoryBankSelected;
    /* Counter for Revert to Idle */
    int                 Revert_To_Idle_Counter;
    bool                Update_Outputs;         /* something has changed and we want to set outputs */
    bool                Shutdown_Output;        /* user commanded output shutdown */
    bool                V1_Error;               /* Use as flag for voltage error (out of bounds)*/
    bool                V2_Error;               /* Use as flag for voltage error (out of bounds) */
    bool                I1_Error;               /* Use as flag for current error (limit) */
    bool                I2_Error;               /* Use as flag for current error (limit) */
    
 
} WELLER_DATA;

/**************************************************************************/
// It would be perfectly reasonable to absorb this into WELLER_DATA
/**************************************************************************/

/* Can't believe I have to define this!!! */
#define Pi (double) 3.141592653590
#define sqrt2 (double) 1.414213562373
#define SpeedOfSound 341210   /* millimetres per second */


// *****************************************************************************
// *****************************************************************************
// Section: Application Implementation Specific Definitions
// *****************************************************************************
// *****************************************************************************
/*** Application Defined Pins ***/
// TIMER STUFF
#define APP_HEARTBEAT_TMR DRV_TMR_INDEX_0
#define APP_HEARTBEAT_TMR_IS_PERIODIC true
#define APP_HEARTBEAT_TMR_PERIOD 0x1000      //was 0x49a6
#define APP_HEARTBEAT_COUNT_MAX 6



// LCD PORT STUFF
#ifdef PIC32MX_PCB
#define APP_LCD_PORT_CS0 PORT_CHANNEL_D
#define APP_LCD_PORT_CS1 PORT_CHANNEL_B
#define APP_LCD_PORT_RESET PORT_CHANNEL_B
#define APP_LCD_PORT_RW PORT_CHANNEL_D
#define APP_LCD_PORT_RS PORT_CHANNEL_D
#define APP_LCD_PORT_ENABLE PORT_CHANNEL_B
#define ADAU_SPI_Port SPI_ID_1           // EEPROM on SPI 1
#define EEPROM_SPI_Port SPI_ID_1       
#endif

#ifdef PIC32MZ_PCB
#define APP_DSP_RESET_L_PORT PORT_CHANNEL_B
#define APP_DSP_RESET_L_MASK 0x08
#define DSP_SET_RESET   SYS_PORTS_Clear(PORTS_ID_0, APP_DSP_RESET_L_PORT, APP_DSP_RESET_L_MASK)
#define DSP_CLEAR_RESET SYS_PORTS_Set(PORTS_ID_0,   APP_DSP_RESET_L_PORT, APP_DSP_RESET_L_MASK, APP_DSP_RESET_L_MASK)

#define APP_LCD_PORT_CS0 PORT_CHANNEL_B
#define APP_LCD_PORT_CS1 PORT_CHANNEL_B
#define APP_LCD_PORT_RESET PORT_CHANNEL_F
#define APP_LCD_PORT_RW PORT_CHANNEL_D
#define APP_LCD_PORT_RS PORT_CHANNEL_B
#define APP_LCD_PORT_ENABLE PORT_CHANNEL_F
#define EEPROM_SPI_Port  SPI_ID_2  // EEPROM SPI port
#endif


#define APP_LCD_PORT_DATA PORT_CHANNEL_B




// *****************************************************************************
// *****************************************************************************
// Section: Application Callback Routines
// *****************************************************************************
// *****************************************************************************
/* These routines are called by drivers when certain events occur.
*/
	
// *****************************************************************************
// *****************************************************************************
// Section: Application Initialization and State Machine Functions
// *****************************************************************************
// *****************************************************************************

/*******************************************************************************
  Function:
    void WELLER_Initialize ( void )

  Summary:
     MPLAB Harmony application initialization routine.

  Description:
    This function initializes the Harmony application.  It places the 
    application in its initial state and prepares it to run so that its 
    APP_Tasks function can be called.

  Precondition:
    All other system initialization routines should be called before calling
    this routine (in "SYS_Initialize").

  Parameters:
    None.

  Returns:
    None.

  Example:
    <code>
    WELLER_Initialize();
    </code>

  Remarks:
    This routine must be called from the SYS_Initialize function.
*/

void WELLER_Initialize ( void );


/*******************************************************************************
  Function:
    void WELLER_Tasks ( void )

  Summary:
    MPLAB Harmony Demo application tasks function

  Description:
    This routine is the Harmony Demo application's tasks function.  It
    defines the application's state machine and core logic.

  Precondition:
    The system and application initialization ("SYS_Initialize") should be
    called before calling this.

  Parameters:
    None.

  Returns:
    None.

  Example:
    <code>
    WELLER_Tasks();
    </code>

  Remarks:
    This routine must be called from SYS_Tasks() routine.
 */

void WELLER_Tasks( void );


#endif /* _WELLER_H */

//DOM-IGNORE-BEGIN
#ifdef __cplusplus
}
#endif
//DOM-IGNORE-END

/*******************************************************************************
 End of File
 */

void Idle_Screen(void);

void Update_Temp_Meas(int);

void WELLER_EEPROM_Initialize(void);
