#include "stdio.h"
 
#include "bme.h"
#include "include/xdsl_fmc.h"
#include "include/framercpu.h"
#include "hostType.h"

static BmeTxCtlMsg_t  NotConfigCtlMsg = {
   0, TX_DISABLED_STATE, 0x00, 0x00, 
   { 0,0,0,0,0, 0,0,0,0,0 }
};

static BmeTxCtlMsg_t  ToneInpCtlMsg = {
   0, TX_TONE_INP_STATE, 0x00, 0x00, 
   { 0,0,0,18,0, 0,0,0,0,0 }
};

static BmeTxCtlMsg_t  InitDataCtlMsg = {
   0, TX_INIT_DATA_STATE, 0x00, 0x00, 
   { 0,0,0,2,0, 0,0,0,0,0 }
};

static BmeTxCtlMsg_t  OpTrainCtlMsg = {
   0, TX_OP_TRAIN_STATE, 0x00, 0x00, 
   { 0,0,0,5,0, 0,0,0,0,0 }
};

static BmeTxCtlMsg_t  OpSynchroTrainCtlMsg = {
   0, TX_OP_SYNCHRO_TRAIN_STATE, 0x00, 0x00, 
   { 0,0,0,5,5, 0,0,0,0,0 }
};

static BmeTxCtlMsg_t  OpMedleyCtlMsg = {
   0, TX_OP_MEDLEY_STATE, 0x00, 0x00, 
   { 0,0,0,5,0, 0,0,0,0,0 }
};

static BmeTxCtlMsg_t  OpSynchroMedleyCtlMsg = {
   0, TX_OP_SYNCHRO_MEDLEY_STATE, 0x00, 0x00, 
   { 0,0,0,5,5, 0,0,0,0,0 }
};

static BmeTxCtlMsg_t  ShowtimeCtlMsg = {
   0, TX_SHOWTIME_STATE, 0x00, 0x00, 
   { 0,0,0,0,0, 0,0,0,0,0 } 
};

static BmeTxCtlMsg_t  KeepCurStateCtlMsg = {
   0, TX_KEEP_CUR_STATE, 0x00, 0x00, 
   { 0,0,0,0,0, 0,0,0,0,0 }
};

extern char capTest;

void framerCpu(int ch_num, FMC_CMD_TYPES cmdtype, int atFrmNum, int bytesPerFrm)
{	
    int  cmdFlags; 
    u16  CycExtnSize; 
    u8   newBitTabOfst; 

    cmdFlags = 0;
    CycExtnSize = 0; 
    newBitTabOfst = 0; 

    if (cmdtype == START_OP_TRAINING) { 
		cmdFlags = FMC_CMD_SET_TX_VBUS_ON; 
		XtFmcChgStateWithCmd( ch_num, TX_KEEP_CUR_STATE, 1, cmdFlags, CycExtnSize, newBitTabOfst, 0); 

		cmdFlags = FMC_CMD_RESET_FRMNUM;  // FMC_CMD_SET_CYC_PFX_ON; 
		XtFmcChgStateWithCmd( ch_num, (0x80 | TX_OP_TRAIN_STATE), 0, cmdFlags, CycExtnSize, newBitTabOfst, 0); 
    } 
    else if (cmdtype == START_OP_SYNCHRO_TRAIN) { 
		XtFmcChgStateWithCmd( ch_num, TX_OP_SYNCHRO_TRAIN_STATE, atFrmNum, cmdFlags, 
						CycExtnSize, newBitTabOfst, 0); 
    }  
    else if (cmdtype == START_OP_MEDLEY) { 
		XtFmcChgStateWithCmd( ch_num, (0x80 | TX_OP_MEDLEY_STATE), atFrmNum, cmdFlags, 
						CycExtnSize, newBitTabOfst, 0); 
    }  
    else if (cmdtype == START_OP_SYNCHRO_MEDLEY) { 
		XtFmcChgStateWithCmd( ch_num, TX_OP_SYNCHRO_MEDLEY_STATE, atFrmNum, cmdFlags, 
						CycExtnSize, newBitTabOfst, 0); 
    }
    else if (cmdtype == START_SHOWTIME) { 
		cmdFlags = 0;  // FMC_CMD_DO_BIT_SWAP; 
        newBitTabOfst = 0x20 * ch_num; 
		XtFmcChgStateWithCmd( ch_num, (0x80 | TX_SHOWTIME_STATE), 0, cmdFlags, 
				CycExtnSize, newBitTabOfst, bytesPerFrm); 
    }
	else if (cmdtype == START_DISABLE) {
		XtFmcChgStateWithCmd( ch_num, (0x80 | TX_DISABLED_STATE), 0, cmdFlags, 
				CycExtnSize, newBitTabOfst, 0); 

	}
}

int get_tx_frm_cnt(int chan_num)
{
	return(readPIO_SingleRegChannel((int *)TX_FRM_CNT_ADDR, chan_num));
}


void 
XtFmcSendTxCtlMsg(BmeTxCtlMsg_t *newCtlMsg) 
{
    int *p = (int *)newCtlMsg; 

    if (!capTest) {
        printf("fmc msg= %08x %08x %08x %08x\n", p[0], p[1], p[2], p[3]); 
    }

    writeFramerCPU_CQ(newCtlMsg->chNum, (int *)newCtlMsg);
}

int 
XtFmcChgStateWithCmd( u8 chNum, u8 newState, u16 atFrmNum, u16 cmdFlags, 
	u16  CycExtnSize, u8 newBitTabOfst, u16 bytesPerFrm)
// sends txCtlMsg with cmdFlags along with change state 
// to 'newState' at 'atFrmNum' and 
{
    BmeTxCtlMsg_t  *newCtlMsg; 
    u16  nState; 

    nState = newState & 0x0f; 
    switch( nState) {

    case TX_KEEP_CUR_STATE:		// keep cur state 
	newCtlMsg = &KeepCurStateCtlMsg; 
    break;

    case TX_DISABLED_STATE:		// NotConfigured state 
	newCtlMsg = &NotConfigCtlMsg; 
    break;

    case TX_SHOWTIME_STATE:
	newCtlMsg = &ShowtimeCtlMsg; 
    break;

    case TX_TONE_INP_STATE:		// Tone data inp State 
	newCtlMsg = &ToneInpCtlMsg; 
    break;

    case TX_INIT_DATA_STATE:		// 'init data from x-fifo' State 
	newCtlMsg = &InitDataCtlMsg; 
    break;

    case TX_OP_TRAIN_STATE:		// VDSL OP-Training State 
	newCtlMsg = &OpTrainCtlMsg; 
    break;

    case TX_OP_SYNCHRO_TRAIN_STATE:	// VDSL OP-Synchro-Training State 
	newCtlMsg = &OpSynchroTrainCtlMsg; 
    break;

    case TX_OP_MEDLEY_STATE:		// VDSL OP-Medley State 
	newCtlMsg = &OpMedleyCtlMsg; 
    break;

    case TX_OP_SYNCHRO_MEDLEY_STATE:	// VDSL OP-Synchro-Medley State 
	newCtlMsg = &OpSynchroMedleyCtlMsg; 
    break;

    default:
	
    logMsg( " ** invalid state in XtFmcChgState: %d **\n", nState);  

    return(-1); 

    } 

    newCtlMsg->chNum = chNum; 
    newCtlMsg->newState = newState; 
    // newCtlMsg->fullFrmNum = atFrmNum; 
    *(u8 *)&(newCtlMsg->fullFrmNum) = ((atFrmNum >> 8) & 0xff); 
    *((u8 *)&(newCtlMsg->fullFrmNum)+1) = (atFrmNum & 0xff); 

    // newCtlMsg->cmdFlags = cmdFlags; 
    *(u8 *)&(newCtlMsg->cmdFlags) = ((cmdFlags >> 8) & 0xff); 
    *((u8 *)&(newCtlMsg->cmdFlags)+1) = (cmdFlags & 0xff); 

    if (nState == TX_SHOWTIME_STATE) {
        newCtlMsg->params[2] = (bytesPerFrm >> 8) & 0xff; 
        newCtlMsg->params[3] = (bytesPerFrm & 0xff); 
    } 
    if (cmdFlags & FMC_CMD_DO_BIT_SWAP) { 
        newCtlMsg->params[5] = newBitTabOfst; 
    } 
    if (cmdFlags & FMC_CMD_SET_TX_VBUS_ON) { 
        newCtlMsg->params[6] = 0; 
        newCtlMsg->params[7] = 1; 
    } 
    if (cmdFlags & FMC_CMD_SET_CYC_PFX_ON) { 
        newCtlMsg->params[8] = (CycExtnSize >> 8) & 0xff; 
        newCtlMsg->params[9] = (CycExtnSize & 0xff); 
    } 
    XtFmcSendTxCtlMsg(newCtlMsg); 

    return(0); 
}

