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

  Company:
    Microchip Technology Inc.

  File Name:
    control.h

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

  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.
*******************************************************************************/


/* use this to determine pinouts between PIC32MX and PIC32MZ boards*/
//#define PIC32MX_PCB 1
#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
#define Chan_1_Port_RW SPI1BUF 
#define Chan_2_Port_RW SPI4BUF 
    
// *****************************************************************************
// *****************************************************************************
// Section: Type Definitions
// Port B
// *****************************************************************************
// *****************************************************************************
/*         Implementation specific Definitions                                */
/* RB2  = Iron Control - Active High output */
#define WELLER_HEAT_ON 2

#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
/* RB4 = LCD_RS (output)*/
#define KS0108_LCD_RS 16
/* RB5  = LCD Chip Select 1 (output) */
#define KS0108_LCD_CS1 32
/* RB5  = LCD Chip Select 2 (output) */
#define KS0108_LCD_CS0 64
#endif


/* RB6 - ADC_0 (input)*/
#define PGA2320_Select 64
/* RB7 - ADC_1 (input)*/
#define WELLER_Temp_ADC 7
    
 /****************************************************************************/   
 // 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
   
    
// *****************************************************************************
// Port D
// you really do have the full set of ways of defining the bit masks for each 
//     port!  Tidy this up sometime!
// *****************************************************************************
/* RD0 SPARE */
/* RD1 = SPI_CS1*/
#define ADAU_CSel_Bit 0x002
/* RD2 = SPI_SCK1*/
/* RD3 = SPI_SDI1 = "0000" = input*/
#define SDI_Out 16
/* RD4 = SDI_SDO1 = "1000"*/
/* RD5 = LCD_RW (output)*/
#define KS0108_LCD_RW 32

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

/* RD8 = DSP_RESET*/
#define Reset_DSP       0x0100   /* Bit 8 of port D */
/* RD9 = SPI_SS1 - "0111"*/
/* RD10 = RESET_DAC*/
#define Reset_DAC 	0x0400   /* bit 10 of port D */
/* RD11 = UNUSED (output)*/

// *****************************************************************************
// Port E
// This is where the buttons live as the user interface    
// *****************************************************************************
/* RE0 = VDD Drive for UI*/
/* RE1 = MODE_SEL (input)*/
/* RE2 = FN_SEL (input)*/
/* RE3 = PHASEA (input)*/
/* RE4 = PHASEB (input)*/
/* RE5 = SPARE*/
/* RE6 - Rotary_Encoder_Select_0 (input)*/
#define Rotary_Encoder_Select_0 64
/* RE7 - Rotary_Encoder_Select_1 (input)*/
#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
/*****************************************************************************/
/* 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 0x0040
#define Port_E_Button_Pressed   (2+4+8+16)

    
    
// *****************************************************************************
// 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 0x0004

// 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 ADAU_SPI_Port SPI_ID_2           // EEPROM on SPI 2
#define EEPROM_SPI_Port  SPI_ID_2  // EEPROM SPI port
#define I2S_CH1 SPI_ID_1
#define I2S_CH2 SPI_ID_4
#define I2S_BAUD_RATE 3150000
#define I2S_CLOCK 12600000
#define I2S_CH1_INT  INT_VECTOR_SPI1
#define I2S_DummyDat 0x00000000
#define Sample_Rate 49218  //this is 12600000/64/4
#endif


#define APP_LCD_PORT_DATA PORT_CHANNEL_B

// ADAU PORT STUFF
#define ADAU_CSEL_PORT PORT_CHANNEL_D
#define More_Than_1_Audio_Frame_uS  100
#define ADAU_RESET_PORT PORT_CHANNEL_D
#define PGA2320_PORT PORT_CHANNEL_B

    // DAC PORT STUFF
#define DAC_RESET_PORT PORT_CHANNEL_D

// USER INTERFACE PORT STUFF
#define APP_UI_PORT PORT_CHANNEL_E
#define APP_UI_PORT_DRIVE 0x0001
#define APP_ENCODER_TYPE_PORT PORT_CHANNEL_E
#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)

/*****************************************************************************/
/*
 * SPI1 Port (Audio i2S)
 * SCK1   - D1
 * SDI1   - D2
 * SDO1   - D3
 * SS1    - D9
 * 
 * SPI2 Port (Data)
 * SCK2   - G6
 * SDI2   - G7
 * SDO2   - G8
 * SS2    - G9
 * 
 * SPI 3 Port
 * 
 * SPI 4 Port  (Audio i2s)
 * SCK4   - D10
 * SDI4   - XXX
 * SDO4   - F3
 * SS4    - D4
 * 
 * /
/*****************************************************************************/


/******************************************************************************/
/*                              LCD 12864 pinouts...                          */
/*
ERM12864 (EGg)  Pin No  MCU Bit         MCU Bit     Comment
                        PIC32MX         PIC32MZ
GND             1       n/a                         Hard wired, no MCU i/F
+5V             2       n/a                         Hard wired, no MCU i/F
V0              3       n/a                         Hard wired, no MCU i/F
RS              4       RD6             RB4
R/W\            5       RD5             RD5
EN              6       RB4             RF5
D0              7       RB8             RB8
D1              8       RB9             RB9
D2              9       RB10            RB10
D3              10      RB11            RB11
D4              11      RB12            RB12
D5              12      RB13            RB13
D6              13      RB14            RB14
D7              14      RB15            RB15
CS0             15      RD7             RB5
CS1             16      RB5             RB6
RST             17      RB3             RF4
VEE             18      N/A                         Hard wired, no MCU i/F             
Anode           19      n/a                         Hard wired, no MCU i/F
Cathode         20      n/a                         Hard wired, no MCU i/F
 */
 /*****************************************************************************/   
    
    
/******************************************************************************/
// Values and limits for the application  
// THESE WILL BE IN DEGREES CELSIUS FOR TEMP     
// THESE WILL BE IN SECONDS FOR TIME     
/******************************************************************************/    
#define	Freq_Normal_Speed     1     /* Seems like a sensible number*/
#define Freq_Fast_Speed       10 
#define Snooze_Counts_PerSec  2
#define	Gain_Speed            5     /* Seems like a sensible number*/
#define	Gain_Normal_Speed     1     /* Seems like a sensible number*/
#define Gain_Step             1     /* seems reasonable*/     
#define	Atten_Step           1     /* Seems like a sensible number*/
#define	Atten_Normal_Speed   1     /* Seems like a sensible number*/
#define	Atten_Speed          5     /* lots of 0.5dB Seems like a sensible number*/
#define	Ratio_Step           1     /* Seems like a sensible number*/
#define	Ratio_Normal_Speed   1     /* Seems like a sensible number*/
#define	Ratio_Speed          5     /* lots of 0.5dB Seems like a sensible number*/
#define	Atten_Min            0     /* Seems like a sensible number*/
#define	Atten_Max            (128*10) /* tenth dB's Seems like a sensible number*/
#define Atten_Default        20 
#define	Revert_To_Idle       (16 * Snooze_Counts_PerSec)   /* Seems like a sensible number*/
#define Time_Fast            10
#define Time_Normal          1
#define Phase_Fast           10
#define Phase_Normal         1
#define Pulse_Fast           10
#define Pulse_Normal         1
#define AM_Fast              10
#define AM_Normal            1
#define FM_Fast              10
#define FM_Normal            1

    
/*****************************************************************************/
// 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

    /* more stuff Use this bitfield to watch what buttons are happening... */
#define HMI_Port SYS_PORTS_Read( PORTS_ID_0, APP_UI_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

/***************************************************/
//  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 debounce_time_us 3000
#define Speed_Init     1
#define Auto_Revert_Init_Val 1600000
#define Key_Press_Delay_Us 150
#define Slow_Counter_Init 150000
#define Fast_Counter_Init 10
#define Delay_After_Save_Ms    500
    

/******************************************************************************/
/* 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))


/***************************************************/
/* Behaviour of the Rotary Encoder                 */
/***************************************************/
#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
/* Old Rotary Encoder = 00XXXXXX*/
#define Encoder_Type_Is_Old (!(SYS_PORTS_Read( PORTS_ID_0, APP_ENCODER_TYPE_PORT ) & (Type_A_Rotary_Encoder + Type_B_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 = 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. */
	CS_INIT=0,
	CS_LCDINIT,
	CS_ATTEN,
	CS_SERVICE_TASKS,
    CS_SAVE,
	CS_LOAD,
    CS_FREQUENCY,
    CS_FREQ_SPEED,
    CS_CHOOSE,
    CS_LEVEL,
    CS_WAVEFORM,
    CS_RATIO,
    CS_SWEEP,
    CS_SWEEP_END,
    CS_SWEEP_TIME,
    CS_PULSE_ON,
    CS_PULSE_CYCLES_ON,
    CS_PULSE_CYCLES_OFF,
    CS_PHASE,
    CS_AM_ON,
    CS_AM_LEVEL,
    CS_AM_FREQ,
    CS_FM_ON,
    CS_FM_EXCURSION,
    CS_FM_FREQ,
} CONTROL_STATES;

typedef enum
{
	/* EQ Types. */
	Sine        = 666,
    Triangle    = 667,
    Square      = 668,
    Pulse       = 669,
    Noise       = 670
} WAVEFORM_TYPES;

typedef enum
{
	/* Application's state machine's initial state. */
	CONTROL_ACTION_INIT=0,
    CONTROL_ACTION_SLEEP,
    CONTROL_ACTION_LOAD,
    CONTROL_ACTION_SAVE,
    CONTROL_ACTION_CH1,
    CONTROL_ACTION_CH2,
    CONTROL_ACTION_YES,
    CONTROL_ACTION_NO,
         
	/* TODO: Define states used by the application state machine. */
} CONTROL_ACTIONS;


//****************************************************************************//
/* This lot are state machine dat for the user interface                      */
//****************************************************************************//


/*****************************************************************************/
/*****************************************************************************/
/*                     DISPLAY RELATED DATA                                  */
/*****************************************************************************/
/*****************************************************************************/
/* Display Strings */
#define UI_DIV 2500    // divider for UI ISR to display update
#define Update_UI_Timer (controlData.UI_Update_Counter > UI_DIV)
#define Reset_UI_Timer controlData.UI_Update_Counter = 0
#define Increment_UI_Timer  if (controlData.UI_Update_Counter <= UI_DIV) controlData.UI_Update_Counter++;
#define Blank_Char_Init 	0x20
#define Line1_Init      	"     TGM DDS    "
#define Line2_Init          "DDS V3 22 Jun 19"
#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 256
// Graphics Macros
#define Refresh_LCD GLCD_WriteBuf(ScreenBuff, 0, 0, KS0108_SCREEN_WIDTH, KS0108_SCREEN_HEIGHT);
#define UI_Vol_X 28
#define UI_Vol_Y 48
#define UI_VOLBAR_XMIN 28
#define UI_VOLBAR_XMAX 125
#define UI_VOLBAR_YMIN 29
#define UI_VOLBAR_YMAX 44
#define UI_Meas_X 54
#define UI_Meas_Y 48
#define UI_BootClr_X1 0
#define UI_BootClr_Y1 26 
#define UI_BootClr_X2 128
#define UI_BootClr_Y2 64
#define UI_BootVer_X 0
#define UI_BootVer_Y 26 
#define UI_BootMod_X 0
#define UI_BootMod_Y 48
#define Saved_X      58
#define Saved_Y      48
#define Save_L1x      78
#define Save_L1y      24
#define Load_L1x      15
#define Load_L1y      24
#define Splash_L1x     0
#define Splash_L1y     0

#define Temp_X1         0
#define Temp_Y1         0
#define Temp_X2         0
#define Temp_Y2         16
#define Temp_X3         0
#define Temp_Y3         32

#define Channel_X1         0
#define Channel_Y1         0
#define Channel_X2         0
#define Channel_Y2         16
#define Channel_X3         0
#define Channel_Y3         32

#define Freq_X1         53
#define Freq_Y1         0
#define Freq_X2         0
#define Freq_Y2         52
#define Freq_X3         0
#define Freq_Y3         39

#define Freq_Speed_X1         53
#define Freq_Speed_Y1         0
#define Freq_Speed_X2         0
#define Freq_Speed_Y2         52
#define Freq_Speed_X3         0
#define Freq_Speed_Y3         39

#define Waveform_X1         0
#define Waveform_Y1         0
#define Waveform_X2         0
#define Waveform_Y2         52
#define Waveform_X3         0
#define Waveform_Y3         39

#define Level_X1         0
#define Level_Y1         4
#define Level_X2         0
#define Level_Y2         49
#define Level_X3         0
#define Level_Y3         32

#define Ratio_X1         54
#define Ratio_Y1         0
#define Ratio_X2         0
#define Ratio_Y2         52
#define Ratio_X3         0
#define Ratio_Y3         39
#define Pixels_per_Percent 2
#define Ratio_X_Zero    2
#define Ratio_y_Zero    19
#define Ratio_Fullwave  50
#define Ratio_Height    16

#define Sweep_On_X1         0
#define Sweep_On_Y1         0
#define Sweep_On_X2         0
#define Sweep_On_Y2         52
#define Sweep_On_X3         74
#define Sweep_On_Y3         25
#define Sweep_On_X4         74
#define Sweep_On_Y4         39

#define Sweep_End_X1         0
#define Sweep_End_Y1         0
#define Sweep_End_X2         0
#define Sweep_End_Y2         52
#define Sweep_End_X3         74
#define Sweep_End_Y3         25
#define Sweep_End_X4         74
#define Sweep_End_Y4         39

#define Sweep_Time_X1         0
#define Sweep_Time_Y1         0
#define Sweep_Time_X2         0
#define Sweep_Time_Y2         52
#define Sweep_Time_X3         74
#define Sweep_Time_Y3         25
#define Sweep_Time_X4         74
#define Sweep_Time_Y4         39

#define Pulse_On_X1         53
#define Pulse_On_Y1         0
#define Pulse_On_X2         0
#define Pulse_On_Y2         52
#define Pulse_On_X3         75
#define Pulse_On_Y3         25
#define Pulse_On_X4         75
#define Pulse_On_Y4         39

#define Pulse_Cycles_On_X1         0
#define Pulse_Cycles_On_Y1         0
#define Pulse_Cycles_On_X2         0
#define Pulse_Cycles_On_Y2         16
#define Pulse_Cycles_On_X3         0
#define Pulse_Cycles_On_Y3         32

#define Phase_X1         0
#define Phase_Y1         0
#define Phase_X2         0
#define Phase_Y2         52
#define Phase_X3         93
#define Phase_Y3         25
#define Phase_X4         93
#define Phase_Y4         39

#define AM_On_X1         0
#define AM_On_Y1         0
#define AM_On_X2         0
#define AM_On_Y2         52
#define AM_On_X3         86
#define AM_On_Y3         25
#define AM_On_X4         86
#define AM_On_Y4         39


#define FM_On_X1         0
#define FM_On_Y1         0
#define FM_On_X2         0
#define FM_On_Y2         52
#define FM_On_X3         91
#define FM_On_Y3         25
#define FM_On_X4         91
#define FM_On_Y4         39


#define HardCode_Ch1    0
#define HardCode_Ch2    1

#define Input_Msg_X    0
#define Input_Msg_Y    0

#define L_Graphic_x    0
#define L_Graphic_y    0
#define M_Graphic_x    42
#define M_Graphic_y    0
#define R_Graphic_x    84
#define R_Graphic_y    0
#define R_Double_Graphic_x    63
#define R_Double_Graphic_y    0

#define Q1_Graphic_x    0
#define Q1_Graphic_y    0
#define Q4_Graphic_x    0
#define Q4_Graphic_y    32
#define Q2_Graphic_x    64
#define Q2_Graphic_y    0
#define Q3_Graphic_x    64
#define Q3_Graphic_y    32
#define Snooze_Line1_x    0
#define Snooze_Line1_y    40
#define Snooze_Bar_Max KS0108_SCREEN_WIDTH
#define Snooze_Bar_Row KS0108_SCREEN_HEIGHT

// *****************************************************************************
// *****************************************************************************
/* 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.
 */
// *****************************************************************************
// *****************************************************************************

/**************************************************************************/
// 
// Crossover Data Structures
// 
/**************************************************************************/

typedef struct{
		int Freq;      /*tenths of a Hz */
        int Freq_Speed;
        int Atten;   /* in half dB steps */
        WAVEFORM_TYPES Waveform;
        int Ratio;
        int Sweep_On;
        int Sweep_End;     /* tenths of a Hz*/
        int Sweep_Time;    /* tenths of a sec */
        int Pulse_On;
        int Pulse_Cycles_On;
        int Pulse_Cycles_Off;
        int Phase_Shift;
        int AM_On;
        int AM_Level;
        int AM_Freq;
        int FM_On;
        int FM_Excursion;
        int FM_Freq;
}  data_val_struct ;


typedef struct
{
    /* The application's current state */
    CONTROL_STATES      state;
    /* UI driver timer handle. */
    DRV_HANDLE          UI_Timer;
    /* UI driver SPI handle. */
    DRV_HANDLE          SPI1_handle;
    /* UI driver I2S handle. */
    DRV_HANDLE          SPI2_handle;    
    /* UI driver I2S handle. */
    DRV_HANDLE          SPI3_handle;    
    /* UI timer timeout count. */
    int                 UI_Count;
    /* UI fast count. */
    int                 UI_Fast_Count;
    /* UI slow count. */
    int                 UI_Slow_Count;
    /* UI update count. */
    unsigned int        UI_Update_Counter;
    /* UI speed - change rate per click. */
    unsigned int        UI_Speed;
    /* Freq speed - change rate per click. */
    unsigned int        Freq_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 */
    CONTROL_ACTIONS      UI_Action;
    /* Heartbeat driver timer handle. */
    DRV_HANDLE          heartbeatTimer;
    /* Heartbeat timer timeout count. */
    unsigned int        heartbeatCount;
    /* Heartbeat LED toggle flag. */
    bool                heartbeatToggle;
    int                 MemoryBankSelected;
     /* Counter for Revert to Idle */
    int                 Revert_To_Idle_Counter;
    /* Used to hold Temp value if changing */
    int                 Atten_Set_Backup;
    /* Data Values for XO*/
    data_val_struct     Data_Values[4];
    /* Channel to update data for */
    int                 DDS_Channel;
     
} CONTROL_DATA;

/***************************************/
/* This is a bit of a hangover from the 
 * previous implementation needs tidy up*/
/* Stuff to allow modes to be tracked
Use these to control the state machine */
/***************************************/
/* note IIR Scaling needs to leave enough "integer bits" in the 32 bit word*/
/* to accomodate te larger of filter gain (10 time for 20dB gain) and 1/Q*/
#define IIR_Scaling  67108864  /*2^26*/
#define DAC_Output_Max 8388607 /* 2^23 - 1*/
#define DAC_Valid_BitMask 0xFF800000
#define DAC_Overflow_Bitmask 0x7F000000

/*************************************/
/* LIMITS - Udate me please!         */
/*************************************/
#define DDS_Channel_Min             0
#define DDS_Channel_Max                 1
#define Waveform_LUT_Size 4096   /* 12 bits long */
#define Waveform_LUT_Size_Bin 0x100000 /* 32-12 = 20 bits worth   */
#define DDS_LUT_Bit_Shift 20     /* 32-12 = 20   */
#define DDS_LUT_Bit_Mask 0xfffff /* 20 bits worth   */
#define Atten_Scale 0x1000000

/***************************************************/
/* 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
#define Default_Mem_Bank            0
/* How big is each set of data in ROM?*/
#define ParmSet_Array_Size          0x0800
/* Approx EEPROM write delay in mS */
#define EEPROM_WR_Delay             10   
/* Approx EEPROM write delay in mS */
#define DAC_RESET_Delay             50   

#define Freq_Offset                 0X0000
#define Freq_Speed_Offset           0X0004
#define Atten_Offset                0X0008
#define Waveform_Offset             0X000C
#define Ratio_Offset                0X0010
#define Sweep_On_Offset             0X0014
#define Sweep_End_Offset            0X0018
#define Sweep_Time_Offset           0X001C
#define Pulse_On_Offset             0X0020
#define Pulse_Cycles_On_Offset      0X0024
#define Pulse_Cycles_Off_Offset     0X0028
#define Phase_Shift_Offset          0X002C
#define AM_On_Offset                0X0030
#define AM_Level_Offset             0X0034
#define AM_Freq_Offset              0X0038
#define FM_On_Offset                0X003C
#define FM_Excursion_Offset         0X0040
#define FM_Freq_Offset              0X0044


#define Channel_Set_Array_Size      0x0080


#define	Freq_Min 1         /* Remember this is in tenths of a Hz*/
#define	Freq_Max 220000    /* Remember this is in tenths of a Hz*/
#define	Freq_Speed_Min 1   /* Remember this is in tenths of a Hz*/
#define	Freq_Speed_Max 1000 /* Remember this is in tenths of a Hz*/
#define Waveform_Min Sine
#define Waveform_Max Noise
#define Ratio_Min 1
#define Ratio_Max 99
#define Sweep_End_Min Freq_Min
#define Sweep_End_Max Freq_Max
#define Sweep_Time_Min 1
#define Sweep_Time_Max 600
#define Pulse_Cycles_On_Min 1
#define Pulse_Cycles_On_Max 1000
#define Pulse_Counter_Init 1000
#define Pulse_Cycles_Off_Min 1
#define Pulse_Cycles_Off_Max 1000
#define Phase_Shift_Min 0
#define Phase_Shift_Max 360
#define AM_Level_Min 1
#define AM_Level_Max 100
#define AM_Freq_Min 1
#define AM_Freq_Max 1000
#define FM_Excursion_Min 1
#define FM_Excursion_Max 1000
#define FM_Freq_Min 1
#define FM_Freq_Max 1000
#define Waveform_Min Sine
#define Waveform_Max Noise
#define Level_Offset 5.0   /* This is 5dB, as the output is 1.79volts or about +5dB */
#define Sweep_Linear 1
#define Sweep_Log 2



/***************************************************************************/
/*  Some handy defines to make the code easier to read...                  */
/***************************************************************************/
#define Acc_Reg_Shift  Acc_Reg = (Acc_Reg >>26);

/**************************************************************************/
// It would be perfectly reasonable to absorb this into CONTROL_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 ***/

/* number of bytes in single parameter transaction */
#define NumBytes_Word_Parms 4
#define Non_Inverted_Gain_Val 0x00800000
#define Inverted_Gain_Val 0xFF800000

// TIMER STUFF
#define APP_HEARTBEAT_TMR DRV_TMR_INDEX_0
#define APP_HEARTBEAT_TMR_IS_PERIODIC true
#define APP_HEARTBEAT_TMR_PERIOD 0x2E51
#define APP_HEARTBEAT_COUNT_MAX 9
// *****************************************************************************
// *****************************************************************************
// Section: Application Callback Routines
// *****************************************************************************
// *****************************************************************************
/* These routines are called by drivers when certain events occur.
*/
	
// *****************************************************************************
// *****************************************************************************
// Section: Application Initialization and State Machine Functions
// *****************************************************************************
// *****************************************************************************

/*******************************************************************************
  Function:
    void CONTROL_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>
    CONTROL_Initialize();
    </code>

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

void CONTROL_Initialize ( void );


/*******************************************************************************
  Function:
    void CONTROL_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>
    CONTROL_Tasks();
    </code>

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

void CONTROL_Tasks( void );


#endif /* _CONTROL_H */

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

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

void Idle_Screen(void);

void Update_Temp_Meas(int);

void CONTROL_EEPROM_Initialize(void);

/* filter type, finter rate, freq, Q, GainGen, Gain, A0, A1, A2, B0, B1, B2*/
void Calc_DSP_Parms(int, int, int, double, int, int, int *, int *, int *, int *, int *, int *);
