/**
 * @file    motion.h
 * @brief   Motion Module
 * @author  Kenny Tran
 * @date    Jan 27 2023
 * @version 0.0.1
 *
 * @section LICENSES
 * Copyright (C) Morgan Advanced Programmable Systems, Inc.
 */


#ifndef MOTION_H_
#define MOTION_H_


/*--------------------------------------------------------------------------------------------------
 * INCLUDE FILES
 *------------------------------------------------------------------------------------------------*/
#include <stdint.h>
#include <stdbool.h>

#include "../bsp/imu.h"


/*--------------------------------------------------------------------------------------------------
 * MACROS & CONSTANTS
 *------------------------------------------------------------------------------------------------*/
#define MOTION_TASK_PERIOD_MS  		 	(50)
#define MOTION_STACK_SIZE       		(2048)
#define MOTION_THREAD_PRIORITY  		(6)

#define MOTION_ANG_THRESHOLD_DEFAULT    (0.035)
#define MOTION_CAL_READINGS     		(100)

#define MOTION_GYRO_RECAL_READINGS 		(50)

#define MOTION_FILENAME	        		("motion")


/*--------------------------------------------------------------------------------------------------
 * TYPE DEFINITIONS & ENUMERATIONS
 *------------------------------------------------------------------------------------------------*/
typedef IMU_data_s MOTION_vector_s;

typedef struct MOTION_calibration_data
{
	MOTION_vector_s offset;
	MOTION_vector_s scalar;
} MOTION_calibration_data_s;

typedef struct MOTION_config
{
	MOTION_calibration_data_s accel_cal;
	MOTION_calibration_data_s gyro_cal;
	float                     angular_threshold;
	float                     back_cross_axis_factor;
	float                     front_cross_axis_factor;
} __attribute__((packed, aligned(1))) MOTION_config_s;

typedef enum MOTION_axis
{
	MOTION_AXIS_X = 0,
	MOTION_AXIS_Y
} MOTION_axis_e;

typedef enum MOTION_cal_orientation
{
	MOTION_CAL_ORIENTATION_FLAT = 0,
	MOTION_CAL_ORIENTATION_BACK,
	MOTION_CAL_ORIENTATION_FRONT,

	MOTION_CAL_ORIENTATION_COUNT,
	MOTION_CAL_ORIENTATION_INVALID = MOTION_CAL_ORIENTATION_COUNT
} MOTION_cal_orientation_e;


/*--------------------------------------------------------------------------------------------------
 * PUBLIC CONSTANTS & VARIABLES
 *------------------------------------------------------------------------------------------------*/


/*--------------------------------------------------------------------------------------------------
 * PUBLIC FUNCTION PROTOTYPES
 *------------------------------------------------------------------------------------------------*/
void MOTION_init (void);

bool MOTION_linear_detected (void);

bool MOTION_angular_detected (void);

void MOTION_angular_threshold_set (float variance);

float MOTION_angle_get (MOTION_axis_e axis);

void MOTION_calibrate (MOTION_cal_orientation_e orientation);

float MOTION_calibrate_status_get (MOTION_cal_orientation_e orientation);

void MOTION_gyro_recalibrate (void);

void MOTION_gyro_recalibrate_abort (void);

float MOTION_gyro_recalibrate_status_get (void);

MOTION_config_s *MOTION_config_get (void);

void MOTION_config_set (MOTION_config_s cfg);

void MOTION_task_suspend (void);

void MOTION_task_resume (void);

void MOTION_task_install (void);

void MOTION_cli_cmd (int32_t argc, char **argv);

void MOTION_detected_flag_set (void);

#endif /* MOTION_H_ */
