//------------------------------------------------------------------------------
//-- BluNode v4
//------------------------------------------------------------------------------
//
// Funciones:
//
//  1. Timer 0: Primer advertising al colocar la pila
//  2. Timer 1: Ventana de tiempo de espera (sleep)
//  3. Timer 2: Ventana de envío de mensajes (advertising)
//
//------------------------------------------------------------------------------


/* Bibliotecas integradas en la aplicación */

#include "mbed.h"
#include "BLE.h"
#include "UARTService.h"

#include "nrf.h"
#include "nrf_temp.h"
#include "nrf_gpio.h"










#define NEED_CONSOLE_OUTPUT 1 /*  Set this if you need debug messages on the console;
* it will have an impact on code-size and power consumption. */

#if NEED_CONSOLE_OUTPUT
#define DEBUG(...) { printf(__VA_ARGS__); }
#else
#define DEBUG(...)
#endif


//------------------------------------------------------------------------------
//-- Funciones utilizadas 
//------------------------------------------------------------------------------

/* Inicializadores */

void adc_channels_init(void);                                                   // Inicialización de los canales análogos (escala, rango, tipo, etc...)
void app_init();                                                                // Inicialización de la "aplicación"
void adv_init();                                                                // Inicialización de los parámetros de advertising
void btn_init();                                                                // Inicialización de eventos de botón

/* Utilitarios de advertising */

void adv_start();                                                               // Función de inicio de advertising
void adv_stop();                                                                // Función de detención del advertising
void adv_clear();                                                               // Función para borrar la data de "payload"
void adv_stop_and_clear();                                                      // Función paera detener y borrar los datos de "payload"
void adv_payload_set4adv(void);                                                 // Función para actualizar los valores de medición y carga datos en "payload"


/* Obtiene resultados de medición de los canales análogos */

uint16_t adc_channel_read(int adcChannel);                                      // Lectura del canal "adcChannel"
void adc_channels_read(void);                                                   // Lectura de todos los canales configurados en adc_channels[]
uint8_t soc_temperature_read(void);                                             // Lectura de temperatura interna del chip (SoC Temperature)


/* Procesos para ejecutar por eventos */

void time_monitor();                                                            // Proceso que se ejecuta en ventanas de tiempos para espera (sleep)
void adv_run();                                                                 // Proceso que ejecuta la activación de envío de advertising de resultados
void adv_run_first_time();                                                      // Proceso que ejecuta el envío de advertising inicial
void btn1_event_monitor();                                                      // Proceso que monitorea si se ha pulsado el botón
void btn1_pressed_time();                                                       // Proceso que monitorea si se mantiene el botón apretado


/* Funciones para pinDetect */

//void pin_key_pressed();

void button1_pressed();

//------------------------------------------------------------------------------


//------------------------------------------------------------------------------
//-- Variables v3
//------------------------------------------------------------------------------

//PinDetect pin( BUTTON1 );                                                       // P0.17 en PCA10028 es el botón 1

//------------------------------------------------------------------------------
















//------------------------------------------------------------------------------
//-- Atributos y variables internas del programa
//------------------------------------------------------------------------------

UARTService *uartServicePtr;
BLE ble;




//DigitalOut activeLed(LED1, 1);
//DigitalOut connectLed(LED2, 0);

//DigitalIn     btn1(BUTTON1);                                                    // Variable que permite obtener el estado del botón 1 (pulsado/no pulsado)
//InterruptIn   btn1_press(BUTTON1);                                              // Variable que permite ejecutar una función dependiente del evento de "pulsar botón 1"


//@2017-03-09, By TIGG (Requested By RVR)
DigitalOut   out_activity_status(P0_21);
DigitalOut   out_adc_enabled(P0_22);                                            // Salida digital para activación de PS de circuito ADC de medición: Se activa antes de medir

DigitalIn     btn1(P0_17);                                                      // Variable que permite obtener el estado del botón 1 (pulsado/no pulsado)
InterruptIn   btn1_press(P0_17);                                                // Variable que permite ejecutar una función dependiente del evento de "pulsar botón 1"




//------------------------------------------------------------------------------
//-- Definitions - Parameters & Macros
//------------------------------------------------------------------------------

const static char     DEVICE_NAME[] = "BN_0302";


#define     BLUCORE_ADV_LENGHT          0x10    // 2 + 1 + 13
#define     BLUCORE_ADV_TYPE_01_LENGHT  0x10    // 2 + 1 + 13
#define     BLUCORE_ADV_PAYLOAD_OFFSET  0x03    // 3
#define     BLUCORE_ADV_PAYLOAD_LENGHT  0x0D    // 13

#define     BLUCORE_COMPANY_ID          0xC7AB
#define     BLUCORE_BLUNODE_TYPE_01     0x01


//@2017-03-09, By TIGG

#define     OUT_ON                      0
#define     OUT_OFF                     1









//------------------------------------------------------------------------------
//-- Definition - Structures
//------------------------------------------------------------------------------

//-- Tipo payload data para nodo tipo 01

union PayloadDataType01 {
    uint8_t raw[16];
    struct {
        uint16_t    CompanyId;
        uint8_t     Type;
        uint16_t    Counter;
        uint16_t    ADC1_Value;
        uint16_t    ADC2_Value;
        uint16_t    ADC3_Value;
        uint16_t    ADC4_Value;
        uint8_t     DataTail[2];
        uint8_t     SOC_Temperature;
    };
};




















//------------------------------------------------------------------------------
//-- Variables
//------------------------------------------------------------------------------


bool isConnected=false;

static int value0,value1,value2,value3; // stored voltage reading from ADC

char dataOu[30];


/* Timers */

Ticker  t0;
Ticker  t1; // Utilizado para esperar n-veces antes de iniciar un broadcast
Ticker  t2; // Utilizado para broadcast de mensaje
Ticker  t3;

Ticker testTimer;

Ticker btn1_timer;                                                               // Temporizador para monitoreo de tiempo de botón 1 pulsado





//------------------------------------------------------------------------------
//-- Agregados para v2
//------------------------------------------------------------------------------


//-- Utils

#define MSB_16(a) (((a) & 0xFF00) >> 8)
#define LSB_16(a) ((a) & 0x00FF)

//-- Variables


#define adc_channel_count 4

static int          adc_channels[adc_channel_count];
static uint16_t     adc_values[adc_channel_count];
static uint16_t     adc_log_values[adc_channel_count];


static uint8_t      soc_temp = 0;

DigitalOut led1(LED1);
DigitalOut led2(LED2);
DigitalOut led3(LED3);
DigitalOut led4(LED4);



//-- flags


static bool adv_run_first_time_flag;
static bool monitor_stop_flag;
static bool adv_stop_flag;

static bool btn1_pressed_flag;
static bool btn1_held_flag;
static bool btn1_monitor_stop_flag;






// MAC ADDRESS

const uint8_t bluNodeMACaddress[] = {0x01,0x00,0xFE,0xCA,0xAB,0xc7};

uint8_t payload[BLUCORE_ADV_LENGHT];


// Variables de control y notificación

static uint16_t adv_count = 0;


//-- Parámetros de tiempo

static int time_monitor_count         = 0;
static int time_monitor_max_count     = 6;

static int adv_time_interval          = 100;           // 1000 ms = 1 sec
static int adv_time_periods           = 10;              // 4 times
static int adv_run_count              = 0;

static int app_time_monitor_interval  = 10; //5;             // 15 sec
static int app_adv_run_interval       = 1;              // 1 sec

static int app_btn1_pressed_time      = 3;                                      // Tiempo de monitoreo para determinar si se ha pulsado o mantenido por más de 3 segundos
static int btn1_pressed_count         = 0;

























































//------------------------------------------------------------------------------
//-- Connection Call Back
//------------------------------------------------------------------------------

void connectionCallback(const Gap::ConnectionCallbackParams_t *params)
{
    //DEBUG("Connected \n");

    //connectLed=1;
    isConnected=true;

}

//------------------------------------------------------------------------------


//------------------------------------------------------------------------------
//-- Disconnection Call Back
//------------------------------------------------------------------------------

void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
{
    //ble.startAdvertising();
    isConnected=false;
}

//------------------------------------------------------------------------------



int advActivePeriod;
int sleepActivePeriod;

//------------------------------------------------------------------------------
//-- onDataWritten
//------------------------------------------------------------------------------

void onDataWritten(const GattWriteCallbackParams *params)
{
    if ((uartServicePtr != NULL) && (params->handle == uartServicePtr->getTXCharacteristicHandle())) {


        if (strncmp("param1=",(const char *)params->data,7)==0) {
            sscanf((const char *)params->data,"param1=%i", &advActivePeriod);
            sprintf(dataOu,"Adver=%i sec\n",advActivePeriod);
            ble.updateCharacteristicValue(uartServicePtr->getRXCharacteristicHandle(),(const uint8_t *)dataOu , 20);

        } else if (strncmp("param2=",(const char *)params->data,7)==0) {
            sscanf((const char *)params->data,"param2=%i",&sleepActivePeriod);
            sprintf(dataOu,"Sleep=%i sec\n",sleepActivePeriod);
            
            ble.updateCharacteristicValue(uartServicePtr->getRXCharacteristicHandle(),(const uint8_t *)dataOu, 20);

        } else if (strncmp("scan",(const char *)params->data,4)==0) {
            ble.updateCharacteristicValue(uartServicePtr->getRXCharacteristicHandle(),(const uint8_t *)dataOu, 20);
            wait(5);

            value1 = (int) (adc_channel_read(2) & 0x00FFFF);
            sprintf(dataOu,"A1=%i \n",value1);
            
            ble.updateCharacteristicValue(uartServicePtr->getRXCharacteristicHandle(),(const uint8_t *)dataOu, 20);
            wait(5);
            value2 = (int) (adc_channel_read(3) & 0x00FFFF);
            sprintf(dataOu,"A2=%i \n",value2);
            DEBUG("%s",dataOu);
            ble.updateCharacteristicValue(uartServicePtr->getRXCharacteristicHandle(),(const uint8_t *)dataOu, 20);
            wait(5);
            //my_analogin_read_u16A3();
            value3 = (int) (adc_channel_read(4) & 0x00FFFF);
            sprintf(dataOu,"A3=%i \n",value3);
            DEBUG("%s",dataOu);
            ble.updateCharacteristicValue(uartServicePtr->getRXCharacteristicHandle(),(const uint8_t *)dataOu, 20);


        }
    }
    
}

//------------------------------------------------------------------------------


















//------------------------------------------------------------------------------
//--
//------------------------------------------------------------------------------

void advActiveFunc (void)
{
    //sleepCall.detach();
    //t1.attach(time_monitor, 10);

}

//------------------------------------------------------------------------------

void SleepFunc(void)
{
    //t.attach(my_analogin_read,1); //repeatedly read analog every second.
    //t.attach(adc_channels_read, 1);
    //t.attach(time_monitor, 10);
    //DEBUG("\nWAKE UP!!");
    //activeLed=1;
}



















































































































//------------------------------------------------------------------------------    ------>>>>  INICIO DE LA APLICACION
//: Inicio de la aplicación                                                         ------------------------------------------------------------------------------
//------>>>





//------------------------------------------------------------------------------
//-- Main: BluNode v3 (1.3.0)
//------------------------------------------------------------------------------

int main(void)
{
    //-- Inicialización de la aplicación

    app_init();

    // t0.attach(adv_first_time, 10);

    // Inicia el conteo de tiempo de espera, hay que ajustar el tiempo de
    // revisión de condiciones para esperar el tiempo definido antes del adv

    t1.attach(time_monitor, app_time_monitor_interval);

    // Activa UART

    UARTService uartService(ble);
    uartServicePtr = &uartService;

    // Active eventos del botón

    //button1Press.fall(&advActiveFunc);
    
    btn1_press.fall(&button1_pressed);
    
    //testTimer.attach(btn1_event_monitor,1);

    // Funciones v3 para detección de botón 1 (P0.17)
    
    //pin.mode( PullDown );
    //pin.attach_asserted(&pin_key_pressed);
    //pin.setSampleFrequency(10000);

    ///// DEBUG
    out_adc_enabled = 0;
    wait_ms(500);
    out_adc_enabled = 1;
    wait_ms(500);
    
    out_adc_enabled = 0;
    wait_ms(500);
    out_adc_enabled = 1;
    wait_ms(500);
    
    out_adc_enabled = 0;
    wait_ms(500);
    out_adc_enabled = 1;
    wait_ms(500);
    
    out_adc_enabled = 0;
    wait_ms(500);
    out_adc_enabled = 1;
    wait_ms(500);
    
    out_adc_enabled = 0;
    wait_ms(500);
    out_adc_enabled = 1;
    wait_ms(500);
    /////
    
    /* Infinite Loop*/

    while(true) {

        // espera por un evento del stack BLE (Temporizadores, botones, etc...)

        ble.waitForEvent();

        // Control de proceso time_monitor

        if (monitor_stop_flag) {
            // detiene ejecución del proceso "time_monitor"
            t1.detach();
            // reset de variables de control
            monitor_stop_flag = false;
            time_monitor_count = 0;
            // Solo para debug
            //led3 = !led3;
            // activa proceso de advertising
            t2.attach(adv_run, app_adv_run_interval);
        }

        // Control de proceso advertising

        if (adv_stop_flag) {
            // detiene ejecución del proceso "adv_run"
            t2.detach();                                                        // detiene el timer del proceso de advertising
            // reset de variables de control
            adv_stop_flag = false;
            adv_run_count = 0;
            // solo para debug
            //led4 = !led4;
            // activa proceso de time_monitor
            t1.attach(time_monitor, app_time_monitor_interval);                 // inicia el timer del proceso de espera
        }
        
        // Control de proceso de monitoreo de botón 1
        
        if (btn1_monitor_stop_flag) {
            // detiene jecución del proceso btn1_pressed_time
            btn1_timer.detach();
            // reset de variables de control
            btn1_monitor_stop_flag = false;
            btn1_pressed_count = 0;
            
            
            if (btn1_pressed_flag && !btn1_held_flag) {
                /* Implementar one-touch button */
                led3 = OUT_ON;
                led4 = OUT_OFF;
            }
            
            if (btn1_pressed_flag && btn1_held_flag) {
                /* Implementar held-touch button */
                led4 = OUT_ON;
                led3 = OUT_OFF;
            }
            
            btn1_pressed_flag = false;
            btn1_held_flag = false;
            
            btn1_press.enable_irq();                                            // Activa la detección de botón
         }
        
        
        

    }
}

//------------------------------------------------------------------------------


//<<<------
//:Fin de Aplicación                                                                ------------------------------------------------------------------------------
//------------------------------------------------------------------------------    <<<<------  FIN DE LA APLICACION






























//------------------------------------------------------------------------------    ------>>>>  INICIO DE IMPLEMENTACION DE FUNCIONES Y PROCESOS
//: Inicio implementación de funciones y procesos                                   ------------------------------------------------------------------------------
//------>>>















//------------------------------------------------------------------------------
//-- Funciones mejoradas v2, v3
//------------------------------------------------------------------------------


//-- Inicializadores


//------------------------------------------------------------------------------
//-- Funciones de inicialización
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
//-- App Init
//------------------------------------------------------------------------------
//
// Inicialización de la aplicación
//
//------------------------------------------------------------------------------

void app_init()
{
    nrf_temp_init();
    ble.init();
    adv_init();
    adc_channels_init();
    // reset LED's
    led1 = 1; //0; // Inicia encendido
    led2 = 1;
    led3 = 1;
    led4 = 1;

    adv_count = 0;
    monitor_stop_flag = false;
    adv_stop_flag = false;

}

//------------------------------------------------------------------------------


//------------------------------------------------------------------------------
//-- advertising init
//------------------------------------------------------------------------------

void adv_init()
{

    /**/

    ble.onDisconnection(disconnectionCallback);
    ble.onDataWritten(onDataWritten);
    ble.onConnection(connectionCallback);

    //-- Set MAC address (like UUID)

    ble.setAddress(Gap::ADDR_TYPE_PUBLIC, bluNodeMACaddress);


}

//------------------------------------------------------------------------------


//------------------------------------------------------------------------------
//-- Inicialización de canales ADC
//------------------------------------------------------------------------------
//  - Configure Resolution to 10 bits
//  - Configure ADC input selection and prescalar settings
//  - Internal reference voltage of 1.2V. Onethird prescaling -> 3.6V
//  - ADC reference selection to internal 1.2V VBG
//  - Select Pin to be used as ADC input pin -> Disable analog pins
//  - Select external reference pin -> No external reference (we use internal reference of 1.2V)
//------------------------------------------------------------------------------

void adc_channels_init(void)
{

    NRF_ADC->ENABLE = ADC_ENABLE_ENABLE_Enabled;
    NRF_ADC->CONFIG = (ADC_CONFIG_RES_10bit << ADC_CONFIG_RES_Pos) |
                      (ADC_CONFIG_INPSEL_AnalogInputOneThirdPrescaling << ADC_CONFIG_INPSEL_Pos) |
                      (ADC_CONFIG_REFSEL_VBG << ADC_CONFIG_REFSEL_Pos) |
                      (ADC_CONFIG_PSEL_AnalogInput0 << ADC_CONFIG_PSEL_Pos) |
                      (ADC_CONFIG_EXTREFSEL_None << ADC_CONFIG_EXTREFSEL_Pos);

}

//------------------------------------------------------------------------------







//-- Utilitarios de advertising


//------------------------------------------------------------------------------
//-- adv_start
//------------------------------------------------------------------------------

void adv_start()
{
    ble.startAdvertising();
}

//------------------------------------------------------------------------------


//------------------------------------------------------------------------------
//-- adv_stop
//------------------------------------------------------------------------------
//
// Detiene la emisión de advertising
//
//------------------------------------------------------------------------------

void adv_stop()
{
    ble.stopAdvertising();
}

//------------------------------------------------------------------------------


//------------------------------------------------------------------------------
//-- adv_clear
//------------------------------------------------------------------------------
//
// borra el contenido del paquete de datos
//
//------------------------------------------------------------------------------

void adv_clear()
{
    ble.clearAdvertisingPayload();
}

//------------------------------------------------------------------------------


//------------------------------------------------------------------------------
//-- adv_stop_and_clear
//------------------------------------------------------------------------------
//
// Detiene la emisión de advertising
// borra el contenido del paquete de datos
//
//------------------------------------------------------------------------------

void adv_stop_and_clear()
{
    ble.stopAdvertising();
    ble.clearAdvertisingPayload();
}

//------------------------------------------------------------------------------


//------------------------------------------------------------------------------
//-- adv_payload_set4adv
//------------------------------------------------------------------------------
// set del payload para envío de data después de la lectura de ADC
//------------------------------------------------------------------------------

void adv_payload_set4adv(void)
{
    //-- Company Id
    payload[0]      = MSB_16(BLUCORE_COMPANY_ID);
    payload[1]      = LSB_16(BLUCORE_COMPANY_ID);
    //-- Node Type
    payload[2]      = BLUCORE_BLUNODE_TYPE_01;
    //-- Counter
    payload[3]      = MSB_16(adv_count);
    payload[4]      = LSB_16(adv_count);
    // ADC Channel 1
    payload[5]      = MSB_16(adc_values[0]);
    payload[6]      = LSB_16(adc_values[0]);
    // ADC Channel 2
    payload[7]      = MSB_16(adc_values[1]);
    payload[8]      = LSB_16(adc_values[1]);
    // ADC Channel 3
    payload[9]      = MSB_16(adc_values[2]),
                      payload[10]     = LSB_16(adc_values[2]);
    // ADC Channel 4
    payload[11]     = MSB_16(adc_values[3]),
                      payload[12]     = LSB_16(adc_values[3]);
    // 2 bytes spare
    payload[13]     = 0x01;
    payload[14]     = 0x02;
    // SOC Temperature
    payload[15]     = soc_temp; //((uint8_t) (( soc_temp & 0x000000FF) & 0xFF ));



    adv_clear();

    ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
    ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
    ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
    ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));

    ble.accumulateAdvertisingPayload(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, payload, sizeof(payload));

    // Set advertising interval

    ble.setAdvertisingInterval(adv_time_interval);

    //ble.startAdvertising();
}

//------------------------------------------------------------------------------






//-- Obtiene resultados de medición de los canales análogos


 //------------------------------------------------------------------------------
//-- lectura de valor canal ADC (1...8)
//------------------------------------------------------------------------------

uint16_t adc_channel_read(int adcChannel)
{
    uint16_t result = 0;

    if (adcChannel > 0 && adcChannel < 9) {

        NRF_ADC->CONFIG   &= ~ADC_CONFIG_PSEL_Msk;

        switch (adcChannel) {
            case 1:
                NRF_ADC->CONFIG   |= ADC_CONFIG_PSEL_AnalogInput0 << ADC_CONFIG_PSEL_Pos;
                break;
            case 2:
                NRF_ADC->CONFIG   |= ADC_CONFIG_PSEL_AnalogInput1 << ADC_CONFIG_PSEL_Pos;
                break;
            case 3:
                NRF_ADC->CONFIG   |= ADC_CONFIG_PSEL_AnalogInput2 << ADC_CONFIG_PSEL_Pos;
                break;
            case 4:
                NRF_ADC->CONFIG   |= ADC_CONFIG_PSEL_AnalogInput3 << ADC_CONFIG_PSEL_Pos;
                break;
            case 5:
                NRF_ADC->CONFIG   |= ADC_CONFIG_PSEL_AnalogInput4 << ADC_CONFIG_PSEL_Pos;
                break;
            case 6:
                NRF_ADC->CONFIG   |= ADC_CONFIG_PSEL_AnalogInput5 << ADC_CONFIG_PSEL_Pos;
                break;
            case 7:
                NRF_ADC->CONFIG   |= ADC_CONFIG_PSEL_AnalogInput6 << ADC_CONFIG_PSEL_Pos;
                break;
            case 8:
                NRF_ADC->CONFIG   |= ADC_CONFIG_PSEL_AnalogInput7 << ADC_CONFIG_PSEL_Pos;
                break;

            default:
                break;
        }

        NRF_ADC->TASKS_START = 1;

        while (((NRF_ADC->BUSY & ADC_BUSY_BUSY_Msk) >> ADC_BUSY_BUSY_Pos) == ADC_BUSY_BUSY_Busy) { }

        result = (uint16_t) ( NRF_ADC -> RESULT & 0x0000FFFF );

    }

    return (result);

}

//------------------------------------------------------------------------------


//------------------------------------------------------------------------------
//-- Lectura de temperatura interna del CPU
//------------------------------------------------------------------------------

uint8_t soc_temperature_read(void)
{
    uint8_t result = 0;
    static uint32_t temp;
    NRF_TEMP->TASKS_START = 1;
    while (NRF_TEMP->EVENTS_DATARDY == 0) {}
    NRF_TEMP->EVENTS_DATARDY = 0;
    temp = NRF_TEMP->TEMP ;
    result = (uint8_t) (( temp & 0x000000FF) & 0xFF );
    NRF_TEMP->TASKS_STOP = 1;

    return (result);

}

//------------------------------------------------------------------------------


//------------------------------------------------------------------------------
//-- Lectura de todos los canales ADC
//------------------------------------------------------------------------------

void adc_channels_read(void)
{
    
    if(!isConnected) {
        for (int i = 0; i < adc_channel_count; i++) {
            adc_values[i] = adc_channel_read(adc_channels[i]);
        }

        soc_temp = soc_temperature_read();
    }
}

//------------------------------------------------------------------------------



//------------------------------------------------------------------------------
//-- Funciones para PinDetect
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
//-- pin_key_pressed
//------------------------------------------------------------------------------
// Agregdado en v3
/*
void pin_key_pressed()
{
    /////DEBUG                                                                  // Flash de LED4 para indicar la detección de pulsar el botón 1
    led4 = 0;
    wait_ms(100);
    led4 = 1; 
    /////
}
*/
//------------------------------------------------------------------------------


















//-- Procesos de base de tiempo y reacción a eventos


//------------------------------------------------------------------------------
//-- Funciones ejecutadas en base a eventos
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
//-- button1_pressed
//------------------------------------------------------------------------------

void button1_pressed()
{
    btn1_press.disable_irq();                                                   // Deshabilita el monitoreo del evento de botón
    btn1_pressed_flag = true;                                                   // Marca de botón pulsado
    
    /////DEBUG                                                                  // Flash de LED4 para indicar la detección de pulsar el botón 1
    led4 = OUT_ON;
    wait_ms(100);
    led4 = OUT_OFF; 
    /////*/
    
    btn1_timer.attach(btn1_event_monitor, 1);                                          // Inicia temporizador para evaluar si el botón sigue pulsado después de 3 segundos
    
    
}

//------------------------------------------------------------------------------



//------------------------------------------------------------------------------
//-- Funciones ejecutadas en base de tiempo
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
//-- T0: Advertising inicial (Agregado en v3)
//------------------------------------------------------------------------------

void adv_run_first_time()
{
    // Not implemented!!!
}

//------------------------------------------------------------------------------


//------------------------------------------------------------------------------
//-- T1: Time Monitor Function
//------------------------------------------------------------------------------
// Se ejecuta cada lapso de tiempo t1
//------------------------------------------------------------------------------

void time_monitor()
{
    time_monitor_count++;

    led1 = OUT_ON;
    wait_ms(100);
    led1 = OUT_OFF;

    if (time_monitor_count > time_monitor_max_count) {
        // lectura del valor de los canales ADC
        adc_channels_read();
        // en esta versión se actualiza la data de "payload" del advertising
        // to-do: implementar lógica de comparación con valores anteriores
        //adv_stop_and_clear();                 // Detiene y borra "payload"
        adv_count++;                // incrementa el contador de paquetes de datos
        adv_payload_set4adv();
        monitor_stop_flag = true;   // flag de detención del proceso de time_monitor
        adv_run_first_time_flag = true;
        //adv_start();                // Inicia advertising con los datos cargados
    }
}

//------------------------------------------------------------------------------


//------------------------------------------------------------------------------
//-- T2: Advertising Run Function
//------------------------------------------------------------------------------
// Se ejecuta cada lapso de tiempo t2
//------------------------------------------------------------------------------

void adv_run()
{
    led2 = OUT_ON;
    wait_ms(100);
    led2 = OUT_OFF;

    if (adv_run_first_time_flag) {
        // reset de la variable de control

        adv_run_first_time_flag = false;

        // inicia el advertising
        // pre-req: Se ha cargado el payload antes de activar la función

        adv_start();



    }
    /**/

    adv_run_count++;

    if (adv_run_count > adv_time_periods) {
        // detención del proceso de envio de advertising

        //adv_stop_and_clear();
        adv_stop();                                                             // detención de advertising
        adv_stop_flag = true;                                                   // indicación de detención del proceso de advertising
    }
}

//------------------------------------------------------------------------------


//------------------------------------------------------------------------------
//-- btn1_event_monitor
//------------------------------------------------------------------------------
// Función que permite realizar el monitoreo del estado del botón 1
//------------------------------------------------------------------------------

void btn1_event_monitor()
{
    
    ///// DEBUG
    //led3 = 0;
    out_activity_status = OUT_ON;
    wait_ms(100);
    //led3 = 1;
    out_activity_status = OUT_OFF;
    /////
    
    btn1_pressed_count++;
    
    ///// DEBUG
    //led4 = btn1.read();
    /////
    
    if (btn1_pressed_count > app_btn1_pressed_time) {
        if (btn1.read() == 0) {
            btn1_held_flag = true;        
        }
        btn1_monitor_stop_flag = true;
    }
     
}

/*
void btn1_debug()
{
    btn1_pressed_count++;
    led3 = btn1.read();
}    
*/
//------------------------------------------------------------------------------





//:Fin de funciones y procesos                                                      ------------------------------------------------------------------------------
//------------------------------------------------------------------------------    <<<<------  FIN DE IMPLEMENTACION DE FUNCIONES Y PROCESOS



