/*******************************************************************************
  Main Source File

  Company:
    Microchip Technology Inc.

  File Name:
    main.c

  Summary:
    This file contains the "main" function for a project.

  Description:
    This file contains the "main" function for a project.  The
    "main" function calls the "SYS_Initialize" function to initialize the state
    machines of all modules in the system
 *******************************************************************************/

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

#include <stddef.h>                     // Defines NULL
#include <stdbool.h>                    // Defines true
#include <stdlib.h>                     // Defines EXIT_FAILURE
#include "definitions.h"                // SYS function prototypes


#include "stdio.h"
#include "1lcd_lib_XC32.h"


bool Timer_Trigger;    //AD変換タイミングフラグ
int Count_10msec = 0;       //10msec経過カウンタ
int delay_Clock = 200000000;   //200MHz
char Buf[32];
bool LED;

void delay_us(volatile unsigned int usec)        //1μsec遅延
{
        volatile  int count;

        count = (int)(delay_Clock/20000000)*usec;


        do      //実測 at 200MH (Clock=200000000)
        {       //delay_us(1000):1000.4μsec  delay_us(100):100.6μsec  delay_us(10):10.5μsec  delay_us(1):1.5μsec
                asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP");asm("NOP");
                asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP");

                count--;
        }while(count != 0);


}

void delay_ms(volatile unsigned int msec)        //1msec遅延
{
        volatile unsigned int i;         //実測:at200MH (Clock=200000000)//delay_ms(1): 1.0006msec   delay_ms(100):100.04msec

        for(i=0; i<msec; i++)
        delay_us(1000);
}



void AdcFunc(void)          //AD変換、表示
{
    unsigned short int AdcValue;
    double Volt;
    Timer_Trigger = 0;
    
        //AD変換開始 Trigger a conversion 
        //ADCHS_ChannelConversionStart();//変換開始(グローバルソフトウェアエッジトリガの場合)//コンパイルエラー:error: too few arguments to function 'ADCHS_ChannelConversionStart'
        ADCHS_ChannelConversionStart(ADCHS_CH4);//変換開始(グローバルソフトウェアエッジトリガの場合)
        //  ADCCON3bits.GSWTRG = 1; //変換開始(グローバルソフトウェアエッジトリガの場合)
                    //Trigger conversion for ADC inputs that have selected the GSWTRG bit as the trigger signal, either
                    //through the associated TRGSRC<4:0> bits in the ADCTRGx registers or through the STRGSRC<4:0>
                    //bits in the ADCCON1 register
                    //Class1 の場合、"ADCCON1bits.STRGSRC = 0;    //スキャン開始トリガなし変換が終了する”(default)にすると
                    //変換終了後、自動的にサンプリングが実行される。

            //変換完了を待つ Wait the conversions to complete
            //AN4
        while(!ADCHS_ChannelResultIsReady(ADCHS_CH4));
        // while (ADCDSTAT1bits.ARDY4 == 0);
           
        //結果の取り出し fetch the result
        AdcValue = ADCHS_ChannelResultGet(ADCHS_CH4);
        //  AdcValue = ADCDATA4;
        
            
    lcd_cmd(0x80);          //1目の先頭へ
    sprintf(Buf,"AdV=%u             ",AdcValue); //バッファーに文字列をセット
    lcd_str(Buf);       // 開始メッセージ1行目表示

    Volt =(double)AdcValue/4095*3.3;

    lcd_cmd(0xC0);          //2行目の先頭へ
    sprintf(Buf,"Volt=%.2f[V]       ",Volt);       //文字列としてバッファーに収納
    lcd_str(Buf);           // 開始メッセージ1行目表示
    
 

}




void TMR9_Callback_Fn(uint32_t status, uintptr_t context) //コールバック関数      //1秒毎に呼び出される
{
    Count_10msec++;
    if(Count_10msec >= 25)  //250msec 経過
    {
        Count_10msec = 0;
        Timer_Trigger = true;
    }

}



// *****************************************************************************
// *****************************************************************************
// Section: Main Entry Point
// *****************************************************************************
// *****************************************************************************



int main ( void )
{
    /* Initialize all modules */
    SYS_Initialize ( NULL );
    
/*    

//レジスタ直接設定の場合    
      
    // Configure ADCCON1 
    ADCCON1 = 0; // No ADCCON1 features are enabled including: Stop-in-Idle, turbo,
    ADCCON1bits.STRGSRC = 1;    //スキャン開始を グローバルソフトウェアエッジトリガに設定   //ADCCON1bits.STRGSRC = 0; でも可
                                //ADCCON1bits.STRGSRC = 0;    //スキャン開始トリガなし  //bit 20-16 STRGSRC<4:0>: Scan Trigger Source Select bits

    // CVD mode, Fractional mode and scan trigger source.
    // Configure ADCCON2 
    ADCCON2 = 0; // Since, we are using only the Class 1 inputs, no setting is

    // required for ADCDIV
    // Initialize warm up time register 
    ADCANCON = 0;
    ADCANCONbits.WKUPCLKCNT = 5; // Wakeup exponent = 32 * TADx

    // Clock setting 
    ADCCON3 = 0;
    ADCCON3bits.ADCSEL = 0; //AD変換クロックTclk選択 0:PBCLK3   //1:System Clock //Select input clock source
    ADCCON3bits.CONCLKDIV = 1; //分周値 1:1/2   //AD変換制御クロックTq = 2 x Tclk  // Control clock frequency is half of input clock
    ADCCON3bits.VREFSEL = 0; //リファレンス電圧 Vref+ = AVdd, Vref- = Vss  //Select AVdd and AVss as reference source


    // Select ADC sample time and conversion clock 
    //専任ADコンバータ用タイミングレジスタ  //Dedicated ADCx Timing Register
    //AN4用
    ADC4TIMEbits.ADCDIV = 1; //ADC4用制御クロック分周値 1:1/2 Tad0 = 2 x Tq  //  ADC4 clock frequency is half of control clock = TAD0
    ADC4TIMEbits.SAMC = 5; //サンプリング周期設定 // サンプリング周期= 5 x Tad0 = 5 x 2 x Tq = 5x2x2xTclk     //ADC4 sampling time = 5 * TAD0
    ADC4TIMEbits.SELRES = 3; //分解能設定 3:12ビット ADC0 resolution is 12 bits


    //入力ポート選択 Select analog input for ADC modules, no presync trigger, not sync sampling
    ADCTRGMODEbits.SH4ALT = 0; // ADC4入力ポート:AN4    //AN45の場合:ADCTRGMODEbits.SH0ALT = 1

    //Input Mode Control Register   // データフォーマット Select ADC input mode 
    //AN4用
    ADCIMCON1bits.SIGN4 = 0; //出力フォーマット: unsigned short int   //  unsigned data format
    ADCIMCON1bits.DIFF4 = 0; //シングルエンド入力 Single ended mode//1:差動入力

    // Configure ADCGIRQENx 
    ADCGIRQEN1 = 0; // No interrupts are used
    ADCGIRQEN2 = 0;

    // Configure ADCCSSx 
    ADCCSS1 = 0; // No scanning is used
    ADCCSS2 = 0;

    //Configure ADCCMPCONx  //コンパレータトリガ変換使用せず
    ADCCMPCON1 = 0; // No digital comparators are used. Setting the ADCCMPCONx
    ADCCMPCON2 = 0; // register to '0' ensures that the comparator is disabled.
    ADCCMPCON3 = 0; // Other registers are “don't care”.
    ADCCMPCON4 = 0;
    ADCCMPCON5 = 0;
    ADCCMPCON6 = 0;

    // Configure ADCFLTRx   //オーバーサンプリングなし
    ADCFLTR1 = 0; // No oversampling filters are used.
    ADCFLTR2 = 0;
    ADCFLTR3 = 0;
    ADCFLTR4 = 0;
    ADCFLTR5 = 0;
    ADCFLTR6 = 0; 


    //エッジトリガ変換使用せず Set up the trigger sources
    ADCTRGSNSbits.LVL4 = 0; // Edge trigger

    //変換開始をグローバルソフトウェアエッジトリガに設定    Global software edge Trigger    //★★
    ADCTRG2bits.TRGSRC4 = 1;    //グローバルソフトウェアエッジトリガ設定    //TRGSRC4<4:0>: Trigger Source for Conversion of Analog Input AN4 Select bits
                            //変換開始を ADCCON3bits.GSWTRG = 1; に設定
                            //Global software edge Trigger (GSWTRG) Set AN0 to trigger from software.


    // Early interrupt 
    ADCEIEN1 = 0; //割り込みなし    // No early interrupt
    ADCEIEN2 = 0;

    // Turn the ADC on 
    ADCCON1bits.ON = 1;     //ADCモジュール イネーブル

    //リファレンス電圧の安定を待つ Wait for voltage reference to be stable
    while(!ADCCON2bits.BGVRRDY); // Wait until the reference voltage is ready   //BGVRRDY: Band Gap Voltage/ADC Reference Voltage Status b
    while(ADCCON2bits.REFFLT); // Wait if there is a fault with the reference voltage

    //ADCアナログ回路のクロックON  // Enable clock to analog circuit
    ADCANCONbits.ANEN4 = 1; // Enable the clock to analog bias

    //ADC準備完了を待つ // Wait for ADC to be ready 
    while(!ADCANCONbits.WKRDY4); // Wait until ADC0 is ready

    //ADCデジタル回路ON //Enable the ADC module
    ADCCON3bits.DIGEN4 = 1; // Enable ADC4  //必須

*/ 

    //★出力フォーマット: unsigned data format
    ADCIMCON1bits.SIGN4 = 0; //出力フォーマット: unsigned short int   //  unsigned data format
    
    lcd_init();				// LCD初期化
    lcd_cmd(0b00001100);    // カーソル:OFF  ブリンク:OFF
        
    lcd_clear();
    lcd_cmd(0x80);          //1目の先頭へ
    sprintf(Buf,"PIC32MZ HARMONY ");//
    lcd_str(Buf);                   //液晶表示
    lcd_cmd(0xC0);          //2行目の先頭へ
    sprintf(Buf,"Now Running !!  ");	//
    lcd_str(Buf);           // 開始メッセージ1行目表示
    delay_ms(2000);
    
    
    TMR9_PeriodSet(3907);  //50 nsec x2  x 3907 x 256 = 1000192μsec = 10.00192msec  
                            //クロック:100MHz
    TMR9_Start();   //タイマ1 スタート
    //T1CONbits.ON = 1;     //レジスタ直接制御
    TMR9_CallbackRegister(TMR9_Callback_Fn, NULL);  //コールバック関数設定 
                                                    //void TMR1_CallbackRegister(TMR_CALLBACK callback_fn, uintptr_t context);  
    

    while ( true )
    {
        /* Maintain state machines of all polled MPLAB Harmony modules. */
        SYS_Tasks ( );
        
        delay_us(1);    //必須
        
        
        if(Timer_Trigger == true)     //AD変換、表示のタイミング
        {  
            AdcFunc();      //AD変換、表示
            
            Timer_Trigger = 0;  
                
            if(LED == 0)
            {
                LED = 1;
                LATGbits.LATG15 = 1;    //LED ON
            }
            else
            {
                LED = 0;
                LATGbits.LATG15 = 0;    //LED OFF
            }
                     
        }
    }

    /* Execution should not come here during normal operation */

    return ( EXIT_FAILURE );
}


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