/*
 * Copyright (c) 2015-2018, Texas Instruments Incorporated
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * *  Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * *  Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * *  Neither the name of Texas Instruments Incorporated nor the names of
 *    its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

// API RADIO

//| Generic API function          | Description                                        |
//|-------------------------------|----------------------------------------------------|
//| EasyLink_init()               | Init's and opens the RF driver and configures the  |
//|                               | specified settings based on EasyLink_Params struct |
//| EasyLink_transmit()           | Blocking Transmit                                  |
//| EasyLink_transmitAsync()      | Non-blocking Transmit                              |
//| EasyLink_transmitCcaAsync()   | Non-blocking Transmit with Clear Channel Assessment|
//| EasyLink_receive()            | Blocking Receive                                   |
//| EasyLink_receiveAsync()       | Non-blocking Receive                               |
//| EasyLink_abort()              | Aborts a non blocking call                         |
//| EasyLink_enableRxAddrFilter() | Enables/Disables RX filtering on the Addr          |
//| EasyLink_getIeeeAddr()        | Gets the IEEE Address                              |
//| EasyLink_setFrequency()       | Sets the frequency                                 |
//| EasyLink_getFrequency()       | Gets the frequency                                 |
//| EasyLink_setRfPower()         | Sets the Tx Power                                  |
//| EasyLink_getRfPower()         | Gets the Tx Power                                  |
//| EasyLink_getRssi()            | Gets the RSSI                                      |
//| EasyLink_getAbsTime()         | Gets the absolute time in RAT ticks                |
//| EasyLink_setCtrl()            | Set RF parameters, test modes or EasyLink options  |
//| EasyLink_getCtrl()            | Get RF parameters or EasyLink options              |
//| EasyLink_getIeeeAddr()        | Gets the IEEE address                              |


// Configurazione HW delle risorse della demoboard + aggiunte
//----------------------------------------------------------------------
// PWM6             pin DIO_0 Timer 3A
// led red test     pin DIO22
// motor            pin IOID_2
// led GREEN (TX)   pin IOID_7  (LED1)
// led RED   (RX)   pin IOID_6  (LED2)
// ADC0             pin DIO23
// UART_RX          pin IOID_3
// UART_TX          pin IOID_4

//Timer 0A
//Timer 1A
//Timer 2A
//-----------------------------------------------------------------------

/*
 *  ======== rfEasyLinkRx_nortos.c ========
 */
/* Application header files */
#include "smartrf_settings/smartrf_settings.h"
#include "Board.h"

/* Standard C Libraries */
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>

/* TI Drivers */
#include <ti/drivers/pin/PINCC26XX.h>
#include <ti/drivers/Power.h>
#include <ti/drivers/rf/RF.h>
#include <ti/drivers/timer/GPTimerCC26XX.h>
#include <ti/devices/DeviceFamily.h>
#include <ti/drivers/UART.h>
#include <ti/drivers/PWM.h>
#include <ti/drivers/ADC.h>

/* Driverlib APIs */
#include DeviceFamily_constructPath(driverlib/sys_ctrl.h)

/* EasyLink API Header files */
#include "easylink/EasyLink.h"



//----------------------------- Defines -------------------------


/* Undefine to remove async mode */
#define RFEASYLINKRX_ASYNC
#define RFEASYLINKTX_BURST_SIZE                 10
#define RFEASYLINKTXPAYLOAD_LENGTH              5
#define PRESCALER_MISURA_BATTERIA_IN_SECONDI    60              //in secondi
#define SOGLIA_BATTERIA_SCARICA                 2000000         //in uv
#define SOGLIA_INTERVENTO_dB                    (-60)           //in dB
#define PERIODO_TRASMISSIONE                    (SysCtrlClockGet() - 1UL)/5 //è 2 secondo //(SysCtrlClockGet() - 1UL)/10 //è 1 secondo

/* ADC sample count */
#define ADC_SAMPLE_COUNT  (10)


/* Pin driver handle */
static PIN_Handle pinHandle;
static PIN_State pinState;

/*
 * Application LED pin configuration table:
 *   - All LEDs board LEDs are off.
 */
PIN_Config pinTable[] = {
    Board_PIN_LED1_GREEN_TX | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
    Board_PIN_LED2_RED_RX | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
//    Board_PIN_TEST | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
    Board_PIN_MOTOR | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
    PIN_TERMINATE
};


/* Sleep time in microseconds */
PWM_Handle pwm6 = NULL;
PWM_Params paramspwm;

UART_Handle uart;
UART_Params uartParams;

char bufferRX[30];          //buffer uso seriale RX
char bufferTX[30];          //buffer uso seriale TX

EasyLink_RxPacket  myrxPacket =  { {0}, 0, 0, {0} };
EasyLink_TxPacket txPacket =  { {0}, 0, 0, {0} };

static uint16_t seqNumber;
static volatile bool txDoneFlag;
static volatile uint8_t txSleepPeriodsElapsed;



#ifdef RFEASYLINKRX_ASYNC
/* GPTimer handle and timeout value */
GPTimerCC26XX_Handle hTimer;
GPTimerCC26XX_Value rxTimeoutVal;

/* GPTimer handle and timeout value */
GPTimerCC26XX_Handle hTimerTX;
GPTimerCC26XX_Value txTimeVal;

/* GPTimer handle and timeout value */
GPTimerCC26XX_Handle hTimerFiltroRx;
GPTimerCC26XX_Value  FiltroRxTimeVal;

/* GP Timer Callback */
void rxTimeoutCb(GPTimerCC26XX_Handle handle,
                 GPTimerCC26XX_IntMask interruptMask);

void start_txCb(GPTimerCC26XX_Handle handle,
                 GPTimerCC26XX_IntMask interruptMask);

void disabilita_filtroRXCb(GPTimerCC26XX_Handle handle,
                 GPTimerCC26XX_IntMask interruptMask);

static volatile bool rxDoneFlag;
static volatile bool rxTimeoutFlag;

uint32_t absTime;
static uint8_t txBurstSize = 0;
uint8_t TXRequest=0;
uint8_t FiltroRx=0;
#endif


bool Beep=false;
bool MotoreOn=false;
char TogglerMotore=0;

char PrescalerTXRequest=0;

int16_t PrescalerBatteria=PRESCALER_MISURA_BATTERIA_IN_SECONDI;

uint32_t FineCorsaFiltro;

/* ADC conversion result variables */
uint16_t adcValue0;
uint32_t adcValue0MicroVolt;
uint16_t adcValue1[ADC_SAMPLE_COUNT];
uint32_t adcValue1MicroVolt[ADC_SAMPLE_COUNT];
uint32_t ris_media;
uint8_t cnt;
int_fast16_t res;
ADC_Handle   adc;

int32_t Vbatteria;

uint8_t ContatoreTXSenzaRX=0;

void Leggo_Vbat (void);



/***** Function definitions *****/
#ifdef RFEASYLINKRX_ASYNC


void rxDoneCb(EasyLink_RxPacket * rxPacket, EasyLink_Status status)
{
    uint32_t currTimerVal, currTimerVal1;

    if (status == EasyLink_Status_Success)
    {
        /* Toggle LED2 to indicate RX */
        PIN_setOutputValue(pinHandle, Board_PIN_LED2_RED_RX, 1);   // led rosso RX
        
        ContatoreTXSenzaRX=0;
        
        /*
         * Stop the Receiver timeout timer, find the current free-running
         * counter value and add it to the existing interval load value
         */
        GPTimerCC26XX_stop(hTimer);
        currTimerVal = GPTimerCC26XX_getValue(hTimer);
        GPTimerCC26XX_setLoadValue(hTimer, rxTimeoutVal + currTimerVal);

        memcpy((uint8_t*)&myrxPacket, (uint8_t*)rxPacket, sizeof(EasyLink_RxPacket));

       if (myrxPacket.rssi>SOGLIA_INTERVENTO_dB)
       {
           Beep=true;
           PWM_start(pwm6);   // attiva BUZZER
           MotoreOn=true;
           FiltroRx=1;

           GPTimerCC26XX_stop(hTimerFiltroRx);          //attiva la base tempi di trasmissione
           currTimerVal1 = GPTimerCC26XX_getValue(hTimerFiltroRx);
           //FineCorsaFiltro=55000000 + currTimerVal1;
           FineCorsaFiltro=FiltroRxTimeVal + currTimerVal1;
           GPTimerCC26XX_setLoadValue(hTimerFiltroRx, FineCorsaFiltro);
           GPTimerCC26XX_start(hTimerFiltroRx);         //attiva la base tempi filtro rx

           sprintf(bufferRX, "BEEP ON, RSSI = %d ID = %d %d %d\r", myrxPacket.rssi , myrxPacket.payload[2], myrxPacket.payload[3], myrxPacket.payload[4]);
       }
       else
       {
               if (FiltroRx==0)
               {
                 Beep=false;
                 PWM_stop(pwm6);     // disattiva BUZZER
                 MotoreOn=false;
               }
               sprintf(bufferRX, " %d%d%d  RSSI = %d ID = %d %d %d\r", txPacket.payload[2], txPacket.payload[3], txPacket.payload[4], myrxPacket.rssi , myrxPacket.payload[2], myrxPacket.payload[3], myrxPacket.payload[4]);
       }
    }
    else if(status == EasyLink_Status_Aborted)
    {
        /* Toggle LED1 to indicate command aborted */
//      sprintf(bufferRX,"RX Timeout!\r");
    }
    else
    {
        /* Toggle LED1 and LED2 to indicate error */
        /*
         * Stop the Receiver timeout timer, find the current free-running
         * counter value and add it to the existing interval load value
         */
        GPTimerCC26XX_stop(hTimer);
        currTimerVal = GPTimerCC26XX_getValue(hTimer);
        GPTimerCC26XX_setLoadValue(hTimer, rxTimeoutVal + currTimerVal);
    }

    rxDoneFlag = true;
}


void txDoneCb(EasyLink_Status status)
{
    if (status == EasyLink_Status_Success)
    {
        /* Toggle LED1 to indicate TX */
//        PIN_setOutputValue(pinHandle, Board_PIN_LED1_GREEN_TX,!PIN_getOutputValue(Board_PIN_LED1_GREEN_TX));   // led verde TX
        sprintf(bufferTX, "TX: ID = %d %d %d\r", txPacket.payload[2], txPacket.payload[3], txPacket.payload[4]);
    }
    else if(status == EasyLink_Status_Aborted)
    {
        /* Toggle LED2 to indicate command aborted */
        sprintf(bufferTX, "Send ABORT ERROR!\r");
    }
    else
    {
        /* Toggle LED1 and LED2 to indicate error */
        sprintf(bufferTX, "Generic ERROR!\r");
    }
    txDoneFlag = true;
    txSleepPeriodsElapsed = 0;
}
#endif //RFEASYLINKRX_ASYNC










//§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§
 //         INIZIO MAIN CON INIZIALIZZAZIONI
 //§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§

void *mainThread(void *arg0)
{

    /* Period and duty in microseconds */
    uint16_t   pwmPeriod = 250;
    //uint16_t   duty = 0;
    //uint16_t   dutyInc = 100;


    /* Open LED pins */
    pinHandle = PIN_open(&pinState, pinTable);
    if (pinHandle == NULL)
    {
        while(1);
    }

    /* Clear LED pins */
    PIN_setOutputValue(pinHandle, Board_PIN_LED1_GREEN_TX, 0);   // led verde TX
    PIN_setOutputValue(pinHandle, Board_PIN_LED2_RED_RX, 0);   // led rosso RX


    const char  startPrompt[] = "Opening UART and RF:\r\n";


    ADC_Params   params_adc;




    UART_init();
    PWM_init();
    ADC_init();


    // va messo dopo init altrimrenti errore
    ADC_Params_init(&params_adc);
    adc = ADC_open(Board_ADC0, &params_adc);   // è stato assegnato



    PWM_Params_init(&paramspwm);
    paramspwm.dutyUnits = PWM_DUTY_US;
    paramspwm.dutyValue = 0;
    paramspwm.periodUnits = PWM_PERIOD_US;
    paramspwm.periodValue = pwmPeriod;




    /* CreatUART_Params_inite a UART with data processing of. */
    UART_Params_init(&uartParams);
    uartParams.writeDataMode = UART_DATA_BINARY;
    uartParams.readDataMode = UART_DATA_BINARY;
    uartParams.readReturnMode = UART_RETURN_FULL;
    uartParams.readEcho = UART_ECHO_OFF;
    uartParams.baudRate = 115200;


    uart = UART_open(Board_UART0, &uartParams);


    if (uart == NULL)
    {
        /* UART_open() failed */
        while (1);
    }


    pwm6 = PWM_open(Board_PWM6, &paramspwm);
    if (pwm6 == NULL)
    {
        /* Board_PWM0 did not open */
        while (1);
    }


    if (adc == NULL)
    {
        //Display_printf(display, 0, 0, "Error initializing ADC0\n");
        while (1);
    }




    PWM_setDuty(pwm6, 125);
    PWM_stop(pwm6);


    /* Write to the UART before starting RX */
    UART_write(uart, startPrompt, sizeof(startPrompt));

    static uint8_t txBurstSize = 0;

    /* Reset the sleep period counter */
    txSleepPeriodsElapsed = 0;
    /* Set the transmission flag to its default state */
    txDoneFlag = false;



#ifdef RFEASYLINKRX_ASYNC
    /* Reset the timeout flag */
    rxTimeoutFlag = false;
    /* Set the reception flag to its default state */
    rxDoneFlag = false;

    /* Open the GPTimer driver */
    GPTimerCC26XX_Params params;
    GPTimerCC26XX_Params_init(&params);
    params.width          = GPT_CONFIG_32BIT;
    params.mode           = GPT_MODE_ONESHOT;
    params.direction      = GPTimerCC26XX_DIRECTION_UP;
    params.debugStallMode = GPTimerCC26XX_DEBUG_STALL_OFF;
    hTimer = GPTimerCC26XX_open(Board_GPTIMER0A, &params);
    if(hTimer == NULL)
    {
        while(1);
    }

    /* Set Timeout value to 300ms */
    rxTimeoutVal = (SysCtrlClockGet()*20UL)/10UL - 1UL;
    GPTimerCC26XX_setLoadValue(hTimer, rxTimeoutVal);


    /* Register the GPTimer interrupt */
    GPTimerCC26XX_registerInterrupt(hTimer, rxTimeoutCb, GPT_INT_TIMEOUT);

#else
    // Create an RX packet
    EasyLink_RxPacket rxPacket = {0};
#endif //RFEASYLINKRX_ASYNC




    // Init timer di filtro ricezione
     /* Open the GPTimer driver */
     // GPTimerCC26XX_Params params;
    GPTimerCC26XX_Params_init(&params);
    params.width          = GPT_CONFIG_32BIT;
    params.mode           = GPT_MODE_ONESHOT;
    params.direction      = GPTimerCC26XX_DIRECTION_UP;
    params.debugStallMode = GPTimerCC26XX_DEBUG_STALL_OFF;
    hTimerFiltroRx = GPTimerCC26XX_open(Board_GPTIMER2A, &params);
    if(hTimerFiltroRx == NULL)
    {
        while(1);
    }


    /* Set il tempo di filtro a 2s: SysCtrlClockGet() ti restituisce 1 sec */
    FiltroRxTimeVal = (SysCtrlClockGet()*20UL)/10UL - 1UL;
    GPTimerCC26XX_setLoadValue( hTimerFiltroRx, FiltroRxTimeVal);

    /* Register the GPTimer interrupt */
    GPTimerCC26XX_registerInterrupt(hTimerFiltroRx, disabilita_filtroRXCb, GPT_INT_TIMEOUT);
//     GPTimerCC26XX_start(hTimerFiltroRx); //attiva la base tempi di trasmissione



    // Set base tempi di trasmissione
    /* Open the GPTimer driver */
    // GPTimerCC26XX_Params params;
    GPTimerCC26XX_Params_init(&params);
    params.width          = GPT_CONFIG_32BIT;
    params.mode           = GPT_MODE_ONESHOT;
    params.direction      = GPTimerCC26XX_DIRECTION_UP;
    params.debugStallMode = GPTimerCC26XX_DEBUG_STALL_OFF;
    hTimerTX = GPTimerCC26XX_open(Board_GPTIMER1A, &params);
    if(hTimerTX == NULL)
    {
        while(1);
    }

//    /* Set Timeout value to 300ms */
//      txTimeVal = (SysCtrlClockGet()*10UL)/10UL - 1UL;

 /* Set Timeout value to 100ms */
    txTimeVal = PERIODO_TRASMISSIONE;
    GPTimerCC26XX_setLoadValue(hTimerTX, txTimeVal);
 /* Register the GPTimer interrupt */
    GPTimerCC26XX_registerInterrupt(hTimerTX, start_txCb, GPT_INT_TIMEOUT);
    GPTimerCC26XX_start(hTimerTX);                  //attiva la base tempi di trasmissione



    // Initialize the EasyLink parameters to their default values
    EasyLink_Params easyLink_params;
    EasyLink_Params_init(&easyLink_params);


    /*
     * Initialize EasyLink with the settings found in easylink_config.h
     * Modify EASYLINK_PARAM_CONFIG in easylink_config.h to change the default
     * PHY
     */
    if (EasyLink_init(&easyLink_params) != EasyLink_Status_Success)
    {
        while(1);
    }

    /*
     * If you wish to use a frequency other than the default, use
     * the following API:
     * EasyLink_setFrequency(868000000);
     */

        EasyLink_setFrequency(930000000);
        EasyLink_setRfPower(-10);



    PIN_setOutputValue(pinHandle, Board_PIN_MOTOR, 0);


    Leggo_Vbat();
    Vbatteria=4000000;   // messo per evitare al primo power on che intervenga funzione batteria scarica




    //§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§
    //         INIZIO MAINLOOP
    //§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§
    while(1)
    {
#ifdef RFEASYLINKRX_ASYNC

    //§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§
    //  SE SERVE VAI IN TX
    //§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§
    if (TXRequest){

        /* Toggle LED1 to indicate TX */
        PIN_setOutputValue(pinHandle, Board_PIN_LED1_GREEN_TX,1);   // led verde TX
        TXRequest=0;
        
        //Se hai fatto 2 trasmissioni senza ricezioni stronca il beep
        ContatoreTXSenzaRX++;
        
        if  (ContatoreTXSenzaRX>=2){
          ContatoreTXSenzaRX=2;
          
            Beep=false;
            PWM_stop(pwm6);     // disattiva BUZZER
            MotoreOn=false;
        }

        //CONFIGURA ED ESEGUI TRASMISSIONE

            /* Create packet with incrementing sequence number and random payload */
            txPacket.payload[0] = (uint8_t)(seqNumber >> 8);
            txPacket.payload[1] = (uint8_t)(seqNumber++);

            txPacket.payload[2] = 91;
            txPacket.payload[3] = 92;
            txPacket.payload[4] = 93;

            txPacket.len = RFEASYLINKTXPAYLOAD_LENGTH;

            /*
             * Address filtering is enabled by default on the Rx device with the
             * an address of 0xAA. This device must set the dstAddr accordingly.
             */
            txPacket.dstAddr[0] = 0xaa;

            /* Add a Tx delay for > 500ms, so that the abort kicks in and brakes the burst */
            if(EasyLink_getAbsTime(&absTime) != EasyLink_Status_Success)
            {
                // Problem getting absolute time
            }

            if(txBurstSize++ >= RFEASYLINKTX_BURST_SIZE)
            {
                /* Set Tx absolute time to current time + 1s */

                txPacket.absTime = absTime + EasyLink_ms_To_RadioTime(1000);
                txBurstSize = 0;
            }
            /* Else set the next packet in burst to Tx in 100ms */
            else
            {
                /* Set Tx absolute time to current time + 100ms */
                txPacket.absTime = absTime + EasyLink_ms_To_RadioTime(1);
            }

            /*
             * Set the Transmit done flag to false, callback will set it to true
             * Also set the sleep counter to 0
             */
            txDoneFlag = false;
            txSleepPeriodsElapsed = 0;

            /* Transmit the packet */
            EasyLink_transmitAsync(&txPacket, txDoneCb);

            while(!txDoneFlag){
                /*
                 * Set the device to sleep for 108ms. The packet transmission is
                 * set 100 ms in the future but takes about 7ms to complete and
                 * for the execution to hit the callback. A 1ms buffer is added to
                 * the sleep time to ensure the callback always execute prior to
                 * the end of usleep().
                 */
                usleep(60000);

                /* check to see if the transmit flag was set during sleep */
                if(!txDoneFlag){
                    txSleepPeriodsElapsed++;
                    if(txSleepPeriodsElapsed == 3){
                        /*3 times executed. We need to abort the transmission */
                        if(EasyLink_abort() == EasyLink_Status_Success)
                        {
                            /*
                             * Abort will cause the txDoneCb to be called and the
                             * txDoneFlag to be set
                             */
                            while(!txDoneFlag){};
                        }
                        break;
                    }
                }
            }
    }else{
        if (PrescalerBatteria)
            PrescalerBatteria--;
        else{
            PrescalerBatteria=PRESCALER_MISURA_BATTERIA_IN_SECONDI;
            Leggo_Vbat();
        }

    }




    //§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§
    //       VAI IN RICEZIONE
    //§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§

    // Set the Receive done flag to false, callback will
        /* Toggle LED1 to indicate TX */
        PIN_setOutputValue(pinHandle, Board_PIN_LED1_GREEN_TX,0);     // led verde TX

        // set it to true
        rxDoneFlag = false;

        // Wait to receive a packet
        EasyLink_receiveAsync(rxDoneCb, 0);

        /*
         * Start the Receiver timeout timer (300ms) before
         * EasyLink_receiveAsync enables the power policy
         */
       // GPTimerCC26XX_start(hTimer);

        while(rxDoneFlag == false){
            bool previousHwiState = IntMasterDisable();
            /*
             * Tricky IntMasterDisable():
             * true  : Interrupts were already disabled when the function was
             *         called.
             * false : Interrupts were enabled and are now disabled.
             */

            IntMasterEnable();
            Power_idleFunc();
            IntMasterDisable();


            if(!previousHwiState)
            {
                IntMasterEnable();
            }

            /* Break if timeout flag is set */
            if((rxTimeoutFlag == true)||(TXRequest)){
                /* Reset the timeout flag */
                rxTimeoutFlag = false;
                /* RX timed out, abort */
                if(EasyLink_abort() == EasyLink_Status_Success)
                {
                /* Wait for the abort */
                    while(rxDoneFlag == false){};
                }
                break;
            }
        }

//        while(rxDoneFlag == false){
//            /* Break if timeout flag is set */
//             if((rxTimeoutFlag == true)||(TXRequest)){
//                 /* Reset the timeout flag */
//                 rxTimeoutFlag = false;
//                 /* RX timed out, abort */
//                 if(EasyLink_abort() == EasyLink_Status_Success)
//                 {
//                 /* Wait for the abort */
//                     while(rxDoneFlag == false){};
//                 }
//                 break;
//             }
//        }
        UART_write(uart, bufferRX , strlen(bufferRX));
        bufferRX[0]=0;

        /* Toggle LED1 to indicate RX */
        PIN_setOutputValue(pinHandle, Board_PIN_LED2_RED_RX, 0);  // led rosso RX

#else
        rxPacket.absTime = 0;
        EasyLink_Status result = EasyLink_receive(&rxPacket);

        if (result == EasyLink_Status_Success)
        {
            /* Toggle LED2 to indicate RX */
            PIN_setOutputValue(pinHandle, Board_PIN_LED2_RED_RX,!PIN_getOutputValue(Board_PIN_LED2_RED_RX));            // led rosso RX
        }
        else
        {
            /* Toggle LED1 and LED2 to indicate error */
            PIN_setOutputValue(pinHandle, Board_PIN_LED1_GREEN_TX,!PIN_getOutputValue(Board_PIN_LED1_GREEN_TX));        // led verde TX
            PIN_setOutputValue(pinHandle, Board_PIN_LED2_RED_RX,!PIN_getOutputValue(Board_PIN_LED2_RED_RX));            // led rosso RX
        }
#endif //RFEASYLINKRX_ASYNC

    }
    //§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§
    //          FINE MAINLOOP
    //§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§


}




#ifdef RFEASYLINKRX_ASYNC




/* GP Timer Callback Function */
void rxTimeoutCb(GPTimerCC26XX_Handle handle,
                 GPTimerCC26XX_IntMask interruptMask)
{
    /* Set the Timeout Flag */
    rxTimeoutFlag = true;

    /*
     * Timer is automatically stopped in one-shot mode and needs to be reset by
     * loading the interval load value
     */
    GPTimerCC26XX_setLoadValue(hTimer, rxTimeoutVal);
}





/* GP Timer Callback Function */
void start_txCb(GPTimerCC26XX_Handle handle,
                 GPTimerCC26XX_IntMask interruptMask)
{
    uint16_t pippo;
    uint32_t gino;

    if (PrescalerTXRequest) PrescalerTXRequest--;
    else{
        PrescalerTXRequest=10;
        TXRequest=1;
    }

    //§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§
    //          GESTIONE USCITA MOTORE
    //§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§
            if (TogglerMotore)
                TogglerMotore--;

            if (TogglerMotore==0){
               TogglerMotore=20;
               //Qui controllo solo se il motore va acceso/spento
               if (MotoreOn){
                   PIN_setOutputValue(pinHandle, Board_PIN_MOTOR, 1);
               }else{
                   PIN_setOutputValue(pinHandle, Board_PIN_MOTOR, 0);
               }
           }

           if (Vbatteria<SOGLIA_BATTERIA_SCARICA){
              if ((TogglerMotore==8)||(TogglerMotore==3)){
                  PIN_setOutputValue(pinHandle, Board_PIN_MOTOR, 1);
              }
               if ((TogglerMotore==7)||(TogglerMotore==2)){
                   PIN_setOutputValue(pinHandle, Board_PIN_MOTOR, 0);
               }
           }else{
               //Qui controllo solo se il motore va acceso/spento
               if (MotoreOn){
                   PIN_setOutputValue(pinHandle, Board_PIN_MOTOR, 1);
               }else{
                   PIN_setOutputValue(pinHandle, Board_PIN_MOTOR, 0);
               }
           }
   //§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§
   //          FINE GESTIONE USCITA MOTORE
   //§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§

       /*
        * Timer is automatically stopped in one-shot mode and needs to be reset by
        * loading the interval load value
        */
       pippo = rand();
       gino  = pippo*30;
       GPTimerCC26XX_setLoadValue(hTimerTX, txTimeVal+gino);
    GPTimerCC26XX_start(hTimerTX);                              //attiva la base tempi di trasmissione
}





void disabilita_filtroRXCb(GPTimerCC26XX_Handle handle,
                 GPTimerCC26XX_IntMask interruptMask)
{

    FiltroRx=0;

  //  PIN_setOutputValue(pinHandle, Board_PIN_MOTOR, 0);

}

#endif // RFEASYLINKRX_ASYNC



void Leggo_Vbat (void)
{
    ris_media = 0;
    for (cnt = 0; cnt < ADC_SAMPLE_COUNT; cnt++)
    {
        res = ADC_convert(adc, &adcValue1[cnt]);

        if (res == ADC_STATUS_SUCCESS)
        {

            adcValue1MicroVolt[cnt] = ADC_convertRawToMicroVolts(adc, adcValue1[cnt]);

            ris_media = ris_media + adcValue1MicroVolt[cnt];

            sprintf(bufferRX, "Valore ADC (uV) = %d\r", adcValue1MicroVolt[cnt]);
            UART_write(uart, bufferRX , strlen(bufferRX));
        }
        else
        {
            //Display_printf(display, 0, 0, "ADC1 convert failed (%d)\n", i);
        }
    }

    ris_media = ris_media /10;
    Vbatteria= ris_media;

    sprintf(bufferRX, "Valore mediato (uV) = %d\r", ris_media);
    UART_write(uart, bufferRX , strlen(bufferRX));
}



