/*******************************************************************************
 TEST medi50  Dec 23
 *******************************************************************************
 *
 * [Module overview]
 * Main event loop timer module (10ms interval, single-shot mode).
 *
 * Dispatches sensor data collection and system control events via flags.
 * Uses app_timer single-shot mode; after processing, call main_timer_start()
 * manually to restart if needed.
 *
 * [Event flags and processing order]
 *   motion_raw_data_enabled -> IMU data read (calls icm42670_main)
 *     - motion_data_once == true: one-shot read (after HW I2C init)
 *     - motion_data_once == false: continuous read (when not waiting for BLE TX)
 *   go_batt                -> Battery voltage measurement (battery_level_meas)
 *   go_device_power_off    -> Device power OFF (device_power_off)
 *   go_sleep_mode_enter    -> Enter sleep mode (sleep_mode_enter)
 *   go_NVIC_SystemReset    -> NVIC system reset
 *
 * [Timer settings]
 *   - Normal mode: 10ms interval (MAIN_LOOP_INTERVAL)
 *   - FEATURE_DETAIL_VALUE_FULL mode: 80ms interval (for detail printout)
 *
 ******************************************************************************/

#include "sdk_common.h"

#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "nrf.h"
#include "nrf_drv_saadc.h"
#include "nrf_drv_ppi.h"
#include "nrf_drv_timer.h"
#include "boards.h"
#include "app_error.h"
#include "nrf_delay.h"
#include "app_util_platform.h"
#include "nrf_pwr_mgmt.h"

#include "nrf_log.h"
#include "nrf_drv_gpiote.h"
#include "battery_saadc.h"
#include "app_timer.h"

#include "main.h"
#include "app_raw_main.h"
#include "main_timer.h"
//#include "fstorage.h"
#include "power_control.h"
#include "main.h"  /* 2026-03-17: cmd_parse.h removed, use main.h */
#include "debug_print.h"
#include "i2c_manager.h" //add cj

/* Main loop single-shot timer instance */
APP_TIMER_DEF(m_main_loop_timer_id);

#if FEATURE_DETAIL_VALUE_FULL
/* Detail printout mode: run main loop at 80ms interval */
#define MAIN_LOOP_INTERVAL              80		/* Timer for Full_Mode main processing when detail printout is enabled */

//extern bool pd_adc_full_a_start;
//extern bool pd_adc_full_b_start;
//extern bool pd_adc_full_c_start;
//extern bool pd_adc_full_d_start;
//extern bool pd_adc_full_end;

extern which_cmd_t cmd_type_t;
#else
/* Normal mode: run main loop at 10ms interval */
#define MAIN_LOOP_INTERVAL              10
#endif

/* ========================================================================== */
/* Event flags (set by external modules, processed in main_loop)              */
/* ========================================================================== */
bool go_batt= false;                    /* Battery measurement request flag */
bool go_device_power_off = false;       /* Device power OFF request flag */
bool go_sleep_mode_enter = false;       /* Sleep mode entry request flag */
bool go_NVIC_SystemReset = false;       /* System reset request flag */
bool motion_raw_data_enabled = false;   /* IMU motion data read enable flag */
bool ble_got_new_data = false;          /* BLE new data transmission complete */
bool motion_data_once = false;          /* IMU one-shot read mode (true: read once) */

/**
 * @brief Main event loop (single-shot timer callback)
 *
 * Flag-based event dispatcher; processes actions based on set flags.
 * Since the timer is single-shot, call main_timer_start() again from
 * within the handler to continue execution.
 *
 * [Processing priority] (checked in code order)
 *   1. IMU motion data (motion_raw_data_enabled)
 *   2. Battery measurement (go_batt)
 *   3. Power OFF (go_device_power_off)
 *   4. Sleep mode (go_sleep_mode_enter)
 *   5. System reset (go_NVIC_SystemReset)
 */
void main_loop(void * p_context)	/* For x ms */
{
	UNUSED_PARAMETER(p_context);

#if FEATURE_DETAIL_VALUE_FULL
//	if(pd_adc_full_a_start == true) {		// A mode
//		main_timer_stop();
//		printf("main_loop_A\r\n");
//		full_adc_start();
//	}else if(pd_adc_full_b_start == true) {	// B mode
//		main_timer_stop();
//		printf("main_loop_B\r\n");
//		full_adc_start();
//	}else if(pd_adc_full_c_start == true) {	// C mode
//		main_timer_stop();
//		printf("main_loop_C\r\n");
//		full_adc_start();
//	}else if(pd_adc_full_d_start == true) {	// D mode
//		main_timer_stop();
//		printf("main_loop_D\r\n");
//		full_adc_start();
//	}else if(pd_adc_full_end == true) { 	// Completed
//		pd_adc_full_end = false;
//		main_timer_stop();
//		printf("main_loop_END\r\n");

//		if(cmd_type_t == CMD_BLE) {
//			full_send_timer_start();
//		}
//	}
#endif
					
	// For Motion Data Sampling

	/* ---- IMU motion data read ---- */
	/*
	 * If motion_raw_data_enabled is true, read IMU (ICM42670P) data.
	 *
	 * motion_data_once == true:
	 *   One-shot read mode. Initialize HW I2C then call icm42670_main() once.
	 *   Used in info4 mode to return to IMU after battery/temp measurement.
	 *
	 * motion_data_once == false:
	 *   Continuous read mode. If not waiting for BLE TX (ble_got_new_data==false),
	 *   call icm42670_main() and restart timer after 10ms for repeated execution.
	 */
	if (motion_raw_data_enabled == true)
	{
		main_timer_stop();   /* Stop timer (prevent re-entry) */
		if (motion_data_once == true)
		{
			/* One-shot mode: init HW I2C then read IMU data once */
			hw_i2c_init_once();     /* Switch to HW TWI mode (400kHz) */
			icm42670_main();        /* Read and process IMU data */
        }
		else
		{
			/* Continuous mode: repeat read if not waiting for BLE TX */
			if (ble_got_new_data==false)
			{
				//for(uint16_t i=0 ; i<60 ;i++)
				//{
				DBG_PRINTF("IMU \r\n");

				icm42670_main();           /* Read IMU data */
				motion_raw_data_enabled = true;   /* Keep flag set (continuous read) */
				main_timer_start_ms(1000);       /* Next IMU read after 1s */
			}
	//		else if(ble_got_new_data==true){
	//			motion_data_once = true;
	//		}
		}
	}
	
	
	/* ---- Battery voltage measurement ---- */
	/*
	 * If go_batt is true, measure battery level.
	 * Called after IMU continuous read in info4 mode.
	 * Timer remains stopped after measurement.
	 */
	if (go_batt == true)
	{
		DBG_PRINTF("IMU BATT\r\n");
		main_timer_stop();       /* Stop timer */
		go_batt = false;         /* Consume flag (one-shot) */
			battery_level_meas();   /* Measure battery voltage via SAADC */
//			nrf_delay_ms(20);
//			m48_adc_start_init();
//		main_timer_start();
	}
	
	/* ---- System control event handling ---- */

	/* Device power OFF handling */
	if (go_device_power_off == true)
	{
		main_timer_stop();              /* Stop timer */
		DBG_PRINTF("Off main_timer\r\n");
		device_power_off();             /* Execute device power OFF */
	}

	/* Sleep mode entry handling */
	if (go_sleep_mode_enter == true)
	{
		main_timer_stop();              /* Stop timer */
		DBG_PRINTF("sleep main timer\r\n");
		sleep_mode_enter();             /* Execute sleep mode entry */
	}

	/* NVIC system reset handling */
	if (go_NVIC_SystemReset == true)
	{
		main_timer_stop();              /* Stop timer */
		NVIC_SystemReset();             /* ARM Cortex-M4 system reset */
	}
}


/**
 * @brief Start main loop timer
 *
 * Single-shot mode; calls main_loop() after MAIN_LOOP_INTERVAL (10ms or 80ms)
 */
void main_timer_start(void)
{
	APP_ERROR_CHECK(app_timer_start(m_main_loop_timer_id, APP_TIMER_TICKS(MAIN_LOOP_INTERVAL), NULL));
}

/**
 * @brief Start main loop timer with specified interval (ms)
 *
 * Used when a different period than the default is needed (e.g. IMU streaming)
 */
void main_timer_start_ms(uint32_t interval_ms)
{
	APP_ERROR_CHECK(app_timer_start(m_main_loop_timer_id, APP_TIMER_TICKS(interval_ms), NULL));
}

/**
 * @brief Stop main loop timer
 */
void main_timer_stop(void)
{
	APP_ERROR_CHECK(app_timer_stop(m_main_loop_timer_id));
}

/**
 * @brief Initialize main loop timer (call once at app startup)
 *
 * Creates a single-shot timer with main_loop() as callback.
 * Must manually restart via main_timer_start() after each firing.
 */
void main_timer_init(void)
{
    APP_ERROR_CHECK(app_timer_create(&m_main_loop_timer_id, APP_TIMER_MODE_SINGLE_SHOT, main_loop));
}
