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

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

/* 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	EQ_Speed             100     /* Seems like a sensible number*/
#define	FL_Speed             100     /* Seems like a sensible number*/
#define	FL_Normal_Speed      5     /* Seems like a sensible number*/
#define	FH_Speed             100     /* Seems like a sensible number*/
#define	FH_Normal_Speed      5     /* Seems like a sensible number*/
#define FL_Step              1     /* seems reasonable*/     
#define FH_Step              1     /* seems reasonable*/     
#define	Delay_Speed             10     /* Seems like a sensible number*/
#define	Delay_Normal_Speed      1     /* Seems like a sensible number*/
#define Delay_Step              1     /* seems reasonable*/     
#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	EQ_Normal_Speed      1     /* Seems like a sensible number*/
#define	Q_Normal_Speed      1     /* Seems like a sensible number*/
#define	Q_Speed             10     /* Seems like a sensible number*/
#define	Atten_Speed          6     /* lots of 0.5dB Seems like a sensible number*/
#define	Atten_Min            -24     /* Seems like a sensible number*/
#define	Atten_Max            (104*2) /* hald dB's Seems like a sensible number*/
#define Atten_Default        66 
#define	Inverted            1     /* True */
#define	Non_Inverted        0     /* False */
#define	Revert_To_Idle      (16 * Snooze_Counts_PerSec)   /* Seems like a sensible number*/
#define	Snooze_Min          (30 * Snooze_Counts_PerSec)   /* Seems like a sensible number*/
#define	Snooze_Max          (3600 * Snooze_Counts_PerSec) /* An hour Seems like a sensible number*/
#define	Snooze_Default      (60  * Snooze_Counts_PerSec) 
#define Snooze_Counts_PerSec 2   /* This should be defined by the ISR Call Rate */
#define Tempco_Normal_Speed 5
#define Tempco_Speed        50
#define	Tempco_Min          (-2*256) /* Need to work this out*/
#define	Tempco_Max          (2*256) /* Need to work this out*/
#define Tempco_Default      256    
#define	Temp_Offset_Min     (-300 * 256) /* Need to work this out*/
#define	Temp_Offset_Max     (300 * 256) /* Need to work this out*/
#define	Temp_Offset_Default     0 /* Need to work this out*/
#define	Tempco_Offset_Default  (10 * 256)
#define Snooze_Normal_Speed (5 * Snooze_Counts_PerSec)
#define Snooze_Speed        (60 * Snooze_Counts_PerSec)

#define ADC_Filter_Coeff    4 /* ADC_Filter_Coeff/256 of new data added to
                                 (256-ADC_Filter_Coeff)/256 of old data */   
    
/*****************************************************************************/
// 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 25
#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. */
	CONTROL_STATE_INIT=0,
	CONTROL_STATE_LCDINIT,
	CONTROL_STATE_IDLE,
	CONTROL_STATE_SERVICE_TASKS,
    CONTROL_STATE_CHOOSING,
    CONTROL_STATE_OPERATIONAL,
	CONTROL_STATE_LOAD,
	CONTROL_STATE_SENSOR_OFFSET,
	CONTROL_STATE_SENSOR_OFFSET_CHANGE,
    CONTROL_STATE_SENSOR_COEFF,
    CONTROL_STATE_SENSOR_COEFF_CHANGE,
    CONTROL_STATE_SLEEP,
    CONTROL_STATE_SAVE,
    CONTROL_STATE_XO_BAND,
    CONTROL_STATE_LO_FREQ,
    CONTROL_STATE_LO_SLOPE,
    CONTROL_STATE_HI_FREQ,
    CONTROL_STATE_HI_SLOPE,
    CONTROL_STATE_DELAY,
    CONTROL_STATE_GAIN,
    CONTROL_STATE_INVERT,
    CONTROL_STATE_BRIDGE,       
    CONTROL_STATE_EQ_BAND,
    CONTROL_STATE_EQ_TYPE,
    CONTROL_STATE_EQ_FREQ,
    CONTROL_STATE_EQ_GAIN,
    CONTROL_STATE_EQ_Q,
    CONTROL_STATE_EQ_CD,
    CONTROL_STATE_IN_SEL
            
            
	/* TODO: Define states used by the application state machine. */
} CONTROL_STATES;

typedef enum
{
	/* EQ Types. */
	EQ_TYPE_NONE=666,
    EQ_TYPE_PARA,
    EQ_TYPE_LPF
} EQ_TYPES;

typedef enum
{
	/* Application's state machine's initial state. */
	CONTROL_ACTION_INIT=0,
	CONTROL_ACTION_SENSOR_OFFSET,
    CONTROL_ACTION_SENSOR_COEFF,
    CONTROL_ACTION_SLEEP,
    CONTROL_ACTION_XO,
    CONTROL_ACTION_EQ,
    CONTROL_ACTION_LOAD,
    CONTROL_ACTION_SAVE,
    CONTROL_ACTION_YES,
    CONTROL_ACTION_NO,
    CONTROL_ACTION_XO_BAND,
    CONTROL_ACTION_LO_FREQ,
    CONTROL_ACTION_LO_SLOPE,
    CONTROL_ACTION_HI_FREQ,
    CONTROL_ACTION_HI_SLOPE,
    CONTROL_ACTION_DELAY,
    CONTROL_ACTION_GAIN,
    CONTROL_ACTION_INVERT,
    CONTROL_ACTION_EQ_BAND,
    CONTROL_ACTION_EQ_TYPE,
    CONTROL_ACTION_EQ_NONE,
    CONTROL_ACTION_EQ_PARA,
    CONTROL_ACTION_EQ_CD,
    CONTROL_ACTION_EQ_FREQ,
    CONTROL_ACTION_EQ_GAIN,
    CONTROL_ACTION_EQ_Q,
    CONTROL_ACTION_EQ_CDON
         
	/* TODO: Define states used by the application state machine. */
} CONTROL_ACTIONS;


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

/* Auto Repeat Counts - how long to wait before starting to Auto Repeat*/
#define Auto_Repeat_Count 6

/* Stuff to allow modes to be tracked Use these to control the state machine  */
#define Choosing_Fn     0
#define Set_Mode        1
#define Save_Mode       2
#define Load_Mode       3

/* Stuff to allow functions to be tracked in Set mode */
#define Temperature_Set 10
#define Sleep_Time_Set  11
#define Sensor_Tempco   12
#define Sensor_Offset   13


/*Stuff to allow functions to be tracked in Save mode */
#define Save_Sel_Fn 	20

/* Stuff to allow functions to be tracked in Load mode */
#define Load_Sel_Fn 	30

/*  Frequency Speed Function */
#define Freq_Speed_Counter_1_fn 	666


/*****************************************************************************/
/*****************************************************************************/
/*                     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      	"  SILICON CHIP  "
#define Line2_Init          "DXO V8 08 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 Zap_X        111
#define Zap_Y        24
#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 BandXO_TGM_X0 0
#define BandXO_TGM_X1 28
#define BandXO_TGM_X2 56
#define BandXO_TGM_X3 84
#define BandXO_TGM_Y  48
#define BandXO_X      0
#define BandXO_X0     15
#define BandXO_X1     45
#define BandXO_X2     73
#define BandXO_X3     102
#define BandXO_Y      2
#define BandEQ_X      0
#define BandEQ_Y      2
#define BandEQ_X1     0
#define BandEQ_Y1     47
#define BandEQ_top_X      0
#define BandEQ_top_Y      3
#define BandEQ_top_X1     64
#define BandEQ_top_Y1     3
#define BandLO_X      44
#define BandLO_Y      48
#define ParaB_X      78
#define ParaB_Y      0
#define ParaNo_X      78
#define ParaNo_Y      16
#define ParaNote_X    78
#define ParaNote_Y    32
#define ParaF_X      70
#define ParaF_Y      48
#define ParaG_X      78
#define ParaG_Y      48
#define Para_Comm_X      2
#define Para_Comm_Y     50
#define Para_CH1_X      97
#define Para_CH1_Y     12
#define Para_CH2_X      97
#define Para_CH2_Y     43

#define BandHi_X      44
#define BandHi_Y      48
#define SlopeLo_X      0
#define SlopeLo_Y      48
#define SlopeHi_X      0
#define SlopeHi_Y      48
#define BandDelay_X    44
#define BandDelay_Y    48
#define BandInvert_X   55
#define BandInvert_Y   48
#define BandBridge_X   55
#define BandBridge_Y   48
#define XO_Band_X      0
#define XO_Band_Y      0
#define XO_Bridge_X    0
#define XO_Bridge_Y    26
#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 Temoco_L1x    0
#define Temoco_L1y    0
#define Temoco_L2y    14
#define Temoco_L3y    28
#define Temoco_L4y    40
#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 Fl;
		int Fu;
		int Sl;
		int Su;
        int Atten;   /* in half dB steps */
		int Delay_mm;
		int Invert;
        int Bridge;
}  data_val_struct ;


typedef struct{
		int CF;
		int Q;
		int Gain;
		EQ_TYPES Type;
}  Para_EQ_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;    
    /* interrupt status */
    int                 Interrupt_Status;
    /* 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;
    /* 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;
    /* desired attenuation in half dB steps */
    int                 Atten_Set;
    /* Last Updated Temp in Degrees time 256 C*/
    int                 Atten_Last_Update;
     /* 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];
    /* Parametrc filter values 3 common filter sets, plus 2 per band */
    Para_EQ_struct EQ_Values[15];						
    /* the crossover nand*/
    int                 XO_Band;
    /* the EQ band*/
    int                 EQ_Band;
    /* the Input Selct nand*/
    int                 Input_Sel;
    
} 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 */
/***************************************/
#define Choosing_Fn	0
#define Ch_1_Mode       1
#define Ch_2_Mode 	2
#define Gen_Para_Mode   3

/* defeine Filter Parameters*/
#define CHInverted  -1
#define CHNonInverted  1
#define NoFilter 109
#define Filter_Min NoFilter
#define SixdB    110
#define TwelvedB 111
#define TwentyFourdB 112
#define Filter_Max  TwentyFourdB
#define Peaking  113
#define G_Filter_Max Peaking
#define EQ_TYPE_MIN EQ_TYPE_NONE
#define EQ_TYPE_MAX EQ_TYPE_PARA

#define LowPass  100
#define HighPass 101
/* 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
/* hardcoded Filter Types for F2, F3, F4, F5, F6 and F7*/
#define F0_LP_Type LowPass
#define F1_LP_Type LowPass
#define F0_Peaking Peaking
#define F1_Peaking Peaking
#define F2_Type HighPass

#define F3_Type HighPass
#define F4_Type LowPass
#define F5_Type LowPass
#define F6_Type HighPass
#define F7_Type HighPass
#define Q_BW   (0.707*10)  //Q is passed in tenths 


/*************************************/
/* LIMITS - Udate me please!         */
/*************************************/
#define Min_XO_Band                 0
#define Max_XO_Band                 1
#define Ch1_Band_No                 0 /* should tidy up - portig old code in */
#define Ch2_Band_No                 1 /* should tidy up - portig old code in */
#define Min_EQ_Band                 0  /* A bit handraulic - 4 common plus 2 per channel*/
#define Max_EQ_Band                 7 /* this is MAx... */
#define Min_CH_EQ                 4
#define Max_CH_EQ                 7 /* this is MAx plus one...*/


/***************************************************/
/* 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 Fl_Offset                   0X0000
#define Fu_Offset                   0X0004
#define Sl_Offset                   0X0008
#define Su_Offset                   0X000C
#define Atten_Offset                0X0010
#define Delay_mm_Offset             0X0014
#define Invert_Offset               0X0048
#define Bridge_Offset               0X004C
#define Channel_Set_Array_Size      0x0080

#define Para_Gen_Base               0x0200
#define Para_Set_Size               0x0040

#define Para_CF_Offset              0x0000
#define Para_Q_Offset               0x0004
#define Para_Gain_Offset            0x0008
#define Para_Type_Offset            0x000c


#define Para_Gen1_CF_Offset         0x02C0
#define Para_Gen1_Q_Offset          0x02C4
#define Para_Gen1_Gain_Offset       0x02C8
#define Para_Gen1_Type_Offset       0x02CC
#define Para_Gen2_CF_Offset         0x02D0
#define Para_Gen2_Q_Offset          0x02D4
#define Para_Gen2_Gain_Offset       0x02D8
#define Para_Gen2_Type_Offset       0x02DC
#define Para_Gen3_CF_Offset         0x02E0
#define Para_Gen3_Q_Offset          0x02E4
#define Para_Gen3_Gain_Offset       0x02E8
#define Para_Gen3_Type_Offset       0x02EC
#define Input_Selected_Offset       0x01F8
#define Volume_Offset               0x01F4


/*  Limit Values for Data Structures  */
#define	EQ_Min 10
#define	EQ_Gain_Max 10
#define	EQ_Gain_Min -10
#define	EQ_Q_Max 100
#define	EQ_Q_Min 1
#define	EQ_Max 15000
#define	Fl_Min 15
#define	Fl_Max 15000
#define	Fu_Min 10
#define	Fu_Max 15000
#define SL_Step 1
#define	Sl_Min NoFilter    /* Sl = 0, None */
				    /* Sl = 1, 6dB Slope */
				    /* Sl = 2, 12dB Slope */
				    /* Sl = 3, LR24 Slope */
				    /* Sl = 4, LR48 Slope */
#define	Sl_Max TwentyFourdB    /* LR 24 Slope */
#define Su_Step 1
#define	Su_Min NoFilter    /* Sl = 0, None */
				    /* Sl = 1, 6dB Slope */
				    /* Sl = 2, 12dB Slope */
				    /* Sl = 3, LR24 Slope */
				    /* Sl = 4, LR48 Slope */
#define	Su_Max TwentyFourdB    /* LR 24 Slope */
#define	Delay_mm_Min 1
/* Note this maximum is determined by the RAM allocated in the DSP */
/* Current allocation is 900 samples, or 6397mm odd */
/* This parameter = (900 / Sample_Rate)*Speed_Of_Sound_in_air */
#define	Delay_Min 1
#define	Delay_Max 900
#define	Delay_mm_Max 6370
#define Invert_True 1
#define Invert_False 0
#define Bridge_True 1
#define Bridge_False 0
#define Atten_On_Loading_Min (unsigned char)80
#define	Gain_Atten_Min (unsigned char) 0     /*steps of 0.5dB */
#define	Gain_Atten_Max (unsigned char) 40    /*steps of 0.5dB */

#define Input_SPDIF (unsigned char) 0
#define Input_ADC (unsigned char)   1
/*Define Value for Mute Volume */
#define  Mute 255

#define Delay_Buf_Size 2048
#define Delay_Buf_Size_Mask 0x000007ff

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

#define Yn_L_Assignment Yn_L = (int)Acc_Reg
#define Yn_R_Assignment Yn_R = (int)Acc_Reg
#define Y1n_L_Assignment Y1n_L = (int)Acc_Reg
#define Y1n_R_Assignment Y1n_R = (int)Acc_Reg
#define Y2n_L_Assignment Y2n_L = (int)Acc_Reg
#define Y2n_R_Assignment Y2n_R = (int)Acc_Reg
#define Y3n_L_Assignment Y3n_L = (int)Acc_Reg
#define Y3n_R_Assignment Y3n_R = (int)Acc_Reg
#define Y4n_L_Assignment Y4n_L = (int)Acc_Reg
#define Y4n_R_Assignment Y4n_R = (int)Acc_Reg
#define Y5n_L_Assignment Y5n_L = (int)Acc_Reg
#define Y5n_R_Assignment Y5n_R = (int)Acc_Reg
#define Y6n_L_Assignment Y6n_L = (int)Acc_Reg
#define Y6n_R_Assignment Y6n_R = (int)Acc_Reg
#define Y7n_L_Assignment Y7n_L = (int)Acc_Reg
#define Y7n_R_Assignment Y7n_R = (int)Acc_Reg
#define Y8n_L_Assignment Y8n_L = (int)Acc_Reg
#define Y8n_R_Assignment Y8n_R = (int)Acc_Reg
#define Y9n_L_Assignment Y9n_L = (int)Acc_Reg
#define Y9n_R_Assignment Y9n_R = (int)Acc_Reg
#define Yan_L_Assignment Yan_L = (int)Acc_Reg
#define Yan_R_Assignment Yan_R = (int)Acc_Reg
#define Ybn_L_Assignment Ybn_L = (int)Acc_Reg
#define Ybn_R_Assignment Ybn_R = (int)Acc_Reg
#define Ycn_L_Assignment Ycn_L = (int)Acc_Reg
#define Ycn_R_Assignment Ycn_R = (int)Acc_Reg
#define Ydn_L_Assignment Ydn_L = (int)Acc_Reg
#define Ydn_R_Assignment Ydn_R = (int)Acc_Reg

#define Para_Update_Base    16   /*use as the base address for update of Para EQ

/**************************************************************************/
// 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 ***/
//ADAU Stuff
/* Addresses of things in the system... */
#define Write_SPI 0X00

/* Register Addresses in ADAU1442 */
#define ADAU1442_Safeload_Base_Parameter 0x0001
#define ADAU1442_Safeload_Target_Address 0x0006
#define ADAU1442_Safeload_Number_Of_Words 0x0007

#define SpeedOfSound 341210   /* millimetres per second */
//#define A1 IIR_B0_B1_B2_A1_A2[3]
//#define A2 IIR_B0_B1_B2_A1_A2[4]
//#define B0 IIR_B0_B1_B2_A1_A2[0]
//#define B1 IIR_B0_B1_B2_A1_A2[1]
//#define B2 IIR_B0_B1_B2_A1_A2[2]

#define A1_2 IIR2_B0_B1_B2_A1_A2[3]
#define A2_2 IIR2_B0_B1_B2_A1_A2[4]
#define B0_2 IIR2_B0_B1_B2_A1_A2[0]
#define B1_2 IIR2_B0_B1_B2_A1_A2[1]
#define B2_2 IIR2_B0_B1_B2_A1_A2[2]

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