/**************************************************************
***************************************************************
**
** BME Firmware, Copyright (C) 2000-2002
** Ikanos Communication, Fremont, CA 
** All rights reserved.
**
** The information and contents of this file are the
** proprietary information of Ikanos Communication and may not
** be disclosed or used without the formal written approval of 
** Ikanos Communication
**
***************************************************************
$Revision: 1.1 $
$Date: 2006/10/16 04:34:50 $
**************************************************************/

#define VTU_R  1

/*******  Include Files         ***************************************/
#define STATIC static


/*******  Include Files         ***************************************/

#define VX_WORKS
#ifdef  VX_WORKS 
#include "ipos.h"

#include <string.h>
#endif
#include "bme.h"
#include "include/framercpu.h"

#include "xdsl_rmc.h"
#include "bme_app.h"
#include "mem.h"


/* Number of ports, 4 for VDSL */
#define RCPU_MAX_NUMBER_LINE	4
#define RCPU_CMD_WORD_LEN		16

/* Should be moved to dma.h when available */
void changeBFIFOInitSize (int size)
{


}

extern u16 	readPIO_short(u16 *addr);

/**************************************************************/
/* Message definition sent to RxCPU:
	Msg[ 0]:	MSB: Line #
				LSB: Tag
	Msg[ 1]:	Frame # for action
	Msg[ 2]:	Command field
	Msg[ 3]:	# of bytes to take from AFIFO
	Msg[ 4]:	# of bytes out of DMAP
	Msg[ 5]:	MSB: HW cmd Flags
				LSB: Header length in byte -12
	Msg[ 6]:	DMAP bytes 0..1
	Msg[ 7]:	DMAP bytes 2..3
	Msg[ 8]:	DFRAMER header
	Msg[ 9]:	Not used yet
	Msg[10]:	Command parameters
	. . .		Command parameters
	Msg[15]:	Command parameters */

/**************************************************************/
/*  Commands                                                  */
/**************************************************************/
#define RCPU_CMD_VBUS					0x0001
/* Param:	Msg[15] =  LSB: State (0x0010 = ON) */

#define RCPU_CMD_HEADER					0x0002
/* Param:	Msg[3-8] */

#define RCPU_CMD_SNR_AVG				0x0004
/* Param:	Msg[13] = Period */
/* Param:	Msg[14] = LSB: Idle  (0xFF = once)  */
/* Param:	Msg[15] = Shift  */

#define RCPU_CMD_TONE_AVG				0x0008
/* Param:	Msg[13] = Period */
/* Param:	Msg[14] = LSB: Idle  (0xFF = once)  */
/* Param:	Msg[15] = Shift  */

#define RCPU_CMD_LOS_TD					0x0010
/* Param:	Msg[13] = Period */
/* Param:	Msg[14] = LSB: Idle  (0xFF = once)  */


#define RCPU_CMD_SKIP					0x0020
/* Param:	Msg[15] = Number of sample | Bit15: Idle */
#define PARAM_SKIP						15

#define RCPU_CMD_REVERB					0x0040
/* Param:	None */
/* Continuous type */

#define RCPU_CMD_MEDLEY					0x0080
/* Param:	None */
/* Continuous type */


#define RCPU_CMD________1				0x0100
/* Param:	Available for new command  */

#define RCPU_CMD_TEQ					0x0200
/* Param:	Msg[10] = MSB: TEQ bypass; RxWindow bypass; TeqScaleShift
					  LSB: Num Taps 
			Msg[11] = Num Prefix Samples
			Msg[12] = Num Suffix Samples
			Msg[13] = Num Out Samples
			Msg[14] = MSB: Delay Line Step
					  LSB: Num Beta Samples
			Msg[15] = MSB: FFT # tone and Scale shift
					  LSB: bit 0: FFT bypass; 
*/

#define RCPU_CMD________2				0x0400
/* Param:	Available for new command  */


#define RCPU_CMD________3				0x0800
/* Param:	Available for new command  */

#define RCPU_CMD_4FIFO					0x1000
/* Param:	None */

#define RCPU_CMD________4				0x2000
/* Param:	Available for new command  */

#define RCPU_CMD_CH_SEQUENCE			0x4000
/* Param:	Msg[11] =  MSB: 1st Ch# - LSB: 2nd Ch# */
/* Param:	Msg[12] =  MSB: 3rd Ch# - LSB: 4th Ch# */

#define RCPU_CMD_DEBUG					0x8000
/* Param:	Msg[3] = Number of ACL cmd to send */
/* Param:	Msg[4] = Address of 1st ACL cmd    */
/* Param:	Msg[5] = Address of 2nd ACL cmd    */
/* Param:	Msg[6] = Address of 3rd ACL cmd    */
/* Param:	Msg[N] = Address of Nth ACL cmd    */
/* !!! Disables the normal behavior of RxCPU   */
/* !!! Should be sent with immediate action    */

/**************************************************************/
/*** General definitions									  */
/**************************************************************/

/* uCode immediate flag */
#define RCPU_IMMEDIATE			0x8000

/* Demap output size definition */
#define RCPU_NUMDATA_INIT_NONE			0x0001
#define RCPU_NUMDATA_INIT_TEQ			0x0002
#define RCPU_NUMDATA_INIT_FFT			0x0003
#define RCPU_NUMDATA_INIT_FEQ			0x0004
#define RCPU_NUMDATA_INIT_REVCHEK		0x0005
#define RCPU_NUMDATA_INIT_SLICER		0x0006
#define RCPU_NUMDATA_SHOW_KF			0x0007
#define RCPU_NUMDATA_NOT_SET			0x000F

/* Pilot Tone present in Header & workaround */
#define RCPU_TONE_IN_HEADER				0x2000
#define RCPU_TONE_SIZE_INIT				8
// #define RCPU_TONE_SIZE_INIT				4  // for orig ptone size - shri
#define RCPU_TONE_SIZE_SHOW				3
#define RCPU_TONE_IN_DMAP				0x1000


/* SNR Idle def for one time only */
#define RCPU_SNR_ONE_TIME				0xFF

/* VBUS param On/ off */
#define PARAM_VBUS_ON					0x0010
#define PARAM_VBUS_OFF					0x0000

/* TEQ fields */
#define RCPU_TEQ_W0_BYP_TEQ				0x0100
#define RCPU_TEQ_W5_BYP_FFT				0x0001

/* Default Header flag&Size */
#define RCPU_HEADER_FLAG_SIZE			0x1E1A

/**************************************************************/
/*** Value definition for DEMAP fields						  */
/**************************************************************/
/* Word 0 */
#define RCPU_DMAP_W0_FEQ_BYPASS			0x0100
#define RCPU_DMAP_W0_FEQ_NORMAL			0x0000
#define RCPU_DMAP_W0_FEQ_NORMAL			0x0000
#define RCPU_DMAP_W0_FEQ_UPDATE			0x0000
#define RCPU_DMAP_W0_FEQ_NO_UPDATE		0x0001
#define RCPU_DMAP_W0_SORTED_TONE		0x0000
#define RCPU_DMAP_W0_SEQ_TONE			0x0800
#define RCPU_DMAP_W0_SET_BIT_TABLE		0x4000
#define RCPU_DMAP_W0_DMAP_BYPASS		0x8000
/* CSIM shows that bits shouldn't be swapped, so 0x0010 instead of 0x0018 */
#define RCPU_DMAP_W0_PRG_ON				0x0010
#define RCPU_DMAP_W0_SLICER_PRG			0x0020
#define RCPU_DMAP_W0_SLICER_DMAP		0x0000

/* Word 1 */
#define RCPU_DMAP_W1_OUT_NORMAL			0x0000
#define RCPU_DMAP_W1_OUT_FFT			0x0200
#define RCPU_DMAP_W1_OUT_FEQ			0x0400
#define RCPU_DMAP_W1_OUT_REVERB_CHECK	0x0600
#define RCPU_DMAP_W1_OUT_NONE			0x0800
#define RCPU_DMAP_W1_FWD_PILOT			0x1000
#define RCPU_DMAP_W1_TAGS_TO_DATA		0x2000

/**************************************************************/
/*** Value definition for DEFRAMER fields						  */
/**************************************************************/
#define RCPU_DFMR_NONE					0x0000
#define RCPU_DFMR_SYNC_SYMBOL			0x0100
#define RCPU_DFMR_SNR_AVG_COMPLETE		0x0400
#define RCPU_DFMR_TOGGLE_CONFIG			0x0800
#define RCPU_DFMR_FWD_DATA_2CORE		0x1000
#define RCPU_DFMR_STATE_IDLE			0x0000
#define RCPU_DFMR_STATE_INIT			0x2000
#define RCPU_DFMR_STATE_SHOW			0x4000

/**************************************************************/
/***          A R R A Y   D E F I N I T I O N               ***/
/**************************************************************/

/**************************************************************/
// RCPU_LINE_DOWN

STATIC const u16 aMsg_LineDown[] = {
	RCPU_TAG_NO_OUT, 0 , RCPU_CMD_VBUS,
	0, 0, 0, 0,	0, 	0, 0, 00, 00, 00, 00, 00, PARAM_VBUS_OFF 
};


/**************************************************************/
/* No TEQ, No Dmap, FFT out, no bit table       		  */
// RCPU_LINE_UP for G.Hs
STATIC const u16 aMsg_LineUp[] = {
	RCPU_TAG_FFT_OUT, 0 , RCPU_CMD_VBUS | RCPU_CMD_TEQ | RCPU_CMD_HEADER,
	0, RCPU_NUMDATA_INIT_FFT, RCPU_HEADER_FLAG_SIZE,
	RCPU_DMAP_W0_FEQ_BYPASS | RCPU_DMAP_W0_FEQ_NO_UPDATE | RCPU_DMAP_W0_SORTED_TONE | RCPU_DMAP_W0_DMAP_BYPASS ,
	RCPU_DMAP_W1_OUT_FFT | RCPU_DMAP_W1_TAGS_TO_DATA,
 	RCPU_DFMR_STATE_INIT | RCPU_DFMR_FWD_DATA_2CORE,
	0, 0x0100, 0x0000, 0x0000, 00, 00, PARAM_VBUS_ON 
};


/**************************************************************/
/* Config TEQ field. no out, No Dmap, TEQ enable, No FEQ */
// RCPU_TR_CONFIG
STATIC const u16 aMsg_TrConfig[] = {
	RCPU_TAG_NO_OUT, 0 , RCPU_CMD_TEQ | RCPU_CMD_HEADER,
	0, RCPU_NUMDATA_INIT_NONE, RCPU_HEADER_FLAG_SIZE,
	RCPU_DMAP_W0_FEQ_BYPASS | RCPU_DMAP_W0_FEQ_NO_UPDATE | RCPU_DMAP_W0_SEQ_TONE | RCPU_DMAP_W0_DMAP_BYPASS ,
	RCPU_DMAP_W1_OUT_NONE,
 	RCPU_DFMR_STATE_INIT,
	0, 0, 0, 0, 0, 0, 0
};


/**************************************************************/
/* TR, No FEQ, No Dmap, No out, do Tone Average (auto-repeat) */
// RCPU_TR_DETECT
#define RCPU_TR_1SNR_PERIOD		32
#define RCPU_TR_1SNR_IDLE		2
#define RCPU_TR_1SNR_SHIFT		5

STATIC const u16 aMsg_TrDetect[] = {
	RCPU_TAG_NO_OUT, 0 , RCPU_CMD_TONE_AVG | RCPU_CMD_HEADER,
	0, RCPU_NUMDATA_INIT_NONE, RCPU_HEADER_FLAG_SIZE,
	RCPU_DMAP_W0_FEQ_BYPASS | RCPU_DMAP_W0_FEQ_NO_UPDATE | RCPU_DMAP_W0_SEQ_TONE | RCPU_DMAP_W0_DMAP_BYPASS | RCPU_DMAP_W0_SLICER_DMAP ,
	RCPU_DMAP_W1_OUT_NONE,
 	RCPU_DFMR_STATE_INIT,
	0, 0, 0, 0, RCPU_TR_1SNR_PERIOD, RCPU_TR_1SNR_IDLE, RCPU_TR_1SNR_SHIFT 
};

/**************************************************************/
/* No FEQ, no update, No data Out, stop SNR */
// RCPU_TR_NO_FEQ_NO_DATA 
STATIC const u16 aMsg_TrNoFeqNoData[] = {
	RCPU_TAG_NO_OUT, 0 , RCPU_CMD_TONE_AVG | RCPU_CMD_HEADER,
	0, RCPU_NUMDATA_INIT_NONE, RCPU_HEADER_FLAG_SIZE,
	RCPU_DMAP_W0_FEQ_BYPASS | RCPU_DMAP_W0_FEQ_NO_UPDATE | RCPU_DMAP_W0_DMAP_BYPASS | RCPU_DMAP_W0_SEQ_TONE,
	RCPU_DMAP_W1_OUT_NONE, 
	RCPU_DFMR_STATE_INIT,
	0, 0, 00, 00, 00, 00, 00 
};

/**************************************************************/
/* TR phase, no TEQ, byp FFT, No FEQ, No Dmap, VBUS out, NO TAG */
// RCPU_TR_VBUS_OUT
STATIC const u16 aMsg_TrVbusOut[] = {
	RCPU_TAG_VBUS_OUT, 0 , RCPU_CMD_HEADER | RCPU_CMD_TEQ,
	0, RCPU_NUMDATA_INIT_TEQ, RCPU_HEADER_FLAG_SIZE,
	RCPU_DMAP_W0_FEQ_BYPASS | RCPU_DMAP_W0_FEQ_NO_UPDATE | RCPU_DMAP_W0_SEQ_TONE | RCPU_DMAP_W0_DMAP_BYPASS ,
	RCPU_DMAP_W1_OUT_FFT,
 	RCPU_DFMR_STATE_INIT | RCPU_DFMR_FWD_DATA_2CORE,
	0, 0, 0, 0, 00, 00, 0 
};

/**************************************************************/
/* TR phase, TEQ off, FFT off, No FEQ, No Dmap, no out, NO TAG */
//	RCPU_TR_TEQ_BYP_NO_DATA
STATIC const u16 aMsg_TrTeqByp[] = {
	RCPU_TAG_NO_OUT, 0 , RCPU_CMD_HEADER | RCPU_CMD_TEQ,
	0, RCPU_NUMDATA_INIT_NONE, RCPU_HEADER_FLAG_SIZE,
	RCPU_DMAP_W0_FEQ_BYPASS | RCPU_DMAP_W0_FEQ_NO_UPDATE | RCPU_DMAP_W0_SEQ_TONE | RCPU_DMAP_W0_DMAP_BYPASS ,
	RCPU_DMAP_W1_OUT_NONE,
 	RCPU_DFMR_STATE_INIT,
	0, 0, 0, 0, 00, 00, 0 
};

/**************************************************************/
/* TR phase, TEQ on, byp FFT, No FEQ, No Dmap, TEQ out, NO TAG */
// RCPU_TR_TEQ_OUT
STATIC const u16 aMsg_TrTeqOut[] = {
	RCPU_TAG_TEQ_OUT, 0 , RCPU_CMD_HEADER | RCPU_CMD_TEQ,
	0, RCPU_NUMDATA_INIT_TEQ, RCPU_HEADER_FLAG_SIZE,
	RCPU_DMAP_W0_FEQ_BYPASS | RCPU_DMAP_W0_FEQ_NO_UPDATE | RCPU_DMAP_W0_SEQ_TONE | RCPU_DMAP_W0_DMAP_BYPASS ,
	RCPU_DMAP_W1_OUT_FFT,
 	RCPU_DFMR_STATE_INIT | RCPU_DFMR_FWD_DATA_2CORE,
	0, 0, 0, 0, 00, 00, 0 
};

/**************************************************************/
/* TR phase, TEQ on, FFT out, No FEQ, No Dmap  */
//	RCPU_TR_TEQ_NORM
STATIC const u16 aMsg_TrTeqNorm[] = {
	RCPU_TAG_FFT_OUT, 0 , RCPU_CMD_HEADER | RCPU_CMD_TEQ,
	0, RCPU_NUMDATA_INIT_FFT, RCPU_HEADER_FLAG_SIZE,
	RCPU_DMAP_W0_FEQ_BYPASS | RCPU_DMAP_W0_FEQ_NO_UPDATE | RCPU_DMAP_W0_SORTED_TONE | RCPU_DMAP_W0_DMAP_BYPASS ,
	RCPU_DMAP_W1_OUT_FFT | RCPU_DMAP_W1_TAGS_TO_DATA,
 	RCPU_DFMR_STATE_INIT | RCPU_DFMR_FWD_DATA_2CORE,
	0, 0, 0, 0, 00, 00, 0 
};


/**************************************************************/
/* Training phase, Symbol boundary detection, Skip sample     */
// RCPU_TR_SKIP_SAMPLE

STATIC const u16 aMsg_TrSkip[] = {
	RCPU_TAG_FFT_OUT, 0 , RCPU_CMD_SKIP, 
	0, RCPU_NUMDATA_NOT_SET, RCPU_HEADER_FLAG_SIZE,
	0,0,
	RCPU_DFMR_STATE_INIT | RCPU_DFMR_FWD_DATA_2CORE,
	0, 0, 00, 00, 00, 00, 00 
};

/**************************************************************/
/* TR, No FEQ, No Dmap, No out, do Tone Average (once) */
// RCPU_TR_UPBO
#if CSIM_INTEG
#define RCPU_TR_2SNR_PERIOD		8
#define RCPU_TR_2SNR_IDLE		RCPU_SNR_ONE_TIME
#define RCPU_TR_2SNR_SHIFT		3
#else
#define RCPU_TR_2SNR_PERIOD		128
#define RCPU_TR_2SNR_IDLE		RCPU_SNR_ONE_TIME
#define RCPU_TR_2SNR_SHIFT		7
#endif

STATIC const u16 aMsg_TrUpbo[] = {
	RCPU_TAG_NO_OUT, 0 , RCPU_CMD_TONE_AVG | RCPU_CMD_HEADER,
	0, RCPU_NUMDATA_INIT_NONE, RCPU_HEADER_FLAG_SIZE,
	RCPU_DMAP_W0_FEQ_BYPASS | RCPU_DMAP_W0_FEQ_NO_UPDATE | RCPU_DMAP_W0_SEQ_TONE | RCPU_DMAP_W0_DMAP_BYPASS | RCPU_DMAP_W0_SLICER_DMAP ,
	RCPU_DMAP_W1_OUT_NONE,
 	RCPU_DFMR_STATE_INIT,
	0, 0, 0, 0, RCPU_TR_2SNR_PERIOD, RCPU_TR_2SNR_IDLE, RCPU_TR_2SNR_SHIFT 
};

/**************************************************************/
/* TR phase, TEQ on, No FEQ, No Dmap, FFT out, Stop SNR Avg	  */
// RCPU_TR_FFT_OUT
STATIC const u16 aMsg_TrFftOut[] = {
	RCPU_TAG_FFT_OUT, 0 , RCPU_CMD_TONE_AVG | RCPU_CMD_HEADER,
	0, RCPU_NUMDATA_INIT_FFT, RCPU_HEADER_FLAG_SIZE,
	RCPU_DMAP_W0_FEQ_BYPASS | RCPU_DMAP_W0_FEQ_NO_UPDATE | RCPU_DMAP_W0_SORTED_TONE | RCPU_DMAP_W0_DMAP_BYPASS ,
	RCPU_DMAP_W1_OUT_FFT | RCPU_DMAP_W1_TAGS_TO_DATA,
 	RCPU_DFMR_STATE_INIT | RCPU_DFMR_FWD_DATA_2CORE,
	0, 0, 0, 0, 00, 00, 00 
};

/**************************************************************/
/* Reverb FEQ training, FEQ update, slicer out PRG, No data out */
// RCPU_TR_FEQ_TRAIN
STATIC const u16 aMsg_TrFeqTrain[] = {
	RCPU_TAG_NO_OUT, 0 , RCPU_CMD_REVERB | RCPU_CMD_HEADER,
	0, RCPU_NUMDATA_INIT_NONE, RCPU_HEADER_FLAG_SIZE,
	RCPU_DMAP_W0_FEQ_NORMAL | RCPU_DMAP_W0_FEQ_UPDATE | RCPU_DMAP_W0_SEQ_TONE | RCPU_DMAP_W0_PRG_ON | RCPU_DMAP_W0_SLICER_PRG,
	RCPU_DMAP_W1_OUT_NONE, 
	RCPU_DFMR_STATE_INIT,
	0, 0, 00, 00, 00, 00, 00 
};

/**************************************************************/
/* SNR estimation during OPTraining, used for 'Fast Track'    */
// RCPU_TR_TST_SNR 

#define RCPU_TR_TST_SNR_PERIOD		1024
#define RCPU_TR_TST_SNR_IDLE		RCPU_SNR_ONE_TIME
#define RCPU_TR_TST_SNR_SHIFT		10

STATIC const u16 aMsg_trTstSnr[] = {
	RCPU_TAG_NO_OUT, 0 , RCPU_CMD_SNR_AVG | RCPU_CMD_REVERB | RCPU_CMD_HEADER,
	0, RCPU_NUMDATA_INIT_NONE, RCPU_HEADER_FLAG_SIZE,
	RCPU_DMAP_W0_FEQ_NORMAL | RCPU_DMAP_W0_FEQ_NO_UPDATE | RCPU_DMAP_W0_SEQ_TONE | RCPU_DMAP_W0_PRG_ON | RCPU_DMAP_W0_SLICER_PRG,
	RCPU_DMAP_W1_OUT_NONE,
 	RCPU_DFMR_STATE_INIT,
	0, 0, 0, 0, RCPU_TR_TST_SNR_PERIOD, RCPU_TR_TST_SNR_IDLE, RCPU_TR_TST_SNR_SHIFT 
};


/**************************************************************/
/* FEQ + FEQ update, No data out */
// RCPU_TR_NO_DATA 

STATIC const u16 aMsg_TrNoData[] = {
	RCPU_TAG_NO_OUT, 0 , RCPU_CMD_HEADER,
	0, RCPU_NUMDATA_INIT_NONE, RCPU_HEADER_FLAG_SIZE,
	RCPU_DMAP_W0_FEQ_NORMAL | RCPU_DMAP_W0_FEQ_UPDATE | RCPU_DMAP_W0_SORTED_TONE | RCPU_DMAP_W0_SLICER_DMAP,
	RCPU_DMAP_W1_OUT_NONE, 
	RCPU_DFMR_STATE_INIT,
	0, 0, 00, 00, 0, 0, 0
};


/**************************************************************/
/* FEQ on, no FEQ update, Slicer out */
// RCPU_TR_SLICER_NO_UPDATE

STATIC const u16 aMsg_TrSliceNoUp[] = {
	RCPU_TAG_SLICER_SEQ_OUT, 0 , RCPU_CMD_HEADER,
	0, RCPU_NUMDATA_INIT_SLICER, RCPU_HEADER_FLAG_SIZE,
	RCPU_DMAP_W0_FEQ_NORMAL | RCPU_DMAP_W0_FEQ_NO_UPDATE | RCPU_DMAP_W0_SEQ_TONE | RCPU_DMAP_W0_SLICER_DMAP,
	RCPU_DMAP_W1_OUT_NORMAL | RCPU_DMAP_W1_TAGS_TO_DATA, 
	RCPU_DFMR_STATE_INIT | RCPU_DFMR_FWD_DATA_2CORE,
	0, 00, 00, 00, 0, 0, 0 };

			
/**************************************************************/
/* Medley FEQ training, FEQ update, slicer out PRG, No data out */
// RCPU_MED_FEQ_TRAIN

STATIC const u16 aMsg_MedFeqTrain[] = {
	RCPU_TAG_NO_OUT, 0 , RCPU_CMD_MEDLEY | RCPU_CMD_HEADER,
	0, RCPU_NUMDATA_INIT_NONE, RCPU_HEADER_FLAG_SIZE,
	RCPU_DMAP_W0_FEQ_NORMAL | RCPU_DMAP_W0_FEQ_UPDATE | RCPU_DMAP_W0_SEQ_TONE | RCPU_DMAP_W0_PRG_ON | RCPU_DMAP_W0_SLICER_PRG,
	RCPU_DMAP_W1_OUT_NONE, 
	RCPU_DFMR_STATE_INIT,
	0, 0, 00, 00, 00, 00, 00 
};


/**************************************************************/
/* Stop FEQ training and update, bypass FEQ mult, No data Out */
// RCPU_MED_NO_FEQ_NO_DATA 
STATIC const u16 aMsg_MedNoFeqNoData[] = {
	RCPU_TAG_NO_OUT, 0 , RCPU_CMD_MEDLEY | RCPU_CMD_HEADER,
	0, RCPU_NUMDATA_INIT_NONE, RCPU_HEADER_FLAG_SIZE,
	RCPU_DMAP_W0_FEQ_BYPASS | RCPU_DMAP_W0_FEQ_NO_UPDATE | RCPU_DMAP_W0_DMAP_BYPASS | RCPU_DMAP_W0_SEQ_TONE,
	RCPU_DMAP_W1_OUT_NONE, 
	RCPU_DFMR_STATE_INIT,
	0, 0, 00, 00, 00, 00, 00 
};

/**************************************************************/
/* Medley, Start SNR, slicer PRG, no FEQ update, no data out */
// RCPU_MED_START_SNR 
#if CSIM_INTEG
#define RCPU_AE_SNR_PERIOD		16
#define RCPU_AE_SNR_IDLE		RCPU_SNR_ONE_TIME
#define RCPU_AE_SNR_SHIFT		4		// Over shift to have good SNR
#else
#define RCPU_AE_SNR_PERIOD		(2*1024)
#define RCPU_AE_SNR_IDLE		RCPU_SNR_ONE_TIME
#define RCPU_AE_SNR_SHIFT		11
#endif

STATIC const u16 aMsg_MedSnr[] = {
	RCPU_TAG_NO_OUT, 0 , RCPU_CMD_SNR_AVG | RCPU_CMD_MEDLEY | RCPU_CMD_HEADER,
	0, RCPU_NUMDATA_INIT_NONE, RCPU_HEADER_FLAG_SIZE,
	RCPU_DMAP_W0_FEQ_NORMAL | RCPU_DMAP_W0_FEQ_NO_UPDATE | RCPU_DMAP_W0_SEQ_TONE | RCPU_DMAP_W0_PRG_ON | RCPU_DMAP_W0_SLICER_PRG,
	RCPU_DMAP_W1_OUT_NONE, 
	RCPU_DFMR_STATE_INIT,
	0, 0, 00, 00, RCPU_AE_SNR_PERIOD, RCPU_AE_SNR_IDLE, RCPU_AE_SNR_SHIFT 
};


/**************************************************************/
/* Medley, FEQ + FEQ update, No data out */
// RCPU_MED_NO_DATA 
STATIC const u16 aMsg_MedNoData[] = {
	RCPU_TAG_NO_OUT, 0 , RCPU_CMD_MEDLEY | RCPU_CMD_HEADER,
	0, RCPU_NUMDATA_INIT_NONE, RCPU_HEADER_FLAG_SIZE,
	RCPU_DMAP_W0_FEQ_NORMAL | RCPU_DMAP_W0_FEQ_UPDATE | RCPU_DMAP_W0_SORTED_TONE | RCPU_DMAP_W0_SLICER_DMAP,
	RCPU_DMAP_W1_OUT_NONE, 
	RCPU_DFMR_STATE_INIT,
	0, 0, 00, 00, 0, 0, 0
};


/**************************************************************/
/* Medley, Start SNR, slicer PRG, no FEQ update, no data out */
// RCPU_MED_SLICER_SNR 
STATIC const u16 aMsg_MedSliceSnr[] = {
	RCPU_TAG_NO_OUT, 0 , RCPU_CMD_SNR_AVG | RCPU_CMD_MEDLEY | RCPU_CMD_HEADER,
	0, RCPU_NUMDATA_INIT_NONE, RCPU_HEADER_FLAG_SIZE,
	RCPU_DMAP_W0_FEQ_NORMAL | RCPU_DMAP_W0_FEQ_UPDATE | RCPU_DMAP_W0_SEQ_TONE | RCPU_DMAP_W0_SLICER_DMAP,
	RCPU_DMAP_W1_OUT_NONE, 
	RCPU_DFMR_STATE_INIT,
	0, 0, 00, 00, RCPU_AE_SNR_PERIOD, RCPU_AE_SNR_IDLE, RCPU_AE_SNR_SHIFT 
};

/**************************************************************/
/* Medley, FEQ + FEQ update, Slicer out */
// RCPU_MED_SLICER_DATA 
STATIC const u16 aMsg_MedSlice[] = {
	RCPU_TAG_SLICER_SEQ_OUT, 0 , RCPU_CMD_MEDLEY | RCPU_CMD_HEADER,
	0, RCPU_NUMDATA_INIT_SLICER, RCPU_HEADER_FLAG_SIZE,
	RCPU_DMAP_W0_FEQ_NORMAL | RCPU_DMAP_W0_FEQ_UPDATE | RCPU_DMAP_W0_SEQ_TONE | RCPU_DMAP_W0_SLICER_DMAP,
	RCPU_DMAP_W1_OUT_NORMAL | RCPU_DMAP_W1_TAGS_TO_DATA, 
	RCPU_DFMR_STATE_INIT | RCPU_DFMR_FWD_DATA_2CORE,
	0, 0, 00, 00, 0, 0, 0
};

/**************************************************************/
/* Medley, FEQ on, no FEQ update, Slicer out */
// RCPU_MED_SLICER_NO_UPDATE
STATIC const u16 aMsg_MedSliceNoUp[] = {
	RCPU_TAG_SLICER_SEQ_OUT, 0 , RCPU_CMD_MEDLEY | RCPU_CMD_HEADER,
	0, RCPU_NUMDATA_INIT_SLICER, RCPU_HEADER_FLAG_SIZE,
	RCPU_DMAP_W0_FEQ_NORMAL | RCPU_DMAP_W0_FEQ_NO_UPDATE | RCPU_DMAP_W0_SEQ_TONE | RCPU_DMAP_W0_SLICER_DMAP,
	RCPU_DMAP_W1_OUT_NORMAL | RCPU_DMAP_W1_TAGS_TO_DATA, 
	RCPU_DFMR_STATE_INIT | RCPU_DFMR_FWD_DATA_2CORE,
	0, 00, 00, 00, 0, 0, 0 };

/**************************************************************/
/* Showtime, FEQ + FEQ update, Slicer out, LOS on */
// RCPU_SHOW_START
#define RCPU_SHOW_LOS_PERIOD	64
#define RCPU_SHOW_LOS_IDLE		0

STATIC const u16 aMsg_ShowStart[] = {
	RCPU_TAG_SLICER_SORT_OUT, 0 , RCPU_CMD_HEADER | RCPU_CMD_LOS_TD,
	0, RCPU_NUMDATA_SHOW_KF, RCPU_HEADER_FLAG_SIZE,
	RCPU_DMAP_W0_FEQ_NORMAL | RCPU_DMAP_W0_FEQ_UPDATE | RCPU_DMAP_W0_SORTED_TONE | RCPU_DMAP_W0_SLICER_DMAP,
	RCPU_DMAP_W1_OUT_NORMAL, 
	RCPU_DFMR_STATE_SHOW | RCPU_DFMR_TOGGLE_CONFIG,
	0, 00, 00, 00, RCPU_SHOW_LOS_PERIOD, RCPU_SHOW_LOS_IDLE, 0 };

/**************************************************************/
/* Showtime, FEQ + FEQ update, Slicer out, Do SNR */
// RCPU_SHOW_SNR
#define RCPU_SHOW_SNR_PERIOD	1024
#define RCPU_SHOW_SNR_IDLE		RCPU_SNR_ONE_TIME
#define RCPU_SHOW_SNR_SHIFT		10

STATIC const u16 aMsg_ShowSnr[] = {
	RCPU_TAG_SLICER_SORT_OUT, 0 , RCPU_CMD_SNR_AVG,
	0, RCPU_NUMDATA_SHOW_KF, RCPU_HEADER_FLAG_SIZE,0,0,0,
	0, 00, 00, 00, RCPU_SHOW_SNR_PERIOD, RCPU_SHOW_SNR_IDLE, RCPU_SHOW_SNR_SHIFT };


/**************************************************************/
/* Modify channel sequencing */
// RCPU_MISC_SEQUENCING
STATIC const u16 aMsg_MiscChSeq[] = {
	RCPU_TAG_SLICER_SORT_OUT, 0 , RCPU_CMD_CH_SEQUENCE,
	0, RCPU_NUMDATA_NOT_SET, 0, 0,0,0,0,0,0,0,0,0,0 };


/**************************************************************/
/* This Array must be similar to the enum in xdsl_rmc.h !!    */
STATIC const u16 * aRcpuCmds[] = {
	aMsg_LineDown,
	aMsg_LineUp,

	aMsg_TrConfig,
	aMsg_TrDetect,
	aMsg_TrNoFeqNoData,
	aMsg_TrVbusOut,
	aMsg_TrTeqByp,
	aMsg_TrTeqOut,
	aMsg_TrTeqNorm,
	aMsg_TrSkip,
	aMsg_TrUpbo,
	aMsg_TrFftOut,
	aMsg_TrFeqTrain,
	aMsg_trTstSnr,
	aMsg_TrNoData,
	aMsg_TrSliceNoUp,

	aMsg_MedFeqTrain,
	aMsg_MedNoFeqNoData,
	aMsg_MedSnr,
	aMsg_MedNoData,
	aMsg_MedSliceSnr,
	aMsg_MedSlice,
	aMsg_MedSliceNoUp,

	aMsg_ShowStart,
	aMsg_ShowSnr,

	aMsg_MiscChSeq,
};

 

/**************************************************************/
/**************************************************************/
#define RCPU_HEADER_ADDR		0x0000
#define RCPU_HEADER_LEN			32
#define RCPU_HEADER_TAG			26
#define RCPU_HEADER_PILOT		20
#define RCPU_DMEM_ADDR			ADDRESS_RXCPU_DCACHE_PIO
#define RCPU_LOG_BUF_POINT		0x900
#define RCPU_LOG_BUF_START		0x902
#define RCPU_LOG_BUF_END		0x1000


/***********************************************************************
	Function: RxCpuGetCurrentFrame
	
	Description: Retreive from RCPU uController the current frame number
	
	Return Value: Frame number
***********************************************************************/
u16	RxCpuGetCurrentFrame( u8 Line)
{
	u16 * addr, tag;
	addr = (u16 *) (RCPU_DMEM_ADDR + Line * RCPU_HEADER_LEN + RCPU_HEADER_TAG);

	
	/* Get the current Frame # for this line */
	// tag = *addr;
	tag = readPIO_short((u16 *)addr);

	return (u16) tag;
}

/**************************************************************/
/***                  I N T E R F A C E                     ***/
/**************************************************************/
typedef struct {
	u16			aCmd[16];
	u16			aCfg[6];
	u16			FftTone;
	u16			NbTone;
	u16			AfifoByte;
	u16			BfifoDmaSize;
} tRcpuStatus;

STATIC SEM_ID			RcpuSemaphore;
STATIC tRcpuStatus		xdsl_Rcpu[RCPU_MAX_NUMBER_LINE];

/***********************************************************************
	Function: RxCpuSendCommand
	
	Description: 
		Builds and send a command to RxCpu.
	
	Return Value: None
***********************************************************************/
void RxCpuSendCommand(u8 Line, u8 CmdId, u32 Frame, u16 * pParam)
{
	u16 * pCmd;
	const u16 *pDefault;
	u16 LineTag;
	u16 Param;
	int i;

	/* Protect access via semaphore */
	iposSemTake( RcpuSemaphore, WAIT_FOREVER);

	/* Log the command */
#ifdef LOG_MSG	
	logMsg("RxCpu: Line %d   Cmd %x   Frame %x\n", Line, CmdId, Frame,0,0,0);
	if(pParam){
		logMsg("RxCpu: Param %x %x %x %x %x %x\n", pParam[0], pParam[1], pParam[2], pParam[3], pParam[4], pParam[5]);
	}
#endif

	/* Set the line number */
	LineTag = (u16) Line << 8;

	/* Set the frame number */
	if( (Frame & RCPU_FRAME_IMMEDIATE)) {
	   LineTag |= RCPU_IMMEDIATE;
	   Frame = 0;
	}
	else if( (Frame & RCPU_FRAME_RELATIVE)){
		Frame += RxCpuGetCurrentFrame(Line);
	}

	/* Copy default buffer */
	pCmd = xdsl_Rcpu[Line].aCmd;
	pDefault = aRcpuCmds[CmdId];
	for(i = 0; i < RCPU_CMD_WORD_LEN; i++){
		pCmd[i] = pDefault[i];
	}
	pCmd[0] |= LineTag;
	pCmd[1] = Frame;

	/* Grab parameters */
	switch(CmdId){
	case RCPU_LINE_UP:
		/* Clean BfifoDmaSize */
		xdsl_Rcpu[Line].BfifoDmaSize = 0;

		/* Get Num tone And FFT scaling */
		Param = pParam[0];
		Param &= 0xF;
		xdsl_Rcpu[Line].AfifoByte = (u16) 4 << Param;
		xdsl_Rcpu[Line].FftTone   = (u16) 1 << Param;
		/* Set TEQ Num out samples */
		pCmd[13]				  = (u16) 2 << Param;
		/* Set FFT num tone */
		Param -= 5;
		Param &= 0x7;
		Param |= (pParam[0] >> 4) & 0xF0;
		Param <<= 8;
		pCmd[15] |= Param;

		/* Get Windowing */
		pCmd[14] =  pParam[1] & 0xFF;
		pCmd[10] = (pParam[1] >> 8) ? 0x0110 : 0x0310;

		/* Get Number of tones in Demapper */
		xdsl_Rcpu[Line].NbTone    = pParam[2];

		/* Force Immediate action */
		pCmd[0] |= RCPU_IMMEDIATE;

		/* Save config */
		for(i=0; i<6; i++){
			xdsl_Rcpu[Line].aCfg[i] = pCmd[i+10];
		}
		break;

	case RCPU_TR_CONFIG:
		/* Get Num tone And FFT scaling */
		Param = pParam[0];
		Param &= 0xF;
		xdsl_Rcpu[Line].FftTone   = (u16) 1 << Param;
		/* Set TEQ Num out samples */
		pCmd[13]                  = (u16) 2 << Param;
		/* Set FFT num tone */
		Param -= 5;
		Param &= 0x7;
		Param |= (pParam[0] >> 4) & 0xF0;
		Param <<= 8;
		pCmd[15] |= Param;

		/* Get Windowing */
		pCmd[14] = pParam[1] & 0xFF;
		pCmd[10] = (pParam[1] >> 8) ? 0x0000 : 0x0200;

		/* Get TEQ scale shift */
		Param = pParam[2] & 0x0F00;
		Param <<= 4;
		pCmd[10] |= Param;
//test
//pCmd[10] |= RCPU_TEQ_W0_BYP_TEQ;

		/* Get num taps */
		Param = pParam[2] & 0xFF;
		pCmd[10] |= Param;

		/* Get num prefix, suffix */
		pCmd[11] = pParam[3];
		pCmd[12] = pParam[4];

		/* Set Afifo bytes */
		xdsl_Rcpu[Line].AfifoByte = (pCmd[13] + pCmd[12] + pCmd[11]) *2;

		/* Set Delay Line Step */
		Param = pCmd[10] & 0xFF;
		if( Param <= ( pCmd[11] + pCmd[12])){
			Param = ( pCmd[13] + Param -1) & 0x3F;
		}
		else {
			Param = ( pCmd[13] + pCmd[12] + pCmd[11]) & 0x3F;
		}
		Param <<= 8;
		pCmd[14] |= Param;

		/* Get Number of tones in Demapper */
		xdsl_Rcpu[Line].NbTone = (pParam[5] & 0x0FFF);

		/* Save config */
		for(i=0; i<6; i++){
			xdsl_Rcpu[Line].aCfg[i] = pCmd[i+10];
		}
		
		/* Check if start from config */
		if(pParam[5] & RCPU_CONFIG_LINE_UP){
			pCmd[2] |= RCPU_CMD_VBUS;
			pCmd[15] |= PARAM_VBUS_ON;

			/* Clean BfifoDmaSize */
			xdsl_Rcpu[Line].BfifoDmaSize = 0;

			/* Force Immediate action */
			pCmd[0] |= RCPU_IMMEDIATE;
		}
		
		break;

	case RCPU_TR_TEQ_OUT:
		/* Unset the bypass TEQ bit */
		xdsl_Rcpu[Line].aCfg[0] &= (u16) ~RCPU_TEQ_W0_BYP_TEQ;

		/* Set the bypass FFT in config */
		xdsl_Rcpu[Line].aCfg[5] |= RCPU_TEQ_W5_BYP_FFT;

		/* Retreive config */
		for(i=0; i<6; i++){
			pCmd[i+10] = xdsl_Rcpu[Line].aCfg[i];
		}
		break;
		
	case RCPU_TR_VBUS_OUT:
	case RCPU_TR_TEQ_BYP_NO_DATA:
		/* Set the bypass TEQ bit */
		xdsl_Rcpu[Line].aCfg[0] |= RCPU_TEQ_W0_BYP_TEQ;

		/* Set the bypass FFT in config */
		xdsl_Rcpu[Line].aCfg[5] |= RCPU_TEQ_W5_BYP_FFT;

		/* Retreive config */
		for(i=0; i<6; i++){
			pCmd[i+10] = xdsl_Rcpu[Line].aCfg[i];
		}
		break;

	case RCPU_TR_TEQ_NORM:
		/* Set the new TEQ scale shift */
		Param  = xdsl_Rcpu[Line].aCfg[0];
		Param &= 0x0FFF;
		Param |= (u16) pParam[0] << 12;

		/* Unset the bypass TEQ bit */
		Param  &= (u16) ~RCPU_TEQ_W0_BYP_TEQ;
		xdsl_Rcpu[Line].aCfg[0] = Param;

		/* Unset the bypass FFT in config */
		xdsl_Rcpu[Line].aCfg[5] &= (u16) ~RCPU_TEQ_W5_BYP_FFT;

		/* Retreive config */
		for(i=0; i<6; i++){
			pCmd[i+10] = xdsl_Rcpu[Line].aCfg[i];
		}
		break;


	case RCPU_TR_SKIP_SAMPLE:
		/* Parameter is number of sample to skip */
		pCmd[15] = pParam[0];
		/* Store number of time to skip */
		if(pParam[0] == 0) 
			pCmd[14] = 0;
		else
			pCmd[14] = pParam[1];
		/* Store Tag */
		pCmd[0] |= (( pParam[2] & 0xF) << 4);
		break;
	case RCPU_SHOW_START:
		/* Parametr is Kf */
		xdsl_Rcpu[Line].NbTone = (u16) pParam[0];

		break;

	case RCPU_MISC_SEQUENCING:
		/* Parameter gives the sequencing */
		pCmd[11] = pParam[0] & 0x0303;
		pCmd[12] = pParam[1] & 0x0303;
		break;

	}

	/* Set AFIFO size */
	pCmd[3] = xdsl_Rcpu[Line].AfifoByte;

	/* Set DeMap out data size */
	Param = (pCmd[6] & RCPU_DMAP_W0_SEQ_TONE) ?
		xdsl_Rcpu[Line].FftTone :
		xdsl_Rcpu[Line].NbTone;

	switch(pCmd[4]){
	case RCPU_NUMDATA_INIT_SLICER:
		pCmd[4] = (Param +3) / 4;
		break;

	case RCPU_NUMDATA_INIT_FFT:
	case RCPU_NUMDATA_INIT_FEQ:
	case RCPU_NUMDATA_INIT_TEQ:
		pCmd[4] = Param * 4;
		break;

	case RCPU_NUMDATA_INIT_REVCHEK:
		pCmd[4] = 4;
		break;

	case RCPU_NUMDATA_INIT_NONE:
		pCmd[4] = 0;
		break;								

	case RCPU_NUMDATA_SHOW_KF:
		pCmd[4] = Param;
		break;
		
	case RCPU_NUMDATA_NOT_SET:
		pCmd[4] = xdsl_Rcpu[Line].BfifoDmaSize;
		break;

	default:
		pCmd[4] = 0xF00L;
		break;		
	}
	/* Add tag size if any */
	if(pCmd[7] & RCPU_DMAP_W1_TAGS_TO_DATA){
		pCmd[4] += 4;
	}

	/* Check if the DMA size has changed */
	if(pCmd[4] && pCmd[4] != xdsl_Rcpu[Line].BfifoDmaSize){
		xdsl_Rcpu[Line].BfifoDmaSize = pCmd[4];
		if( CmdId < RCPU_SHOW_START){
			/* Let driver know */
			changeBFIFOInitSize(pCmd[4]);
		}
	}

#ifdef VTU_R
	/* CPE, set pilot tone */
	/* Set pilot bit in header flag */
	pCmd[5] |= RCPU_TONE_IN_HEADER;

	/* Set Extended header length for pilot */
	/* Pilot tone workaround */
	Param = pCmd[5] & 0xFF;
	pCmd[5] &= 0xFF00;
	if( CmdId < RCPU_SHOW_START)
		Param += RCPU_TONE_SIZE_INIT;
	else
		Param += RCPU_TONE_SIZE_SHOW;
	pCmd[5] |= (Param & 0xFF);

	/* Set the copy tone to header bit in Dmapper */
	pCmd[7] |= RCPU_TONE_IN_DMAP;
#endif

	/* Send the command to RxCpu */
		writeRxCPU_CQ( Line, (int *) xdsl_Rcpu[Line].aCmd);

	/* Release the Semaphore */
	iposSemGive( RcpuSemaphore);
}



/***********************************************************************
	Function: RxCpuInit
	
	Description: 
		Initialized RCPU line structures
	
	Return Value: None
***********************************************************************/
void RxCpuInit( void )
{
	memset( xdsl_Rcpu, 0, sizeof(xdsl_Rcpu));

	RcpuSemaphore = semMCreate( SEM_Q_PRIORITY | SEM_INVERSION_SAFE);
}


void rx_cfg( void)
{
	u16 param[6];

	param[0] = 0x0a0b;
	param[1] = 0x0000;
	param[2] = 0x0610;
	param[3] = 0x00c0;
	param[4] = 0x0080;
	param[5] = 0x87fc;

	RxCpuSendCommand( 1, RCPU_TR_CONFIG, RCPU_FRAME_IMMEDIATE, param);
}