

#define	_IN_TMC260_C
#include "tmc260.h"

//-------------------------------------------------------------------------

#if (TMC260_DRV_NUM != 0)

//-------------------------------------------------------------------------

#include "trigger.h"
#include "shell.h"
#include "inout.h"

//-------------------------------------------------------------------------


//------------------------------------------------------------------------

typedef struct
{
	TSpiCtrlConfig spiCtrlConfig;
	TStepDirConfig stepDirConfig;
	TChopperConfig chopperConfig;
	TSmartEnergyControl smartEnergyControl;
	TStallGuardConfig stallGuardConfig;
	TDriverConfig driverConfig;

	TReadStatus readStatus;
	u32 readData;
}TCConfig;

//------------------------------------------------------------------------

TCConfig g_tcConfig[TMC260_DRV_NUM];

//------------------------------------------------------------------------

#define SReadWrite(cs, dat)		SpiReadWrite(cs, dat, 20)	// 读写20位数据

void SpiCsOff(SpiCs cs)
{
#if (TMC260_DRV_NUM >= 1)
	SetDriver1CsOff();
#endif
#if (TMC260_DRV_NUM >= 2)
	SetDriver2CsOff();
#endif
#if (TMC260_DRV_NUM >= 3)
	SetDriver3CsOff();
#endif
#if (TMC260_DRV_NUM >= 4)
	SetDriver4CsOff();
#endif
#if (TMC260_DRV_NUM >= 5)
	SetDriver5CsOff();
#endif
#if (TMC260_DRV_NUM >= 6)
	SetDriver6CsOff();
#endif
}

void SpiCsOn(SpiCs cs)
{
	SpiCsOff(cs);

	switch(cs)
	{
	case SC_MOTO1:
#if (TMC260_DRV_NUM >= 1)
		SetDriver1CsOn();
#endif
		break;
	case SC_MOTO2:
#if (TMC260_DRV_NUM >= 2)
		SetDriver2CsOn();
#endif
		break;
	case SC_MOTO3:
#if (TMC260_DRV_NUM >= 3)
		SetDriver3CsOn();
#endif
		break;
	case SC_MOTO4:
#if (TMC260_DRV_NUM >= 4)
		SetDriver4CsOn();
#endif
		break;
	case SC_MOTO5:
#if (TMC260_DRV_NUM >= 5)
		SetDriver5CsOn();
#endif
		break;
	case SC_MOTO6:
#if (TMC260_DRV_NUM >= 6)
		SetDriver6CsOn();
#endif
		break;
	default:
		break;
	}
}

// 软件模拟 SPI 读数据子程序，最多支持64位
uint64_t SpiReadWrite(SpiCs cs, uint64_t dat, u8 bitlen)
{
	int i;
	uint64_t rslt;
	uint64_t mod;

	SClockHigh();
	SpiCsOn(cs);	// 片选有效，开始执行读写过程

	rslt = 0;
	mod = 0x01;
	mod <<= (bitlen-1);

	for(i = 0; i < bitlen; i++)
	{
		// 设置好数据
		if ((dat&mod) != 0)
		{
			SMdoDataOne();
		}
		else
		{
			SMdoDataZero();
		}

		SClockLow();		// 设置为低电平，下降沿芯片准备好输出数据
		SClockHigh();		// 设置为高电平，上升沿芯片读取设置好的数据

		if (SMdiRead() != 0)	// 读取数据
		{
			rslt |= mod;
		}
		mod >>= 1;
	}

	SpiCsOff(cs);
	//printf("SPI cs =0x%x, data =0x%x, rslt = 0x%x \r\n",cs,dat,rslt);

	return(rslt);
}

//------------------------------------------------------------------------

int GetIdxFormCs(SpiCs moto)
{
	int idx = moto - 1;
	if (idx < 0 || idx >= TMC260_DRV_NUM)
	{
		printf("not support moto idx\r\n");
		return -1;
	}
	return idx;
}

//------------------------------------------------------------------------
// 细分设置初始化子程序
void WriteStepDirConfig(SpiCs moto)
{
	u32 temp;
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return;
	}
	temp = DRVCTRL0;

	if (g_tcConfig[idx].stepDirConfig.intpol != 0)
	{
		temp |= INTPOL;	// 使能输出脉冲的16倍频功能
	}

	if (g_tcConfig[idx].stepDirConfig.dEdge != 0)
	{
		temp |= DEDGE;	// 使能双边沿脉冲
	}

	if (g_tcConfig[idx].stepDirConfig.mRes > MRES1)
	{
		g_tcConfig[idx].stepDirConfig.mRes = MRES1;
	}

	temp |= g_tcConfig[idx].stepDirConfig.mRes;

	g_tcConfig[idx].readData = SReadWrite(moto, temp);
}

//------------------------------------------------------------------------
// SPI 控制配置

void WriteSpiCtrlConfig(SpiCs moto)
{
	u32 temp;
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return;
	}
	temp = DRVCTRL1;

	if (g_tcConfig[idx].spiCtrlConfig.polarityA != 0)
	{
		temp |= PHA;
	}

	if (g_tcConfig[idx].spiCtrlConfig.currentA > 255)
	{
		g_tcConfig[idx].spiCtrlConfig.currentA = 255;
	}

	temp |= ((u32)g_tcConfig[idx].spiCtrlConfig.currentA) << 9;

	if (g_tcConfig[idx].spiCtrlConfig.polarityB != 0)
	{
		temp |= PHB;
	}

	if (g_tcConfig[idx].spiCtrlConfig.currentB > 255)
	{
		g_tcConfig[idx].spiCtrlConfig.currentB = 255;
	}

	temp |= ((u32)g_tcConfig[idx].spiCtrlConfig.currentB);

	g_tcConfig[idx].readData = SReadWrite(moto, temp);
}


//------------------------------------------------------------------------
// 斩波寄存器初始化程序

void WriteChopperConfig(SpiCs moto)
{
	u32 temp;
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return;
	}
  	temp = CHOPCONF;

  	if (g_tcConfig[idx].chopperConfig.blankTime > 3)
	{
		g_tcConfig[idx].chopperConfig.blankTime = 3;
	}

  	if (g_tcConfig[idx].chopperConfig.hysteresisDecay > 3)
	{
		g_tcConfig[idx].chopperConfig.hysteresisDecay = 3;
	}

  	if (g_tcConfig[idx].chopperConfig.hysteresisEnd > 15)
	{
		g_tcConfig[idx].chopperConfig.hysteresisEnd = 15;
	}

  	if (g_tcConfig[idx].chopperConfig.hysteresisStart > 7)
	{
		g_tcConfig[idx].chopperConfig.hysteresisStart = 7;
	}

 	if (g_tcConfig[idx].chopperConfig.tOff > 15)
	{
		g_tcConfig[idx].chopperConfig.tOff = 15;
	}

  	temp |= ((u32)g_tcConfig[idx].chopperConfig.blankTime) << 15;

  	if (g_tcConfig[idx].chopperConfig.chopperMode != 0)
	{
		temp |= CHM;
	}

  	if (g_tcConfig[idx].chopperConfig.randomTOff != 0)
	{
		temp |= RNDTF;
	}

  	temp |= ((u32)g_tcConfig[idx].chopperConfig.hysteresisDecay) << 11;
  	temp |= ((u32)g_tcConfig[idx].chopperConfig.hysteresisEnd) << 7;
  	temp |= ((u32)g_tcConfig[idx].chopperConfig.hysteresisStart) << 4;
	if (g_tcConfig[idx].chopperConfig.enable != 0)
	{
		temp |= ((u32)g_tcConfig[idx].chopperConfig.tOff);
	}

	g_tcConfig[idx].readData = SReadWrite(moto, temp);
}

//------------------------------------------------------------------------
// 自适应电流控制初始化子程序
void WriteStallGuardConfig(SpiCs moto)
{
	u32 temp;
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return;
	}
	temp = SGCSCONF;

	// 8 位有符号数转为7位有符号数, 7位有符号数第7位和符号位对于(-64--63）之间的数是相同的
	if (g_tcConfig[idx].stallGuardConfig.stallGuardThreshold > 63)
	{
		g_tcConfig[idx].stallGuardConfig.stallGuardThreshold = 63;
	}
	else if (g_tcConfig[idx].stallGuardConfig.stallGuardThreshold < -64)
	{
		g_tcConfig[idx].stallGuardConfig.stallGuardThreshold = -64;
	}

	if(g_tcConfig[idx].stallGuardConfig.filterEnable != 0)
	{
		temp |= SFILT;
	}

	temp |= (((u32) g_tcConfig[idx].stallGuardConfig.stallGuardThreshold & 0x7f) << 8);
	temp |= (g_tcConfig[idx].stallGuardConfig.currentScale & 0x1F);

	g_tcConfig[idx].readData = SReadWrite(moto, temp);
}

//------------------------------------------------------------------------
// 自适应电流控制初始化程序
void WriteSmartEnergyConfig(SpiCs moto)
{
	u32 temp;
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return;
	}
	temp = SMARTEN;

	if (g_tcConfig[idx].smartEnergyControl.smartIMin != 0)
	{
		temp |= SEIMIN;
	}

	if (g_tcConfig[idx].smartEnergyControl.smartDownStep > 3)
	{
		g_tcConfig[idx].smartEnergyControl.smartDownStep = 3;
	}

	if (g_tcConfig[idx].smartEnergyControl.smartStallLevelMax > 15)
	{
		g_tcConfig[idx].smartEnergyControl.smartStallLevelMax = 15;
	}

	if (g_tcConfig[idx].smartEnergyControl.smartUpStep > 3)
	{
		g_tcConfig[idx].smartEnergyControl.smartUpStep = 3;
	}

	if (g_tcConfig[idx].smartEnergyControl.smartStallLevelMin > 15)
	{
		g_tcConfig[idx].smartEnergyControl.smartStallLevelMin = 15;
	}

	temp |= ((u32)g_tcConfig[idx].smartEnergyControl.smartDownStep)  << 13;
	temp |= ((u32)g_tcConfig[idx].smartEnergyControl.smartStallLevelMax) << 8;
	temp |= ((u32)g_tcConfig[idx].smartEnergyControl.smartUpStep) << 5;
	temp |= ((u32)g_tcConfig[idx].smartEnergyControl.smartStallLevelMin);

	g_tcConfig[idx].readData = SReadWrite(moto, temp);
}



//------------------------------------------------------------------------
// 驱动器控制寄存器初始化程序

void WriteDriverConfig(SpiCs moto)
{
	u32 temp;
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return;
	}
  	temp = DRVCONF;

	if (g_tcConfig[idx].driverConfig.testMode != 0)
	{
		temp |= TST;
	}

	temp |= ((u32)g_tcConfig[idx].driverConfig.slopeHighSide & 0x03) << 14;
	temp |= ((u32)g_tcConfig[idx].driverConfig.slopeLowSide & 0x03) << 12;

	if (g_tcConfig[idx].driverConfig.protectionDisable != 0)
	{
		temp |= DISS2G;
	}

	temp |= ((u32)g_tcConfig[idx].driverConfig.protectionTimer & 0x03) << 8;

	if (g_tcConfig[idx].driverConfig.stepDirDisable != 0)
	{
		temp |= SDOFF;
	}

	if (g_tcConfig[idx].driverConfig.vSenseScale != 0)
	{
		temp |= VSENSE;
	}

	temp |= ((u32) g_tcConfig[idx].driverConfig.readBackSelect & 0x03) << 4;

	g_tcConfig[idx].readData = SReadWrite(moto, temp);
}

//------------------------------------------------------------------------
// 读取状态反馈值

void ReadDriverState(SpiCs moto)
{
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return;
	}
	WriteDriverConfig(moto);

  	switch(g_tcConfig[idx].driverConfig.readBackSelect)		// 读取返回项,0:微步位置,1:负载值0--9位, 2:负载值高5位(5--9位)及设置电流控制值大小
  	{
		case 0:       // 0 A相微步位置
		{
			g_tcConfig[idx].readStatus.phases = (g_tcConfig[idx].readData >> 18) & 0x01;	// STEP/DIR模式下的极性位; 0：电流从OA1引脚流向OA2引脚。 1：电流从OA2引脚流向OA1引脚。
			g_tcConfig[idx].readStatus.mSteps = (g_tcConfig[idx].readData >> 10) & 0x1FF;	// 线圈A在正弦表中的微步位置
			break;
		}
		case 1:			// 1 负载值
		{
			g_tcConfig[idx].readStatus.stallGuard = (g_tcConfig[idx].readData >> 10) & 0x3FF;
			break;
		}
		case 2: 		// 2负载高5位及当前电流值大小
		{
			g_tcConfig[idx].readStatus.stallGuard &= 0x1f;
			g_tcConfig[idx].readStatus.stallGuard |= (g_tcConfig[idx].readData >> 10) & 0x3E0;
			g_tcConfig[idx].readStatus.smartEnergy = (g_tcConfig[idx].readData >> 10) & 0x1f;
			break;
		}
  	}

	g_tcConfig[idx].readStatus.flags = g_tcConfig[idx].readData & 0xff;	// 停顿标志位检测, STEP脉冲检测
}

//------------------------------------------------------------------------
// 驱动器初始化程序

void InitMotorDrivers(SpiCs moto)
{
	int idx;

	idx = moto-1;
	if (idx < 0 || idx >= TMC260_DRV_NUM)
	{
		return;
	}

	memset(&(g_tcConfig[idx]), 0, sizeof(TCConfig));

	g_tcConfig[idx].stallGuardConfig.filterEnable = 1;				// 失步检测滤波 0:标准模式，1: 4个fullstep滤波
	g_tcConfig[idx].stallGuardConfig.stallGuardThreshold = 2;		// 带符号失步门限-64~63，值越大灵敏度越低，不建议小于-10
	g_tcConfig[idx].stallGuardConfig.currentScale = 1;				// 驱动电流0~31
	WriteStallGuardConfig(moto);									// 0xd020a

	g_tcConfig[idx].driverConfig.slopeHighSide = 2;					// 上功率管控制斜率0:最小3: 最大
	g_tcConfig[idx].driverConfig.slopeLowSide = 2;					// 下功率管控制斜率0:最小3: 最大
	g_tcConfig[idx].driverConfig.protectionDisable = 0;				// 0:短路保护使能 1:不使能
	g_tcConfig[idx].driverConfig.protectionTimer = 0;				// 短路保护时间0: 3.2uS, 1: 1.6uS, 2: 1.2uS, 3: 0.8uS
	g_tcConfig[idx].driverConfig.stepDirDisable = 0;	    		// 0: 脉冲方向模式，1:SPI模式
	g_tcConfig[idx].driverConfig.vSenseScale = 0;					// 检测参考电压，0: 305mV, 1: 165mV
	g_tcConfig[idx].driverConfig.readBackSelect = 1;				// 读取返回项,0:微步位置,1:负载值0--9位, 2:负载值高5位(5--9位)及设置电流控制值大小
	WriteDriverConfig(moto);										// 0xea010

	g_tcConfig[idx].smartEnergyControl.smartIMin = 1;				// 智能控制最小电流0: 1/2, 1: 1/4
	g_tcConfig[idx].smartEnergyControl.smartDownStep = 0;			// 电流减少速度0: 32, 1: 8, 2: 2, 3: 1
	g_tcConfig[idx].smartEnergyControl.smartStallLevelMax = 0;		// 高位安全门限0~15
	g_tcConfig[idx].smartEnergyControl.smartUpStep = 0;				// 电流增加速度0: 1, 1: 2, 2: 4, 3: 8
	g_tcConfig[idx].smartEnergyControl.smartStallLevelMin = 0;		// 低位安全门限0~15
	WriteSmartEnergyConfig(moto);									// 0xa8000

	g_tcConfig[idx].stepDirConfig.intpol = 0;						// 16倍频模式
	g_tcConfig[idx].stepDirConfig.dEdge = 0;						// 双边沿模式
	g_tcConfig[idx].stepDirConfig.mRes = MRES4;						// 细分数
	WriteStepDirConfig(moto);										// 0x0

	g_tcConfig[idx].chopperConfig.blankTime = 1;					// 斩波空白时间，也就是关断时间，0: 16, 1: 24, 2: 36, 3: 54
	g_tcConfig[idx].chopperConfig.chopperMode = 0;					// 0: 斩波模式, 1: 常系数模式，一般选择0
	g_tcConfig[idx].chopperConfig.hysteresisDecay = 0;				// 衰减设置0...3, 0:fast decrement  3:very slow decrement
	g_tcConfig[idx].chopperConfig.hysteresisEnd = 3;				// 快速衰减结束值设置 0...15
	g_tcConfig[idx].chopperConfig.hysteresisStart = 3;				// 快速衰减开始值设置 0...7
	g_tcConfig[idx].chopperConfig.tOff = 5;							// 斩波慢衰减时间，影响开关频率
	g_tcConfig[idx].chopperConfig.enable = 1;						// mosfet输出允许
	WriteChopperConfig(moto);										// 0x881b5
}

//------------------------------------------------------------------------------------------------------------------------------------------------


//------------------------------------------------------------------------
// 微细分设置子程序
void SetStepDirMStepRes(SpiCs moto, u32 microstepResolution)
{
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return;
	}
	g_tcConfig[idx].stepDirConfig.mRes = microstepResolution;
	WriteStepDirConfig(moto);
}

// 
void SetStepDirInterpolation(SpiCs moto, u32 interpolation)
{
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return;
	}
	g_tcConfig[idx].stepDirConfig.intpol = interpolation;
	WriteStepDirConfig(moto);
}

// 
void SetStepDirDoubleEdge(SpiCs moto, u32 doubleEdge)
{
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return;
	}
	g_tcConfig[idx].stepDirConfig.dEdge = doubleEdge;
	WriteStepDirConfig(moto);
}

// 
u32 GetStepDirMStepRes(SpiCs moto)
{
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return 0;
	}
	return g_tcConfig[idx].stepDirConfig.mRes;
}

// 
u32 GetStepDirInterpolation(SpiCs moto)
{
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return 0;
	}
	return g_tcConfig[idx].stepDirConfig.intpol;
}

// 
u32 GetStepDirDoubleEdge(SpiCs moto)
{
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return 0;
	}
	return g_tcConfig[idx].stepDirConfig.dEdge;
}

//------------------------------------------------------------------------
// 
void SetChopperBlankTime(SpiCs moto, u32 blankTime)
{
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return;
	}
	g_tcConfig[idx].chopperConfig.blankTime = blankTime;
	WriteChopperConfig(moto);
}

// 
void SetChopperMode(SpiCs moto, u32 mode)
{
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return;
	}
	g_tcConfig[idx].chopperConfig.chopperMode = mode;
	WriteChopperConfig(moto);
}

// 
void SetChopperRandomTOff(SpiCs moto, u32 randomTOff)
{
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return;
	}
	g_tcConfig[idx].chopperConfig.randomTOff = randomTOff;
	WriteChopperConfig(moto);
}

// 
void SetChopperHysteresisDecay(SpiCs moto, u32 hysteresisDecay)
{
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return;
	}
	g_tcConfig[idx].chopperConfig.hysteresisDecay = hysteresisDecay;
	WriteChopperConfig(moto);
}

// 
void SetChopperHysteresisEnd(SpiCs moto, u32 hysteresisEnd)
{
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return;
	}
	g_tcConfig[idx].chopperConfig.hysteresisEnd = hysteresisEnd;
	WriteChopperConfig(moto);
}

// 
void SetChopperHysteresisStart(SpiCs moto, u32 hysteresisStart)
{
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return;
	}
	g_tcConfig[idx].chopperConfig.hysteresisStart = hysteresisStart;
	WriteChopperConfig(moto);
}

// 
void SetChopperTOff(SpiCs moto, u32 tOff)
{
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return;
	}
	g_tcConfig[idx].chopperConfig.tOff = tOff;
	WriteChopperConfig(moto);
}

void SetChopperEnable(SpiCs moto, u32 enable)
{
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return;
	}
	g_tcConfig[idx].chopperConfig.enable = enable;
	WriteChopperConfig(moto);
}

// 
u32 GetChopperBlankTime(SpiCs moto)
{
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return 0;
	}
	return g_tcConfig[idx].chopperConfig.blankTime;
}

// 
u32 GetChopperMode(SpiCs moto)
{
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return 0;
	}
	return g_tcConfig[idx].chopperConfig.chopperMode;
}

// 
u32 GetChopperRandomTOff(SpiCs moto)
{
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return 0;
	}
	return g_tcConfig[idx].chopperConfig.randomTOff;
}

// 
u32 GetChopperHysteresisDecay(SpiCs moto)
{
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return 0;
	}
	return g_tcConfig[idx].chopperConfig.hysteresisDecay;
}

// 
u32 GetChopperHysteresisEnd(SpiCs moto)
{
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return 0;
	}
	return g_tcConfig[idx].chopperConfig.hysteresisEnd;
}

// 
u32 GetChopperHysteresisStart(SpiCs moto)
{
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return 0;
	}
	return g_tcConfig[idx].chopperConfig.hysteresisStart;
}

// 
u32 GetChopperTOff(SpiCs moto)
{
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return 0;
	}
	return g_tcConfig[idx].chopperConfig.tOff;
}

u32 GetChopperEnable(SpiCs moto)
{
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return 0;
	}
	return g_tcConfig[idx].chopperConfig.enable;
}

//------------------------------------------------------------------------
// 
void SetSmartEnergyIMin(SpiCs moto, u32 smartIMin)
{
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return;
	}
	g_tcConfig[idx].smartEnergyControl.smartIMin = smartIMin;
	WriteSmartEnergyConfig(moto);
}

// 
void SetSmartEnergyDownStep(SpiCs moto, u32 smartDownStep)
{
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return;
	}
	g_tcConfig[idx].smartEnergyControl.smartDownStep = smartDownStep;
	WriteSmartEnergyConfig(moto);
}

// 
void SetSmartEnergyStallLevelMax(SpiCs moto, u32 stallLevelMax)
{
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return;
	}
	g_tcConfig[idx].smartEnergyControl.smartStallLevelMax = stallLevelMax;
	WriteSmartEnergyConfig(moto);
}

// 
void SetSmartEnergyUpStep(SpiCs moto, u32 smartUpStep)
{
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return;
	}
	g_tcConfig[idx].smartEnergyControl.smartUpStep = smartUpStep;
	WriteSmartEnergyConfig(moto);
}

// 
void SetSmartEnergyStallLevelMin(SpiCs moto, u32 stallLevelMin)
{
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return;
	}
	g_tcConfig[idx].smartEnergyControl.smartStallLevelMin = stallLevelMin;
	WriteSmartEnergyConfig(moto);
}

// 
u32 GetSmartEnergyIMin(SpiCs moto)
{
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return 0;
	}
	return g_tcConfig[idx].smartEnergyControl.smartIMin;
}

// 
u32 GetSmartEnergyDownStep(SpiCs moto)
{
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return 0;
	}
	return g_tcConfig[idx].smartEnergyControl.smartDownStep;
}

// 
u32 GetSmartEnergyStallLevelMax(SpiCs moto)
{
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return 0;
	}
	return g_tcConfig[idx].smartEnergyControl.smartStallLevelMax;
}

// 
u32 GetSmartEnergyUpStep(SpiCs moto)
{
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return 0;
	}
	return g_tcConfig[idx].smartEnergyControl.smartUpStep;
}

//
u32 GetSmartEnergyStallLevelMin(SpiCs moto)
{
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return 0;
	}
	return g_tcConfig[idx].smartEnergyControl.smartStallLevelMin;
}

//------------------------------------------------------------------------
// 
void SetStallGuardFilter(SpiCs moto, u32 enable)
{
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return;
	}
	g_tcConfig[idx].stallGuardConfig.filterEnable = enable;
	WriteStallGuardConfig(moto);
}

// 
void SetStallGuardThreshold(SpiCs moto, s32 threshold)
{
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return;
	}
	g_tcConfig[idx].stallGuardConfig.stallGuardThreshold = threshold;
	WriteStallGuardConfig(moto);
}

// 
void SetStallGuardCurrentScale(SpiCs moto, u32 currentScale)
{
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return;
	}
	g_tcConfig[idx].stallGuardConfig.currentScale = currentScale;
	WriteStallGuardConfig(moto);
}

// 
u32 GetStallGuardFilter(SpiCs moto)
{
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return 0;
	}
	return g_tcConfig[idx].stallGuardConfig.filterEnable;
}

// 
s32 GetStallGuardThreshold(SpiCs moto)
{
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return 0;
	}
	return g_tcConfig[idx].stallGuardConfig.stallGuardThreshold;
}

// 
u32 GetStallGuardCurrentScale(SpiCs moto)
{
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return 0;
	}
	return g_tcConfig[idx].stallGuardConfig.currentScale;
}

//------------------------------------------------------------------------
// 
void SetDriverSlopeHighSide(SpiCs moto, u32 slopeHighSide)
{
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return;
	}
	g_tcConfig[idx].driverConfig.slopeHighSide = slopeHighSide;
	WriteDriverConfig(moto);
}

// 
void SetDriverSlopeLowSide(SpiCs moto, u32 slopeLowSide)
{
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return;
	}
	g_tcConfig[idx].driverConfig.slopeHighSide = slopeLowSide;
	WriteDriverConfig(moto);
}

// 
void SetDriverDisableProtection(SpiCs moto, u32 disableProtection)
{
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return;
	}
	g_tcConfig[idx].driverConfig.protectionDisable = disableProtection;
	WriteDriverConfig(moto);
}

// 
void SetDriverProtectionTimer(SpiCs moto, u32 protectionTimer)
{
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return;
	}
	g_tcConfig[idx].driverConfig.protectionTimer = protectionTimer;
	WriteDriverConfig(moto);
}

// 
void SetDriverStepDirectionOff(SpiCs moto, u32 sDOff)
{
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return;
	}
	g_tcConfig[idx].driverConfig.stepDirDisable = sDOff;
	WriteDriverConfig(moto);
}

// 
void SetDriverVSenseScale(SpiCs moto, u32 scale)
{
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return;
	}
	g_tcConfig[idx].driverConfig.vSenseScale = scale;
	WriteDriverConfig(moto);
}

// 
void SetDriverReadSelect(SpiCs moto, u32 readSelect)
{
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return;
	}
	g_tcConfig[idx].driverConfig.readBackSelect = readSelect;
	WriteDriverConfig(moto);
}

// 
void SetDriverTestMode(SpiCs moto, u32 testMode)
{
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return;
	}
	g_tcConfig[idx].driverConfig.testMode = testMode;
	WriteDriverConfig(moto);
}

// 
u32 GetDriverSlopeHighSide(SpiCs moto)
{
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return 0;
	}
	return g_tcConfig[idx].driverConfig.slopeHighSide;
}

// 
u32 GetDriverSlopeLowSide(SpiCs moto)
{
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return 0;
	}
	return g_tcConfig[idx].driverConfig.slopeLowSide;
}

// 
u32 GetDriverDisableProtection(SpiCs moto)
{
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return 0;
	}
	return g_tcConfig[idx].driverConfig.protectionDisable;
}

// 
u32 GetDriverProtectionTimer(SpiCs moto)
{
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return 0;
	}
	return g_tcConfig[idx].driverConfig.protectionTimer;
}

// 
u32 GetDriverStepDirectionOff(SpiCs moto)
{
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return 0;
	}
	return g_tcConfig[idx].driverConfig.stepDirDisable;
}

// 
u32 GetDriverVSenseScale(SpiCs moto)
{
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return 0;
	}
	return g_tcConfig[idx].driverConfig.vSenseScale;
}

// 
u32 GetDriverReadSelect(SpiCs moto)
{
	int idx;
	idx = moto-1;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return 0;
	}
	return g_tcConfig[idx].driverConfig.readBackSelect;
}

// 
u32 GetDriverTestMode(SpiCs moto)
{
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return 0;
	}
	return g_tcConfig[idx].driverConfig.testMode;
}

//------------------------------------------------------------------------

u32 GetPhases(SpiCs moto)
{
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return 0;
	}

	return g_tcConfig[idx].readStatus.phases;
}

//------------------------------------------------------------------------
u32 GetMStepPos(SpiCs moto)
{
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return 0;
	}

	return g_tcConfig[idx].readStatus.mSteps;
}

//------------------------------------------------------------------------
u32 GetStallGuard(SpiCs moto)
{
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return 0;
	}

	return g_tcConfig[idx].readStatus.stallGuard;
}

//------------------------------------------------------------------------
u32 GetSmartEnergy(SpiCs moto)
{
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return 0;
	}

	return g_tcConfig[idx].readStatus.smartEnergy;
}

//------------------------------------------------------------------------
// 
u32 GetDriverFlag(SpiCs moto)
{
	int idx;
	idx = GetIdxFormCs(moto);
	if (idx < 0)
	{
		return 0;
	}
	return g_tcConfig[idx].readStatus.flags;
}

// 
void DriveDisable(SpiCs moto)
{
	SetChopperEnable(moto, 0);
}

// 
void DriveEnable(SpiCs moto)
{
	SetChopperEnable(moto, 1);
}

//----------------------------------------------------------------------------------------------------------------------------------------------


//------------------------------------------------------------------------

//------------------------------------------------------------------------


void InitTmc260(void)
{
	InitMotorDrivers(SC_MOTO1);
	InitMotorDrivers(SC_MOTO2);
	InitMotorDrivers(SC_MOTO3);
	InitMotorDrivers(SC_MOTO4);
	InitMotorDrivers(SC_MOTO5);
	InitMotorDrivers(SC_MOTO6);
}

//------------------------------------------------------------------------

int GetResConfigFromLvnum(int subd)
{
	switch(subd)
	{
	case 1:		// 1细分
		return MRES1;
	case 2:		// 2细分
		return MRES2;
	case 4:		// 4细分
		return MRES4;
	case 8:		// 8细分
		return MRES8;
	case 16:	// 16细分
		return MRES16;
	case 32:	// 32细分
		return MRES32;
	case 64:	// 64细分
		return MRES64;
	case 128:	// 128细分
		return MRES128;
	case 256:	// 256细分
		return MRES256;
	default:
		return MRES256;
	};
}

#endif


