Proyecto ABInBev para la tarjeta Guaria 1/2.

main.cpp

Committer:
fmanzano_dtk
Date:
24 months ago
Revision:
19:5580a9a54ad5
Parent:
16:772ea817ec43

File content as of revision 19:5580a9a54ad5:

/**
 * @file    main.cpp
 * @author  Felícito Manzano (felicito.manzano@detektor.com.sv)
 * @brief 
 *          Proyecto para ABInBev Cervecería Nacional de Panamá, incluye el soporte 
 *          para para 5 entradas digitales, conexión vía Bluetooth SPP con equipo
 *          Teltonika FMU130 para el envío y recepción de mensajes al servidor
 *          del ecosistema Detektor, también incluye un puerto serial TTL para
 *          controlar el módulo de voz JQ8400, puerto serial para el lector de
 *          huellas GT521Fx y puerto serial RS232 con el sensor de lluvia RG9.
 * @version 0.1
 * @date    2020-09-26
 * 
 * @copyright Copyright (c) 2020
 * 
 */

#include "mbed.h"
//#include "platform/mbed_thread.h"
#include "stm32f4xx_hal_iwdg.h"
#include "BufferedSerial.h"
#include "ics5_pinout.hpp"
#include "jq8400_voice.hpp"
#include "voice_cn_pa.hpp"
#include "New_GT521Fx.hpp"
#include "gpio_exe.hpp"
#include "fmu130_exe.hpp"
#include "fingerprint_exe.hpp"
#include "playlist_exe.hpp"
#include "playlist.hpp"
#include "teltonika_fmu130.hpp"
#include "fireup_exe.hpp"
#include "safety_tip_exe.hpp"
#include "eeprom.h"
#include "flash_eeprom.h"
#include "eeprom_exe.hpp"
#include "flash_ee_exe.hpp"
#include "USBSerial.h"
#include "custom_def.hpp"
#include "flash_eeprom.h"
#include <ctype.h>

// Las funciones de FLASH son arreglos
uint16_t    VirtAddVarTab[NB_OF_VAR]    = {ADDR_FINGERPRINT, 
                                           ADDR_OVERRIDE_FP,
                                           ADDR_OVERRIDE_QT,
                                           ADDR_IDLE_SHUTDOWN,
                                           ADDR_IDLE_REMINDER,
                                           ADDR_IDLE_S_TIME,
                                           ADDR_IDLE_R_TIME,
                                           ADDR_SEATBELT_READ,
                                           ADDR_ENFORCE_SB,
                                           ADDR_PILOT_BTYPE,
                                           ADDR_COPILOT_BTYPE,
                                           ADDR_CREW_BTYPE,
                                           ADDR_RAINSENSOR,
                                           ADDR_RS_SILENTMODE,
                                           ADDR_RS_SAMPLE_T,
                                           ADDR_WET_LIMIT,
                                           ADDR_WET_WARNING,
                                           ADDR_DRY_LIMIT,
                                           ADDR_DRY_WARNING,
                                           ADDR_SAFETY_TIP,
                                           ADDR_SAFETY_TIP_T,
                                           ADDR_GEOZONE,
                                           ADDR_VOLUME,
                                           ADDR_BLE_RESET,
                                           ADDR_BLE_RESET_T};
uint16_t        VarDataTab[NB_OF_VAR]   = {0}; 

/**
 *  INTERFACES:
 *          Se utiliza la librería ICS5_Pinout para hacer el cambio de pines
 *          en base a la tarjeta para la que se compilará. Se tiene soporte para
 *          las tarjetas NUCLEO F303K8, NUCLEO F091RC, ICS3 e ICS5.
 */
#define             M_DEBUG           1
#define             FP_READER_GT521   1
extern const bool   external_eeprom;

#if (ICS_BOARD_ID == 11)
    // Serial
    BufferedSerial      avl_uart(BLE_TX, BLE_RX, 1024, 2);               //! UART TTL para enlace con el equipo Teltonika FMU130.
    BufferedSerial      voice_uart(TTL_VOICE_TX, TTL_VOICE_RX);                     //! UART TTL para comunicación con el módulo de voz JQ8400.

    #if FP_READER_GT521 == 1
        BufferedSerial      fingerprint(TTL_TX, TTL_RX);
    #else

    #endif
    #ifdef M_DEBUG
        USBSerial           myPC_debug;
    #endif
    
    // PCB Support
    InterruptIn         mybutton(USER_BUTTON);
    DigitalIn           bluetooth_state(BT_STATE);
    DigitalOut          myled(USER_LED1);
    DigitalOut          flashLED(USER_LED2);
    DigitalOut          out2_ble_reset(BT_RESET);

    // Outputs
    DigitalOut          out1_fingerprint(OUTPUT1_NEGATIVE);
    DigitalOut          out3_gt521fx(OUTPUT2_NEGATIVE);
    DigitalOut          out4_gt521fx(OUTPUT3_NEGATIVE);

    // Inputs
    DigitalIn           in1_ignition(INPUT1_POSITIVE);
    DigitalIn           in2_pilot(INPUT2_NEGATIVE);
    DigitalIn           in3_copilot(INPUT3_NEGATIVE);
    DigitalIn           in4_crew(INPUT4_NEGATIVE);
    DigitalIn           in5_rain_sensor(INPUT5_NEGATIVE);
#endif

// EEPROM
EEPROM ep(I2C_SDA_EE, I2C_SCL_EE, 0x0, EEPROM::T24C32);
int32_t eeprom_size,max_size;
#define EEPROM_ADDR 0x0
#define MIN(X,Y) ((X) < (Y) ? (X) : (Y))
#define MAX(X,Y) ((X) > (Y) ? (X) : (Y))
typedef struct _MyData {
                int16_t sdata;
                int32_t idata;
                float fdata;
} MyData;
static void myerror(std::string msg) {
  printf("Error %s\n",msg.c_str());
  exit(1);
}

// FLASH
/* Start @ of user Flash area */
#define FLASH_USER_START_ADDR   ADDR_FLASH_SECTOR_2                             
/* End @ of user Flash area : sector start address + sector size -1 */
#define FLASH_USER_END_ADDR     ADDR_FLASH_SECTOR_7 +  GetSectorSize(ADDR_FLASH_SECTOR_7) -1
#define DATA_32                 ((uint32_t)0x12345678)
       
// VOICE
queue                       colaPlaylist(10);

// HAL BASED
static IWDG_HandleTypeDef   my_iwdg;


//  FUNCIONALIDADES
// Nuevas banderas para habilitar/deshabilitar funciones.
bool    functionality_idle_shutdown;
bool    functionality_idle_reminder;
bool    functionality_seatbelt_reading;
bool    functionality_force_driver_buclke;
bool    functionality_rain_sensor;
bool    functionality_rainSensor_silentMode;
bool    functionality_fingerprint_reader;
bool    functionality_safety_tip;
bool    functionality_geo_warning;
bool    functionality_ble_autoreset;
bool    fingerprint_remotly_disable;
bool    fingerprint_override;
bool    finterprint_flag_working    = false;
bool    fingerprint_flag_poweroff   = false;

/**
 *  BANDERAS:
 *          Se utiliza un esquema de banderas para indicar el cambio de un estado
 *          y que se debe realizar un procesamiento especial (transmitir un 
 *          evento, activar un accesorio, etc.)
 */

float   time_safety_tip;        // 15 minutos = 900
float   time_sample_rain;       // muestras a 9 equivalen a 90 segundos o minuto y medio.
float   time_ble_autoreset;
bool    flag_rain_no_answer         = false;
bool    flag_idle_force_shutdown    = false;
bool    flag_idle_reminder          = false;
bool    flag_fingerprint_Sleep      = false;
bool    flag_driver_loggin          = false;
bool    flag_playingSound           = false;
bool    flag_safety_tip             = false;
bool    rain_sensor_type            = false;    // True = RS232, False = DIN
bool    flag_query_rain_sensor;
bool    flag_notify_rain_sensor;
bool    flag_read_inputs;
bool    flag_fingerprint_turOn;
bool    flag_fri_ics;
int     flag_fingerprint_query;
int     flag_ignition;
int     flag_pilot_seatbelt;
int     flag_copilot_seatbelt;
int     flag_crew_pilot_seatbelt;
int     flag_ble_connection_state;
int     flag_rainsensorDigInput;

/**
 * ENTRADAS:
 *          Para la lectura de entradas digitales se utiliza un estructura de 4
 *          variables que incluyen el estado actual de la entrada, el estado previo 
 *          de la entrada, un arreglo de cuatro posiciones para tomar muestras y
 *          realizar la función de debug y un contador para indicar la posición en
 *          el arreglo para capturar la muestra de la entrada.
 */
bool    ignition;
bool    estado_actual_ignicion;
bool    ignition_prev;
bool    ignition_samples[4];
int     ignition_counter;

bool    pilot_seatbelt;
bool    pilot_seatbelt_prev;
bool    pilot_seatbelt_samples[4];
int     pilot_seatbelt_c;

bool    copilot_seatbelt;
bool    copilot_seatbelt_prev;
bool    copilot_seatbelt_samples[4];
int     copilot_seatbelt_c;

bool    crew_seatbelt;
bool    crew_seatbelt_prev;
bool    crew_seatbelt_samples[4];
int     crew_seatbelt_c;

bool    ble_connection_state;
bool    ble_connection_state_prev;
bool    ble_connection_state_samples[4];
int     ble_connection_state_samples_c;

bool    rg9_raining;
bool    rg9_raining_prev;
bool    rg9_raining_samples[10];
int     rg9_raining_samples_c;


/**
 * FMU130:
 *          Se definen las variables para recepción de datos del equipo FMU130 vía
 *          enlace Bluetooth SPP
 */
char    fmu130_payload[1024];
int     fmu130_payload_type;
int     incoming_bytes;
int     temp_JQ8400_Volume;

/**
 * HUELLAS:
 *          Se definen las variables para el procesamiento del módulo lector de 
 *          huellas conectado a un UART-TTL
 */
int     bluetooth_cmd_id;
int     fingerprint_id;
int     fingerprint_login;
char    fingerprint_hex[997];
char    fingerprint_asc[499];
char    fingerprint_cmd[4];

/**
 * EVENTOS_TELTONIKA:
 *          Se definen las variables para el procesamiento de Tramas del equipo
 *          Teltonika FMU130 con eventos como los hábitos de manejo.
 */
char    avl_fmu130_header[2];
char    avl_fmu130_imei[16];
int     avl_fmu130_id;
int     avl_fmu130_status;

// Inicialización de variables de Velocidad
int     wet_Speed_Warning;
int     wet_Speed_Limit;
int     dry_Speed_Warning;
int     dry_Speed_Limit;
char    wet_Speed_CMD[30];
char    dry_Speed_CMD[30];

// Fingerprint Override
int     fp_override_limit;   // Limite de lecturas fallidas antes de autorizar
int     fp_unauthorized_count   = 0;
int     items_queue             = 0;           

// Inicialización de Entradas Digitales para Cinturón de Seguridad
// Detalle de entradas por cada cinturon
bool    pilot_buckle_type;
int     pilot_buckleUp;
int     pilot_unfasten;
bool    copilot_buckle_type;
int     copilot_buckleUp;
int     copilot_unfasten;
bool    crew_buckle_type;
int     crew_buckleUp;
int     crew_unfasten;

/**
 * TICKER DE mbed:
 *          Definición de eventos gestionados por eventos temporizados.
 */
Ticker  tick_blink;
Ticker  tick_rain_sensor;                                                     // para comunicación vía UART
Ticker  tick_readInputs;
Ticker  tick_fingerprint;
Ticker  tick_idle_shutdown;
Ticker  tick_idle_reminder;
Ticker  tick_safety_tip;
Ticker  tick_playingAudio;
Ticker  tick_fri_ics;
Ticker  tick_autoreset_ble;

/**
 * @brief   Función para hacer titilar el LED de usuario.
 * 
 */
void blink_led() {
    myled = !myled;
}

/**
 * @brief   Activación de la bandera para leer entradas digitales.
 * 
 */
void readInputs() {
    flag_read_inputs = true;
}

// Función al presionar boton
void pressed() {
    if (external_eeprom) {
        eeprom_Default();
    } else {
        flash_Default();
    }
    wait_ms(100);
    NVIC_SystemReset();
}

int main() {
    
    /**
     * @brief   INICIAR INTERFACES
     *          Se define el baudrate para las interfaces USART, y el modo para 
     *          las entradas digitales. También se envía a tierra el pin para la
     *          interface Bluetooth.
     */
    avl_uart.baud(115200);
    #if FP_READER_GT521 == 1
        fingerprint.baud(9600);    
    #else

    #endif
    voice_uart.baud(9600);
    in1_ignition.mode(PullDown);
    in2_pilot.mode(PullDown);
    in3_copilot.mode(PullDown);
    in4_crew.mode(PullDown);
    in5_rain_sensor.mode(PullDown);
    wait_us(1000000);
    out1_fingerprint = 0;
    out2_ble_reset = 0;
    out3_gt521fx = 0;
    out4_gt521fx = 0;
    mybutton.fall(&pressed);

    //Load Flash
    boot_message();
    if (external_eeprom) {
        eeprom_size = ep.getSize();
        load_eepromVar();
    } else { 
        readFlash_Booting();
    }
    
    // Configuración Inicial de Nivel de volumen.
    jq8400_iniVol(temp_JQ8400_Volume, &voice_uart);

    // Iniciar comandos variables de cambio de velocidad
    sprintf(dry_Speed_CMD, "setparam 11104:%d;50092:%d", dry_Speed_Warning, dry_Speed_Limit);
    sprintf(wet_Speed_CMD, "setparam 11104:%d;50092:%d", wet_Speed_Warning, wet_Speed_Limit);

    /**
     * @brief   Se asignan las funciones para los eventos temporizados de titilar
     *          el LED de usuario, realizar el muestreo de las entradas digitales
     *          y la consulta al sensor de lluvia.
     */
    tick_blink.attach(&blink_led, 2.0);
    tick_readInputs.attach(&readInputs, 0.250);
    if (functionality_rain_sensor) {
        tick_rain_sensor.attach(&queryRG9, time_sample_rain);
    }
    if (functionality_ble_autoreset) {
        tick_autoreset_ble.attach(&BLE_reset, time_ble_autoreset);
    }

    /**
     * @brief   INICIAR WATCHDOG
     *          Se crea una instancia para el Watchdog, se define el pre-escaler
     *          y el valor máximo en caso que no se actualice se genera el reinicio.
    */
    my_iwdg.Instance        = IWDG;
    my_iwdg.Init.Prescaler  = IWDG_PRESCALER_32;
    my_iwdg.Init.Reload     = 0x0FFF;
    HAL_IWDG_Init(&my_iwdg);
    
    while (true) {
        
        //! Procesamiento del puerto serial vinculado al FMU130 vía Bluetooth.
        process_FMU130();

        //! Verificar si deben efectuarse la lectura de entradas digitales.
        if(flag_read_inputs) {
            process_Inputs();
        }

        //! Verificar si debe activarse el lector de huellas.
        if (flag_fingerprint_query) {
            HAL_IWDG_Refresh(&my_iwdg);
            #if FP_READER_GT521 == 1
                identify_fingerPrint();
            #else

            #endif            
        }

        //! Verificar si se debe apagar el lector de huellas.
        if (fingerprint_flag_poweroff) {
            out3_gt521fx = out4_gt521fx = finterprint_flag_working = fingerprint_flag_poweroff = false;
            #ifdef M_DEBUG
                myPC_debug.printf("[MAIN] - OUT3:FALSE\r\n");
            #endif
        }

        //! Verificar si debe consultarse el estado del sensor de lluvia.
        if (flag_query_rain_sensor) {   
            //process_rainSensor();
            process_inputRainSensor();
        }

        //! verificar si debe ejecutarse un evento de apagado por ralentí.
        if (flag_idle_force_shutdown) {
            exe_idle_shutdown();            
        }

        if (flag_idle_reminder) {
            exe_idle_reminder();
        }

        if (flag_safety_tip) {
            exe_SafetyTip();
        }

        if (flag_fri_ics) {
            tx_fri_ics();
        }

        if (!(flag_playingSound)) {
            processPlaylist();
        }

        //! Actualizar Watchdog
        HAL_IWDG_Refresh(&my_iwdg);
    }
}