/*
 * MAIN.c
 *
 * Created: 6/24/2019 11:49:48 AM
 * 
 *  ######################################################################################################
 *  DISCLAIMER:
 *  OptConnect Management, LLC provides this documentation in support of its products for the internal use
 *  of its current and prospective customers. The publication of this document does not create any other
 *  right or license in any party to use any content contained in or referred to in this document and any
 *  modification or redistribution of this document is not permitted. While efforts are made to ensure
 *  accuracy, typographical and other errors may exist in this document. OptConnect Management, LLC reserves
 *  the right to modify or discontinue its products and to modify this and any other product documentation
 *  at any time.
 * 
 *  All OptConnect products are sold subject to its published Terms and Conditions and subject to any
 *  separate terms agreed with its customers. No warranty of any type is extended by publication of this
 *  documentation, including, but not limited to, implied warranties of merchantability, fitness for a
 *  particular purpose and non-infringement.
 * 
 *  OptConnect is a trademark, and OptConnect ema is a trademark, of OptConnect Management, LLC. All
 *  trademarks, service marks and similar designations referenced in this document are the property of
 *  their respective owners
 *  #######################################################################################################
 * 
 *  version: 1.0
 * 
 *  History:
 *  Version     Description                                     Date
 *  1.0         Initial Release                                 5/19/2020
 */ 

#include <atmel_start.h>
#include "emaPlay.h"
#include "oc_leaf.h"
#include <stdio.h>

int main(void)
{
    // structures to hold AT transaction, ema, and ema:Play data
    struct modem_at_context ema_modem_handle;
    struct emaLink_context emaLink_handle;
    static struct ema_status ema;
    static struct emaPlay_status emaPlay;

    // timers
    uint32_t system_task_exec_timer;
    uint32_t system_adc_scan_timer;
    uint32_t system_env_read_timer;

    // event(input sw, din) status
    uint8_t ev_sts = 0;

    #if OPT_AUTO_START
    uint8_t powered_up = 0;
    #endif

    // Initializes MCU, drivers and middleware 
    atmel_start_init();
    // init the system 1ms tick time base
    emaPlay_init_sys1ms_tick( );

    // init q's for modem uart rx data
    emaPlay_q_init( &modem_uart_sync_rx_q, modem_uart_sync_rx_q_buff, sizeof(modem_uart_sync_rx_q_buff) );
    emaPlay_q_init( &modem_uart_async_rx_q, modem_uart_async_rx_q_buff, sizeof(modem_uart_async_rx_q_buff) );
    // init q's for emaLink uart rx data
    emaPlay_q_init( &link_uart_sync_rx_q, link_uart_sync_rx_q_buff, sizeof(link_uart_sync_rx_q_buff) );
    emaPlay_q_init( &link_uart_async_rx_q, link_uart_async_rx_q_buff, sizeof(link_uart_async_rx_q_buff) );

    // complete setup of the modem uart 
    emaPlay_uart_setup( &ema_modem_uart, &ema_modem_uart_io, (usart_cb_t)emaPlay_modem_tx_cb, (usart_cb_t)emaPlay_modem_rx_cb );
    // complete setup of the emaLink uart 
    emaPlay_uart_setup( &ema_mgmt_uart, &ema_mgmt_uart_io, (usart_cb_t)emaPlay_emaLink_tx_cb, (usart_cb_t)emaPlay_emaLink_rx_cb );

    // set the AT send/receive handler for the modem uart
    emaModemAT_Init( &ema_modem_handle, emaPlay_modem_at_query );
    // set the AT send/receive handler for the emaLink uart
    emaLinkAT_Init( &emaLink_handle, emaPlay_emaLink_at_query );

    TIME_DELAY_ms(500);

    // init the debug input/output 
    #ifdef DEBUG
    uint32_t dbg_timer;
    emaPlay_q_init( &dbg_rx_q, dbg_q_rx_buff, sizeof(dbg_q_rx_buff) );
    emaPlay_q_init( &dbg_tx_q, dbg_q_tx_buff, sizeof(dbg_q_tx_buff) );
    emaPlay_uart_setup( &emaPlay_debug_uart, &emaPlay_dbg_uart_io, (usart_cb_t)emaPlay_dbg_tx_cb, (usart_cb_t)emaPlay_dbg_rx_cb );
    usart_async_enable( &emaPlay_debug_uart );
    emaPlay_dbg_uart_send( "\r\n\r\nema:Play \"Getting Started with ema demo\" FW Version: ", sizeof("\r\n\r\nema:Play \"Getting Started with ema demo\" FW Version: "), 50, 0 );
    emaPlay_dbg_uart_send( __DATE__, sizeof(__DATE__), 20, 0 );
    emaPlay_dbg_uart_send( "\r\n'?' for menu\r\n", sizeof("\r\n'?' for menu\r\n"), 20, 0 );
    dbg_timer = TIME_ELAPSED_ms(0);
    #endif

    //init adc
    adc_sync_enable_channel( &ADC_0, 0 );

    // init i2c for sht30 sensor
	i2c_m_sync_set_slaveaddr( &I2C, 0x0045, I2C_M_SEVEN );
	i2c_m_sync_enable( &I2C );

    // turn on the photo detector
    gpio_set_pin_level( n_photosense_en, false );

    // read chip uniue serial number
    emaPlay_get_chip_SN( emaPlay.sn );
	
	// init timers
    system_task_exec_timer = TIME_ELAPSED_ms(0);
    system_adc_scan_timer = TIME_ELAPSED_ms(0);
    system_env_read_timer = TIME_ELAPSED_ms(0);

    // main application loop
    while (1) {

        // handle any asynch URCs from the emaLink UART, this must be called frequently and periodically
        emaPlay_emaLink_URC_handler( &emaLink_handle, &ema_modem_handle );

        // execute the main system task every SYS_TASK_EXECUTION_INTERVAL, or if an event occurs
        if ( ( TIME_ELAPSED_ms(system_task_exec_timer) >= SYS_TASK_EXECUTION_INTERVAL ) || ev_sts ){
            system_task_exec_timer = TIME_ELAPSED_ms(0);
            #if OPT_AUTO_START
            if ( powered_up == 0 ) {
                powered_up = 1;
                ev_sts = 2;
            }
            #endif
            emaPlay_system_task(&emaLink_handle, &ema_modem_handle, &ema, &emaPlay, &ev_sts);
        }

        // scan the adc inputs every ADC_SCAN_INTERVAL_MS
        if ( TIME_ELAPSED_ms(system_adc_scan_timer) >= ADC_SCAN_INTERVAL_MS ){
            system_adc_scan_timer = TIME_ELAPSED_ms(0);
            emaPlay_scan_analog_inputs( &emaPlay );
        }

        // get the environment temp/hum every ENV_READ_INTERVAL
        if ( TIME_ELAPSED_ms(system_env_read_timer) >= ENV_READ_INTERVAL ){
            system_env_read_timer = TIME_ELAPSED_ms(0);
            emaPlay_read_temp_humidiity( &emaPlay );
        }

        // process any events that occured
        ev_sts = emaPlay_check_events( &emaPlay );

        // process debug input/ouput
        #ifdef DEBUG
        if ( TIME_ELAPSED_ms(dbg_timer) >= DBG_TASK_INTERVAL ){
            dbg_timer = TIME_ELAPSED_ms(0);
            dbg_task( &emaLink_handle, &ema_modem_handle, &ema, &emaPlay );
        }
        #endif
    }
}
