/***************************4****************************************************
*   モジュール名称      :APP13 Mission TLM (L&M) PI tasks                     *
*   モジュールラベル    :app13_PIs                                            *
*   タスク区分          :Application-13  SORBET task for Mission TLM (L&M)    *
*   機能                :                                                     *
*   コーリングシーケンス:void app13_SOR                                       *
*   引数                :なし                                                 *
*   戻り値              :なし                                                 *
*   使用上の注意        :グローバル変数はアプリケーション01でまとめて初期化 *
*   エラー処理          :なし                                                 *
*   注意				:  EDIT権限は、SORBET(core)組                         *
*   作成日・作成者      :2015/2/10     Y.K.                                   *
*******************************************************************************/
#include "app_common.h"
#include "app_EWO.h"

// *** Local Macro ***
// void	app13_SOR_putTLM		( int, unsigned int, int, unsigned char *, int);

// *** APP13 Common Grobal Variable (in app_common.h & app_common_variable.c) ***
//#define  				d_dataRawLen	0x40000
//#define  				d_dataPacLen	0x2000
//extern unsigned char	G13uc_data  [d_dataRawLen];			// for RAW data:    262.11 kB [EWO:80packet, Others:more than 1Block]
//extern unsigned char	G13uc_packet[d_dataPacLen];			// for Packet data: 8kB - max [Packet size to DMC: 1kB-max]


void	app13_SOR( unsigned int ui_sunpulseCnt )
{
	int				i, k;
	int				i_TRG_cnt;
	int				i_flag;
	int				i_SORstatus = 0xFF;
	// === BLOCK read ===
	int				i_bufId;												// Buffer ID
	int				i_numNewBlock;											// Num of blocks with new data
	unsigned int	ui_timeData;											// Processing data TI
	M_T_BLOCK_INFO 	t_blockInfo;											// unsigned int 	ui_createTime	Block 生成開始時衛星時刻(1LSB=31,25ms)
																			// int 				i_replyNum		Block 登録Read-Reply個数
																			// char 			c_invalidFlg	Block 内データ異常	 [0:異常なし 1:異常あり]
																			// unsigned int 	ui_blockIndex	LongBuffer/ShortBuffer 内Block特定番号 (先頭Block:0)

	// === SOR data output ===
	int				i_dataId, i_dataLen;									// SOR-Header: DataID
	int				i_calId;												// SOR-Header: CalID
	int				i_dataSize;												// SOR-Header: Data Size
	unsigned int	ui_dataTi;												// SOR-Header: TI
	unsigned int	ui_spincount;

	// -----------------------------------------------------------
	// -- Set at the buffer with the oldest non-processed block --
	// -----------------------------------------------------------
	i_bufId = app_CheckNonProcBlock     ( Gd_N_SOR, 0, 						// [INPUT]  Node/Data ID
										  Gui_TLMm_blockTime[Gd_N_SOR],		// [INPUT]  TI of Processed Block
										  & ui_timeData);					// [OUTPUT] TI of Newest Block in the selected buffer
																			// (return) Buffer-ID  (0:L, 1:S, -1:no data)
	if ( i_bufId < 0 )  return;												//  === No data ===

	// -------------------------------------------
	// -- Set at the oldest non-processed block --
	// -------------------------------------------
	// Newest Block
	i_numNewBlock	= app_SetNonProcBlock( Gd_N_SOR, 0,	 					// [INPUT]  NodeID = Gd_N_SOR,  Data ID = 0
										   i_bufId, 						// [INPUT]  Buffer ID = 0 (LONG) 	[SORBET does not use Short-buffer.]
										   Gui_TLMm_blockTime[Gd_N_SOR],	// [INPUT]  TI of Processed Block	[lsb = 32msec]
										   &t_blockInfo);					// [OUTPUT] Block Info
																			// (return)	>0:Num of blocks, <=0:No data (error)
	if ( i_numNewBlock < 1 ) {
		Gui_TLMm_blockTime[Gd_N_SOR]  = ui_timeData;						//  === shift to newest data for SKIP ===
		return;
	}

	// ---------------------
	// -- Read Block data --
	// ---------------------
	for (i=0; i<i_numNewBlock; i++) {
		if ( t_blockInfo.ui_createTime > Gui_TLMm_blockTime[Gd_N_SOR]	&&	// NEW data
			 t_blockInfo.i_replyNum    > 0								&&	// Data available
			 t_blockInfo.c_invalidFlg == 0 								&&	// Data correct
			 i >= i_numNewBlock-4 ) {										// latest 2 packets		[Max-packet production: 2 in 1-spin]

			// ****************************
			// **** Packet header read ****
			// ****************************
			//		RMAP-read-header	  12B
			//		--------------------------------------------------------------------------------------
			//		Contents			4096B
			//			[SORBET Header]	  20B 	(0x00-0x13)
			//					0B	Length of Data body		b7		CAL flag	[0:nml 1:CAL]
			//												b6		LM flag		[0:L 1:M]
			//												b5-0	0x**00 		[higher 6bit]
			//					1B	Length of Data body		b7-0	0x00**		[lower 8bit]			(If it exceeds ‘0x3FF’, it will be DUMMY packet.)
			//					2-3B	PWI Status			B2	PWI-Status CMD ID	
			//												B3	PWI-Status data registered in SORBET
			//
			//			[COMMON-USE BYTES]10B	(0x14-0x1D)
			//					TIME		#1	0x14(highest)-0x15		TI register  MSB
			//									0x16-0x17(lowest)		TI register  LSB
			//									0x18(high)-0x19(low)	TI Counter
			//										*Density index		Fp = (code)HEXx10Hz
			//											PlasmaFreq#1	0x1A: MSB	0x1B: LSB
			//										*Temperature index	QTN = (code)HEXx1dB
			//											QTN#1			0x1C: MSB	0x1D: LSB
			i_flag = app_GetBlock(	13,													// [INPUT]  App-No:3
									Gd_N_SOR, 0, 										// [INPUT]  NodeID = Gd_N_SOR,  Data ID = 0
									i_bufId,  											// [INPUT]  Buffer ID = 0 (LONG) 	[SORBET does not use Short-buffer.]
									&t_blockInfo,										// [INPUT]  Block Info
									G13uc_data );										// [OUTPUT] 1 Block Data - copied

			if ( i_flag == 0 ) {
				// ===========================================================================================================
				// ===========================================================================================================
				// ===========================================================================================================
				Gui_TLMm_blockTime[Gd_N_SOR] = t_blockInfo.ui_createTime;				// !!! Successfuly Processed !!!

				// -------------------
				// -- Decode Packet --
				// -------------------
				i_dataSize = 	((int)(G13uc_data[12+0x00] & 0x3F) <<  8) + 
								((int)(G13uc_data[12+0x01])             );

				if ( i_dataSize < 0x400 ) {														// Size: < 0x400
					i_calId     =       (int)(G13uc_data[12+0x00] & 0x80);						// CAL:	 0:none  0x80:CAL
					i_dataLen   = G13uc_data[12+0x00] & 0x40;
					i_SORstatus = G13uc_data[12+0x03];											// PWI-Status data registered in SORBET

					// ************
					// **** TI ****
					// ************
					memcpy( &ui_dataTi, &(G13uc_data[12+0x14]), 4);								// lsb:1.953msec
				/*	ui_dataTi  = 	  ((unsigned int)  (G13uc_data[12+0x14]) << 24) + 			// lsb:1.953msec
							    	  ((unsigned int)  (G13uc_data[12+0x15]) << 16) + 
							    	  ((unsigned int)  (G13uc_data[12+0x16]) <<  8) + 
									  ((unsigned int)  (G13uc_data[12+0x17])      );	*/
					ui_dataTi  += app_ti_spinRate ( ui_dataTi, Gd_N_SOR, &ui_spincount );		// added: 111224
					i_TRG_cnt  =  app_tiTrgSearch ( ui_dataTi, Gd_N_SOR );						// added: 111214
					ui_dataTi  +=     ((unsigned int)  (G13uc_data[12+0x18]) <<  8) + 
									  ((unsigned int)  (G13uc_data[12+0x19])      );
					//
					memcpy( &(G6uc_packet[0x800]), &(G13uc_data[12+0x04]), 4);					// Nominal Temp. Housekeeping
																								// Redundant Temp. Housekeeping
																								// 5V Housekeeping 
																								// 12V Housekeeping
					
					// ****************************
					// **** COMMON DATA の代入 ****
					// ****************************
					if (i_calId == 0) {
						// *******************************************************
						// **** TRG-BUF data ****		revised on 2 Nov 2012
						// *******************************************************
						if (i_TRG_cnt) {
							/* 	**********************************************************
								***** Plasma Frequency ****
									N      =  DATA(0x1B)		[31<N<128]
									F(kHz) =  2.554742872 * 4^(N/32)
									---------------------------------------------------
									(ex)    DATA(0x1B) = 0x2F
									   -->           N = 0x2F = 47
									            F(kHz) = 2.554742872 * 4^(47/32) => 19.5 kHz
								**********************************************************  */
							Guc_TRG2_SOR_N[i_TRG_cnt] = G13uc_data[12+0x1B];

							/* 	***** QTN ****
									QTN-CODE =  (DATA(0x1C) * 256 + DATA(0x1D)
									AGC_B    = [(DATA(0x5C) * 16 + DATA(0x5D) / 16
								 				[for LM=0 (short packet or L-mode)]
									         = [(DATA(0xEE) * 16 + DATA(0xEF) / 16
												for LM=1 (long packet or M-mode)
									QTN      = 10Log_10 (QTN-Code) - AGC_B/40.
								 		---------------------------------------------------
								 		(ex)    DATA(0x1C)    = 0x1F	DATA(0x1D)    = 0x7E
								 		        DATA(0x5C/EE) = 0x21	DATA(0x5D/EF) = 0x48
								 		   -->  QTN-CODE = 0x1F7E  =  8062
								 		        AGC_B    = 0x214   =   532
								 		        QTN      = 39.06 - 532/40 = 25.76dB
													[Dynamic range: +48 ‾ -102dB]
												-------------------------------------------
								 		   -->  QTN-CODE = 0x1F7E  =  8062
								 		        AGC_B    = 0x21    =    33
								 		        QTN      = 39.06 - 33/(40/16) = 25.86dB
													[Dynamic range: +48 ‾ -102dB]
											[Yes, this accuracy is enough!]
								 	###########################################################	*/
							i_flag = 10.00 * app_math_log10( G13uc_data[12+0x1C]*256 + G13uc_data[12+0x1D] );		// 10Log_10(QTN-Code)
							if (i_dataLen == 0) i_flag -= (int)( (G13uc_data[12+0x5C]) / 2.5 );		// AGC_B in L
							else				i_flag -= (int)( (G13uc_data[12+0xEE]) / 2.5 );		// AGC_B in M
							i_flag = - (i_flag - 48);
							Guc_TRG2_SOR_T[i_TRG_cnt] = (unsigned char) i_flag;
						}
					}

					// *****************
					// **** Put TLM ****
					// *****************
					i_dataId   = 3;																// --> 3:M
					k          = (1 << ( Guc_EFD_mode >> 7) );									// n7=0: 1/5spin  1:1/10spin
					if ( i_dataLen )	{														// DR:	  0:short "0x40:long"
						Guc_SOR_LM ++;
						if  (Guc_OpeMode      && Guc_SOR_LM >= k) {
							i_dataId = 2;
							Guc_SOR_LM = 0;
						}
					}
					else if (Guc_OpeMode == 0 && Guc_SOR_LM >= k) {								// DR:	 "0:short" 0x40:long
						i_dataId   = 2;															// --> 2:L
						Guc_SOR_LM = 0;
					}
					for (i=3; i>=i_dataId; i--) {
						i_flag = app_PutTlm( 	13,						// [INPUT]  APP-NUM = 13
												Gd_N_SOR,				// [INPUT]	Node-ID
												0,						// [INPUT]	Data-ID
												Gd_N_SOR,				// [INPUT]	Header-ID (for PID-ID, CAT-ID setting)
												i,						// [INPUT]	DR-ID     (for CAT-ID) [0:HK 1:OS 2:L 3:M 4-9:H(0-5)]
												Guc_TLMm_cmp[Gd_N_SOR], // [INPUT]	Comp mode			   [0:non 1:Arith0 2:Arith1 4:RICE 3,4-7:others]
												(int)(G13uc_data[12]), 	// [INPUT]	Packet ID 		<<<< USER-DEF:       0x00-      0xFF >>>>
												ui_dataTi, 				// [INPUT]	Data TI			<<<< USER-DEF: 0x00000000-0xFFFFFFFF >>>>
												Guc_cmdDummy, 			// [INPUT]	Comment			<<<< USER-DEF: <128B                 >>>>
												0, 						// [INPUT]	Comment - Size 	<<<< USER-DEF: <128B                 >>>>
												&(G13uc_data[12]), 		// [INPUT]	Data			<<<< USER-DEF: <0x1E00               >>>>
												i_dataSize); 			// [INPUT]	Data - Size		<<<< USER-DEF: <0x1E00               >>>>
					}
				} 
				// ===========================================================================================================
				// ===========================================================================================================
				// ===========================================================================================================
			}
		}

		// To next block
		i_flag = app_NextBlock( 	Gd_N_SOR, 0, 				// [INPUT]  NodeID = Gd_N_SOR,  Data ID = 0
									i_bufId,  					// [INPUT]  Buffer ID = 0 (LONG) 	[SORBET does not use Short-buffer.]
									&t_blockInfo);				// [OUTPUT] Block Info
		if ( i_flag )				break;						// no data
	}

	Guc_SOR_data_status0 = i_SORstatus;					// PWI-Status data registered in SORBET
	return;
}