This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Power off by acceleration detection with application timer.

We, I am using nRF 5 SDK v 14.2.0.
This time, without using WDT, using only the application timer,
We are developing a process to send data by detecting acceleration and interrupting acceleration.
In main.c and the acceleration detection function, it is as follows.
int main(void)
{
            gpio_init();
            nrf_drv_gpiote_in_event_enable(PIN_IN, true);
        for (;;)
        {
            while (!( accel_int_detect  )){
                    NRF_LOG_INFO("----while start.----\n");
                    NRF_LOG_FLUSH();
                    err_code = sd_app_evt_wait();
                    APP_ERROR_CHECK(err_code);
                    nrf_delay_ms(1000);
            }
            nrf_drv_gpiote_in_event_disable(PIN_IN);
            send_mail();
        }
}

static void in_pin_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
{
    uint8_t ret;
    NRF_LOG_INFO("%s %d", __func__, __LINE__);
    NRF_LOG_FLUSH();
    nrf_drv_gpiote_in_event_disable(PIN_IN);
    NRF_LOG_INFO("--- INT disabled");
    accel_int_detect = true;
    }
    NRF_LOG_INFO("Motion detected");
    NRF_LOG_FLUSH();
    __SEV();
    return;
}

void gpio_init(void)
{
    ret_code_t err_code;
    if (!nrf_drv_gpiote_is_init())
    {
        err_code = nrf_drv_gpiote_init();
        APP_ERROR_CHECK(err_code);
    }
    nrf_drv_gpiote_in_config_t in_config = GPIOTE_CONFIG_IN_SENSE_TOGGLE(true);
    err_code = nrf_drv_gpiote_in_init(PIN_IN, &in_config, in_pin_handler);
    APP_ERROR_CHECK(err_code);
    nrf_drv_gpiote_in_event_enable(PIN_IN, true);
}
A.
When checking in SEGGER debug mode,
---- while start .----
Is displayed twice and then it becomes SLEEP.
sd_app_evt_wait ();
Is SLEEP such a thing like that?

B.
In this state, when I made it work, it got in SLEEP state with sd_app_evt_wait ();
After several hours the power has been turned off.
If you operate with the acceleration detection part commented, it will operate normally after several hours.
As with the WDT, if you operate the acceleration handler in a state where reset is not applied, memory leaks
Will it be turned off?
Please let me know if there is any countermeasure.
Thank you.
Parents Reply
  • Hi,
    The above was a mistake.
    In send_mail (); after exiting the while loop, setting false for accel_int_detect,
    With while in main.c,
    err_code = sd_app_evt_wait ();
    Since we are doing, __ SEV (); itself is not executed in in_pin_handler.
    However, when an application interrupt occurs, in_pin_handler will be executed,
    After that, you can not exit with the while loop that goes back, and it is in the state of power shutdown (only with the power button being pressed).
    Which is considered to be the cause?
    I do not know where to go.

Children
  •  could share your project so I can take a deeper look at the code and could you please the answer the previous asked questions? 

  • Thank you for your reply.
    Our main.c and the handler system program will be below.

    /////////////////////////////////////////////////
    //2019-02-06:hitsato  Global variables         //
    // Be sure to update at the time of correction //
    /////////////////////////////////////////////////
    #define VERSION_MAJOR_1 0
    #define VERSION_MAJOR_2 1
    #define VERSION_SUB_1   0
    #define VERSION_SUB_2   0
    #define VERSION_BUILD_8 18
    /////////////////////////////////////////////////
    
    #include <stdbool.h>
    #include <stdint.h>
    #include <string.h>
    
    #include "nordic_common.h"
    #include "nrf.h"
    #include "app_error.h"
    #include "ble.h"
    #include "ble_hci.h"
    #include "ble_srv_common.h"
    #include "ble_advdata.h"
    #include "ble_advertising.h"
    #include "ble_conn_params.h"
    #include "nrf_sdh.h"
    #include "nrf_sdh_soc.h"
    #include "nrf_sdh_ble.h"
    #include "nrf_drv_wdt.h"
    #include "app_timer.h"
    #include "ble_nus.h"
    #include "app_uart.h"
    #include "app_util_platform.h"
    #include "fds.h"
    #include "peer_manager.h"
    #include "bsp_btn_ble.h"
    #include "sensorsim.h"
    #include "ble_conn_state.h"
    #include "nrf_ble_gatt.h"
    #include "nrf_sdm.h"
    
    #include "custom_board.h"
    
    #if defined (UART_PRESENT)
    #include "nrf_uart.h"
    #endif
    #if defined (UARTE_PRESENT)
    #include "nrf_uarte.h"
    #endif
    
    #include "nrf_log.h"
    #include "nrf_log_ctrl.h"
    #include "nrf_log_default_backends.h"
    
    #include "nrf_delay.h"
    
    #include "sub_uart.h"
    #include "sub_twi.h"
    #include "sub_spi.h"
    #include "sub_pin.h"
    #include "sub_pwm.h"
    
    #define APP_FEATURE_NOT_SUPPORTED       BLE_GATT_STATUS_ATTERR_APP_BEGIN + 2    /**< Reply when unsupported features are requested. */
    
    #define DEVICE_NAME                     "GPS_Track_"                       /**< Name of device. Will be included in the advertising data. */
    #define MANUFACTURER_NAME               "AAAA"                   /**< Manufacturer. Will be passed to Device Information Service. */
    #define NUS_SERVICE_UUID_TYPE           BLE_UUID_TYPE_VENDOR_BEGIN                  /**< UUID type for the Nordic UART Service (vendor specific). */
    //#define APP_ADV_INTERVAL                300                                     /**< The advertising interval (in units of 0.625 ms. This value corresponds to 187.5 ms). */
    #define APP_ADV_INTERVAL                64                                          /**< The advertising interval (in units of 0.625 ms. This value corresponds to 40 ms). */
    #define APP_ADV_TIMEOUT_IN_SECONDS      180                                     /**< The advertising timeout in units of seconds. */
    //#define APP_ADV_TIMEOUT_IN_SECONDS      30                                     /**< The advertising timeout in units of seconds. */
    
    #define APP_BLE_OBSERVER_PRIO           3                                       /**< Application's BLE observer priority. You shouldn't need to modify this value. */
    #define APP_BLE_CONN_CFG_TAG            1                                       /**< A tag identifying the SoftDevice BLE configuration. */
    
    //#define MIN_CONN_INTERVAL               MSEC_TO_UNITS(100, UNIT_1_25_MS)        /**< Minimum acceptable connection interval (0.1 seconds). */
    #define MIN_CONN_INTERVAL               MSEC_TO_UNITS(20, UNIT_1_25_MS)             /**< Minimum acceptable connection interval (20 ms), Connection interval uses 1.25 ms units. */
    //#define MAX_CONN_INTERVAL               MSEC_TO_UNITS(200, UNIT_1_25_MS)        /**< Maximum acceptable connection interval (0.2 second). */
    #define MAX_CONN_INTERVAL               MSEC_TO_UNITS(75, UNIT_1_25_MS)             /**< Maximum acceptable connection interval (75 ms), Connection interval uses 1.25 ms units. */
    #define SLAVE_LATENCY                   0                                       /**< Slave latency. */
    //#define CONN_SUP_TIMEOUT                MSEC_TO_UNITS(4000, UNIT_10_MS)         /**< Connection supervisory timeout (4 seconds). */
    #define CONN_SUP_TIMEOUT                MSEC_TO_UNITS(4000, UNIT_10_MS)             /**< Connection supervisory timeout (4 seconds), Supervision Timeout uses 10 ms units. */
    
    #define FIRST_CONN_PARAMS_UPDATE_DELAY  APP_TIMER_TICKS(5000)                   /**< Time from initiating event (connect or start of notification) to first time sd_ble_gap_conn_param_update is called (5 seconds). */
    #define NEXT_CONN_PARAMS_UPDATE_DELAY   APP_TIMER_TICKS(30000)                  /**< Time between each call to sd_ble_gap_conn_param_update after the first call (30 seconds). */
    #define MAX_CONN_PARAMS_UPDATE_COUNT    3                                       /**< Number of attempts before giving up the connection parameter negotiation. */
    
    #define SEC_PARAM_BOND                  1                                       /**< Perform bonding. */
    #define SEC_PARAM_MITM                  0                                       /**< Man In The Middle protection not required. */
    #define SEC_PARAM_LESC                  0                                       /**< LE Secure Connections not enabled. */
    #define SEC_PARAM_KEYPRESS              0                                       /**< Keypress notifications not enabled. */
    #define SEC_PARAM_IO_CAPABILITIES       BLE_GAP_IO_CAPS_NONE                    /**< No I/O capabilities. */
    #define SEC_PARAM_OOB                   0                                       /**< Out Of Band data not available. */
    #define SEC_PARAM_MIN_KEY_SIZE          7                                       /**< Minimum encryption key size. */
    #define SEC_PARAM_MAX_KEY_SIZE          16                                      /**< Maximum encryption key size. */
    
    #define NON_CONNECTABLE_ADV_INTERVAL    MSEC_TO_UNITS(100, UNIT_0_625_MS) /**< The advertising interval for non-connectable advertisement (100 ms). This value can vary between 100ms to 10.24s). */
    
    #define APP_BEACON_INFO_LENGTH          0x17                              /**< Total length of information advertised by the Beacon. */
    #define APP_ADV_DATA_LENGTH             0x15                              /**< Length of manufacturer specific data in the advertisement. */
    #define APP_DEVICE_TYPE                 0x02                              /**< 0x02 refers to Beacon. */
    #define APP_MEASURED_RSSI               0xC3                              /**< The Beacon's measured RSSI at 1 meter distance in dBm. */
    #define APP_COMPANY_IDENTIFIER          0x0059                            /**< Company identifier for Nordic Semiconductor ASA. as per www.bluetooth.org. */
    #define APP_MAJOR_VALUE                 0x01, 0x02                        /**< Major value used to identify Beacons. */
    #define APP_MINOR_VALUE                 0x03, 0x04                        /**< Minor value used to identify Beacons. */
    #define APP_BEACON_UUID                 0x01, 0x12, 0x23, 0x34, \
                                            0x45, 0x56, 0x67, 0x78, \
                                            0x89, 0x9a, 0xab, 0xbc, \
                                            0xcd, 0xde, 0xef, 0xf0            /**< Proprietary UUID for Beacon. */
    
    #define DEAD_BEEF                       0xDEADBEEF                                  /**< Value used as error code on stack dump, can be used to identify stack location on stack unwind. */
    
    #define UART_TX_BUF_SIZE                256                                         /**< UART TX buffer size. */
    #define UART_RX_BUF_SIZE                256                                         /**< UART RX buffer size. */
    
    //Sigfox Setting:buffer size
    #define SIGFOXBUFLEN  12
    
    
    #define SGT_COMMAND_BUF_SIZE  256
    
    #define SGT_MODE_NONE   0
    #define SGT_MODE_TAG    1
    #define SGT_MODE_LINK   2
    #define SGT_MODE_BLEOFF 3
    #define SGT_MODE_STR_TAG    "1"
    #define SGT_MODE_STR_LINK   "2"
    #define SGT_MODE_STR_BLEOFF "3"
    #define DEFAULT_G_THS_TAG     0x04
    #define DEFAULT_G_THS_LINK    0.5
    #define DEFAULT_G_THS_BLEOFF  2.0
    
    #define GPS_TIMEOUT_INIT_FTAG 90//90
    #define GPS_MAX_RETRY_TAG     2
    
    #define GPS_TIMEOUT_INIT_LINK 120
    #define GPS_TIMEOUT_CONT_LINK 10
    #define GPS_MAX_RETRY_LINK    30
    
    #define GPS_TIMEOUT_INIT_BLEOFF 120
    #define GPS_TIMEOUT_CONT_BLEOFF 10
    #define GPS_MAX_RETRY_BLEOFF   
    
    #define WAITING_TAG     60UL
    #define WAITING_LINK    300UL
    #define WAITING_BLEOFF  0UL // not effective
    
    
    #define PERIOD_TAG    (60 * 60UL) //default 
    #define PERIOD_LINK   (60 * 60UL)
    #define PERIOD_BLEOFF (15 * 60UL)
    #define PERIOD_N_TAG    24
    #define PERIOD_N_LINK   24
    #define PERIOD_N_BLEOFF 1
    
    #define BUTTON_MODE_DURATION  1
    #define BUTTON_MODE_INTERVAL  (60U)
    
    int sgt_mode = SGT_MODE_NONE;
    uint8_t sgt_command_buf[SGT_COMMAND_BUF_SIZE];
    uint32_t periodic_interval;
    uint32_t periodic_interval_n;
    uint32_t waiting_time;
    
    volatile bool sending = false;
    volatile bool periodic_int_detect = false;
    volatile bool waiting_int_detect = false;
    volatile bool alert_int_detect = false;
    
    nrf_drv_wdt_channel_id m_channel_id;
    
    //////////////////////////////////////////
    //2018-12-12:hitsato  Global variables  //
    //////////////////////////////////////////
    #include "sub_extern.h"
    int    vib_sensitivity;             //Vibration sensitivity(0:1.0(impact),1:0.5(Insensitivity),2:0.2(Normal),3:0.1(delicate) : default=2:0.2 )
    int    tone_buzzer;                 //Tone of security buzzer(0(Normal),1(Treble),2(bass) : default=0 )
    int    gps_acquisition_method;      //GPS acquisition method(1:Battery priority,2:Positioning priority(Do not turn off GPS, AND Turn off the GPS if there is no change for 2 minutes) : default=0 )
    int    trans_timing;                //Transmission timing(Communication during walking 0:OFF,1:ON : default=1 )
    int    equidistant_comm_rest;       //Equidistant communication,At rest(0:OFF,60:1H,180:3H,360:6H,720:12H,1440:24H,9999:Send unconditionally : default=9999=1 )
    int    equidistant_comm_walk;       //Equidistant communication,When walking(0:OFF,1:1min,5:5min,10:10min,15:15min,30:30min,60:1H,120:2H, 9999:Send unconditionally : default=9999=1 )
    int    beacon_operation;            //Beacon operation(Transmission interval 0:OFF,1:1sec,3:3sec,10:10sec,30:30sec,60:1min,300:5min : default=0 )
    int    act_after_abnormal_detect;   //Action after abnormality detection(Transmission interval 0:OFF,30:Continuous 30 min,60:Continuous 60 min,120:Continuous 120 min,99999:Until the battery runs out : default=0 )
    
    int    emergency_status_report;
    uint8_t sigfox_id[4];
    uint8_t sigfox_id_char1[3];
    uint8_t sigfox_id_char2[3];
    uint8_t sigfox_id_char3[3];
    uint8_t sigfox_id_char4[3];
    int vbat;
    
    int version_major_1;
    int version_major_2;
    int version_sub_1;
    int version_sub_2;
    int version_build_8;
    
    bool   gps_on_flg = false;
    bool   sigfox_send_flg = false;
    //////////////////////////////////////////
    int befor_vbat;
    int sleep_cnt = 0;
    //////////////////////////////////////////
    
    BLE_NUS_DEF(m_nus,2);                                                                 /**< BLE NUS service instance. */
    NRF_BLE_GATT_DEF(m_gatt);                                                       /**< GATT module instance. */
    BLE_ADVERTISING_DEF(m_advertising);                                             /**< Advertising module instance. */
    
    APP_TIMER_DEF(periodic_timer_id);
    APP_TIMER_DEF(waiting_timer_id);
    
    static volatile uint16_t m_conn_handle = BLE_CONN_HANDLE_INVALID;                        /**< Handle of the current connection. */
    static uint16_t   m_ble_nus_max_data_len = BLE_GATT_ATT_MTU_DEFAULT - 3;            /**< Maximum length of data (in bytes) that can be transmitted to the peer by the Nordic UART service module. */
    
    static ble_gap_adv_params_t m_adv_params;                                 /**< Parameters to be passed to the stack when starting advertising. */
    
    static uint8_t m_beacon_info[APP_BEACON_INFO_LENGTH] =                    /**< Information advertised by the Beacon. */
    {
        APP_DEVICE_TYPE,     // Manufacturer specific information. Specifies the device type in this
                             // implementation.
        APP_ADV_DATA_LENGTH, // Manufacturer specific information. Specifies the length of the
                             // manufacturer specific data in this implementation.
        APP_BEACON_UUID,     // 128 bit UUID value.
        APP_MAJOR_VALUE,     // Major arbitrary value that can be used to distinguish between Beacons.
        APP_MINOR_VALUE,     // Minor arbitrary value that can be used to distinguish between Beacons.
        APP_MEASURED_RSSI    // Manufacturer specific information. The Beacon's measured TX power in
                             // this implementation.
    };
    
    
    
    /* YOUR_JOB: Declare all services structure your application is using
     *  BLE_XYZ_DEF(m_xyz);
     */
    
    // YOUR_JOB: Use UUIDs for service(s) used in your application.
    static ble_uuid_t m_adv_uuids[] =                                               /**< Universally unique service identifiers. */
    {
        {BLE_UUID_NUS_SERVICE, NUS_SERVICE_UUID_TYPE}
    
    };
    
    
    
    static uint8_t mac_addr[6];
    
    static void advertising_start(bool erase_bonds);
    
    
    /**@brief Callback function for asserts in the SoftDevice.
     *
    CUSTOM_BOARD_HCUSTOM_BOARD_HCUSTOM_BOARD_HCUSTOM_BOARD_HCUSTOM_BOARD_HCUSTOM_BOARD_HCUSTOM_BOARD_H
     * @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.
     */
    ////////////////////////////////////
    //       assert_nrf_callback      //
    ////////////////////////////////////
    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 handling Peer Manager events.
     *
     * @param[in] p_evt  Peer Manager event.
     */
    ////////////////////////////////////
    //         pm_evt_handler         //
    ////////////////////////////////////
    static void pm_evt_handler(pm_evt_t const * p_evt)
    {
        ret_code_t err_code;
    
        switch (p_evt->evt_id)
        {
            case PM_EVT_BONDED_PEER_CONNECTED:
            {
                NRF_LOG_INFO("Connected to a previously bonded device.");
                NRF_LOG_FLUSH();
            } break;
    
            case PM_EVT_CONN_SEC_SUCCEEDED:
            {
                NRF_LOG_INFO("Connection secured: role: %d, conn_handle: 0x%x, procedure: %d.",
                             ble_conn_state_role(p_evt->conn_handle),
                             p_evt->conn_handle,
                             p_evt->params.conn_sec_succeeded.procedure);
                NRF_LOG_FLUSH();
            } break;
    
            case PM_EVT_CONN_SEC_FAILED:
            {
                /* Often, when securing fails, it shouldn't be restarted, for security reasons.
                 * Other times, it can be restarted directly.
                 * Sometimes it can be restarted, but only after changing some Security Parameters.
                 * Sometimes, it cannot be restarted until the link is disconnected and reconnected.
                 * Sometimes it is impossible, to secure the link, or the peer device does not support it.
                 * How to handle this error is highly application dependent. */
            } break;
    
            case PM_EVT_CONN_SEC_CONFIG_REQ:
            {
                // Reject pairing request from an already bonded peer.
                pm_conn_sec_config_t conn_sec_config = {.allow_repairing = false};
                pm_conn_sec_config_reply(p_evt->conn_handle, &conn_sec_config);
            } break;
    
            case PM_EVT_STORAGE_FULL:
            {
                // Run garbage collection on the flash.
                err_code = fds_gc();
                if (err_code == FDS_ERR_BUSY || err_code == FDS_ERR_NO_SPACE_IN_QUEUES)
                {
                    // Retry.
                }
                else
                {
                    APP_ERROR_CHECK(err_code);
                }
            } break;
    
            case PM_EVT_PEERS_DELETE_SUCCEEDED:
            {
                advertising_start(false);
            } break;
    
            case PM_EVT_LOCAL_DB_CACHE_APPLY_FAILED:
            {
                // The local database has likely changed, send service changed indications.
                pm_local_database_has_changed();
            } break;
    
            case PM_EVT_PEER_DATA_UPDATE_FAILED:
            {
                // Assert.
                APP_ERROR_CHECK(p_evt->params.peer_data_update_failed.error);
            } break;
    
            case PM_EVT_PEER_DELETE_FAILED:
            {
                // Assert.
                APP_ERROR_CHECK(p_evt->params.peer_delete_failed.error);
            } break;
    
            case PM_EVT_PEERS_DELETE_FAILED:
            {
                // Assert.
                APP_ERROR_CHECK(p_evt->params.peers_delete_failed_evt.error);
            } break;
    
            case PM_EVT_ERROR_UNEXPECTED:
            {
                // Assert.
                APP_ERROR_CHECK(p_evt->params.error_unexpected.error);
            } break;
    
            case PM_EVT_CONN_SEC_START:
            case PM_EVT_PEER_DATA_UPDATE_SUCCEEDED:
            case PM_EVT_PEER_DELETE_SUCCEEDED:
            case PM_EVT_LOCAL_DB_CACHE_APPLIED:
            case PM_EVT_SERVICE_CHANGED_IND_SENT:
            case PM_EVT_SERVICE_CHANGED_IND_CONFIRMED:
            default:
                break;
        }
    }
    
    ////////////////////////////////////
    //         send_version           //
    ////////////////////////////////////
    void send_version(uint8_t header2){
        static uint8_t buf[SIGFOXBUFLEN+2];
    
        nrf_gpio_cfg_output(P_LED_RED);
        nrf_gpio_cfg_output(P_LED_GREEN);
        nrf_gpio_cfg_output(P_LED_BLUE);
        nrf_gpio_pin_clear(P_LED_GREEN);
        nrf_gpio_pin_clear(P_LED_BLUE);
    
        make_ver_data(buf, header2);
        decode_loc_data(buf);//debug
        sigfox_send(SIGFOXBUFLEN, buf);
    
        //2019-03-07 hitsato
        for (int i=0 ; i < 6; i++){
            if( sigfox_send_flg ){
                nrf_delay_ms(10000);
                sigfox_send(SIGFOXBUFLEN, buf);
            }
        }
    
        nrf_gpio_pin_set(P_LED_RED);
        nrf_gpio_pin_set(P_LED_GREEN);
        nrf_gpio_pin_set(P_LED_BLUE);
    
    }
    
    ////////////////////////////////////
    //         send_position          //
    ////////////////////////////////////
    void send_position(uint8_t header2)
    {
        //uint8_t buf[SIGFOXBUFLEN];
        static uint8_t buf[SIGFOXBUFLEN+2];//fudouta
    
        //nrf_gpio_cfg_output(P_LED_RED);     //2019-01-09 hitsato
        //nrf_gpio_cfg_output(P_LED_GREEN);   //2019-01-09 hitsato
        //nrf_gpio_pin_clear(P_LED_RED);      //2019-01-09 hitsato
        //nrf_gpio_pin_clear(P_LED_GREEN);    //2019-01-09 hitsato
        make_loc_data(buf, header2);
        //nrf_gpio_pin_set(P_LED_RED);        //2019-01-09 hitsato
        //nrf_gpio_pin_set(P_LED_GREEN);      //2019-01-09 hitsato
    
        decode_loc_data(buf);//debug
        //nrf_drv_wdt_feed();
        //nrf_gpio_cfg_output(P_LED_BLUE);  //2019-01-09 hitsato
        //nrf_gpio_pin_clear(P_LED_BLUE);   //2019-01-09 hitsato
        //nrf_delay_ms(1);                  //2019-01-09 hitsato
        //nrf_gpio_cfg_output(P_LED_BLUE);  //2019-01-09 hitsato
        //nrf_gpio_pin_set(P_LED_BLUE);     //2019-01-09 hitsato
        //nrf_delay_ms(10);                 //2019-01-09 hitsato
    
        nrf_gpio_cfg_output(P_LED_RED);     //2019-01-09 hitsato
        nrf_gpio_cfg_output(P_LED_GREEN);   //2019-01-09 hitsato
        nrf_gpio_cfg_output(P_LED_BLUE);    //2019-01-09 hitsato
        nrf_gpio_pin_clear(P_LED_GREEN);    //2019-01-09 hitsato
        nrf_gpio_pin_clear(P_LED_BLUE);    //2019-01-09 hitsato
        sigfox_send(SIGFOXBUFLEN, buf);
    
        //2019-03-07 hitsato
        for (int i=0 ; i < 6; i++){
            if( sigfox_send_flg ){
                nrf_delay_ms(10000);
                sigfox_send(SIGFOXBUFLEN, buf);
            }
        }
    
        nrf_gpio_pin_set(P_LED_RED);        //2019-01-09 hitsato
        nrf_gpio_pin_set(P_LED_GREEN);      //2019-01-09 hitsato
        nrf_gpio_pin_set(P_LED_BLUE);       //2019-01-09 hitsato
        
        //nrf_delay_ms(10);                 //2019-01-09 hitsato
        //nrf_gpio_cfg_output(P_LED_BLUE);  //2019-01-09 hitsato
        //nrf_gpio_pin_clear(P_LED_BLUE);   //2019-01-09 hitsato
        //nrf_delay_ms(1);                  //2019-01-09 hitsato
        //nrf_gpio_cfg_output(P_LED_BLUE);  //2019-01-09 hitsato
        //nrf_gpio_pin_set(P_LED_BLUE);     //2019-01-09 hitsato
    }
    
    
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    //2019-01-22 hitsato polling section Add.                                                                        //
    //
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /**
     * @brief 
     */
    typedef struct Event_s {
        //Signal s;
        //EventDataT p;
        int s;
        int p;
    } Event;
    
    
    /**
     * @brief MainStateMachine 
     * @param e [in] 
     */
    void send_event(const Event *e);
    
    
    /**
     * @brief main
     */
    bool polling(void);
    
    
    /**
     * @brief 
     */
    typedef enum State_e {
        STATE_A,
        STATE_B,
    } State;
    
    
    /**
     * @brief
     */
    typedef uint8_t (*StateFunc)(const Event *e);
    
    
    static State main_state_machine;    
    // StateMachine
    //#define SM_EVENT_QUEUE_LENGTH (10)            
    #define EVENT_QUEUE_LENGTH (10)               
    static Event event_queue[EVENT_QUEUE_LENGTH];    
    static uint8_t event_queue_head = 0;             
    static uint8_t event_queue_empty_head = 0;      
    
    
    
    ////////////////////////////////////
    //           send_event           //
    ////////////////////////////////////
    void send_event(const Event *e) {
        if (((event_queue_empty_head + 1) == event_queue_head)
            || ((event_queue_empty_head == (EVENT_QUEUE_LENGTH-1)) && (event_queue_head == 0))) {
            //    queue full
            //ERROR_PRINT("Event queue is full!! FatalError!!!\n");
            NRF_LOG_DEBUG("Event queue is full!! FatalError!!!\n");
            NRF_LOG_FLUSH();
            //return RETURN_QUEUE_FULL;
            return;
        }
        event_queue[event_queue_empty_head] = *e;
        event_queue_empty_head = (event_queue_empty_head >= (EVENT_QUEUE_LENGTH -1))
            ? 0 : event_queue_empty_head + 1;
        return;
    }
    
    
    
    /**
     * @brief A
     */
    ////////////////////////////////////
    //           StateFunc_A          //
    ////////////////////////////////////
    uint8_t StateFunc_A(const Event *e) {
        switch(e->s) {
            //case EVENT_SIG_HOGE:
            case 10:
    NRF_LOG_INFO("------------EVENT_SIG_HOGE.------------\n"); //2018-12-13:hitsato
    NRF_LOG_FLUSH();
    
                break;
            default:
    
                return true;
        }
        return false;
    }
    
    
    /**
     * @brief B
     */
    ////////////////////////////////////
    //           StateFunc_B          //
    ////////////////////////////////////
    uint8_t StateFunc_B(const Event *e) {
        switch(e->s) {
            //case EVENT_SIG_HOGERA:
            case 20:
    NRF_LOG_INFO("------------EVENT_SIG_HOGERA.------------\n"); //2018-12-13:hitsato
    NRF_LOG_FLUSH();
    
                break;
            default:
    
                return true;
        }
        return false;
    }
    
    
    /**
     * @brief 
    */
    ////////////////////////////////////
    //         StateFunc_Common       //
    ////////////////////////////////////
    uint8_t StateFunc_Common(const Event *e) {
    
        switch(e->s) {
            //case EVENT_SIG_HOGE:
            case 10:
    NRF_LOG_INFO("------------COMMON_EVENT_SIG_HOGE.------------\n"); //2018-12-13:hitsato
    NRF_LOG_FLUSH();
                break;
            //case EVENT_SIG_HOGERA:
            case 20:
    NRF_LOG_INFO("------------COMMON_EVENT_SIG_HOGERA.------------\n"); //2018-12-13:hitsato
    NRF_LOG_FLUSH();
                break;
            default:
                break;
        }
        return false;
    }
    
    
    static StateFunc state_func_table[] = {StateFunc_A, StateFunc_B};
    
    ////////////////////////////////////
    //       uint8_t dispatch         //
    ////////////////////////////////////
    static uint8_t dispatch(const Event *e) {
        while (state_func_table[main_state_machine](e)) {
            StateFunc_Common(e);
            break;
        }
    }
    
    ////////////////////////////////////
    //             polling            //
    ////////////////////////////////////
    bool polling() {
        if (event_queue_empty_head == event_queue_head) {
            // empty
            return false;
        }
        dispatch(&event_queue[event_queue_head]);
        event_queue_head = (event_queue_head >= (EVENT_QUEUE_LENGTH -1))
            ? 0 : event_queue_head + 1;
        return true;
    }
    
    
    ////////////////////////////////////
    //      debug_sleep_checker       //
    ////////////////////////////////////
    void debug_sleep_checker(void){
        
        while(1){
            NRF_LOG_RAW_INFO("------------SLEEP_CNT:%d------------\n", sleep_cnt);
            NRF_LOG_FLUSH();
            //power_manage();
            ret_code_t err_code = sd_app_evt_wait();
            APP_ERROR_CHECK(err_code);
            sleep_cnt++;
        }
    }
    
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
    
    ////////////////////////////////////
    //      waiting_timer_start       //
    ////////////////////////////////////
    static void waiting_timer_start(void)
    {
        ret_code_t err_code;
    
        NRF_LOG_RAW_INFO("\nStarting waiting timer: %u\n", waiting_time);
        NRF_LOG_FLUSH();
    
        err_code = app_timer_start(waiting_timer_id, APP_TIMER_TICKS(1000UL * waiting_time), NULL);
        APP_ERROR_CHECK(err_code);
    }
    
    ////////////////////////////////////
    // 2018-12-21 hitsato             //
    //      waiting_timer_stop        //
    ////////////////////////////////////
    static void waiting_timer_stop(void)
    {
        ret_code_t err_code;
    
        NRF_LOG_RAW_INFO("\nStopping waiting timer: %u\n", waiting_time);
        NRF_LOG_FLUSH();
    
        err_code = app_timer_stop(waiting_timer_id);
        APP_ERROR_CHECK(err_code);
    }
    
    
    ////////////////////////////////////
    //      waiting_timer_handler     //
    ////////////////////////////////////
    static void waiting_timer_handler(void * p_context)
    {
        UNUSED_PARAMETER(p_context);
    
        ret_code_t err_code;
    
        NRF_LOG_RAW_INFO("\n------------------------(waiting_timer_handler)%s(%d)----------------\n", __func__, __LINE__);
        NRF_LOG_FLUSH();
    
        NRF_LOG_RAW_INFO("waiting_int_detect=true\n");
        NRF_LOG_FLUSH();
    
        waiting_int_detect = true;
    
    //    ////////////////////////////////////
    //    //Event e = {EVENT_SIG_HOGE, param};
    //    Event e = {10, p_context};
    //    send_event(&e);
    //    ////////////////////////////////////
    
    }
    
    
    /**@brief Function for the Timer initialization.
     *
     * @details Initializes the timer module. This creates and starts application timers.
     */
    ////////////////////////////////////
    //           timers_init          //
    ////////////////////////////////////
    static void timers_init(void)
    {
        // Initialize timer module.
        ret_code_t err_code = app_timer_init();
        APP_ERROR_CHECK(err_code);
    
        // Create timers.
    
        err_code = app_timer_create(&waiting_timer_id, APP_TIMER_MODE_SINGLE_SHOT, waiting_timer_handler);
        APP_ERROR_CHECK(err_code);
    }
    
    
    /**@brief Function for the GAP initialization.
     *
     * @details This function sets up all the necessary GAP (Generic Access Profile) parameters of the
     *          device including the device name, appearance, and the preferred connection parameters.
     */
    ////////////////////////////////////
    //        gap_params_init         //
    ////////////////////////////////////
    static void gap_params_init(void)
    {
        ret_code_t              err_code;
        ble_gap_conn_params_t   gap_conn_params;
        ble_gap_conn_sec_mode_t sec_mode;
    
        BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);
    
        char *device_name  = DEVICE_NAME;
        char *device_name1 = sigfox_id_char1;
        char *device_name2 = sigfox_id_char2;
        char *device_name3 = sigfox_id_char3;
        char *device_name4 = sigfox_id_char4;
        char buf[25];
        strcpy(buf, device_name);
        strcat(buf, device_name2);
        strcat(buf, device_name3);
        strcat(buf, device_name4);
    
        err_code = sd_ble_gap_device_name_set(&sec_mode,
                                               //(const uint8_t *)DEVICE_NAME, //2019-01-09 hitsato
                                              (uint8_t *)buf,         //2019-01-09 hitsato
                                              //strlen(DEVICE_NAME));           //2019-01-09 hitsato
                                              strlen(buf));           //2019-01-09 hitsato
        APP_ERROR_CHECK(err_code);
    
        /* YOUR_JOB: Use an appearance value matching the application's use case.
           err_code = sd_ble_gap_appearance_set(BLE_APPEARANCE_);
           APP_ERROR_CHECK(err_code); */
    
        memset(&gap_conn_params, 0, sizeof(gap_conn_params));
    
        gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL;
        gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL;
        gap_conn_params.slave_latency     = SLAVE_LATENCY;
        gap_conn_params.conn_sup_timeout  = CONN_SUP_TIMEOUT;
    
        err_code = sd_ble_gap_ppcp_set(&gap_conn_params);
        APP_ERROR_CHECK(err_code);
    }
    
    
    /**@brief Function for handling events from the GATT library. */
    ////////////////////////////////////
    //        gatt_evt_handler        //
    ////////////////////////////////////
    void gatt_evt_handler(nrf_ble_gatt_t * p_gatt, nrf_ble_gatt_evt_t const * p_evt)
    {
        if ((m_conn_handle == p_evt->conn_handle) && (p_evt->evt_id == NRF_BLE_GATT_EVT_ATT_MTU_UPDATED))
        {
            m_ble_nus_max_data_len = p_evt->params.att_mtu_effective - OPCODE_LENGTH - HANDLE_LENGTH;
            NRF_LOG_INFO("Data len is set to 0x%X(%d)", m_ble_nus_max_data_len, m_ble_nus_max_data_len);
        }
        NRF_LOG_INFO("ATT MTU exchange completed. central 0x%x peripheral 0x%x",
                      p_gatt->att_mtu_desired_central,
                      p_gatt->att_mtu_desired_periph);
        NRF_LOG_FLUSH();
    }
    
    
    /**@brief Function for initializing the GATT module.
     */
    ////////////////////////////////////
    //            gatt_init           //
    ////////////////////////////////////
    static void gatt_init(void)
    {
        ret_code_t err_code;
    
        //ret_code_t err_code = nrf_ble_gatt_init(&m_gatt, NULL);
        err_code = nrf_ble_gatt_init(&m_gatt, gatt_evt_handler);
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_ble_gatt_att_mtu_periph_set(&m_gatt, 64);
        APP_ERROR_CHECK(err_code);
    }
    
    
    /**@brief Function for handling the YYY Service events.
     * YOUR_JOB implement a service handler function depending on the event the service you are using can generate
     *
     * @details This function will be called for all YY Service events which are passed to
     *          the application.
     *
     * @param[in]   p_yy_service   YY Service structure.
     * @param[in]   p_evt          Event received from the YY Service.
     *
     *
    ////////////////////////////////////
    //            on_yys_evt          //
    ////////////////////////////////////
    static void on_yys_evt(ble_yy_service_t     * p_yy_service,
                           ble_yy_service_evt_t * p_evt)
    {
        switch (p_evt->evt_type)
        {
            case BLE_YY_NAME_EVT_WRITE:
                APPL_LOG("[APPL]: charact written with value %s. ", p_evt->params.char_xx.value.p_str);
                break;
    
            default:
                // No implementation needed.
                break;
        }
    }
    */
    
    
    ////////////////////////////////////
    //            set_sgt_mode        //
    ////////////////////////////////////
    static void set_sgt_mode(uint8_t *cmd)
    {
        if (strncmp(cmd, SGT_MODE_STR_TAG, strlen(SGT_MODE_STR_TAG)) == 0) {
            sgt_mode = SGT_MODE_TAG;
        } else if (strncmp(cmd, SGT_MODE_STR_LINK, strlen(SGT_MODE_STR_LINK)) == 0) {
            sgt_mode = SGT_MODE_LINK;
        } else if (strncmp(cmd, SGT_MODE_STR_BLEOFF, strlen(SGT_MODE_STR_BLEOFF)) == 0) {
            sgt_mode = SGT_MODE_BLEOFF;
        } else {
            NRF_LOG_INFO("unknown command");
            NRF_LOG_FLUSH();
        }
    
    
    }
    
    
    
    
    /**@brief Function for handling the Connection Parameters Module.
     *
     * @details This function will be called for all events in the Connection Parameters Module which
     *          are passed to the application.
     *          @note All this function does is to disconnect. This could have been done by simply
     *                setting the disconnect_on_fail config parameter, but instead we use the event
     *                handler mechanism to demonstrate its use.
     *
     * @param[in] p_evt  Event received from the Connection Parameters Module.
     */
    ////////////////////////////////////
    //        on_conn_params_evt      //
    ////////////////////////////////////
    static void on_conn_params_evt(ble_conn_params_evt_t * p_evt)
    {
        ret_code_t err_code;
    
        if (p_evt->evt_type == BLE_CONN_PARAMS_EVT_FAILED)
        {
            err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_CONN_INTERVAL_UNACCEPTABLE);
            APP_ERROR_CHECK(err_code);
        }
    }
    
    
    /**@brief Function for handling a Connection Parameters error.
     *
     * @param[in] nrf_error  Error code containing information about what went wrong.
     */
    ////////////////////////////////////
    //  conn_params_error_handler     //
    ////////////////////////////////////
    static void conn_params_error_handler(uint32_t nrf_error)
    {
        APP_ERROR_HANDLER(nrf_error);
    }
    
    
    /**@brief Function for initializing the Connection Parameters module.
     */
    ////////////////////////////////////
    //        conn_params_init        //
    ////////////////////////////////////
    static void conn_params_init(void)
    {
        ret_code_t             err_code;
        ble_conn_params_init_t cp_init;
    
        memset(&cp_init, 0, sizeof(cp_init));
    
        cp_init.p_conn_params                  = NULL;
        cp_init.first_conn_params_update_delay = FIRST_CONN_PARAMS_UPDATE_DELAY;
        cp_init.next_conn_params_update_delay  = NEXT_CONN_PARAMS_UPDATE_DELAY;
        cp_init.max_conn_params_update_count   = MAX_CONN_PARAMS_UPDATE_COUNT;
        cp_init.start_on_notify_cccd_handle    = BLE_GATT_HANDLE_INVALID;
        cp_init.disconnect_on_fail             = false;
        cp_init.evt_handler                    = on_conn_params_evt;
        cp_init.error_handler                  = conn_params_error_handler;
    
        err_code = ble_conn_params_init(&cp_init);
        APP_ERROR_CHECK(err_code);
    }
    
    
    /**@brief Function for putting the chip into sleep mode.
     *
     * @note This function will not return.
     */
    ////////////////////////////////////
    //        sleep_mode_enter        //
    ////////////////////////////////////
    static void sleep_mode_enter(void)
    {
        ret_code_t err_code;
    
        err_code = bsp_indication_set(BSP_INDICATE_IDLE);
        APP_ERROR_CHECK(err_code);
    
        // Prepare wakeup buttons.
        err_code = bsp_btn_ble_sleep_mode_prepare();
        APP_ERROR_CHECK(err_code);
    
        // Go to system-off mode (this function will not return; wakeup will cause a reset).
        err_code = sd_power_system_off();
        APP_ERROR_CHECK(err_code);
    }
    
    
    /**@brief Function for handling advertising events.
     *
     * @details This function will be called for advertising events which are passed to the application.
     *
     * @param[in] ble_adv_evt  Advertising event.
     */
    ////////////////////////////////////
    //            on_adv_evt          //
    ////////////////////////////////////
    static void on_adv_evt(ble_adv_evt_t ble_adv_evt)
    {
        ret_code_t err_code;
    
        switch (ble_adv_evt)
        {
            case BLE_ADV_EVT_FAST:
                NRF_LOG_INFO("Fast advertising.");
                NRF_LOG_FLUSH();
                err_code = bsp_indication_set(BSP_INDICATE_ADVERTISING);
                APP_ERROR_CHECK(err_code);
                break;
    
            case BLE_ADV_EVT_IDLE:
                NRF_LOG_INFO("Idle detected.");
                NRF_LOG_FLUSH();
                break;
    
            default:
                break;
        }
    }
    
    
    /**@brief Function for handling BLE events.
     *
     * @param[in]   p_ble_evt   Bluetooth stack event.
     * @param[in]   p_context   Unused.
     */
    ////////////////////////////////////
    //         ble_evt_handl          //
    ////////////////////////////////////
    static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
    {
        ret_code_t err_code = NRF_SUCCESS;
    
        switch (p_ble_evt->header.evt_id)
        {
            case BLE_GAP_EVT_DISCONNECTED:
                NRF_LOG_INFO("Disconnected.");
                NRF_LOG_FLUSH();
                // LED indication will be changed when advertising starts.
                m_conn_handle = BLE_CONN_HANDLE_INVALID;
                break;
    
            case BLE_GAP_EVT_CONNECTED:
                NRF_LOG_INFO("Connected.");
                NRF_LOG_FLUSH();
                err_code = bsp_indication_set(BSP_INDICATE_CONNECTED);
                APP_ERROR_CHECK(err_code);
                m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
                break;
    
    #ifndef S140
            case BLE_GAP_EVT_PHY_UPDATE_REQUEST:
            {
                NRF_LOG_DEBUG("PHY update request.");
                NRF_LOG_FLUSH();
                ble_gap_phys_t const phys =
                {
                    .rx_phys = BLE_GAP_PHY_AUTO,
                    .tx_phys = BLE_GAP_PHY_AUTO,
                };
                err_code = sd_ble_gap_phy_update(p_ble_evt->evt.gap_evt.conn_handle, &phys);
                APP_ERROR_CHECK(err_code);
            } break;
    #endif
    
            case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
                // Pairing not supported
                err_code = sd_ble_gap_sec_params_reply(m_conn_handle, BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL, NULL);
                APP_ERROR_CHECK(err_code);
                break;
    #if !defined (S112)
             case BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST:
            {
                ble_gap_data_length_params_t dl_params;
    
                // Clearing the struct will effectivly set members to @ref BLE_GAP_DATA_LENGTH_AUTO
                memset(&dl_params, 0, sizeof(ble_gap_data_length_params_t));
                err_code = sd_ble_gap_data_length_update(p_ble_evt->evt.gap_evt.conn_handle, &dl_params, NULL);
                APP_ERROR_CHECK(err_code);
            } break;
    #endif //!defined (S112)
            case BLE_GATTS_EVT_SYS_ATTR_MISSING:
                // No system attributes have been stored.
                err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0, 0);
                APP_ERROR_CHECK(err_code);
                break;
    
            case BLE_GATTC_EVT_TIMEOUT:
                // Disconnect on GATT Client timeout event.
                NRF_LOG_DEBUG("GATT Client Timeout.");
                NRF_LOG_FLUSH();
                err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gattc_evt.conn_handle,
                                                 BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
                APP_ERROR_CHECK(err_code);
                break;
    
            case BLE_GATTS_EVT_TIMEOUT:
                // Disconnect on GATT Server timeout event.
                NRF_LOG_DEBUG("GATT Server Timeout.");
                NRF_LOG_FLUSH();
                err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gatts_evt.conn_handle,
                                                 BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
                APP_ERROR_CHECK(err_code);
                break;
    
            case BLE_EVT_USER_MEM_REQUEST:
                err_code = sd_ble_user_mem_reply(p_ble_evt->evt.gattc_evt.conn_handle, NULL);
                APP_ERROR_CHECK(err_code);
                break;
    
            case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST:
            {
                ble_gatts_evt_rw_authorize_request_t  req;
                ble_gatts_rw_authorize_reply_params_t auth_reply;
    
                req = p_ble_evt->evt.gatts_evt.params.authorize_request;
    
                if (req.type != BLE_GATTS_AUTHORIZE_TYPE_INVALID)
                {
                    if ((req.request.write.op == BLE_GATTS_OP_PREP_WRITE_REQ)     ||
                        (req.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_NOW) ||
                        (req.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL))
                    {
                        if (req.type == BLE_GATTS_AUTHORIZE_TYPE_WRITE)
                        {
                            auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE;
                        }
                        else
                        {
                            auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_READ;
                        }
                        auth_reply.params.write.gatt_status = APP_FEATURE_NOT_SUPPORTED;
                        err_code = sd_ble_gatts_rw_authorize_reply(p_ble_evt->evt.gatts_evt.conn_handle,
                                                                   &auth_reply);
                        APP_ERROR_CHECK(err_code);
                    }
                }
            } break; // BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST
    
            default:
                // No implementation needed.
                break;
        }
    }
    
    
    /**@brief Function for initializing the BLE stack.
     *
     * @details Initializes the SoftDevice and the BLE event interrupt.
     */
    ////////////////////////////////////
    //        ble_stack_init          //
    ////////////////////////////////////
    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);
    
    
        static ble_gap_addr_t addr;
        err_code = sd_ble_gap_addr_get(&addr);
        APP_ERROR_CHECK(err_code);
    
        strcpy(log_str, "BLE Address: ");
        for (int i = 0; i < BLE_GAP_ADDR_LEN; i++)
            sprintf(log_str + strlen(log_str), " %02x", addr.addr[i]);
        sprintf(log_str + strlen(log_str), ", addr_type: %d", addr.addr_type);
        NRF_LOG_INFO("%s", log_str);
        NRF_LOG_FLUSH();
    
        // Register a handler for BLE events.
        NRF_SDH_BLE_OBSERVER(m_ble_observer, APP_BLE_OBSERVER_PRIO, ble_evt_handler, NULL);
    }
    
    
    /**@brief Function for the Peer Manager initialization.
     */
    ////////////////////////////////////
    //        peer_manager_init       //
    ////////////////////////////////////
    static void peer_manager_init(void)
    {
        ble_gap_sec_params_t sec_param;
        ret_code_t           err_code;
    
        err_code = pm_init();
        APP_ERROR_CHECK(err_code);
    
        memset(&sec_param, 0, sizeof(ble_gap_sec_params_t));
    
        // Security parameters to be used for all security procedures.
        sec_param.bond           = SEC_PARAM_BOND;
        sec_param.mitm           = SEC_PARAM_MITM;
        sec_param.lesc           = SEC_PARAM_LESC;
        sec_param.keypress       = SEC_PARAM_KEYPRESS;
        sec_param.io_caps        = SEC_PARAM_IO_CAPABILITIES;
        sec_param.oob            = SEC_PARAM_OOB;
        sec_param.min_key_size   = SEC_PARAM_MIN_KEY_SIZE;
        sec_param.max_key_size   = SEC_PARAM_MAX_KEY_SIZE;
        sec_param.kdist_own.enc  = 1;
        sec_param.kdist_own.id   = 1;
        sec_param.kdist_peer.enc = 1;
        sec_param.kdist_peer.id  = 1;
    
        err_code = pm_sec_params_set(&sec_param);
        APP_ERROR_CHECK(err_code);
    
        err_code = pm_register(pm_evt_handler);
        APP_ERROR_CHECK(err_code);
    }
    
    
    /**@brief Clear bond information from persistent storage.
     */
    ////////////////////////////////////
    //         delete_bonds           //
    ////////////////////////////////////
    static void delete_bonds(void)
    {
        ret_code_t err_code;
    
        NRF_LOG_INFO("Erase bonds!");
        NRF_LOG_FLUSH();
    
        err_code = pm_peers_delete();
        APP_ERROR_CHECK(err_code);
    }
    
    
    /**@brief Function for handling events from the BSP module.
     *
     * @param[in]   event   Event generated when button is pressed.
     */
    ////////////////////////////////////
    //       bsp_event_handler        //
    ////////////////////////////////////
    static void bsp_event_handler(bsp_event_t event)
    {
        ret_code_t err_code;
    
        switch (event)
        {
            case BSP_EVENT_SLEEP:
                sleep_mode_enter();
                break; // BSP_EVENT_SLEEP
    
            case BSP_EVENT_DISCONNECT:
                err_code = sd_ble_gap_disconnect(m_conn_handle,
                                                 BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
                if (err_code != NRF_ERROR_INVALID_STATE)
                {
                    APP_ERROR_CHECK(err_code);
                }
                break; // BSP_EVENT_DISCONNECT
    
            case BSP_EVENT_WHITELIST_OFF:
                if (m_conn_handle == BLE_CONN_HANDLE_INVALID)
                {
                    err_code = ble_advertising_restart_without_whitelist(&m_advertising);
                    if (err_code != NRF_ERROR_INVALID_STATE)
                    {
                        APP_ERROR_CHECK(err_code);
                    }
                }
                break; // BSP_EVENT_KEY_0
    
            default:
                break;
        }
    }
    
    
    
    /**@brief Function for initializing the Advertising functionality.
     */
    ////////////////////////////////////
    //       advertising_init         //
    ////////////////////////////////////
    static void advertising_init(void)
    {
        ret_code_t             err_code;
        ble_advertising_init_t init;
    
        memset(&init, 0, sizeof(init));
    
        init.advdata.name_type               = BLE_ADVDATA_FULL_NAME;
        //init.advdata.include_appearance      = true;
        init.advdata.include_appearance      = false;
        //init.advdata.flags                   = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
        init.advdata.flags                   = BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE;
        //init.advdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
        //init.advdata.uuids_complete.p_uuids  = m_adv_uuids;
    
        init.srdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
        init.srdata.uuids_complete.p_uuids  = m_adv_uuids;
    
        init.config.ble_adv_fast_enabled  = true;
        init.config.ble_adv_fast_interval = APP_ADV_INTERVAL;
        init.config.ble_adv_fast_timeout  = APP_ADV_TIMEOUT_IN_SECONDS;
    
        init.evt_handler = on_adv_evt;
    
        err_code = ble_advertising_init(&m_advertising, &init);
        APP_ERROR_CHECK(err_code);
    
        ble_advertising_conn_cfg_tag_set(&m_advertising, APP_BLE_CONN_CFG_TAG);
    }
    
    
    
    /**@brief Function for initializing the nrf log module.
     */
    ////////////////////////////////////
    //            log_init            //
    ////////////////////////////////////
    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 the Power manager.
     */
    ////////////////////////////////////
    //           power_manage         //
    ////////////////////////////////////
    static void power_manage(void)
    {
        ret_code_t err_code = sd_app_evt_wait();
        APP_ERROR_CHECK(err_code);
    }
    
    
    
    /**@brief Function for starting advertising.
     */
    ////////////////////////////////////
    //       advertising_start        //
    ////////////////////////////////////
    static void advertising_start(bool erase_bonds)
    {
        if (erase_bonds == true)
        {
            delete_bonds();
            // Advertising is started by PM_EVT_PEERS_DELETED_SUCEEDED evetnt
        }
        else
        {
            ret_code_t err_code = ble_advertising_start(&m_advertising, BLE_ADV_MODE_FAST);
    
            APP_ERROR_CHECK(err_code);
        }
    }
    
    
    ////////////////////////////////////
    //          set_ble_addr          //
    ////////////////////////////////////
    static void set_ble_addr(void)
    {
        ble_gap_addr_t addr;
        const uint8_t *mac = (uint8_t *)&NRF_UICR->CUSTOMER[0];
        uint8_t a;
        ret_code_t err_code;
    
        for (int i = 0; i < 6; i++)
            addr.addr[i] = mac[5 - i];
    
        a = 0;
        if (mac[0] == a && mac[1] == a && mac[2] == a && mac[3] == a && mac[4] == a && mac[5] == a) {
            NRF_LOG_RAW_INFO("%s(%d) exiting (all bytes are 0x00)\n", __func__, __LINE__);
            NRF_LOG_FLUSH();
            return;
        }
    
        a = 0xff;
        if (mac[0] == a && mac[1] == a && mac[2] == a && mac[3] == a && mac[4] == a && mac[5] == a) {
            NRF_LOG_RAW_INFO("%s(%d) exsiting (all bytes are 0xff)\n", __func__, __LINE__);
            NRF_LOG_FLUSH();
            return;
        }
    
        addr.addr_type = BLE_GAP_ADDR_TYPE_PUBLIC;
        //addr.addr_type = BLE_GAP_ADDR_TYPE_RANDOM_STATIC;
    
        err_code = sd_ble_gap_addr_set(&addr);
        //APP_ERROR_CHECK(err_code);
        NRF_LOG_RAW_INFO("%s(%d) err_code=%u\n", __func__, __LINE__, err_code);
        NRF_LOG_FLUSH();
    }
    
    ////////////////////////////////////
    //     reset_for_errata89         //
    ////////////////////////////////////
    void reset_for_errata89(void){
        //If TWIM1 or SPIM1 is used: 
        *(volatile uint32_t *)0x40004FFC = 0;
        *(volatile uint32_t *)0x40004FFC;
        *(volatile uint32_t *)0x40004FFC = 1;
    }
    
    
    
    ////////////////////////////////////
    //2019-01-09 hitsato              //
    // monochromatic LED flash        //
    ////////////////////////////////////
    void mono_led_flashing(uint32_t led_number, uint32_t ncount)
    {
        nrf_gpio_cfg_output(led_number);
     
        for (int n = 0; n < ncount; n++){
        nrf_gpio_pin_toggle(led_number);
        nrf_delay_ms(100);
        }
        nrf_gpio_pin_set(led_number);
    }
    ////////////////////////////////////
    
    ////////////////////////////////////////////////////////////////////////////
    //2019-01-09 hitsato                                                      //
    // Multi LED flash                                                        //
    // You need nrf_gpio_cfg_output in advance and nrf_gpio_pin_set after it. //
    ////////////////////////////////////////////////////////////////////////////
    void multi_led_flashing(uint32_t led_number, uint32_t ncount)
    {
        nrf_gpio_cfg_output(led_number);
        //nrf_gpio_cfg_output(P_LED_GREEN);
        //nrf_gpio_cfg_output(P_LED_BLUE);
    
        //nrf_gpio_pin_set(P_LED_RED);
        //nrf_gpio_pin_set(P_LED_GREEN);
        //nrf_gpio_pin_set(P_LED_BLUE);
     
        for (int n = 0; n < ncount; n++){
        nrf_gpio_pin_toggle(led_number);
        nrf_delay_ms(100);
        }
    
        //nrf_gpio_pin_clear(P_LED_RED);
        //nrf_gpio_pin_clear(P_LED_GREEN);
        //nrf_gpio_pin_clear(P_LED_BLUE);
    
        nrf_gpio_pin_set(led_number);
        //nrf_gpio_pin_set(P_LED_GREEN);
        //nrf_gpio_pin_set(P_LED_BLUE);
    }
    ////////////////////////////////////
    
    
    ////////////////////////////////////
    //2018-12-12:hitsato              //
    //  Temporary   Setting items     //
    ////////////////////////////////////
    #define VIB_SENSITIVITY             2     //Vibration sensitivity(0:1.0(impact),1:0.5(Insensitivity),2:0.2(Normal),3:0.1(delicate) : default=2:0.2 )
    #define TONE_BUZZER                 0     //Tone of security buzzer(0(Normal),1(Treble),2(bass) : default=0 )
    #define GPS_ACQUISITION_METHOD      2     //GPS acquisition method(1:Battery priority,2:Positioning priority(Do not turn off GPS, AND Turn off the GPS if there is no change for 2 minutes) : default=1 )
    #define TRANS_TIMING                1     //Transmission timing(Communication during walking 0:OFF,1:ON : default=1 )
    #define EQUIDISTANT_COMM_REST       720   //Equidistant communication,At rest(0:OFF,60:1H,180:3H,360:6H,720:12H,1440:24H,9999:Send unconditionally : default=9999=1 )
    #define EQUIDISTANT_COMM_WALK       5     //Equidistant communication,When walking(0:OFF,1:1min,5:5min,10:10min,15:15min,30:30min,60:1H,120:2H, 9999:Send unconditionally : default=9999=1 )
    #define BEACON_OPERATION            0     //Beacon operation(Transmission interval 0:OFF,1:1sec,3:3sec,10:10sec,30:30sec,60:1min,300:5min : default=0 )
    #define ACT_AFTER_ABNORMAL_DETECT   30    //Action after abnormality detection(Transmission interval 0:OFF,30:Continuous 30 min,60:Continuous 60 min,120:Continuous 120 min,99999:Until the battery runs out : default=0 )
    
    
    /**@brief Function for application main entry.
     */
    ////////////////////////////////////
    //             main               //
    ////////////////////////////////////
    int main(void)
    //
    {
        int wrk_vib_sensitivity;
        int wrk_tone_buzzer;
        int wrk_gps_acquisition_method;
        int wrk_trans_timing;
        int wrk_equidistant_comm_rest;
        int wrk_equidistant_comm_walk;
        int wrk_beacon_operation;
        int wrk_act_after_abnormal_detect;
        int wrk_emergency_status_report = 0;
    
        ret_code_t err_code;
    
        nrf_delay_ms(1000);           //2019-01-16 hitsato
        //SW Enable(no need SW1 push
        nrf_gpio_cfg_output(P_SW_EN);
        nrf_gpio_pin_set(P_SW_EN);
        
        // Initialize.
        log_init();
        timers_init();// + 0.4mA
    
    NRF_LOG_INFO("------------main started.------------\n"); //2018-12-13:hitsato
    NRF_LOG_FLUSH();
    
        version_major_1 = VERSION_MAJOR_1;
        version_major_2 = VERSION_MAJOR_2;
        version_sub_1   = VERSION_SUB_1;
        version_sub_2   = VERSION_SUB_2;
        version_build_8 = VERSION_BUILD_8;
    
        //float g_ths = 0x08;
        int g_ths = 0x08;
    
        int period_times = 0;
        int limited_time;
        bool accel_skip_flg = false;
    
        NRF_LOG_INFO("sigfox Initialize.");
        NRF_LOG_FLUSH();
        sigfox_init();
        twi_init();
    
        vib_sensitivity = VIB_SENSITIVITY;
        tone_buzzer = TONE_BUZZER;
        gps_acquisition_method = GPS_ACQUISITION_METHOD;
        trans_timing = TRANS_TIMING;
        equidistant_comm_rest = EQUIDISTANT_COMM_REST;
        equidistant_comm_walk = EQUIDISTANT_COMM_WALK;
        beacon_operation = BEACON_OPERATION;
        act_after_abnormal_detect = ACT_AFTER_ABNORMAL_DETECT;
    
        wrk_vib_sensitivity = VIB_SENSITIVITY;
        wrk_tone_buzzer = TONE_BUZZER;
        wrk_gps_acquisition_method = GPS_ACQUISITION_METHOD;
        wrk_trans_timing = TRANS_TIMING;
        wrk_equidistant_comm_rest = EQUIDISTANT_COMM_REST;
        wrk_equidistant_comm_walk = EQUIDISTANT_COMM_WALK;
        wrk_beacon_operation = BEACON_OPERATION;
        wrk_act_after_abnormal_detect = ACT_AFTER_ABNORMAL_DETECT;
    
    /////////////////////////////////////
    //2018-12-13:hitsato               //
    //  Flash Read value set           //
    /////////////////////////////////////
        if( vib_sensitivity == 3 ){   //0x04 //0.125G
            //g_ths = G_0_1G_THS_TAG;
            g_ths = 0x04; //0.125G //2019-02-07 hitsato
        }
        if( vib_sensitivity == 2 ){   //0x08 //0.25G
            //g_ths = G_0_2G_THS_TAG;
            g_ths = 0x08; //0.25G //2019-02-07 hitsato
        }
        if( vib_sensitivity == 1 ){   //0x10 //0.5G
            //g_ths = G_0_5G_THS_TAG;
            g_ths = 0x10; //0.5G  //2019-02-07 hitsato
        }
        if( vib_sensitivity == 0 ){   //0x20 //1.0G
            //g_ths = G_1_0G_THS_TAG;
            g_ths = 0x20; //1.0G  //2019-02-07 hitsato
        }
    ////////////////////////////////////
    
        buzzer_init(); //2019-02-06 Add.
        gpio_pin_init();
    
        gpio_init();
        gpio_init2();
        vbat_init();
    
    waiting_time = 60UL;
      
        //gps setting
        nrf_gpio_cfg_output(P_GPS_RSTN);
        nrf_gpio_pin_set(P_GPS_RSTN);
    
        //2019-02-06 P_Buzzer_PWM OFF
        nrf_gpio_cfg_output(P_Buzzer_PWM);
        nrf_gpio_pin_set(P_Buzzer_PWM);
        nrf_gpio_pin_clear(P_Buzzer_PWM);
    
    NRF_LOG_INFO("------------LIS2DW12_set_mode(g_ths).----------\n"); //2018-12-13:hitsato
    NRF_LOG_FLUSH();
    
        LIS2DW12_set_mode(g_ths);
        //reset because of Errata 89
    /////    LIS2DW12_reset();
    
        accel_int_detect_disabled();
    
    NRF_LOG_INFO("------------Version notification(send_version).----------\n"); //2018-12-13:hitsato
        send_version(HEADER2_VERSION);
    
    NRF_LOG_INFO("------------Initial notification(send_position).----------\n"); //2018-12-13:hitsato
        send_position(HEADER2_PERIODIC);
    
        err_code = nrf_sdh_enable_request();
        APP_ERROR_CHECK(err_code);
    
        int two_sec_count = 0;         //2019-01-11 hitsato
        int accel_int_detect_fast = 0; //2019-01-15 hitsato
    
        if(equidistant_comm_rest == 9999 ){ //Always
            limited_time = 1;
        }else{
            limited_time = equidistant_comm_rest;
        }
    
        NRF_LOG_INFO("-----------------For loop start ---------------\n");
        NRF_LOG_FLUSH();
    
        for (;;)
        {
    
            for (;;)
            {
    
                waiting_timer_start();
    
                if(limited_time != 0 && period_times >= limited_time){
                    NRF_LOG_RAW_INFO("----(Equidistant communication start 1)period_times:%d limited_time:%d----\n\n", period_times,limited_time);
                    NRF_LOG_FLUSH();
                    
                    periodic_int_detect = true;
                    period_times = 0;
                    
                }else{
                    if(limited_time == 0){
                        period_times = 0;
                    }
                    NRF_LOG_RAW_INFO("(Set time display)period_times:%d Limited_Times:%d\n\n", period_times,limited_time);
                    NRF_LOG_FLUSH();
                }
    
                ///////////////////////////////////////////////////////
                //2019-01-30 hitsato                                 //
                //Make acceleration detection only within the while. //
                ///////////////////////////////////////////////////////
                gpio_int_enable();
                ///////////////////////////////////////////////////////
    
                while (!( 
                          accel_int_detect     ||
                          periodic_int_detect  || 
                          waiting_int_detect      )){
    
                        NRF_LOG_INFO("--------------------------------------while start.--------------------------------\n");
                        NRF_LOG_FLUSH();
                   
                        nrf_gpio_pin_set(P_LED_BLUE);
                        nrf_gpio_pin_set(P_LED_GREEN);
                         
                        vbat = vbat_read();
                        befor_vbat = vbat;
    
                        if(vbat > befor_vbat){
                            nrf_gpio_cfg_output(P_LED_GREEN);
                            nrf_gpio_pin_clear(P_LED_GREEN);
                        }
    
                        if(vbat >= 270){  //LED BLUE
                            nrf_gpio_cfg_output(P_LED_BLUE);
                            nrf_gpio_pin_clear(P_LED_BLUE);
                        }
    
                        if( (vbat <= 269 && vbat >= 241 ) && ( vbat <= befor_vbat ) ){  //LED BLACK
                        }
    
                        if(vbat <= 240){  //LED RED
                        }
    
                        //SW Enable(no need SW1 push
                        nrf_gpio_cfg_output(P_SW_EN);
                        nrf_gpio_pin_set(P_SW_EN);
    
                        //2019-02-06 P_Button Enable
                        nrf_gpio_cfg_output(P_Button);
                        nrf_gpio_pin_set(P_Button);
    
                        app_uart_close();    //2019-01-25 hitsato Serial communication at wait close.
    
                        err_code = sd_app_evt_wait();
                        APP_ERROR_CHECK(err_code);
    /////                    __SEV();
    /////                    __WFE();
    /////                    __WFE();
                        nrf_delay_ms(1000);
                        
                }
    
                NRF_LOG_INFO("--------------------------------------while end.--------------------------------\n");
                NRF_LOG_FLUSH();
    
                nrf_gpio_pin_set(P_LED_BLUE);
                nrf_gpio_pin_set(P_LED_GREEN);
    
                ///////////////////////////////////////////////////////
                //2019-01-30 hitsato                                 //
                //Added invalid function for acceleration detection. //
                ///////////////////////////////////////////////////////
                accel_int_detect_disabled();
                ///////////////////////////////////////////////////////
    
                NRF_LOG_RAW_INFO("---(Check vbat value)vbat:%d---\n", vbat);
                NRF_LOG_FLUSH();
    
                NRF_LOG_RAW_INFO("(Check button mode 2)accel:%d, periodic:%d, wait:%d\n", accel_int_detect, periodic_int_detect, waiting_int_detect);
                NRF_LOG_FLUSH();
    
                if (periodic_int_detect) {
                    NRF_LOG_INFO("------------periodic_int_detect start.------------\n");
                    NRF_LOG_FLUSH();
    
                    waiting_timer_stop();
    
                    send_position(HEADER2_PERIODIC);
    
                    periodic_int_detect = false;
                    period_times = 0;
                    
                    accel_int_detect_fast = 0;
                    accel_int_detect = false;
                    continue;
                    
                }
    
                if(waiting_int_detect && !accel_int_detect){
                    two_sec_count++;
    
                    if(two_sec_count == 2){
                        two_sec_count = 0;
    
                        if( gps_on_flg ){
                            NRF_LOG_INFO("------------GPS off: 2 minutes after no vibration------------\n");
                            NRF_LOG_FLUSH();
    
                            gps_on();
                            gps_off();
                            gps_on_flg = false;
                        }
    
                        emergency_status_report = 0 ;     //2019-01-11 hitsato In order to do gps_off of sub_uart.c.
                        wrk_emergency_status_report = 0 ; //2019-01-11 hitsato In order to do gps_off of sub_uart.c.
                    }else{
                        emergency_status_report = 1 ;     //2019-01-11 hitsato In order to do NOT gps_off of sub_uart.c.
                        wrk_emergency_status_report = 1 ; //2019-01-11 hitsato In order to do NOT gps_off of sub_uart.c.
                    }
                }else{
                        emergency_status_report = 1 ;     //2019-01-11 hitsato In order to do NOT gps_off of sub_uart.c.
                        wrk_emergency_status_report = 1 ; //2019-01-11 hitsato In order to do NOT gps_off of sub_uart.c.
                }
    
                if(waiting_int_detect){     //2019-01-11 hitsato Send XX hours after the last transmission
                    NRF_LOG_INFO("------------waiting_int_detect start.------------\n");
                    NRF_LOG_FLUSH();
    
                    period_times++;
                    waiting_int_detect = false;
                    continue;
                }
    
                if( trans_timing == 0 ){  //Communication when walking is OFF
                    periodic_int_detect = false;
    
                    if(accel_int_detect){
                      accel_int_detect = false;
                    }
                    continue;
                }
    
                if( accel_int_detect ){
                    NRF_LOG_RAW_INFO("-----%s(%d) Accel-- gps_acquisition_method = %d ---\n", __func__, __LINE__, gps_acquisition_method);
                    NRF_LOG_FLUSH();
    
                    accel_int_detect = false;
    
                    if( accel_int_detect_fast == 1 && trans_timing == 1 ){
                        if(equidistant_comm_walk == 9999 ){ //Always
                            limited_time = 1;
                        }else{
                            limited_time = equidistant_comm_walk;
                        }
                    }
    
                    if(accel_int_detect_fast == 1 && limited_time != 0 && period_times < limited_time){
                        NRF_LOG_RAW_INFO("----(skip)period_times:%d limited_time:%d----\n", period_times,limited_time);
                        NRF_LOG_FLUSH();
    
                       accel_skip_flg = true;
    
                        if( (vbat <= 269 && vbat >= 241 ) && ( vbat <= befor_vbat ) ){  //LED GREEN
                            nrf_gpio_cfg_output(P_LED_GREEN);
                            nrf_gpio_pin_clear(P_LED_GREEN);
                            nrf_delay_ms(300);
                            nrf_gpio_pin_set(P_LED_GREEN);
                        }
    
                        if(vbat <= 240){  //LED RED
                            nrf_gpio_cfg_output(P_LED_RED);
                            nrf_gpio_pin_clear(P_LED_RED);
                            nrf_delay_ms(300);
                            nrf_gpio_pin_set(P_LED_RED);
                        }
    
                        if(equidistant_comm_rest == 9999 ){ //Always
                            limited_time = 1;
                        }else{
                            limited_time = equidistant_comm_rest;
                        }
    
                    }else{
    
                        NRF_LOG_RAW_INFO("----(Equidistant communication start 2)period_times:%d limited_time:%d----\n", period_times,limited_time);
                        NRF_LOG_FLUSH();
    
                        //LIS2DW12_set_mode(g_ths);
     
                        waiting_timer_stop();           //2019-01-17 hitsato During transmission, timer stops.
    
                        send_position(HEADER2_MOTION);
    
                        period_times = 0; //2019-01-11 hitsato:Send XX hours after the last transmission
     
                        if(equidistant_comm_rest == 9999 ){ //Always
                            limited_time = 1;
                        }else{
                            limited_time = equidistant_comm_rest;
                        }
                    }
    
                   if(gps_acquisition_method == 2){
                        accel_int_detect_fast = 1;
                    }
     
                }
    
                continue;
    
            }
    
        }
    
    }
    

    /*
        sub_twi.c:Acceleromator
     */
    
    #include <stdio.h>
    #include <math.h>
    #include "boards.h"
    #include "app_util_platform.h"
    #include "app_error.h"
    #include "nrf_drv_twi.h"
    #include "nrfx_twi.h"
    #include "nrf_delay.h"
    #include "nrf_drv_gpiote.h"
    
    
    #include "nrf_log.h"
    #include "nrf_log_ctrl.h"
    #include "nrf_log_default_backends.h"
    
    #include "sub_uart.h"
    #include "sub_twi.h"
    #include "custom_board.h"
    
    //////////////////////////////////////////
    //2018-12-12:hitsato  Global variables  //
    //////////////////////////////////////////
    #include "sub_extern.h"
    //////////////////////////////////////////
    
    /* TWI instance ID. */
    //#define TWI_INSTANCE_ID     1
    #define TWI_INSTANCE_ID     0
    
    //#define LIS2DW12_ADDR  0x18U
    #define LIS2DW12_ADDR  0x19U
    
    #define I2C_SCL_PIN P_GS_SCL
    #define I2C_SDA_PIN P_GS_SDA
    #define LIS2DW12_INT1_PIN   P_GS_INT1
    #define LIS2DW12_INT2_PIN   P_GS_INT2
    
    #define LIS2DW12_REG_WHO_AM_I             0x0FU
    #define LIS2DW12_REG_CTRL1                0x20U
    #define LIS2DW12_REG_CTRL2                0x21U
    #define LIS2DW12_REG_CTRL3                0x22U
    #define LIS2DW12_REG_CTRL4_INT1_PAD_CTRL  0x23U
    #define LIS2DW12_REG_CTRL4_INT2_PAD_CTRL  0x24U
    #define LIS2DW12_REG_CTRL6                0x25U
    #define LIS2DW12_REG_OUT_T                0x26U
    #define LIS2DW12_REG_STATUS               0x27U
    #define LIS2DW12_REG_OUT_X_L              0x28U
    #define LIS2DW12_REG_OUT_X_H              0x29U
    #define LIS2DW12_REG_OUT_Y_L              0x2AU
    #define LIS2DW12_REG_OUT_Y_H              0x2BU
    #define LIS2DW12_REG_OUT_Z_L              0x2CU
    #define LIS2DW12_REG_OUT_Z_H              0x2DU
    #define LIS2DW12_REG_WAKE_UP_THS          0x34U
    #define LIS2DW12_REG_WAKE_UP_DUR          0x35U
    #define LIS2DW12_REG_FREE_FALL            0x36U
    #define LIS2DW12_REG_ALL_INT_SRC          0x3BU
    #define LIS2DW12_REG_CTRL7                0x3FU
    
    #define BUTTON  P_Button
    
    #define LED_RED_PIN         P_LED_RED
    #define LED_GREEN_PIN       P_LED_GREEN
    #define LED_BLUE_PIN        P_LED_BLUE
    
    #define PIN_IN  LIS2DW12_INT1_PIN
    //#define PIN_IN  BUTTON
    #define PIN_OUT LED_BLUE_PIN
    
    #define PIN_IN2 LIS2DW12_INT2_PIN
    #define PIN_OUT2  LED_GREEN_PIN
    
    #define COLOR_DEFAULT "\x1B[0m"
    #define COLOR_BLACK   "\x1B[1;30m"
    #define COLOR_RED     "\x1B[1;31m"
    #define COLOR_GREEN   "\x1B[1;32m"
    #define COLOR_YELLOW  "\x1B[1;33m"
    #define COLOR_BLUE    "\x1B[1;34m"
    #define COLOR_MAGENTA "\x1B[1;35m"
    #define COLOR_CYAN    "\x1B[1;36m"
    #define COLOR_WHITE   "\x1B[1;37m"
    
    /* Indicates if operation on TWI has ended. */
    //static volatile bool m_xfer_done = false;
    
    volatile bool accel_int_detect = false;
    volatile bool accel_enable = true;
    int accel_count = 0;
    #define ACOUNT_LIMIT -1
    volatile bool test = true;
    
    /* TWI instance. */
    static const nrf_drv_twi_t m_twi = NRF_DRV_TWI_INSTANCE(TWI_INSTANCE_ID);
    //static const nrfx_twi_t m_twi = NRFX_TWI_INSTANCE(TWI_INSTANCE_ID);
    
    /* Buffer for samples read from temperature sensor. */
    //static uint8_t m_sample;
    //static uint8_t m_sample[6];
    static uint8_t m_sample[7];
    //static uint8_t m_sample[1];
    
    
    /**
     * @brief Function for setting active mode on MMA7660 accelerometer.
     */
    
    void LIS2DW12_reset(void)
    {
        //uninit twi
        nrf_drv_twi_disable(&m_twi);
        nrf_drv_twi_uninit(&m_twi);
        //Errata 89
        *(volatile uint32_t *)0x40004FFC = 0;
        *(volatile uint32_t *)0x40004FFC;
        *(volatile uint32_t *)0x40004FFC = 1;
        //re-initialize
        twi_init();
    
    }
    
    
    void LIS2DW12_set_mode_sub(uint8_t *reg, int reg_len)
    {
        ret_code_t err_code;
    
        err_code = nrf_drv_twi_tx(&m_twi, LIS2DW12_ADDR, reg, reg_len, false);
        APP_ERROR_CHECK(err_code);
    }
    
    #define FS  2
    
    //void LIS2DW12_set_mode(float threshold)
    void LIS2DW12_set_mode(int threshold)   //2019-02-07 hitsato
    {
        //ret_code_t err_code;
    
        uint8_t reg[2];
    
        uint8_t th = threshold;
        //comment out because of high currency 20180815
    //    sprintf(log_str, "threshold=%f, WK_THS=%u", threshold, th);
    //    NRF_LOG_INFO("%s(%d) %s", __func__, __LINE__, log_str);
    //    NRF_LOG_FLUSH();
    
        // Activity/Inactivity recognition, AN5038 p.35
    
        NRF_LOG_INFO("Interrupt generation: Activity/Inactivity recognition");
        NRF_LOG_FLUSH();
    
        reg[0] = LIS2DW12_REG_CTRL1;
        reg[1] = 0x50;  // Turn on the accelerometer; ODR = 100 Hz, Low-power
        //reg[1] = 0x20;  // Turn on the accelerometer; ODR = 12.5 Hz, Low-power
        LIS2DW12_set_mode_sub(reg, 2);
    
        reg[0] = LIS2DW12_REG_CTRL6;
        reg[1] = 0x04;  // FS 2 g LOW_NOISE enabled
        LIS2DW12_set_mode_sub(reg, 2);
    
        ASSERT( (2 << ((reg[1] & 0x30) >> 4)) == FS);
    
        // missing in the sample
        reg[0] = LIS2DW12_REG_CTRL7;
        reg[1] = 0x20;  // Use HP filter, enable interrupts
        LIS2DW12_set_mode_sub(reg, 2);
    
        reg[0] = LIS2DW12_REG_WAKE_UP_DUR;
        reg[1] = 0x42;   // Set duration for inactivity detection; Set duration for wake-up detection
        LIS2DW12_set_mode_sub(reg, 2);
    
        reg[0] = LIS2DW12_REG_WAKE_UP_THS;
        //reg[1] = 0x42;  // Set activity/inactivity threshold; Enable activity/inactivity detection
        reg[1] = 0x40 | th;
        LIS2DW12_set_mode_sub(reg, 2);
    
        NRF_LOG_RAW_INFO("%s(%d) WAKE_UP_THS: 0x%x\n", __func__, __LINE__, reg[1]);
        NRF_LOG_FLUSH();
    
        reg[0] = LIS2DW12_REG_CTRL4_INT1_PAD_CTRL;
        reg[1] = 0x20;  // Activity (wakeup) interrupt driven to INT1 pin
        LIS2DW12_set_mode_sub(reg, 2);
    
    
    
    }
    
    void LIS2DW12_set_command_status(void)
    {
        ret_code_t err_code;
    
        uint8_t reg[] = {LIS2DW12_REG_STATUS};
    
        err_code = nrf_drv_twi_tx(&m_twi, LIS2DW12_ADDR, reg, sizeof(reg), false);
        APP_ERROR_CHECK(err_code);
    
    }
    
    void LIS2DW12_set_command_out_xyz(void)
    {
        ret_code_t err_code;
    
        uint8_t reg[] = {LIS2DW12_REG_OUT_X_L};
    
        err_code = nrf_drv_twi_tx(&m_twi, LIS2DW12_ADDR, reg, sizeof(reg), false);
        APP_ERROR_CHECK(err_code);
    
    }
    
    /**
     * @brief UART initialization.
     */
    void twi_init (void)
    {
        ret_code_t err_code;
    
        const nrf_drv_twi_config_t twi_lis2dw12_config = {
           .scl                = I2C_SCL_PIN,
           .sda                = I2C_SDA_PIN,
           .frequency          = NRF_TWI_FREQ_100K,
           .interrupt_priority = APP_IRQ_PRIORITY_HIGH,
           .clear_bus_init     = false
        };
    
        //err_code = nrf_drv_twi_init(&m_twi, &twi_lis2dw12_config, twi_handler, NULL); // non-blocking mode
        err_code = nrf_drv_twi_init(&m_twi, &twi_lis2dw12_config, NULL, NULL); // blocking mode
        /////err_code = nrfx_twi_init(&m_twi, &twi_lis2dw12_config, NULL, NULL); // blocking mode
        APP_ERROR_CHECK(err_code);
    
        nrf_drv_twi_enable(&m_twi);
    }
    
    /**
     * @brief Function for reading data from temperature sensor.
     */
    void read_sensor_data()
    {
        //m_xfer_done = false;
    
        /* Read 1 byte from the specified address - skip 3 bits dedicated for fractional part of temperature. */
        ret_code_t err_code = nrf_drv_twi_rx(&m_twi, LIS2DW12_ADDR, m_sample, 7);
        APP_ERROR_CHECK(err_code);
        //NRF_LOG_INFO("Temperature: %d Celsius degrees.!", m_sample);
    }
    
    //char log_str[128];  // nrf_log_push() seems buggy
    
    static uint8_t read_int_src(void)
    {
        ret_code_t err_code;
    
        uint8_t reg[] = {LIS2DW12_REG_ALL_INT_SRC};
    
        err_code = nrf_drv_twi_tx(&m_twi, LIS2DW12_ADDR, reg, sizeof(reg), false);
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_drv_twi_rx(&m_twi, LIS2DW12_ADDR, m_sample, 1);
        APP_ERROR_CHECK(err_code);
        //sprintf(log_str, "%02x: ", m_sample[0])
        NRF_LOG_RAW_INFO("%02x: ", m_sample[0]);
    
        //NRF_LOG_INFO("%s", log_str);
        //NRF_LOG_FLUSH();
        //sprintf(log_str + strlen(log_str), "SLEEP_CHANGE_IA: %s", (m_sample[0] & 32) ? COLOR_RED "1" COLOR_DEFAULT : "0")
        //sprintf(log_str + strlen(log_str), ", 6D_IA: %s", (m_sample[0] & 16) ? COLOR_RED "1" COLOR_DEFAULT : "0")
        //sprintf(log_str + strlen(log_str), ", DOUBLE_TAP: %s", (m_sample[0] & 8) ? COLOR_RED "1" COLOR_DEFAULT : "0")
        //sprintf(log_str + strlen(log_str), ", SINGLE_TAP: %s", (m_sample[0] & 4) ? COLOR_RED "1" COLOR_DEFAULT : "0")
        //sprintf(log_str + strlen(log_str), ", WU_IA: %s", (m_sample[0] & 2) ? COLOR_RED "1" COLOR_DEFAULT : "0")
        //sprintf(log_str + strlen(log_str), ", FF_IA: %s", (m_sample[0] & 1) ? COLOR_RED "1" COLOR_DEFAULT : "0")
        //NRF_LOG_INFO("%s", log_str)
    
        NRF_LOG_RAW_INFO("SLEEP_CHANGE_IA: %s", (m_sample[0] & 32) ? COLOR_RED "1" COLOR_DEFAULT : "0");
        NRF_LOG_RAW_INFO(", 6D_IA: %s", (m_sample[0] & 16) ? COLOR_RED "1" COLOR_DEFAULT : "0");
        NRF_LOG_RAW_INFO(", DOUBLE_TAP: %s", (m_sample[0] & 8) ? COLOR_RED "1" COLOR_DEFAULT : "0");
        NRF_LOG_RAW_INFO(", SINGLE_TAP: %s", (m_sample[0] & 4) ? COLOR_RED "1" COLOR_DEFAULT : "0");
        NRF_LOG_RAW_INFO(", WU_IA: %s", (m_sample[0] & 2) ? COLOR_RED "1" COLOR_DEFAULT : "0");
        NRF_LOG_RAW_INFO(", FF_IA: %s", (m_sample[0] & 1) ? COLOR_RED "1" COLOR_DEFAULT : "0");
        NRF_LOG_FLUSH();
    
        return m_sample[0];
    }
    
    void wait_for_ready(void)
    {
        ret_code_t err_code;
    
        do {
            LIS2DW12_set_command_status();
            err_code = nrf_drv_twi_rx(&m_twi, LIS2DW12_ADDR, m_sample, 1);
            APP_ERROR_CHECK(err_code);
        } while ((m_sample[0] & 1) == 0);
    }
    
    int n = 0;
    
    void get_out_xyz(void)
    {
            wait_for_ready();
            LIS2DW12_set_command_out_xyz();
            read_sensor_data();
    
            float out_x, out_y, out_z, overall;
            out_x = *(int16_t *)(m_sample + 0) / 4 * 0.244 / 1000.0;
            out_y = *(int16_t *)(m_sample + 2) / 4 * 0.244 / 1000.0;
            out_z = *(int16_t *)(m_sample + 4) / 4 * 0.244 / 1000.0;
    
            overall = sqrt(out_x * out_x + out_y * out_y + out_z * out_z);
            //sprintf(log_str, "%5d %.3f %.3f %.3f %.3f", ++n, out_x, out_y, out_z, overall)
            //NRF_LOG_INFO("%s", log_str)
    
            //NRF_LOG_RAW_INFO("%5d %.3f %.3f %.3f %.3f", ++n, out_x, out_y, out_z, overall);
            //NRF_LOG_FLUSH();
    }
    
    static void in_pin_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
    {
        uint8_t ret;
        NRF_LOG_INFO("%s %d", __func__, __LINE__);
        NRF_LOG_FLUSH();
    
        //ret = read_int_src();  //2019-01-25 fudouta
        
        //motion interrupt mujouken zikkou
       // if (ret & (32 + 2)) { // SLEEP_CHANGE_IA | WU_IA
    //    nrf_drv_gpiote_in_event_disable(PIN_IN);
    //    nrf_drv_gpiote_in_event_disable(PIN_IN2);
    //    NRF_LOG_INFO("--- INT disabled for button and jack");
    
    
    
        accel_count++;
        if(accel_count > ACOUNT_LIMIT){
            nrf_drv_gpiote_in_event_disable(PIN_IN);
            nrf_drv_gpiote_in_event_disable(PIN_IN2);
            NRF_LOG_INFO("--- INT disabled for button and jack");
    
            NRF_LOG_RAW_INFO("accel_int_detect=true\n");
            NRF_LOG_FLUSH();
            accel_int_detect = true;
            accel_count = 0;
        }
        NRF_LOG_INFO("Motion detected in_pin_handler-Return");
        NRF_LOG_FLUSH();
     //   }
    
    //    __SEV();
    //    __WFE();
    //    __WFE();
        return;
    }
    
    static void in_pin_handler2(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
    {
        NRF_LOG_INFO("%s %d", __func__, __LINE__);
        NRF_LOG_FLUSH();
    
        ret_code_t err_code;
    
        uint8_t reg[] = {LIS2DW12_REG_STATUS};
    
        err_code = nrf_drv_twi_tx(&m_twi, LIS2DW12_ADDR, reg, sizeof(reg), false);
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_drv_twi_rx(&m_twi, LIS2DW12_ADDR, m_sample, 1);
        APP_ERROR_CHECK(err_code);
    
        //sprintf(log_str, "%02x: ", m_sample[0])
        NRF_LOG_RAW_INFO("%02x: ", m_sample[0]);
    
        //STATUS:
    
        NRF_LOG_RAW_INFO("FIFO_THS: %s", (m_sample[0] & 128) ? COLOR_RED "1" COLOR_DEFAULT : "0");
        NRF_LOG_RAW_INFO(", WU_IA: %s", (m_sample[0] & 64) ? COLOR_RED "1" COLOR_DEFAULT : "0");
        NRF_LOG_RAW_INFO(", SLEEP_STATE: %s", (m_sample[0] & 32) ? COLOR_RED "1" COLOR_DEFAULT : "0");
        NRF_LOG_RAW_INFO(", DOUBLE_TAP: %s", (m_sample[0] & 16) ? COLOR_RED "1" COLOR_DEFAULT : "0");
        NRF_LOG_RAW_INFO(", SINGLE_TAP: %s", (m_sample[0] & 8) ? COLOR_RED "1" COLOR_DEFAULT : "0");
        NRF_LOG_RAW_INFO(", 6D_IA: %s", (m_sample[0] & 4) ? COLOR_RED "1" COLOR_DEFAULT : "0");
        NRF_LOG_RAW_INFO(", FF_IA: %s", (m_sample[0] & 2) ? COLOR_RED "1" COLOR_DEFAULT : "0");
        NRF_LOG_RAW_INFO(", DRDY: %s", (m_sample[0] & 1) ? COLOR_RED "1" COLOR_DEFAULT : "0");
        NRF_LOG_FLUSH();
    
        get_out_xyz();
    
        //accel_int_detect = true;
    
    }
    /**
     * @brief Function for configuring: PIN_IN pin for input, PIN_OUT pin for output,
     * and configures GPIOTE to give an interrupt on pin change.
     */
    /*static */void gpio_init(void)
    {
        ret_code_t err_code;
    
        if (!nrf_drv_gpiote_is_init())
        {
            err_code = nrf_drv_gpiote_init();
            //VERIFY_SUCCESS(err_code);
            APP_ERROR_CHECK(err_code);
        }
    
        nrf_drv_gpiote_in_config_t in_config = GPIOTE_CONFIG_IN_SENSE_TOGGLE(true);
    
        err_code = nrf_drv_gpiote_in_init(PIN_IN, &in_config, in_pin_handler);
        APP_ERROR_CHECK(err_code);
    
        nrf_drv_gpiote_in_event_enable(PIN_IN, true);
    }
    
    /*static */void gpio_init2(void)
    {
        ret_code_t err_code;
    
        if (!nrf_drv_gpiote_is_init())
        {
            err_code = nrf_drv_gpiote_init();
            //VERIFY_SUCCESS(err_code);
            APP_ERROR_CHECK(err_code);
        }
    
        nrf_drv_gpiote_in_config_t in_config = GPIOTE_CONFIG_IN_SENSE_TOGGLE(true);
    
        err_code = nrf_drv_gpiote_in_init(PIN_IN2, &in_config, in_pin_handler2);
        APP_ERROR_CHECK(err_code);
    
        nrf_drv_gpiote_in_event_enable(PIN_IN2, true);
    }
    
    void gpio_int_enable(void)
    {
        nrf_drv_gpiote_in_event_enable(PIN_IN2, true);
        nrf_drv_gpiote_in_event_enable(PIN_IN, true);
            NRF_LOG_INFO("--- accel_int_detect Enabled ---");
    }
    
    ///////////////////////////////////////////////////////
    //2019-01-30 hitsato                                 //
    //Added invalid function for acceleration detection. //
    ///////////////////////////////////////////////////////
    void accel_int_detect_disabled(void)
    {
            nrf_drv_gpiote_in_event_disable(PIN_IN);
            nrf_drv_gpiote_in_event_disable(PIN_IN2);
            NRF_LOG_INFO("--- accel_int_detect Disabled ---");
    }
    
    ///////////////////////////////////////////////////////
    //2019-01-30 hitsato                                 //
    //Added invalid function for acceleration detection. //
    ///////////////////////////////////////////////////////
    void gpio_uninit(void)
    {
           nrf_drv_gpiote_in_uninit(PIN_IN);
           nrf_drv_gpiote_in_uninit(PIN_IN2);
            NRF_LOG_INFO("--- gpio_uninit ---");
    }

    When debugging with SEGGER, it stopped with "<info> app: Motion detected in _ pin_handler - Return".

    Starting waiting timer: 60
    (Set time display)period_times:15 Limited_Times:720
    
    <info> app: --- accel_int_detect Enabled ---
    <info> app: --------------------------------------while start.--------------------------------
    
    
    ------------------------(waiting_timer_handler)waiting_timer_handler(944)----------------
    waiting_int_detect=true
    <info> app: --------------------------------------while end.--------------------------------
    
    <info> app: --- accel_int_detect Disabled ---
    ---(Check vbat value)vbat:255---
    (Check button mode 2)accel:0, periodic:0, wait:1
    <info> app: ------------waiting_int_detect start.------------
    
    
    Starting waiting timer: 60
    (Set time display)period_times:16 Limited_Times:720
    
    <info> app: --- accel_int_detect Enabled ---
    <info> app: --------------------------------------while start.--------------------------------
    
    
    ------------------------(waiting_timer_handler)waiting_timer_handler(944)----------------
    waiting_int_detect=true
    <info> app: --------------------------------------while end.--------------------------------
    
    <info> app: --- accel_int_detect Disabled ---
    ---(Check vbat value)vbat:255---
    (Check button mode 2)accel:0, periodic:0, wait:1
    <info> app: ------------waiting_int_detect start.------------
    
    
    Starting waiting timer: 60
    (Set time display)period_times:17 Limited_Times:720
    
    <info> app: --- accel_int_detect Enabled ---
    <info> app: --------------------------------------while start.--------------------------------
    
    <info> app: in_pin_handler 320
    <info> app: --- INT disabled for button and jack
    accel_int_detect=true
    <info> app: Motion detected in_pin_handler-Return
    

  • Application timer interrupt that operates after 720 minutes is the same phenomenon.

  • Is it necessary to clear something after handler interrupt?

  • Also, I forgot to mention,
    err_code = sd_app_evt_wait ();
    not,
    __ SEV ();
    __ WFE ();
    __ WFE ();
    Even if it changes to, the phenomenon is similar.

Related