#include "IDIBUS_Speedster.h"

IdiBus_Test::IdiBus_Test (IdiBusSerialLine *SlaveLine, uint8_t SlaveAddress) : IdiBusSlave(SlaveLine, SlaveAddress)
{
	for (uint8_t I=0; I<IDIBUS_Test_CH_COUNT; I++)
	{
		this->CH[I].MMES_Error = 0;
		this->CH[I].state = 0x1040FF0A; //Start seed
		for (uint16_t i = 0; i < 256; i++){
			this->CH[I].RNG[i] = 0;
			this->CH[I].DATA[i] = 0;
		}
		//this->CH[I].STATUS.Enable = 0;
	}
}

IdiBus_Test::IdiBus_Test () : IdiBusSlave()
{
	for (uint8_t I=0; I<IDIBUS_Test_CH_COUNT; I++)
	{
		this->CH[I].MMES_Error = 0;
		this->CH[I].state = 0x1040FF0A; //Start seed
		for (uint16_t i = 0; i < 256; i++){
			this->CH[I].RNG[i] = 0;
			this->CH[I].DATA[i] = 0;
		}
		//this->CH[I].STATUS.Enable = 0;
	}
}

IDIBUS_Test_DATA_TYPE IdiBus_Test::getChData(uint8_t ChNum){
	if ( ChNum < IDIBUS_Test_CH_COUNT ) { return this->CH[ChNum]; }
	else								{ return this->CH[IDIBUS_Test_CH_COUNT-1]; }
}

uint8_t IdiBus_Test::sendPacket(uint8_t ChNum)
{
	//Generate random sequence
	this->CH[ChNum].state = this->xorshift32(this->CH[ChNum].state,this->CH[ChNum].RNG);

	if (ChNum >= IDIBUS_Test_CH_COUNT) { return IDIERMST_INVALID_CHN_NUM; }
	IdiBusMMES MMES(this->Address);
	MMES.DEV.NUM	= IDIBUS_Test_CNTRL_DEV;
	MMES.CHNL.NUM   = ChNum;
	MMES.ComFunc    = 0x01;	//Send packet
	MMES.TxDataLength = 256;
	MMES.TxData = this->CH[ChNum].RNG;
	uint16_t ChDataSize = 256;		//uint8_t[256]
	uint8_t RequestError = this->SendRequestMMES(&MMES);
	if      ( RequestError   != IDIER_NOPE )          { this->CH[ChNum].MMES_Error = RequestError;   }
	else if ( MMES.RxDataLength == 1 )                { this->CH[ChNum].MMES_Error = MMES.RxData[0]; }
	else if ( MMES.RxDataLength != (ChDataSize + 1) ) { this->CH[ChNum].MMES_Error = IDIERMST_INVALID_RX_REQUEST_FORMAT; }
	else {
		this->CH[ChNum].MMES_Error = MMES.RxData[0];
		if ( this->CH[ChNum].MMES_Error == IDIER_NOPE )
		{
			for (uint16_t i = 0; i < 256; i++)
				this->CH[ChNum].DATA[i] = MMES.RxData[i+1];
		}
	}
	return this->CH[ChNum].MMES_Error;

}

void IdiBus_Test::setAllChErr(uint8_t ErrCode)
{
	for (uint8_t I=0; I<IDIBUS_Test_CH_COUNT; I++) { this->CH[I].MMES_Error = ErrCode; }
}

uint32_t IdiBus_Test::xorshift32(uint32_t state,uint8_t *data) {
	for (uint8_t i = 0; i < 256/4; i++){
		state ^= state << 13;
		state ^= state >> 17;
		state ^= state << 5;
		data[i*4+0] = (uint8_t)state;
		data[i*4+1] = (uint8_t)(state>>8);
		data[i*4+2] = (uint8_t)(state>>16);
		data[i*4+3] = (uint8_t)(state>>24);
	}	
	return state;
}
