// *********************************************************************
// *                           DDC-SE-01-light                         *
// *                            Demo example                           *
// *********************************************************************
// Using of Analog-to-Digital Converter with light sensor connected.
//
// Intended for:
//   HW: - TR-72G + DK-EVAL-04x development kit with DDC-SE-01 connected
//
//   OS: - v4.06G
//
// Description:
//   AD conversion is called in 2s period. Three light statuses are
//   recognized. RF packet is sent on every status change. It can be
//   received by example E03-TR.c and displayed in terminal of IQRF IDE.
//   For more info about ADC setting see PIC datasheet
//
// ---------------------------------------------------------------------
// Online IQRF OS Reference Guide: https://doc.iqrf.org/IQRF-OS-Reference-guide
//
// Copyright (c) IQRF Tech s.r.o.
//
// File:    DDC-SE-01-light.c
// Version: v3.00                                   Revision: 16/06/2021
//
// Revision history:
//   v3.00: 16/06/2021  First release for TR-7xG.
//
// *********************************************************************
// Default IQRF include (modify the path according to your setup)
#include "IQRF.h"

// *********************************************************************
#define DAY         1
#define TWILIGHT    2
#define NIGHT       3

#define limit1      0x0295
#define limit2      0x00F0

// *********************************************************************
void InitADC(void);
void ReadAnalogInput(void);

// *********************************************************************
uns16 ADC_result;
uns8 state, prew_state;

// *********************************************************************

void APPLICATION()
{
    TRISA.0 = 1;                            // Light senzor pin C1 (ANA0) as input
    InitADC();                               
    pulseLEDG();                            // reset indication
    waitDelay(10);
    
    while(1)
    {   
        waitDelay(200);                     // reading of AN input is every 2s
        ReadAnalogInput();

        if (ADC_result > limit1)
            state = NIGHT;
        else if (ADC_result < limit2)
            state = DAY;
        else
            state = TWILIGHT;
            
        if (state != prew_state)
        {
            prew_state = state;
        
            switch(state)
            {
                case DAY:
                    bufferRF[0] = 'D';
                    bufferRF[1] = 'A';
                    bufferRF[2] = 'Y';
                    DLEN = 3;
                    break;
                    
                case TWILIGHT:
                    bufferRF[0] = 'T';
                    bufferRF[1] = 'W';
                    bufferRF[2] = 'I';
                    bufferRF[3] = 'L';
                    bufferRF[4] = 'I';
                    bufferRF[5] = 'G';
                    bufferRF[6] = 'H';
                    bufferRF[7] = 'T';
                    DLEN = 8;
                    break;
                    
                case NIGHT:
                    bufferRF[0] = 'N';
                    bufferRF[1] = 'I';
                    bufferRF[2] = 'G';
                    bufferRF[3] = 'H';
                    bufferRF[4] = 'T';
                    DLEN = 5;
                    break;
            }
    
            pulseLEDR();            
            PIN  = 0;
            RFTXpacket();
        }
    }   
}
// *********************************************************************
// Note:
// If a packet received the A/D converter control registers are changed so InitADC
// must be called again (see RFRXpacket function side effects in IQRF Reference Guide).
// This is not case of this example because it does not call RFRXpacket function.

void InitADC(void)          // ADC init (for more info about registers see PIC datasheet)
{
    ANSELA.0 = 1;                           // pin C1 (ANA0) as analog input
    setADPCH(0b00000000);                   // ADC setting (ANA0 channel)
                                            //   This register (ADPCH) can not be written directly due to OS restriction
    ADCLK = 0b00000111;                     // Fosc/16
    ADCON0 = 0b10000100;                    // ADC result - right justified
}
//----------------------------------------------------------------------

void ReadAnalogInput(void)
{
    ADGO = 1;                               // start ADC
    while(ADGO);                            // wait for ADC finish
    
    ADC_result.high8 = ADRESH & 0x03;       // 10b result is stored
    ADC_result.low8  = ADRESL;              //   in ADRESH and ADRESL
}
//----------------------------------------------------------------------
