/**
 * Copyright (c) 2014 - 2019, Nordic Semiconductor ASA
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form, except as embedded into a Nordic
 *    Semiconductor ASA integrated circuit in a product or a software update for
 *    such product, 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.
 *
 * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
 *    contributors may be used to endorse or promote products derived from this
 *    software without specific prior written permission.
 *
 * 4. This software, with or without modification, must only be used with a
 *    Nordic Semiconductor ASA integrated circuit.
 *
 * 5. Any software provided in binary form under this license must not be reverse
 *    engineered, decompiled, modified and/or disassembled.
 *
 * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
 *
 */
/** @file
 *
 * @defgroup ble_sdk_app_beacon_main main.c
 * @{
 * @ingroup ble_sdk_app_beacon
 * @brief Beacon Transmitter Sample Application main file.
 *
 * This file contains the source code for an Beacon transmitter sample application.
 */

#include <stdbool.h>
#include <stdint.h>
#include "nordic_common.h"
#include "bsp.h"
#include "nrf_soc.h"
#include "nrf_sdh.h"
#include "nrf_sdh_ble.h"
#include "ble_advdata.h"
#include "app_timer.h"
#include "nrf_pwr_mgmt.h"

#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"
// 2019.01.11 For BLE_Press_Start
#include "app_scheduler.h"
#include "nrf_spi_mngr.h"
#include "nrf_delay.h"

#include "nrf_drv_twis.h"
#include "app_util_platform.h"
#include "nrf_drv_clock.h"
#include "nrf_mtx.h"

//nrf_mtx_t g_mtx;                 // add 2021.03.16 wired_honda (for MUTEX)

void sensor_update(void * p_event_data, uint16_t event_size); // add 2021.04.07

static uint8_t          i2c_spi_data[] = {                /**< Manufacturer specific data in Advertising. */
                                0x00,                                   /**< Sequence No. */
                                0xC4, 0x09,                             /**< Temperature Data. [e.g. 0x09C4 (25 deg)] */
                                0x00, 0x54, 0x3F,                       /**< Pressure Data[0]. [e.g. 0x3F5400 (1013hPa)] */
                                0x00, 0x64, 0x3F,                       /**< Pressure Data[1]. [e.g. 0x3F6400 (1013hPa)] */
                                0x00, 0x74, 0x3F,                       /**< Pressure Data[2]. [e.g. 0x3F7400 (1013hPa)] */
                                0x00, 0x84, 0x3F,                       /**< Pressure Data[3]. [e.g. 0x3F8400 (1013hPa)] */
                                0x00, 0x94, 0x3F                        /**< Pressure Data[4]. [e.g. 0x3F9400 (1013hPa)] */
                                  };

/**
 * @brief Structure for TWIS configuration.
 */
typedef struct
{
    uint8_t slave_addr;                //!< Slave address that this simulator will use to respond to master.
    uint8_t scl_s;                     //!< Slave SCL.
    uint8_t sda_s;                     //!< Slave SCL.
    uint32_t flash_start_addr;         //!< Flash start address for the EEPROM simulation.
} eeprom_sim_config_t;

/* if EEPROM_SIM_ADDRESS_LEN_BYTES == 2, below will configure which byte is sent first by master */
/**
 * @enum address_byte_endian
 * @brief Endianness of the address byte that is received from master.
 */
typedef enum
{
    /*lint -save -e30*/
    BIG_ENDIAN = 0,   /**< MSB is sent first by master for address. */
    LITTLE_ENDIAN,    /**< LSB is sent first by master for address. */
} address_byte_endian;

/**
 * @brief EEPROM simulator configuration.
 *
 * When the emulator is initialized, the configuration is stored here.
 */
static eeprom_sim_config_t m_config;

#define EEPROM_SIM_SIZE                   (320u) //!< Simulated EEPROM size.

/**
 * @brief Memory array.
 *
 * Place that will simulate the memory.
 */
static uint8_t m_memory[EEPROM_SIM_SIZE]; 

#define EEPROM_SIM_SEQ_WRITE_MAX_BYTES    200

/* Maximum number of bytes writable to this slave emulator in one sequential access.
   Maximum allowed is 255.
 */
#define EEPROM_SIM_SEQ_READ_MAX_BYTES     200     //<! Number of data bytes transfer in single request

#define EEPROM_SIM_ADDR                   0x5A      // #49501 //!< seonsor substrate TWI slave address.
//#define EEPROM_SIM_ADDR                   0x5B      // #49502 //!< seonsor substrate TWI slave address.
//#define EEPROM_SIM_ADDR                   0x5C      // #49503 //!< seonsor substrate TWI slave address.
//#define EEPROM_SIM_ADDR                   0x5D      // #49504 //!< seonsor substrate TWI slave address.
//#define EEPROM_SIM_ADDR                   0x5E      // #49505 //!< seonsor substrate TWI slave address.
//#define EEPROM_SIM_ADDR                   0x5F      // #49506 //!< seonsor substrate TWI slave address.
//#define EEPROM_SIM_ADDR                   0x60      // #49507 //!< seonsor substrate TWI slave address.
//#define EEPROM_SIM_ADDR                   0x61      // #49508 //!< seonsor substrate TWI slave address.
//#define EEPROM_SIM_ADDR                   0x62      // #49509 //!< seonsor substrate TWI slave address.
//#define EEPROM_SIM_ADDR                   0x63      // #49510 //!< seonsor substrate TWI slave address.
//#define EEPROM_SIM_ADDR                   0x64      // #49511 //!< seonsor substrate TWI slave address.
//#define EEPROM_SIM_ADDR                   0x65      // #49512 //!< seonsor substrate TWI slave address.
//#define EEPROM_SIM_ADDR                   0x66      // #49513 //!< seonsor substrate TWI slave address.
//#define EEPROM_SIM_ADDR                   0x67      // #49514 //!< seonsor substrate TWI slave address.
//#define EEPROM_SIM_ADDR                   0x68      // #49515 //!< seonsor substrate TWI slave address.
//#define EEPROM_SIM_ADDR                   0x69      // #49516 //!< seonsor substrate TWI slave address.
//#define EEPROM_SIM_ADDR                   0x6A      // #49517 //!< seonsor substrate TWI slave address.
//#define EEPROM_SIM_ADDR                   0x6B      // #49518 //!< seonsor substrate TWI slave address.
//#define EEPROM_SIM_ADDR                   0x6C      // #49519 //!< seonsor substrate TWI slave address.
//#define EEPROM_SIM_ADDR                   0x6D      // #49520 //!< seonsor substrate TWI slave address.
//#define EEPROM_SIM_ADDR                   0x6E      // #49521 //!< seonsor substrate TWI slave address.
//#define EEPROM_SIM_ADDR                   0x6F      // #49522 //!< seonsor substrate TWI slave address.
//#define EEPROM_SIM_ADDR                   0x70      // #49523 //!< seonsor substrate TWI slave address.
//#define EEPROM_SIM_ADDR                   0x71      // #49524 //!< seonsor substrate TWI slave address.
//#define EEPROM_SIM_ADDR                   0x72      // #49525 //!< seonsor substrate TWI slave address.
//#define EEPROM_SIM_ADDR                   0x73      // #49526 //!< seonsor substrate TWI slave address.
//#define EEPROM_SIM_ADDR                   0x74      // #49527 //!< seonsor substrate TWI slave address.
//#define EEPROM_SIM_ADDR                   0x75      // #49528 //!< seonsor substrate TWI slave address.
//#define EEPROM_SIM_ADDR                   0x76      // #49529 //!< seonsor substrate TWI slave address.
//#define EEPROM_SIM_ADDR                   0x77      // #49530 //!< seonsor substrate TWI slave address.


#define EEPROM_SIM_SCL_S         9   //!< Slave SCL pin.
#define EEPROM_SIM_SDA_S         10   //!< Slave SDA pin.

#define EEPROM_SIM_TWIS_INST     1    //!< TWIS interface used by EEPROM simulator.

/* Flash start address to load the RAM with at startup */
#define EEPROM_SIM_FLASH_ADDRESS  0x8000

/* Slave memory addressing byte length */
#define EEPROM_SIM_ADDRESS_LEN_BYTES    2

#define TWI_ADDRESS_CONFIG    LITTLE_ENDIAN

/**
 * @brief Current memory address.
 *
 * Memory pointer for any operation that will be processed on memory array.
 */
static uint16_t m_addr = 0;

/**
 * @brief Receive buffer.
 *
 * Receiving buffer must contain the address and EEPROM_SIM_SEQ_WRITE_MAX_BYTES bytes of data.
 */
static uint8_t m_rxbuff[EEPROM_SIM_ADDRESS_LEN_BYTES + EEPROM_SIM_SEQ_WRITE_MAX_BYTES];

/**
 * @brief Internal error flag.
 *
 * This flag is set if any communication error is detected.
 * It can be cleared by calling the @ref eeprom_simulator_error_get function.
 */
static bool m_error_flag;

/**
* @brief TWIS instance.
*
* TWIS driver instance used by this EEPROM simulator.
*/
static const nrf_drv_twis_t m_twis = NRF_DRV_TWIS_INSTANCE(EEPROM_SIM_TWIS_INST);

/**
 * @brief Start after the READ command.
 *
 * Function sets pointers for TWIS to transmit data from the current address to the end of memory.
 */
static void ees_readBegin(void)
{
    uint32_t read_len = EEPROM_SIM_SEQ_READ_MAX_BYTES;
    volatile uint16_t temp_addr = m_addr;

    if (m_addr + EEPROM_SIM_SEQ_READ_MAX_BYTES > sizeof(m_memory))
    {
        read_len = EEPROM_SIM_SIZE - m_addr;
        temp_addr = 0;
    }

    (void) nrf_drv_twis_tx_prepare(&m_twis, m_memory + m_addr, read_len);
    m_addr = temp_addr;

    sensor_update(NULL, 0); // add 2021.04.07

}

/**
 * @brief Finalize the READ command.
 *
 * Call this function when the read command is finished.
 * It adjusts the current m_addr pointer.
 * @param cnt Number of bytes read.
 */
static void ees_readEnd(size_t cnt)
{
    //m_addr += cnt;
    /*
    m_memory[0] = 0xaa;
    m_memory[1] = 0xbb;
    m_memory[2] = 0xcc;
    m_memory[3] = 0xdd;
    m_memory[4] = 0xee;
    m_memory[5] = 0xff;
    m_memory[6] = 0x11;
    m_memory[7] = 0x22;
    m_memory[8] = 0x33;
    m_memory[9] = 0x44;
    m_memory[10] = 0x55;
    m_memory[11] = 0x66;
    m_memory[12] = 0x77;
    m_memory[13] = 0x88;
    m_memory[14] = 0x99;
    m_memory[15] = 0x00;
    m_memory[16] = 0x01;
    m_memory[17] = 0x02;
    */

    //memcpy(m_memory, i2c_spi_data, 18);

    // start MUTEX 2021.03.16 wired_honda
    //memset(m_memory, 0xff, sizeof(m_memory)); // del 2021.04.07
    //if(nrf_mtx_trylock(&g_mtx))               // del 2021.04.07
    {
  
         //m_addr += cnt; // 2021.02.25 wired_honda
         memcpy(m_memory, i2c_spi_data, 18);
         //nrf_mtx_unlock(&g_mtx);               // del 2021.04.07

     }
    // end MUTEX 2021.03.16 wired_honda
}

/**
 * @brief Set the current address pointer.
 *
 * Sets address for the next operation on the memory array.
 * @param addr Address to set.
 */
static void ees_setAddr(uint16_t addr)
{
    m_addr = addr;
}

/**
 * @brief Perform a write operation on the memory array.
 *
 * Write a single byte into the memory array using @ref m_addr as a write pointer.
 * @param data Data to be written.
 */
static void ees_write(uint8_t data)
{
    if (m_addr >= sizeof(m_memory))
        m_addr = 0;
    m_memory[m_addr++] = data;
}

/**
 * @brief Start after the WRITE command.
 *
 * Function sets pointers for TWIS to receive data.
 * WRITE command does not write directly to memory array.
 * Temporary receive buffer is used.
 * @sa m_rxbuff
 */
static void ees_writeBegin(void)
{
    (void)nrf_drv_twis_rx_prepare(&m_twis, m_rxbuff, sizeof(m_rxbuff));
}

/**
 * @brief Finalize the WRITE command.
 *
 * Call this function when the write command is finished.
 * It sets a memory pointer and writes all received data to the memory array.
 */
static void ees_writeEnd(size_t cnt)
{
    if (cnt > (EEPROM_SIM_ADDRESS_LEN_BYTES - 1))
    {
        size_t n;
#if (EEPROM_SIM_ADDRESS_LEN_BYTES == 1)
        ees_setAddr(m_rxbuff[0]);
#endif

#if (EEPROM_SIM_ADDRESS_LEN_BYTES == 2)
        uint16_t rxbuff;

        if (TWI_ADDRESS_CONFIG == LITTLE_ENDIAN)
        {
            rxbuff = ((m_rxbuff[1] << 8 ) | (m_rxbuff[0]));
        }
        else
        {
            rxbuff = ((m_rxbuff[0] << 8 ) | (m_rxbuff[1]));
        }

        ees_setAddr(rxbuff);
#endif



        for (n=EEPROM_SIM_ADDRESS_LEN_BYTES; n<cnt; ++n)
        {
            ees_write(m_rxbuff[n]);
        }
    }
}

/**
 * @brief Event processing.
 *
 *
 */
static void twis_event_handler(nrf_drv_twis_evt_t const * const p_event)
{
    switch (p_event->type)
    {
    case TWIS_EVT_READ_REQ:
        if (p_event->data.buf_req)
        {
            ees_readBegin();
        }
        break;
    case TWIS_EVT_READ_DONE:
        ees_readEnd(p_event->data.tx_amount);
        break;
    case TWIS_EVT_WRITE_REQ:
        if (p_event->data.buf_req)
        {
            ees_writeBegin();
        }
        break;
    case TWIS_EVT_WRITE_DONE:
        ees_writeEnd(p_event->data.rx_amount);
        break;

    case TWIS_EVT_READ_ERROR:
    case TWIS_EVT_WRITE_ERROR:
    case TWIS_EVT_GENERAL_ERROR:
        m_error_flag = true;
        break;
    default:
        break;
    }
}

/** @} */
 
ret_code_t eeprom_simulator_init(void)
{
    ret_code_t ret;

    m_config.slave_addr                = EEPROM_SIM_ADDR;
    m_config.scl_s                     = EEPROM_SIM_SCL_S;
    m_config.sda_s                     = EEPROM_SIM_SDA_S;
    m_config.flash_start_addr          = EEPROM_SIM_FLASH_ADDRESS;

    /* Initialize RAM with contents of flash */
    for (uint32_t n=0; n<EEPROM_SIM_SIZE; ++n)
    {
        m_memory[n] = *(uint8_t *)(m_config.flash_start_addr + n);
    }
    m_addr = 0;

    const nrf_drv_twis_config_t config =
    {
        .addr               = {m_config.slave_addr, 0},
        .scl                = m_config.scl_s,
        .scl_pull           = NRF_GPIO_PIN_PULLUP,
        .sda                = m_config.sda_s,
        .sda_pull           = NRF_GPIO_PIN_PULLUP,
        .interrupt_priority = APP_IRQ_PRIORITY_HIGH
    };

    /* Init TWIS */
    do
    {
        ret = nrf_drv_twis_init(&m_twis, &config, twis_event_handler);
        if (NRF_SUCCESS != ret)
        {
            break;
        }

        nrf_drv_twis_enable(&m_twis);
    }while (0);
    return ret;

}

// 2019.01.11 For BLE_Press_Start
//------------------------------------------------------------------------------
/**@brief Constant variables of BLE board address. */
//
//static const uint8_t      BD_ADDR[]   = { 0x01, 0x01, 0x00, 0xCA, 0xEA, 0x80 };   /**< Local Bluetooth identity address (1) */
//static const uint8_t      BD_ADDR[]   = { 0x02, 0x01, 0x00, 0xCA, 0xEA, 0x80 };   /**< Local Bluetooth identity address (2) */
//static const uint8_t      BD_ADDR[]   = { 0x03, 0x01, 0x00, 0xCA, 0xEA, 0x80 };   /**< Local Bluetooth identity address (3) */
//static const uint8_t      BD_ADDR[]   = { 0x04, 0x01, 0x00, 0xCA, 0xEA, 0x80 };   /**< Local Bluetooth identity address (4) */
//static const uint8_t      BD_ADDR[]   = { 0x05, 0x01, 0x00, 0xCA, 0xEA, 0x80 };   /**< Local Bluetooth identity address (5) */
// 2019.09.24 Start ### for Extending perpheral address. (DEVICE_HPS4) ###
//static const uint8_t      BD_ADDR[]   = { 0x06, 0x01, 0x00, 0xCA, 0xEA, 0x80 };   /**< Local Bluetooth identity address (6) */
//static const uint8_t      BD_ADDR[]   = { 0x07, 0x01, 0x00, 0xCA, 0xEA, 0x80 };   /**< Local Bluetooth identity address (7) */
//static const uint8_t      BD_ADDR[]   = { 0x08, 0x01, 0x00, 0xCA, 0xEA, 0x80 };   /**< Local Bluetooth identity address (8) */
//static const uint8_t      BD_ADDR[]   = { 0x09, 0x01, 0x00, 0xCA, 0xEA, 0x80 };   /**< Local Bluetooth identity address (9) */
//static const uint8_t      BD_ADDR[]   = { 0x0A, 0x01, 0x00, 0xCA, 0xEA, 0x80 };   /**< Local Bluetooth identity address (10) */
//static const uint8_t      BD_ADDR[]   = { 0x0B, 0x01, 0x00, 0xCA, 0xEA, 0x80 };   /**< Local Bluetooth identity address (11) */
//static const uint8_t      BD_ADDR[]   = { 0x0C, 0x01, 0x00, 0xCA, 0xEA, 0x80 };   /**< Local Bluetooth identity address (12) */
//static const uint8_t      BD_ADDR[]   = { 0x0D, 0x01, 0x00, 0xCA, 0xEA, 0x80 };   /**< Local Bluetooth identity address (13) */
//static const uint8_t      BD_ADDR[]   = { 0x0E, 0x01, 0x00, 0xCA, 0xEA, 0x80 };   /**< Local Bluetooth identity address (14) */
//static const uint8_t      BD_ADDR[]   = { 0x0F, 0x01, 0x00, 0xCA, 0xEA, 0x80 };   /**< Local Bluetooth identity address (15) */
//static const uint8_t      BD_ADDR[]   = { 0x10, 0x01, 0x00, 0xCA, 0xEA, 0x80 };   /**< Local Bluetooth identity address (16) */
//static const uint8_t      BD_ADDR[]   = { 0x11, 0x01, 0x00, 0xCA, 0xEA, 0x80 };   /**< Local Bluetooth identity address (17) */
//static const uint8_t      BD_ADDR[]   = { 0x12, 0x01, 0x00, 0xCA, 0xEA, 0x80 };   /**< Local Bluetooth identity address (18) */
//static const uint8_t      BD_ADDR[]   = { 0x13, 0x01, 0x00, 0xCA, 0xEA, 0x80 };   /**< Local Bluetooth identity address (19) */
//static const uint8_t      BD_ADDR[]   = { 0x14, 0x01, 0x00, 0xCA, 0xEA, 0x80 };   /**< Local Bluetooth identity address (20) */
//static const uint8_t      BD_ADDR[]   = { 0x15, 0x01, 0x00, 0xCA, 0xEA, 0x80 };   /**< Local Bluetooth identity address (21) */
//static const uint8_t      BD_ADDR[]   = { 0x16, 0x01, 0x00, 0xCA, 0xEA, 0x80 };   /**< Local Bluetooth identity address (22) */
//static const uint8_t      BD_ADDR[]   = { 0x17, 0x01, 0x00, 0xCA, 0xEA, 0x80 };   /**< Local Bluetooth identity address (23) */
//static const uint8_t      BD_ADDR[]   = { 0x18, 0x01, 0x00, 0xCA, 0xEA, 0x80 };   /**< Local Bluetooth identity address (24) */
//static const uint8_t      BD_ADDR[]   = { 0x19, 0x01, 0x00, 0xCA, 0xEA, 0x80 };   /**< Local Bluetooth identity address (25) */
//static const uint8_t      BD_ADDR[]   = { 0x1A, 0x01, 0x00, 0xCA, 0xEA, 0x80 };   /**< Local Bluetooth identity address (26) */
//static const uint8_t      BD_ADDR[]   = { 0x1B, 0x01, 0x00, 0xCA, 0xEA, 0x80 };   /**< Local Bluetooth identity address (27) */
//static const uint8_t      BD_ADDR[]   = { 0x1C, 0x01, 0x00, 0xCA, 0xEA, 0x80 };   /**< Local Bluetooth identity address (28) */
//static const uint8_t      BD_ADDR[]   = { 0x1D, 0x01, 0x00, 0xCA, 0xEA, 0x80 };   /**< Local Bluetooth identity address (29) */
//static const uint8_t      BD_ADDR[]   = { 0x1E, 0x01, 0x00, 0xCA, 0xEA, 0x80 };   /**< Local Bluetooth identity address (30) */
//static const uint8_t      BD_ADDR[]   = { 0x1F, 0x01, 0x00, 0xCA, 0xEA, 0x80 };   /**< Local Bluetooth identity address (31) */
//static const uint8_t      BD_ADDR[]   = { 0x20, 0x01, 0x00, 0xCA, 0xEA, 0x80 };   /**< Local Bluetooth identity address (32) */
//static const uint8_t      BD_ADDR[]   = { 0x21, 0x01, 0x00, 0xCA, 0xEA, 0x80 };   /**< Local Bluetooth identity address (33) */
//static const uint8_t      BD_ADDR[]   = { 0x22, 0x01, 0x00, 0xCA, 0xEA, 0x80 };   /**< Local Bluetooth identity address (34) */
//static const uint8_t      BD_ADDR[]   = { 0x23, 0x01, 0x00, 0xCA, 0xEA, 0x80 };   /**< Local Bluetooth identity address (35) */
//static const uint8_t      BD_ADDR[]   = { 0x24, 0x01, 0x00, 0xCA, 0xEA, 0x80 };   /**< Local Bluetooth identity address (36) */
//static const uint8_t      BD_ADDR[]   = { 0x25, 0x01, 0x00, 0xCA, 0xEA, 0x80 };   /**< Local Bluetooth identity address (37) */
//static const uint8_t      BD_ADDR[]   = { 0x26, 0x01, 0x00, 0xCA, 0xEA, 0x80 };   /**< Local Bluetooth identity address (38) */
//static const uint8_t      BD_ADDR[]   = { 0x27, 0x01, 0x00, 0xCA, 0xEA, 0x80 };   /**< Local Bluetooth identity address (39) */
//static const uint8_t      BD_ADDR[]   = { 0x28, 0x01, 0x00, 0xCA, 0xEA, 0x80 };   /**< Local Bluetooth identity address (40) */
//static const uint8_t      BD_ADDR[]   = { 0x29, 0x01, 0x00, 0xCA, 0xEA, 0x80 };   /**< Local Bluetooth identity address (41) */
//static const uint8_t      BD_ADDR[]   = { 0x2A, 0x01, 0x00, 0xCA, 0xEA, 0x80 };   /**< Local Bluetooth identity address (42) */
//static const uint8_t      BD_ADDR[]   = { 0x2B, 0x01, 0x00, 0xCA, 0xEA, 0x80 };   /**< Local Bluetooth identity address (43) */
//static const uint8_t      BD_ADDR[]   = { 0x2C, 0x01, 0x00, 0xCA, 0xEA, 0x80 };   /**< Local Bluetooth identity address (44) */
//static const uint8_t      BD_ADDR[]   = { 0x2D, 0x01, 0x00, 0xCA, 0xEA, 0x80 };   /**< Local Bluetooth identity address (45) */
//static const uint8_t      BD_ADDR[]   = { 0x2E, 0x01, 0x00, 0xCA, 0xEA, 0x80 };   /**< Local Bluetooth identity address (46) */
//static const uint8_t      BD_ADDR[]   = { 0x2F, 0x01, 0x00, 0xCA, 0xEA, 0x80 };   /**< Local Bluetooth identity address (47) */
//static const uint8_t      BD_ADDR[]   = { 0x30, 0x01, 0x00, 0xCA, 0xEA, 0x80 };   /**< Local Bluetooth identity address (48) */
//static const uint8_t      BD_ADDR[]   = { 0x31, 0x01, 0x00, 0xCA, 0xEA, 0x80 };   /**< Local Bluetooth identity address (49) */
//static const uint8_t      BD_ADDR[]   = { 0x32, 0x01, 0x00, 0xCA, 0xEA, 0x80 };   /**< Local Bluetooth identity address (50) */
// 2019.09.24 End   ### for Extending perpheral address. (DEVICE_HPS4) ###
// 2020.01.31 Start ### for multi pressure sensor. (DEVICE_HPS5) ###
//static const uint8_t      BD_ADDR[]   = { 0x33, 0x01, 0x00, 0xCA, 0xEA, 0x80 };   /**< Local Bluetooth identity address (51) */
//static const uint8_t      BD_ADDR[]   = { 0x34, 0x01, 0x00, 0xCA, 0xEA, 0x80 };   /**< Local Bluetooth identity address (52) */
//static const uint8_t      BD_ADDR[]   = { 0x35, 0x01, 0x00, 0xCA, 0xEA, 0x80 };   /**< Local Bluetooth identity address (53) */
//static const uint8_t      BD_ADDR[]   = { 0x36, 0x01, 0x00, 0xCA, 0xEA, 0x80 };   /**< Local Bluetooth identity address (54) */
  static const uint8_t      BD_ADDR[]   = { 0x37, 0x01, 0x00, 0xCA, 0xEA, 0x80 };   /**< Local Bluetooth identity address (55) */
// 2020.01.31 End   ### for multi pressure sensor. (DEVICE_HPS5) ###
// 2020.02.28 Start ### for multi pressure sensor. (DEVICE_HAS1) ###
//static const uint8_t      BD_ADDR[]   = { 0x38, 0x01, 0x00, 0xCA, 0xEA, 0x80 };   /**< Local Bluetooth identity address (56) */
//static const uint8_t      BD_ADDR[]   = { 0x39, 0x01, 0x00, 0xCA, 0xEA, 0x80 };   /**< Local Bluetooth identity address (57) */
//static const uint8_t      BD_ADDR[]   = { 0x3A, 0x01, 0x00, 0xCA, 0xEA, 0x80 };   /**< Local Bluetooth identity address (58) */
//static const uint8_t      BD_ADDR[]   = { 0x3B, 0x01, 0x00, 0xCA, 0xEA, 0x80 };   /**< Local Bluetooth identity address (59) */
//static const uint8_t      BD_ADDR[]   = { 0x3C, 0x01, 0x00, 0xCA, 0xEA, 0x80 };   /**< Local Bluetooth identity address (60) */
// 2020.02.28 End   ### for multi pressure sensor. (DEVICE_HAS1) ###

// 2020.01.31 Mod_Start ### for multi pressure sensor. ###
/**< Defintion of the device name and the process. Should select only one device. */
/**----------------------------------------------------------------------------------------------------------*/
#define     DEVICE_HPS4     0                                   /**< 1 pressure sensor, 5 times measurement. */
#define     DEVICE_HPS5     1                                   /**< 5 pressure sensors. */
#define     DEVICE_HAS1     0                                   /**< Future function. */
/**----------------------------------------------------------------------------------------------------------*/

#define     DBG_DATA        0                                   /**< Fill Advertising packet with debag data. */

#if (DEVICE_HAS1)
    static const uint8_t    APP_DEVICE_NAME[]   = "HAS1";       /**< Complete Name data part : 0x48, 0x41, 0x53, 0x31 (unused) */
#endif
#if (DEVICE_HPS5)
    static const uint8_t    APP_DEVICE_NAME[]   = "HPS5";       /**< Complete Name data part : 0x48, 0x50, 0x53, 0x35 */
#endif
#if (DEVICE_HPS4)
    static const uint8_t    APP_DEVICE_NAME[]   = "HPS4";       /**< Complete Name data part : 0x48, 0x50, 0x53, 0x34 */
#endif
// 2020.01.31 Mod_End   ### for multi pressure sensor. ###


//------------------------------------------------------------------------------
/**@brief AD structure : Definition & variables of manufacturer specific data. */
//
#define APP_COMPANY_IDENTIFIER          0x0004                  /**< Company identifier for Toshiba Corp. as per www.bluetooth.org. */

#if (DEVICE_HAS1)
    #define APP_MANUFAC_DATA_LEN        (30)                    /**< Length of manufacturer specific data part. */
    static uint8_t          m_manufac_data[] = {                /**< Manufacturer specific data in Advertising. */
                                0x00,                                   /**< Sequence No. */
                                0x00,                                   /**< Data type. */
                                0x00,                                   /**< Temperature (offset from 23 deg) [e.g. 21deg] */
                                0x00, 0x00, 0x00,                       /**< Acceleration[0] */
                                0x00, 0x00, 0x00,                       /**< Acceleration[1] */
                                0x00, 0x00, 0x00,                       /**< Acceleration[2] */
                                0x00, 0x00, 0x00,                       /**< Acceleration[3] */
                                0x00, 0x00, 0x00,                       /**< Acceleration[4] */
                                0x00, 0x00, 0x00,                       /**< Acceleration[5] */
                                0x00, 0x00, 0x00,                       /**< Acceleration[6] */
                                0x00, 0x00, 0x00                        /**< Acceleration[7] */
                            };
    #define APP_MANU_DATA_TYPE          (1)                     /**< Position of data-type in manufacturer specific data. */
    #define APP_MANU_TEMPERA_OFFSET     (2)                     /**< Position of temperature top-data in manufacturer specific data. */
    #define APP_MANU_ACCELE_OFFSET      (3)                     /**< Position of acceleration top-data in manufacturer specific data. */
                                                 
    static uint8_t const        m_accele_ini_data1[] = {        /**< Manufacturer specific data in Advertising. */
                                0x00,                                   /**< Sequence No. */
                                0x00,                                   /**< Data type. */
                                0xFE,                                   /**< Temperature (offset from 23 deg) [e.g. 21deg] */
                                0xC0, 0x20, 0xE0,                       /**< Acceleration[0] [e.g. x=-2.00g, y=+1.00g, z=-1.00g] */
                                0xE0, 0x10, 0xF0,                       /**< Acceleration[1] [e.g. x=-1.00g, y=+0.50g, z=-0.50g] */
                                0xF0, 0x08, 0xF8,                       /**< Acceleration[2] [e.g. x=-0.50g, y=+0.25g, z=-0.25g] */
                                0x00, 0x01, 0xFF,                       /**< Acceleration[3] [e.g. x= 0.00g, y=+0.03g, z=-0.03g] */
                                0x08, 0x20, 0xE0,                       /**< Acceleration[4] [e.g. x= 0.25g, y=+0.50g, z=-0.50g] */
                                0x10, 0x20, 0xE0,                       /**< Acceleration[5] [e.g. x= 0.50g, y=+0.50g, z=-0.50g] */
                                0x20, 0x20, 0xE0,                       /**< Acceleration[6] [e.g. x= 1.00g, y=+1.00g, z=-1.00g] */
                                0x40, 0x20, 0xE0                        /**< Acceleration[7] [e.g. x= 2.00g, y=+1.00g, z=-1.00g] */
                            };
    static uint8_t const        m_accele_ini_data2[] = {        /**< Manufacturer specific data in Advertising. */
                                0x00,                                   /**< Sequence No. */
                                0x00,                                   /**< Data type. */
                                0xFD,                                   /**< Temperature (offset from 23 deg) [e.g. 20deg] */
                                0xC0, 0x0E, 0x00, 0xF0, 0x0F, 0x80,     /**< Acceleration[0] [e.g. x/y/z= -2.00g, -1.00g, -0.50g, -0.25g] */
                                0xE0, 0x0F, 0x00, 0x80, 0x0F, 0xFF,     /**< Acceleration[0] [e.g. x/y/z= -1.00g, -0.50g, -0.25g, -0.002g] */
                                0x20, 0x01, 0x00, 0x08, 0x00, 0x01,     /**< Acceleration[0] [e.g. x/y/z= +1.00g, +0.50g, +0.25g, +0.002g] */
                                0x40, 0x02, 0x00, 0x10, 0x00, 0x80      /**< Acceleration[0] [e.g. x/y/z= +2.00g, +1.00g, +0.50g, -0.25g] */
                            };

#else   // i.e. HPS5 or HPS4
    #define APP_MANUFAC_DATA_LEN        (18)                    /**< Length of manufacturer specific data part. */
    static uint8_t          m_manufac_data[] = {                /**< Manufacturer specific data in Advertising. */
                                0x00,                                   /**< Sequence No. */
                                0xC4, 0x09,                             /**< Temperature Data. [e.g. 0x09C4 (25 deg)] */
                                0x00, 0x54, 0x3F,                       /**< Pressure Data[0]. [e.g. 0x3F5400 (1013hPa)] */
                                0x00, 0x64, 0x3F,                       /**< Pressure Data[1]. [e.g. 0x3F6400 (1013hPa)] */
                                0x00, 0x74, 0x3F,                       /**< Pressure Data[2]. [e.g. 0x3F7400 (1013hPa)] */
                                0x00, 0x84, 0x3F,                       /**< Pressure Data[3]. [e.g. 0x3F8400 (1013hPa)] */
                                0x00, 0x94, 0x3F                        /**< Pressure Data[4]. [e.g. 0x3F9400 (1013hPa)] */
                            };
    #define APP_MANU_TEMPERA_OFFSET     (1)                     /**< Position of temperature top-data in manufacturer specific data. */
    #define APP_MANU_PRESS_OFFSET       (3)                     /**< Position of pressure top-data in manufacturer specific data. */
#endif  //#if (DEVICE_HAS1)

static uint8_t          SequenceCount   = 0;                    /**< Sequence counter that placed at manufacturer specific data. */

// 2020.01.31 Mod_Start ### for multi pressure sensors. ###
#if (DEVICE_HPS4)
    #define MEAS_CNT_MAX                (5)                     /**< Number of measurement pressure data in manufacturer data. */
    static uint8_t          measCount   = 0;                    /**< Counter of measurement pressure data in manufacturer data. */
#endif
// 2020.01.31 Mod_End   ### for multi pressure sensors. ###

// 2020.01.31 Add_Start ### for multi pressure sensors. ###
/**< The interval for advertising */
#if (DEVICE_HAS1)
    #define ADV_INTERVAL_BASE           (20)
#endif
#if (DEVICE_HPS5)
    #define ADV_INTERVAL_BASE           (100)
#endif
#if (DEVICE_HPS4)
    #define ADV_INTERVAL_BASE           (115)
#endif

/**< The interval for sensor reading */
#if (DEVICE_HAS1)
    #define SNS_INTERVAL_BASE           (ADV_INTERVAL_BASE +5)
#endif
#if (DEVICE_HPS5)
    //#define SNS_INTERVAL_BASE           (ADV_INTERVAL_BASE +15)
    #define SNS_INTERVAL_BASE           (12) // 2021.04.02
#endif
#if (DEVICE_HPS4)
    #define SNS_INTERVAL_BASE           (25)
#endif
// 2020.01.31 Add_End   ### for multi pressure sensors. ###


//------------------------------------------------------------------------------
/**@brief Definition & variables of SPI. */
//
#define SPI0_CONFIG_SCK_PIN             3                       // Port(P0.03)      :  9pin
#define SPI0_CONFIG_MOSI_PIN            4                       // Port(P0.04)      : 10pin
#define SPI0_CONFIG_MISO_PIN            28                      // Port(P0.28_AIN4) : 24pin
#define SPI0_CONFIG_SS_PIN              2                       // Port(P0.02)      : 23pin
#define SPI0_CONFIG_IRQ_PRIORITY        APP_IRQ_PRIORITY_LOW

#define SPI_INSTANCE  0 
static const nrf_drv_spi_t              m_spi_ms0 = NRF_DRV_SPI_INSTANCE(SPI_INSTANCE); 
static volatile bool                    spi_xfer_done = false;
//static uint8_t                        m_tx_buf[2];            /**< Control/Addr byte plus optionally used data byte for reg writes. */
//static uint8_t                        m_rx_buf[2];            /** Always just 1 data byte returned. */

// 2020.01.31 Add_Start Initial data ### for multi pressure sensors. ###
#define SPI_BURST_MAX                   (48)
static uint8_t                          m_tx_buf[SPI_BURST_MAX +2]; /**< Control/Addr byte plus optionally used data byte for reg writes. */
static uint8_t                          m_rx_buf[SPI_BURST_MAX +2]; /** Burst reading data byte returned. */

#define SPI_WAIT_MAX                    (2)                     /**< SPI transfered event wait time for single access. ((n+2)*(wait time unit) usec) */
#define SPI_WAIT_MAX_BURST              (15)                    /**< SPI transfered event wait time for burst access. ((n+2)*(wait time unit) usec) */
#define SPI_WAIT_TIME_UNIT              (10)                    /**< SPI transfered event wait time unit [usec] */

#if (DEVICE_HAS1)
    static uint8_t                      m_measure_mode  = 0;    /**< mode of acceleration measurement. */
    #define MEAS_MODE_3_AXES            (0)                     /**< 3-axes 500Hz sampling  */
    #define MEAS_MODE_X_AXiS            (1)                     /**< X-axis 1000Hz sampling */
    #define MEAS_MODE_Y_AXiS            (2)                     /**< X-axis 1000Hz sampling */
    #define MEAS_MODE_Z_AXiS            (3)                     /**< X-axis 1000Hz sampling */

    #define SNS_RESET_WAIT_TIME         (10)                    /**< Wait time after software reset. [usec] */

    static const uint8_t                m_softreset_addr    = 0x14;
    static const uint8_t                m_softreset_data    = 0xB6;

    #define SENS_REG_NUM                (6)                     /**< Number of registers for future sensor. */
    static const uint8_t                m_addr_list[SENS_REG_NUM] = {
                                            0x0F,0x10,0x13,0x36,0x37,0x3E
                                        };
    static const uint8_t                m_data_list_0[SENS_REG_NUM] = {
                                            0x05,0x0D,0x40,0x07,0x00,0x80
                                        };                      /**< 4g, BW=250Hz, shadow=dis, slow_offset=en, HPF=BW/1000, FIFO=stream(x+y+z) */

    static const uint8_t                m_data_list_1[SENS_REG_NUM] = {
                                            0x05,0x0E,0x00,0x07,0x00,0x81
                                        };                      /**< 4g, BW=500Hz, shadow=en,  slow_offset=en, HPF=BW/1000, FIFO=stream(x) */

    static const uint8_t                m_data_list_2[SENS_REG_NUM] = {
                                            0x05,0x0E,0x00,0x07,0x00,0x82
                                        };                      /**< 4g, BW=500Hz, shadow=en,  slow_offset=en, HPF=BW/1000, FIFO=stream(y) */

    static const uint8_t                m_data_list_3[SENS_REG_NUM] = {
                                            0x05,0x0E,0x00,0x07,0x00,0x83
                                        };                      /**< 4g, BW=500Hz, shadow=en,  slow_offset=en, HPF=BW/1000, FIFO=stream(z) */

#else   // i.e. HPS5 or HPS4
    #define SENS_REG_NUM                (13)                    /**< Number of registers for LPS22HB-sensor. */
    static const uint8_t                m_addr_list[SENS_REG_NUM] = {
                                            0x0B,0x0C,0x0D,0x10,0x11,0x12,0x14,0x15,0x16,0x17,0x18,0x19,0x1A
                                        };
    static const uint8_t                m_data_list[SENS_REG_NUM] = {
                                            0x00,0x00,0x00,0x42,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
                                        };                      /**< Bypass mode */
#endif  //#if (DEVICE_HAS1)
// 2020.01.31 Add_End   Initial data ### for multi pressure sensors. ###

// 2020.01.31 Add_Start ### for multi pressure sensors. ###
//------------------------------------------------------------------------------
//
/**@brief Definition & variables of GPIO : For SPI SS(Slave Selct)pin  */
#if (DEVICE_HAS1)
    #define SENS_DEV_NUM                (1)
#endif
#if (DEVICE_HPS5)
    #define SENS_DEV_NUM                (5)
#endif
#if (DEVICE_HPS4)
    #define SENS_DEV_NUM                (1)
#endif

#define PIN_NUM_SPI_SS0                 2                       // Port(P0.02)       : 23pin
//#define PIN_NUM_SPI_SS1               9                       // Port(P0.09_NFC)   :  3pin
//#define PIN_NUM_SPI_SS2               10                      // Port(P0.10_NFC)   : 15pin
#define PIN_NUM_SPI_SS1                 0                       // Port(P0.00_XL1)   :  4pin
#define PIN_NUM_SPI_SS2                 1                       // Port(P0.01_XL2)   :  5pin
#define PIN_NUM_SPI_SS3                 18                      // Port(P0.18)       : 22pin
#define PIN_NUM_SPI_SS4                 20                      // Port(P0.20)       : 25pin

static uint32_t                         m_sspin_num[5]   = {
                                            PIN_NUM_SPI_SS0,
                                            PIN_NUM_SPI_SS1,
                                            PIN_NUM_SPI_SS2,
                                            PIN_NUM_SPI_SS3,
                                            PIN_NUM_SPI_SS4
                                        };

static uint8_t                          GPIO_SS_PIN = PIN_NUM_SPI_SS0;          // for external reference to API of nrfx_spim.c (unused)

/**@brief Definition of GPIO : For input of switces. */
#define PIN_NUM_DSW_1                   18                      // Port(P0.18)       : 22pin
#define PIN_NUM_DSW_2                   20                      // Port(P0.20)       : 25pin
// 2020.01.31 Add_End   ### for multi pressure sensors. ###


//------------------------------------------------------------------------------
/**@brief Definition & variable of the Timer for measurement pressure. */
//

/**< Pressure measurement interval (ticks). */
#define PRESSURE_MEAS_INTERVAL          APP_TIMER_TICKS(SNS_INTERVAL_BASE)      // 2020.01.31 Mod (symbolizing) ### for multi pressure sensors. ###

APP_TIMER_DEF(m_press_timer_id);                                                /**< Pressure timer. */


//------------------------------------------------------------------------------
/**@brief Definition of using scheduler with SoftDevice. */
#define SCHED_MAX_EVENT_DATA_SIZE       APP_TIMER_SCHED_EVENT_DATA_SIZE          /**< Maximum size of scheduler events. Note that scheduler BLE stack events do not contain any data, as the events are being pulled from the stack in the event handler. */
#ifdef SVCALL_AS_NORMAL_FUNCTION
#define SCHED_QUEUE_SIZE                20                                       /**< Maximum number of events in the scheduler queue. More is needed in case of Serialization. */
#else
#define SCHED_QUEUE_SIZE                10                                       /**< Maximum number of events in the scheduler queue. */
#endif


//------------------------------------------------------------------------------
/**@brief BLE SoftDevice */
//------------------------------------------------------------------------------
#define APP_BLE_CONN_CFG_TAG            1                                       /**< A tag identifying the SoftDevice BLE configuration. */

#define DEAD_BEEF                       0xDEADBEEF                              /**< Value used as error code on stack dump, can be used to identify stack location on stack unwind. */

// 2020.01.31 Mod (Symbolizing) ### for multi pressure sensors. ###
#define NON_CONNECTABLE_ADV_INTERVAL    MSEC_TO_UNITS(ADV_INTERVAL_BASE, UNIT_0_625_MS) /**< The advertising interval for non-connectable advertisement (msec). */
                                                                                        /**<    This value can vary between 20ms to 10.24s). */

#define APP_ADV_DURATION                BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED   /**< The advertising time-out (in units of seconds). When set to 0, we will never time out. */

#define TX_POWER_LEVEL                  (0)                                     /**< Radio transmit power in dBm. Select in -40, -20, -16, -12, -8, -4, 0, 3, 4 dBm */


//------------------------------------------------------------------------------
/**@brief Global variables of advertising handler & parameter. */
//
static ble_gap_adv_params_t     m_adv_params;                                   /**< Parameters to be passed to the stack when starting advertising. */
static uint8_t                  m_adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET;  /**< Advertising handle used to identify an advertising set. */

//------------------------------------------------------------------------------
/**@brief Struct that contains pointers to the encoded advertising data. */
static uint8_t                  m_adv_buff_sel  = 0;                            /**< Selection of Advertising buffer for updateing while advertising. */
/* buffer_1 */
static uint8_t                  m_enc_advdata1[BLE_GAP_ADV_SET_DATA_SIZE_MAX];  /**< Buffer for storing an encoded advertising set. */
static ble_gap_adv_data_t m_adv_data1 =
{
    .adv_data =
    {
        .p_data = m_enc_advdata1,
        .len    = BLE_GAP_ADV_SET_DATA_SIZE_MAX
    },
    .scan_rsp_data =
    {
        .p_data = NULL,
        .len    = 0
    }
};

/* buffer_2 */
static uint8_t                  m_enc_advdata2[BLE_GAP_ADV_SET_DATA_SIZE_MAX];  /**< Buffer for storing an encoded advertising set. */
static ble_gap_adv_data_t m_adv_data2 =
{
    .adv_data =
    {
        .p_data = m_enc_advdata2,
        .len    = BLE_GAP_ADV_SET_DATA_SIZE_MAX
    },
    .scan_rsp_data =
    {
        .p_data = NULL,
        .len    = 0
    }
};


// 2020.01.31 Add_Start ### for multi pressure sensors. ###
/**@brief Function for initializing GPIO
 *
 */
void gpio_init(void)
{
    uint8_t     cnt;
    for (cnt = 0; cnt < SENS_DEV_NUM; cnt++) {
        // SSpin initial status [Dir.= output, Lvl.= 1]
        nrf_gpio_pin_set(NRF_GPIO_PIN_MAP(0, m_sspin_num[cnt]));    // It may have any effect.
        nrf_gpio_cfg_output(NRF_GPIO_PIN_MAP(0, m_sspin_num[cnt])); // Set SSpin direction.
        nrf_gpio_pin_set(NRF_GPIO_PIN_MAP(0, m_sspin_num[cnt]));    // Set SSpin = 1;
    }
}


/**@brief mode initialize
 *
 */
void mode_init(void)
{
#if (DEVICE_HAS1)
    uint32_t    port;
    uint8_t     work = 0;

    // Direction of GPIO is input with pullup.
    nrf_gpio_cfg_input(NRF_GPIO_PIN_MAP(0, PIN_NUM_DSW_1), NRF_GPIO_PIN_PULLUP);
    nrf_gpio_cfg_input(NRF_GPIO_PIN_MAP(0, PIN_NUM_DSW_2), NRF_GPIO_PIN_PULLUP);

    // '0' if switch is ON.
    port = nrf_gpio_pin_read(NRF_GPIO_PIN_MAP(0, PIN_NUM_DSW_1));
    work = (0 == port)? (work | 0x01): (work & ~0x01);
    port = nrf_gpio_pin_read(NRF_GPIO_PIN_MAP(0, PIN_NUM_DSW_2));
    work = (0 == port)? (work | 0x02): (work & ~0x02);

    if (0 == work)      {  m_measure_mode   = MEAS_MODE_3_AXES; }
    else if (1 == work) {  m_measure_mode   = MEAS_MODE_X_AXiS; }
    else if (2 == work) {  m_measure_mode   = MEAS_MODE_Y_AXiS; }
    else                {  m_measure_mode   = MEAS_MODE_Z_AXiS; }

    // Direction of GPIO is input with no-pullup.
    nrf_gpio_cfg_input(NRF_GPIO_PIN_MAP(0, PIN_NUM_DSW_1), NRF_GPIO_PIN_NOPULL);
    nrf_gpio_cfg_input(NRF_GPIO_PIN_MAP(0, PIN_NUM_DSW_2), NRF_GPIO_PIN_NOPULL);

#endif
}
// 2020.01.31 Add_End   ### for multi pressure sensors. ###


/**@brief Function for handling the spi driver.
 *
 * @details This function will be called spi event.
 *
 * @param[in]   p_event     not used.
 * @param[in]   p_context   Pointer used for passing some arbitrary information (context).
 *
 */
void spi_event_handler(nrf_drv_spi_evt_t const * p_event, void *  p_context)
{
    UNUSED_PARAMETER(p_context);
//  nrf_delay_ms(10);

    spi_xfer_done = true;
}

/**@brief Function for initializing SPI
 *
 */
void spi_init(void)
{
    ret_code_t err_code;

    nrf_drv_spi_config_t    spi_config = NRF_DRV_SPI_DEFAULT_CONFIG;
    //spi_config.ss_pin     = SPI0_CONFIG_SS_PIN;
    spi_config.ss_pin       = NRF_DRV_SPI_PIN_NOT_USED;         // 2020.01.31 Mod (SS is local control.) ### for multi pressure sensors. ###
    spi_config.sck_pin      = SPI0_CONFIG_SCK_PIN;
    spi_config.mosi_pin     = SPI0_CONFIG_MOSI_PIN;
    spi_config.miso_pin     = SPI0_CONFIG_MISO_PIN;
    //spi_config.frequency    = NRF_DRV_SPI_FREQ_4M;              // Default. 4M (up to 10M in LPS22HB)
    spi_config.frequency    = NRF_DRV_SPI_FREQ_8M;              // 8M (up to 10M in LPS22HB)
    spi_config.mode         = NRF_DRV_SPI_MODE_3;               // SCK active low, sample on trailing edge of clock. (but default is mode 0.)
                                                                // Clock Polarity= 1(Trailing), Clock Phase= 1(Active Low)
    spi_config.bit_order    = NRF_DRV_SPI_BIT_ORDER_MSB_FIRST;  // Default. (MSB first in LPS22HB)
    spi_config.irq_priority = SPI0_CONFIG_IRQ_PRIORITY;

    err_code    = nrf_drv_spi_init(&m_spi_ms0, &spi_config, spi_event_handler, NULL);
    APP_ERROR_CHECK(err_code);
}

/**@brief Function for SPI writing access
 *
 */
void spi_write_acc(uint8_t regAddr, uint8_t data, uint8_t devNo)
{
    int8_t  waitCnt = 0;

    // Reset transfer done flag
    spi_xfer_done   = false;
    m_tx_buf[0]     = regAddr;
    m_tx_buf[1]     = data;

    // SPI-SS activation
    GPIO_SS_PIN = m_sspin_num[devNo];                                   // 2020.01.31 Add ### for multi pressure sensors. ###
    nrf_gpio_pin_clear(m_sspin_num[devNo]);                             // 2020.01.31 Add ### for multi pressure sensors. ###

    // SPI writing
    APP_ERROR_CHECK(nrf_drv_spi_transfer(&m_spi_ms0, m_tx_buf, 2, NULL, 0));

    while (1)
    {
        nrf_delay_us(SPI_WAIT_TIME_UNIT);   // (1/4M)*16clk = 4usec     // 2020.01.31 Mod (Symbolizing) ### for multi pressure sensors. ###
        if (spi_xfer_done) {
            break;
        }
        if (SPI_WAIT_MAX < waitCnt++) {
            break;
        }
    }

    // SPI-SS negation
    nrf_gpio_pin_set(m_sspin_num[devNo]);                               // 2020.01.31 Add ### for multi pressure sensors. ###

}


// 2020.01.31 Mod_Start ### for multi pressure sensors. ###
//      Modifing for selecatble slave device and burst accessable.
//
/**@brief Function for SPI reading burst access.
 *
 */
void spi_read_acc(uint8_t regAddr, uint8_t* data, uint8_t dataLen, uint8_t devNo)
{
    uint32_t        err_code;
    int8_t          waitCnt = 0;

    // Reset rx buffer, Set tx buffer and transfer done flag
    memset(m_rx_buf, 0, (SPI_BURST_MAX +2));
    memset(m_tx_buf, 0, (SPI_BURST_MAX +2));
    m_tx_buf[0]     = (regAddr | 0x80);
    spi_xfer_done   = false;

    // SPI-SS activation
    GPIO_SS_PIN = m_sspin_num[devNo];
    nrf_gpio_pin_clear(m_sspin_num[devNo]);

    // SPI reading
    err_code = nrf_drv_spi_transfer(&m_spi_ms0, m_tx_buf, dataLen+1, m_rx_buf, dataLen+1);
    APP_ERROR_CHECK(err_code);

    while (1)
    {
        nrf_delay_us(SPI_WAIT_TIME_UNIT);   // (1/4M)*(49*8)clk = 100usec
        if (spi_xfer_done) {
            memcpy(data, &m_rx_buf[1], dataLen);
            break;
        }
        if (SPI_WAIT_MAX_BURST < waitCnt++) {
            memset(data, 0, dataLen);
            break;
        }
    }

    // SPI-SS negation
    nrf_gpio_pin_set(m_sspin_num[devNo]);
}
// 2020.01.31 Mod_End   ### for multi pressure sensors. ###


// 2020.01.31 Mod_Start ### for multi pressure sensors. ###
/**@brief Function for initializing Sensor.
 */
void sensor_init(void)
{
    // Sensor initialize.
        // + < NOTE >
        //      Change "Optimization Level"setting from "Optimize For Size" to "None"
        //      to avoid optimization warning of GPIO control.
        // -
    uint16_t    cntDev, cntReg;

#if (DEVICE_HAS1)
    const uint8_t *   datalistPtr;

    if (MEAS_MODE_X_AXiS == m_measure_mode) {
        datalistPtr = m_data_list_1;
    }
    else if (MEAS_MODE_Y_AXiS == m_measure_mode) {
        datalistPtr = m_data_list_2;
    }
    else if (MEAS_MODE_Z_AXiS == m_measure_mode) {
        datalistPtr = m_data_list_3;
    }
    else {
        datalistPtr = m_data_list_0;
    }

    for (cntDev = 0; cntDev < SENS_DEV_NUM; cntDev++) {
        // Software Reset
        spi_write_acc(m_softreset_addr, m_softreset_data, cntDev);
        nrf_delay_us(SNS_RESET_WAIT_TIME);

        // Setting registers
        for (cntReg = 0; cntReg < SENS_REG_NUM; cntReg++) {
            spi_write_acc(m_addr_list[cntReg], datalistPtr[cntReg], cntDev);
        }
    }

#else  // i.e. HPS5 or HPS4
    for (cntDev = 0; cntDev < SENS_DEV_NUM; cntDev++) {
        // Setting registers
        for (cntReg = 0; cntReg < SENS_REG_NUM; cntReg++) {
            spi_write_acc(m_addr_list[cntReg], m_data_list[cntReg], cntDev);
        }
    }
#endif  //#if (DEVICE_HAS1)
}


/**@brief Function for the process of intializing spi
 *                 and inintializing sennsor register.
 */
void initialize_spi_and_sensor(void)
{
    uint16_t    cntDev, cntReg;

    // initialize SPI.
    spi_init();

    // initialize Sensor.
    sensor_init();
}
// 2020.01.31 Mod_End   ### for multi pressure sensors. ###


/**@brief Function for setting the advatising data
 *
 */
void set_adv_data(bool init) 
{

// 2020.01.31 Mod_Start ### for multi pressure sensors. ###
#if (DEVICE_HAS1)
    uint32_t        err_code;
    ble_advdata_t   advdata;
    ble_advdata_manuf_data_t manuf_specific_data;

    // Build and set advertising data.
    memset(&advdata, 0, sizeof(advdata));

    manuf_specific_data.company_identifier = APP_COMPANY_IDENTIFIER;
    manuf_specific_data.data.p_data = (uint8_t *)m_manufac_data;
    manuf_specific_data.data.size   = APP_MANUFAC_DATA_LEN;
    advdata.p_manuf_specific_data   = &manuf_specific_data;

    if (MEAS_MODE_X_AXiS == m_measure_mode) {
        memcpy(m_manufac_data, m_accele_ini_data1, (APP_MANUFAC_DATA_LEN -3));
    }
    else {
        memcpy(m_manufac_data, m_accele_ini_data2, (APP_MANUFAC_DATA_LEN -3));
    }

#else  // i.e. HPS5 or HPS4
    uint32_t        err_code;
    ble_advdata_t   advdata;
    uint8_t         flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
    ble_advdata_manuf_data_t manuf_specific_data;

    // Build and set advertising data.
    memset(&advdata, 0, sizeof(advdata));

    advdata.name_type                      = BLE_ADVDATA_FULL_NAME;
    advdata.flags                          = flags;

    manuf_specific_data.company_identifier = APP_COMPANY_IDENTIFIER;
    manuf_specific_data.data.p_data = (uint8_t *)m_manufac_data;
    manuf_specific_data.data.size   = APP_MANUFAC_DATA_LEN;
    advdata.p_manuf_specific_data   = &manuf_specific_data;
#endif  //#if (DEVICE_HAS1)
// 2020.01.31 Mod_End   ### for multi pressure sensors. ###

    if (0 == m_adv_buff_sel) {
        err_code = ble_advdata_encode(&advdata, m_adv_data2.adv_data.p_data, &m_adv_data2.adv_data.len);
        APP_ERROR_CHECK(err_code);

        err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &m_adv_data2, NULL);
        APP_ERROR_CHECK(err_code);

        m_adv_buff_sel = 1;
    }
    else {
        err_code = ble_advdata_encode(&advdata, m_adv_data1.adv_data.p_data, &m_adv_data1.adv_data.len);
        APP_ERROR_CHECK(err_code);

        err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &m_adv_data1, NULL);
        APP_ERROR_CHECK(err_code);

        m_adv_buff_sel = 0;
    }
} 

/**@brief Function for performing pressure measurement and updating
 *        for advertisng.
 */

// 2020.01.31 Mod_Start ### for multi pressure sensors. ###
#if (DEVICE_HAS1)
void sensor_update(void * p_event_data, uint16_t event_size)
{
    uint8_t     work[SPI_BURST_MAX];
    uint8_t     measCnt;

    UNUSED_PARAMETER(p_event_data);
    UNUSED_PARAMETER(event_size);

    if (MEAS_MODE_3_AXES == m_measure_mode) {
        // Obtain FIFO frame counter.
        spi_read_acc(0x0E, work, 1, 0);
        if ((work[0] & 0x7F) < 8) {
            return;
        }
        m_manufac_data[0]                   = ++SequenceCount;
        m_manufac_data[APP_MANU_DATA_TYPE]  = m_measure_mode;

        // Obtain acceleration value
        spi_read_acc(0x3F, work, SPI_BURST_MAX, 0);
        for (measCnt = 0; measCnt < 8; measCnt++) {
            // x-axis
            m_manufac_data[APP_MANU_ACCELE_OFFSET +(measCnt *3) ]   = work[(measCnt *6) +1];
            // y-axis
            m_manufac_data[APP_MANU_ACCELE_OFFSET +(measCnt *3) +1] = work[(measCnt *6) +3];
            // z-axis
            m_manufac_data[APP_MANU_ACCELE_OFFSET +(measCnt *3) +2] = work[(measCnt *6) +5];
            // Even elements are LSBs of acceleration value.
        }
        // Obtain temperature value
        spi_read_acc(0x08, work, 1, 0);
        m_manufac_data[APP_MANU_TEMPERA_OFFSET] = work[0];
    }
    else {
        // Obtain FIFO frame counter.
        spi_read_acc(0x0E, work, 1, 0);
        if ((work[0] & 0x7F) < 16) {
            return;
        }
        m_manufac_data[0]                   = ++SequenceCount;
        m_manufac_data[APP_MANU_DATA_TYPE]  = m_measure_mode;

        // Obtain acceleration value
        spi_read_acc(0x3F, work, 32, 0);
        for (measCnt = 0; measCnt < 8; measCnt++) {
            m_manufac_data[APP_MANU_ACCELE_OFFSET +(measCnt *2) ]   = work[(measCnt *4) +1];
            m_manufac_data[APP_MANU_ACCELE_OFFSET +(measCnt *2) +1] = ((work[(measCnt *4)]  & 0xF0) | (work[(measCnt *4) +3] >> 4));
            m_manufac_data[APP_MANU_ACCELE_OFFSET +(measCnt *2) +2] = ((work[(measCnt *4) +3] << 4) | (work[(measCnt *4) +2] >> 4));
        }
        // Obtain temperature value
        spi_read_acc(0x08, work, 1, 0);
        m_manufac_data[APP_MANU_TEMPERA_OFFSET] = work[0];
    }
}
#endif  //#if (DEVICE_HAS1)


#if (DEVICE_HPS5)
void sensor_update(void * p_event_data, uint16_t event_size)
{
    uint8_t     work;
    uint8_t     cntDev;
    #if (DBG_DATA)  // for filling debug data.
    uint8_t     workDbg1, workDbg2, workDbg3;
    #endif

    UNUSED_PARAMETER(p_event_data);
    UNUSED_PARAMETER(event_size);

    m_manufac_data[0]    = ++SequenceCount;

    for (cntDev = 0; cntDev < SENS_DEV_NUM ; cntDev++) {

        if (0 == cntDev) {
            #if (DBG_DATA)  // for filling debug data.
            workDbg1 = m_manufac_data[APP_MANU_TEMPERA_OFFSET];
            workDbg2 = m_manufac_data[APP_MANU_TEMPERA_OFFSET +1];
            #endif

            // Obtain the temperature by SPI/I2C-device.
            spi_read_acc(0x2B, &work, 1, cntDev);
            m_manufac_data[APP_MANU_TEMPERA_OFFSET]    = work;
            spi_read_acc(0x2C, &work, 1, cntDev);
            m_manufac_data[APP_MANU_TEMPERA_OFFSET +1] = work;

            #if (DBG_DATA)  // for filling debug data.
            m_manufac_data[APP_MANU_TEMPERA_OFFSET]    = workDbg1+1;
            m_manufac_data[APP_MANU_TEMPERA_OFFSET +1] = workDbg2;
            #endif
        }

        #if (DBG_DATA)  // for filling debug data.
        workDbg1 = m_manufac_data[APP_MANU_PRESS_OFFSET + (cntDev *3)];
        workDbg2 = m_manufac_data[APP_MANU_PRESS_OFFSET + (cntDev *3) +1];
        workDbg3 = m_manufac_data[APP_MANU_PRESS_OFFSET + (cntDev *3) +2];
        #endif

        // Obtain the pressure by SPI/I2C-device.
        spi_read_acc(0x28, &work, 1, cntDev);
        m_manufac_data[APP_MANU_PRESS_OFFSET + (cntDev *3)]    = work;
        spi_read_acc(0x29, &work, 1, cntDev);
        m_manufac_data[APP_MANU_PRESS_OFFSET + (cntDev *3) +1] = work;
        spi_read_acc(0x2A, &work, 1, cntDev);
        m_manufac_data[APP_MANU_PRESS_OFFSET + (cntDev *3) +2] = work;

        #if (DBG_DATA)  // for filling debug data.
        m_manufac_data[APP_MANU_PRESS_OFFSET + (cntDev *3)]    = workDbg1;
        m_manufac_data[APP_MANU_PRESS_OFFSET + (cntDev *3) +1] = workDbg2 + 0x10;
        m_manufac_data[APP_MANU_PRESS_OFFSET + (cntDev *3) +2] = workDbg3;
        #endif
    }

    // start MUTEX 2021.03.16 wired_honda
    //if(nrf_mtx_trylock(&g_mtx))  // del 2021.04.07
    {
      memcpy(i2c_spi_data, m_manufac_data, 18);
      //nrf_mtx_unlock(&g_mtx);  // del 2021.04.07
    }
    // end MUTEX 2021.03.16 wired_honda
    //set_adv_data(false);
}
#endif  // #if (DEVICE_HPS5)


#if (DEVICE_HPS4)
void sensor_update(void * p_event_data, uint16_t event_size)
{
    uint8_t     work;
    uint8_t     cntDev;
    #if (DBG_DATA)  // for filling debug data.
    uint8_t     workDbg1, workDbg2, workDbg3;
    #endif

    UNUSED_PARAMETER(p_event_data);
    UNUSED_PARAMETER(event_size);

    if (measCount < MEAS_CNT_MAX) {

        if (0 == measCount) {
            m_manufac_data[0]    = ++SequenceCount;

            #if (DBG_DATA)  // for filling debug data.
            workDbg1 = m_manufac_data[APP_MANU_TEMPERA_OFFSET];
            workDbg2 = m_manufac_data[APP_MANU_TEMPERA_OFFSET +1];
            #endif

            // Obtain the temperature by SPI/I2C-device.
            spi_read_acc(0x2B, &work, 1, 0);
            m_manufac_data[APP_MANU_TEMPERA_OFFSET]    = work;
            spi_read_acc(0x2C, &work, 1, 0);
            m_manufac_data[APP_MANU_TEMPERA_OFFSET +1] = work;

            #if (DBG_DATA)  // for filling debug data.
            m_manufac_data[APP_MANU_TEMPERA_OFFSET]    = workDbg1+1;
            m_manufac_data[APP_MANU_TEMPERA_OFFSET +1] = workDbg2;
            #endif
        }
        #if (DBG_DATA)  // for filling debug data.
        workDbg1 = m_manufac_data[APP_MANU_PRESS_OFFSET + (measCount *3)];
        workDbg2 = m_manufac_data[APP_MANU_PRESS_OFFSET + (measCount *3) +1];
        workDbg3 = m_manufac_data[APP_MANU_PRESS_OFFSET + (measCount *3) +2];
        #endif

        // Obtain the pressure by SPI/I2C-device.
        spi_read_acc(0x28, &work, 1, 0);
        m_manufac_data[APP_MANU_PRESS_OFFSET + (measCount *3)]    = work;
        spi_read_acc(0x29, &work, 1, 0);
        m_manufac_data[APP_MANU_PRESS_OFFSET + (measCount *3) +1] = work;
        spi_read_acc(0x2A, &work, 1, 0);
        m_manufac_data[APP_MANU_PRESS_OFFSET + (measCount *3) +2] = work;

        #if (DBG_DATA)  // for filling debug data.
        m_manufac_data[APP_MANU_PRESS_OFFSET + (measCount *3)]    = workDbg1;
        m_manufac_data[APP_MANU_PRESS_OFFSET + (measCount *3) +1] = workDbg2 + 0x10;
        m_manufac_data[APP_MANU_PRESS_OFFSET + (measCount *3) +2] = workDbg3;
        #endif
        if (MEAS_CNT_MAX <= ++measCount) {
            measCount = 0;
            set_adv_data(false);
        }
    }
    else {
        measCount = 0;
    }
}
#endif  // #if (DEVICE_HPS4)
// 2020.01.31 Mod_End   ### for multi pressure sensors. ###


/**@brief Function for handling the Pressure measurement timer timeout.
 *
 * @details This function will be called each time the pressure measurement timer expires.
 *
 * @param[in]   p_context   Pointer used for passing some arbitrary information (context) from the
 *                          app_start_timer() call to the timeout handler.
 */
static void pressure_meas_timeout_handler(void * p_context)
{
 // del start 2021.04.07
 /*
    ret_code_t  err_code;
    UNUSED_PARAMETER(p_context);

    err_code    = app_sched_event_put(NULL, 0, sensor_update);
    APP_ERROR_CHECK(err_code);
  */
 // del end 2021.04.07
}

/**@brief Function for starting application timers.
 */
static void application_timers_start(void)
{
    ret_code_t err_code;

    // Start application timers.
    err_code = app_timer_start(m_press_timer_id, PRESSURE_MEAS_INTERVAL, NULL);
    APP_ERROR_CHECK(err_code);
}
// 2019.01.11 For BLE_Press_End

/**@brief Callback function for asserts in the SoftDevice.
 *
 * @details This function will be called in case of an assert in the SoftDevice.
 *
 * @warning This handler is an example only and does not fit a final product. You need to analyze
 *          how your product is supposed to react in case of Assert.
 * @warning On assert from the SoftDevice, the system can only recover on reset.
 *
 * @param[in]   line_num   Line number of the failing ASSERT call.
 * @param[in]   file_name  File name of the failing ASSERT call.
 */
void assert_nrf_callback(uint16_t line_num, const uint8_t * p_file_name)
{
    app_error_handler(DEAD_BEEF, line_num, p_file_name);
}

/**@brief Function for initializing the Advertising functionality.
 *
 * @details Encodes the required advertising data and passes it to the stack.
 *          Also builds a structure to be passed to the stack when starting advertising.
 */
static void advertising_init(void)
{

// 2019.01.11 For BLE_Press_Start
// 2020.01.31 Mod_Start ### for multi pressure sensors. ###
#if (DEVICE_HAS1)
    uint32_t                    err_code;
    ble_gap_addr_t              board_addr;
    ble_advdata_t               advdata;
    ble_advdata_manuf_data_t    manuf_specific_data;

    // Set Board Address.
    board_addr.addr_type = BLE_GAP_ADDR_TYPE_PUBLIC;
    memcpy(board_addr.addr, BD_ADDR, BLE_GAP_ADDR_LEN);
    err_code = sd_ble_gap_addr_set(&board_addr); 
    APP_ERROR_CHECK(err_code);

    // Build and set advertising data.
    memset(&advdata, 0, sizeof(advdata));

    manuf_specific_data.company_identifier  = APP_COMPANY_IDENTIFIER;
    manuf_specific_data.data.p_data         = (uint8_t *)m_manufac_data;
    manuf_specific_data.data.size           = APP_MANUFAC_DATA_LEN;
    advdata.p_manuf_specific_data           = &manuf_specific_data;


#else  // i.e. HPS5 or HPS4
    uint32_t                    err_code;
    ble_gap_addr_t              board_addr;
    ble_gap_conn_sec_mode_t     sec_mode;
    ble_advdata_t               advdata;
    uint8_t                     flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
    ble_advdata_manuf_data_t    manuf_specific_data;

    // Set Board Address.
    board_addr.addr_type = BLE_GAP_ADDR_TYPE_PUBLIC;
    memcpy(board_addr.addr, BD_ADDR, BLE_GAP_ADDR_LEN);
    err_code = sd_ble_gap_addr_set(&board_addr); 
    APP_ERROR_CHECK(err_code);

    // Set Device name.
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);
    err_code = sd_ble_gap_device_name_set(&sec_mode, 
                                           (const uint8_t *)APP_DEVICE_NAME, 
                                            strlen(APP_DEVICE_NAME)); 
    APP_ERROR_CHECK(err_code);

    // Build and set advertising data.
    memset(&advdata, 0, sizeof(advdata));

    advdata.name_type                       = BLE_ADVDATA_FULL_NAME;
    advdata.flags                           = flags;

    manuf_specific_data.company_identifier  = APP_COMPANY_IDENTIFIER;
    manuf_specific_data.data.p_data         = (uint8_t *)m_manufac_data;
    manuf_specific_data.data.size           = APP_MANUFAC_DATA_LEN;
    advdata.p_manuf_specific_data           = &manuf_specific_data;
#endif  //#if (DEVICE_HAS1)
// 2019.01.11 For BLE_Press_End

    // Initialize advertising parameters (used when starting advertising).
    memset(&m_adv_params, 0, sizeof(m_adv_params));

    m_adv_params.properties.type = BLE_GAP_ADV_TYPE_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED;
    m_adv_params.p_peer_addr     = NULL;    // Undirected advertisement.
    m_adv_params.filter_policy   = BLE_GAP_ADV_FP_ANY;
    m_adv_params.interval        = NON_CONNECTABLE_ADV_INTERVAL;
    m_adv_params.duration        = 0;       // Never time out.

    // ### If you want to restrict advertising channels, then enable following statements.(2020.01.31) ###
    //
    //m_adv_params.channel_mask[4] = 0xC0;    // ch38,ch39 is not used.
    //m_adv_params.channel_mask[4] = 0xA0;    // ch37,ch39 is not used.
    //m_adv_params.channel_mask[4] = 0x60;    // ch37,ch38 is not used.

    err_code = ble_advdata_encode(&advdata, m_adv_data1.adv_data.p_data, &m_adv_data1.adv_data.len);
    APP_ERROR_CHECK(err_code);

    err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &m_adv_data1, &m_adv_params);
    APP_ERROR_CHECK(err_code);

    err_code = sd_ble_gap_tx_power_set(BLE_GAP_TX_POWER_ROLE_ADV, m_adv_handle, TX_POWER_LEVEL);
    APP_ERROR_CHECK(err_code);

    m_adv_buff_sel  = 0;        // indicate selecting Advertising buffer.
}


/**@brief Function for starting advertising.
 */
static void advertising_start(void)
{
    ret_code_t err_code;

    err_code = sd_ble_gap_adv_start(m_adv_handle, APP_BLE_CONN_CFG_TAG);
    APP_ERROR_CHECK(err_code);

    err_code = bsp_indication_set(BSP_INDICATE_ADVERTISING);
    APP_ERROR_CHECK(err_code);
}


/**@brief Function for initializing the BLE stack.
 *
 * @details Initializes the SoftDevice and the BLE event interrupt.
 */
static void ble_stack_init(void)
{
    ret_code_t err_code;

    err_code = nrf_sdh_enable_request();
    APP_ERROR_CHECK(err_code);

    // Configure the BLE stack using the default settings.
    // Fetch the start address of the application RAM.
    uint32_t ram_start = 0;
    err_code = nrf_sdh_ble_default_cfg_set(APP_BLE_CONN_CFG_TAG, &ram_start);
    APP_ERROR_CHECK(err_code);

    // Enable BLE stack.
    err_code = nrf_sdh_ble_enable(&ram_start);
    APP_ERROR_CHECK(err_code);
}


/**@brief Function for initializing logging. */
static void log_init(void)
{
    ret_code_t err_code = NRF_LOG_INIT(NULL);
    APP_ERROR_CHECK(err_code);

    NRF_LOG_DEFAULT_BACKENDS_INIT();
}

/**@brief Function for initializing LEDs. */
static void leds_init(void)
{
    ret_code_t err_code = bsp_init(BSP_INIT_LEDS, NULL);
    APP_ERROR_CHECK(err_code);
}


/**@brief Function for initializing timers. */
static void timers_init(void)
{
// 2019.01.11 For BLE_Press_Start
    // Initialize timer module.
    ret_code_t err_code;

    // Initialize timer module.
    err_code = app_timer_init();
    APP_ERROR_CHECK(err_code);

    // Create timers.
    err_code = app_timer_create(&m_press_timer_id,
                                APP_TIMER_MODE_REPEATED,
                                pressure_meas_timeout_handler);
    /*
    err_code = app_timer_create(&m_press_timer_id,
                                APP_TIMER_MODE_SINGLE_SHOT,
                                pressure_meas_timeout_handler);
    */

    APP_ERROR_CHECK(err_code);
// 2019.01.11 For BLE_Press_End
}


/**@brief Function for initializing power management.
 */
static void power_management_init(void)
{
    ret_code_t err_code;
    err_code = nrf_pwr_mgmt_init();
    APP_ERROR_CHECK(err_code);
}


/**@brief Function for initializing the Event Scheduler.
 */
static void scheduler_init(void)
{
    APP_SCHED_INIT(SCHED_MAX_EVENT_DATA_SIZE, SCHED_QUEUE_SIZE);
}


/**@brief Function for handling the idle state (main loop).
 *
 * @details If there is no pending log operation, then sleep until next the next event occurs.
 */
static void idle_state_handle(void)
{
    app_sched_execute();
    if (NRF_LOG_PROCESS() == false)
    {
        nrf_pwr_mgmt_run();
    }
}


/**
 * @brief Function for application main entry.
 */
int main(void)
{
    ret_code_t err_code;                // 2021.03.15 Add ### for wired_honda ###
    bool epprom_error = 0;              // 2021.03.15 Add ### for wired_honda ###

    // Initialize.
    log_init();

    gpio_init();                        // 2020.01.31 Add ### for multi pressure sensors. ###
    mode_init();                        // 2020.01.31 Add ### for multi pressure sensors. ###

    bsp_board_init(BSP_INIT_LEDS);      // 2021.03.15 Add ### for wired_honda ###

    /* Initializing simulated EEPROM */
    err_code = eeprom_simulator_init(); // 2021.03.15 Add ### for wired_honda ###
    APP_ERROR_CHECK(err_code);          // 2021.03.15 Add ### for wired_honda ###

    /*
    err_code = nrf_drv_clock_init();    // 2021.03.15 Add ### for wired_honda ###
    APP_ERROR_CHECK(err_code);          // 2021.03.15 Add ### for wired_honda ###
    nrf_drv_clock_lfclk_request(NULL);  // 2021.03.15 Add ### for wired_honda ###
    */

    timers_init();
    //leds_init();                      // 2020.01.31 Del ### for multi pressure sensors. ###
    power_management_init();
    ble_stack_init();
    //advertising_init();

    scheduler_init();                   // 2019.01.11 Add for BLE_Press
    initialize_spi_and_sensor();        // 2019.01.11 Add for BLE_Press

    // Start execution.
    NRF_LOG_INFO("Beacon example started.");
    //advertising_start();

    application_timers_start();         // 2019.01.11 Add for BLE_Press

    // Enter main loop.
    for (;; )
    {
        idle_state_handle();
    }
}


/**
 * @}
 */
