

#ifndef __TMC260_H__
#define	__TMC260_H__


#include "config.h"
#include "inout.h"

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

// 寄存器和位定义

// 寄存器共5个, 每个20个位

// 地址
#define	CFR			0x80000
#define	CFRSEL1		0x40000
#define	CFRSEL0		0x20000

#define	DRVCTRL0	0				// 当 SDOFF == 0 时
#define	DRVCTRL1	0				// 当 SDOFF == 1 时
#define	CHOPCONF	(CFR)
#define	SMARTEN		(CFR|CFRSEL0)
#define	SGCSCONF	(CFR|CFRSEL1)
#define	DRVCONF		(CFR|CFRSEL1|CFRSEL0)

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

// SPI方式控制寄存器
// sdoff == 1 DRVCTRL 配置 spi方式

#ifdef DRVCTRL1

// SPI 控制配置
typedef struct
{
  	u32 polarityA;		// A相电流方向; 0, 电流从OA1管脚到OA2管脚; 1, 电流从OA2管脚到OA1管脚
	u32 currentA;		// 电流流过线圈A的大小。范围为0至248，如果滞后或偏移完全使用。 施加滞后或偏移后的结果值不能超过255。

  	u32 polarityB;		// B电流方向; 0, 电流从OB1管脚到OB2管脚; 1, 电流从OB2管脚到OB1管脚
	u32 currentB;		// 电流流过线圈B的大小。范围为0至248，如果滞后或偏移完全使用。 施加滞后或偏移后的结果值不能超过255。

}TSpiCtrlConfig;

#define	PHA			0x20000
#define	CA			0x1FE00
#define	PHB			0x00100
#define	CB			0x000FF

#endif






#endif




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

// 脉冲+方向控制方式 控制寄存器

// sdoff == 0 DRVCTRL 配置为 step dir 方式

#ifdef DRVCTRL0

typedef struct
{
  	u32 intpol;	// 倍频功能
  	u32 dEdge;	// 双边沿脉冲
  	u32 mRes;	// 微步距配置
}TStepDirConfig;

#define	INTPOL		0x00200		// 使能输出脉冲的16倍频功能

#define	DEDGE		0x00100		// 使能双边沿脉冲，可以减少对步进频率的要求

#define	MRES1		0x00008		// 1细分
#define	MRES2		0x00007		// 2细分
#define	MRES4		0x00006		// 4细分
#define	MRES8		0x00005		// 8细分
#define	MRES16		0x00004		// 16细分
#define	MRES32		0x00003		// 32细分
#define	MRES64		0x00002		// 64细分
#define	MRES128		0x00001		// 128细分
#define	MRES256		0x00000		// 256细分

#define	MRES		0x0000F		// 只有最低4位有效

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

// 斩波寄存器
#ifdef CHOPCONF

typedef struct
{
	u32 blankTime;			// 比较器空白时间选择; 00：空白时间为 16 个时钟周期; 01：空白时间为 24 个时钟周期; 10：空白时间为 36 个时钟周期; 11：空白时间为 54 个时钟周期;
	u32 chopperMode;		// 斩波模式; 0：标准模式 1：Toff 为常数的快衰减模式
	u32 randomTOff;			// 随机 TOFF 时间: 0：斩波时间固定 1：斩波时间可调
	u32 hysteresisDecay;	// chopperMode==0时, 衰减周期设置; 00：16 个时钟周期; 01：32 个时钟周期; 10：48 个时钟周期; 11：64 个时钟周期;
							// chopperMode==1时, FDMODE 设置; bit0==1: 禁止电流比较器作为快衰减的终止; bit1:快衰减的时间最高位设置
	u32 hysteresisEnd;		// chopperMode==0时, 衰减低位值; 0--15 对应衰减值为 -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 9, 10, 11, 12
							// chopperMode==1时, 正弦波偏置
	u32 hysteresisStart;	// chopperMode==0时, 衰减开始值, 衰减设置 0--7：hysteresisEnd 增加 1 -- 8
							// chopperMode==1时, 快衰时间设置,  时间 = (((hysteresisDecay&0x02) << 2) | (hysteresisStart&0x07)) * 32 个时钟周期
	u32 tOff;				// 缓慢衰变阶段的持续时间; 1, TBL(blankTime) 最小 24 个时钟周期; 2--15, 使用公式 12 + (32 x tOffAndDisable) 最小 64 个时钟周期。
	u32 enable;				// mosfet输出允许 == 0, 禁止驱动输出; = 1, 允许驱动输出

}TChopperConfig;


#define	TBL			0x18000		// 2个位

#define	CHM			0x04000
#define	RNDTF		0x02000
#define	HDEC		0x01800		// 2个位
#define	HEND		0x00780		// 4个位
#define HSTRT		0x00070		// 3个位
#define	TOFF		0x0000F		// 4个位

#define	DRIVE_OFF	0
#define	DRIVE_ON	1


#endif


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

// 智能输出寄存器 (coolStep 配置)

#ifdef SMARTEN

typedef struct
{
	u32 smartIMin;			// 智能控制最小电流; = 0，1/2设定电流; = 1, 1/4设定电流
	u32 smartDownStep;		// 电流减小速度; 00：每 32 个负载衰减值电流减小一个单位; 01：每 8 个负载衰减值电流减小一个单位; 10：每 2 个负载衰减值电流减小一个单位; 11：每1个负载衰减值电流减小一个单位
	u32 smartStallLevelMax;	// 最小电流控制时负载的衰减值; 如果负载检测值>=(SEMIN+SEMAX+1)*32 电机电流回到安全值。 设定范围 0--15
	u32 smartUpStep;		// 电流上升幅度; 00: 每 1 个负载测量值电流上升一个单位; 01: 每 2 个负载测量值电流上升一个单位; 00: 每 4 个负载测量值电流上升一个单位; 00: 每 8 个负载测量值电流上升一个单位;
	u32 smartStallLevelMin;	// 智能电流控制的最小负载检测值和电流使能; 如果负载检测值 < SEMIN*32，电机电流减小负载转动角度将增加; 0：禁止电流控制; 1--15 负载检测值
}TSmartEnergyControl;

#define	SEIMIN		0x08000

#define	SEND		0x06000		// 2个位
#define	SEMAX		0x00F00		// 4个位
#define	SEUP		0x00060		// 2个位
#define	SEMIN		0x0000F		// 4个位

#endif


//------------------------------------------------------------
// 失速保护和电流设定寄存器

#ifdef SGCSCONF

typedef struct
{
	u32 filterEnable;			// 使能失速检测滤波; 0, 标准模式, 最快反应时间; 1, 过滤模式，每四步完成一次更新，以补偿电机结构的变化，最高精度;
	s32 stallGuardThreshold;	// 失速检测阀值设定，数值越低, 灵敏度越高, 失速时的转矩越低; 有符号数, 设置范围为-64 -- +63 一般设置为0，不建议设置低于-10
	u32 currentScale;			// 电流缩放比例，设定值 0--31 对应 1/32 -- 32/32. 例如 CS = 0, 电流是 1/32。

}TStallGuardConfig;


#define	SFILT		0x10000
#define	SGT			0x07F00		// 7个位
#define	CS			0x0001F		// 5个位



#endif



//------------------------------------------------------------
// 驱动芯片配置寄存器

#ifdef DRVCONF

typedef struct
{
  	u32 testMode;				// 为测试模式保留; 一般设置为 0。当此位变成 1 时，SG_TST 输出数字测试值, TEST_ANA 输出模拟测试值，通过 SGT1 和 SGT0 进行设置
  	u32 slopeHighSide;			// 高端上升沿控制; 00：最小值; 01：最小值+tc; 10：中间值+tc 11：最大值; 在温度补偿模式下，这里的设定值作为驱动强度的一个补偿。
  	u32 slopeLowSide;			// 低端上升沿控制; 00和01：最小值; 10：中间值; 11：最大值
  	u32 protectionDisable;		// 短路保护关闭; 0, 使能; 1, 关闭
  	u32 protectionTimer;		// 短路检测定时器; 00：3.2us，01：1.6us，10：1.2us，0.8us
  	u32 stepDirDisable;			// 脉冲和方向模式输入关闭; 0：使能脉冲和方向模式，1：使能 SPI 模式（关闭脉冲和方向模式）
  	u32 vSenseScale;			// 电流设定的采样电阻值边界; 0：采样电压值最大量程 305mV; 1:采样电压值最大量程 165mV. (满量程是指当前设置为31，DAC值为255)
  	u32 readBackSelect;			// 读出输出位选择, 00：返回微步位置，01：返回负载值，10：读回负载值和智能电流级别，11：保留，未使用
}TDriverConfig;

#define	TST			0x10000
#define	SLPH		0x0C000
#define	SLPL		0x03000

#define	DISS2G		0x00400
#define	TS2G		0x00300
#define	SDOFF		0x00080
#define	VSENSE		0x00040
#define	RDSEL		0x00030

#endif

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

// 读取信息寄存器
typedef struct
{
	u32 phases;			// 极性: 0：电流从OA1引脚流向OA2引脚。1：电流从OA2引脚流向OA1引脚。
	u32 mSteps;			// 微步数，STEP/DIR模式下线圈A的正弦表中的微步位置。
	u32 stallGuard;		// 失速检测值
	u32 smartEnergy;	// 电流值
	u32 flags;			// 输出标志

}TReadStatus;


#define	MSTEP		0xFFC00
#define	SG			0xFFC00
#define	SE			0x03C00


// flags 定义
#define	ST_STST		0x0080		// 步进保持指示， 1：指示在最近 2^20 次方时钟周期内没有步进脉冲
#define	ST_OLB		0x0040		// 绕组B 开负载指示，无斩波动作时设置为 1， 当有一个最大电流的1/16 通过绕组时，被清零
#define	ST_OLA		0x0020		// 绕组A 开负载指示，无斩波动作时设置为 1， 当有一个最大电流的1/16 通过绕组时，被清零
#define	ST_S2GB		0x0010		// 绕组B 短路指示, 短路发生后，斩波终止，短路计数器加一，当发生 3 次时，需要复位启动驱动器
#define	ST_S2GA		0x0008		// 绕组A 短路指示, 短路发生后，斩波终止，短路计数器加一，当发生 3 次时，需要复位启动驱动器
#define	ST_OTPW		0x0004		// 过温预保护，1：执行保护阀值
#define	ST_OT		0x0002		// 过温标志, 1：驱动器因过温而保护
#define	ST_SG		0x0001		// 过载状态，1：超过负载阀值，SG 输出高电平


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


#ifndef TMC260_DRV_NUM
#define	TMC260_DRV_NUM		0
#endif

#if (TMC260_DRV_NUM	> 6)
#unfine	TMC260_DRV_NUM
#define	TMC260_DRV_NUM		6
#endif

#if (TMC260_DRV_NUM	< 0)
#unfine	TMC260_DRV_NUM
#define	TMC260_DRV_NUM		0
#endif

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

typedef enum
{
	SC_MOTO1=1,
	SC_MOTO2,
	SC_MOTO3,
	SC_MOTO4,
	SC_MOTO5,
	SC_MOTO6,
}SpiCs;

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

void WriteStepDirConfig(SpiCs moto);
void WriteSpiCtrlConfig(SpiCs moto);
void WriteChopperConfig(SpiCs moto);
void WriteStallGuardConfig(SpiCs moto);
void WriteSmartEnergyConfig(SpiCs moto);
void WriteDriverConfig(SpiCs moto);
void ReadDriverState(SpiCs moto);

void InitMotorDrivers(SpiCs moto);

void SetStepDirMStepRes(SpiCs moto, u32 microstepResolution);
void SetStepDirInterpolation(SpiCs moto, u32 interpolation);
void SetStepDirDoubleEdge(SpiCs moto, u32 doubleEdge);
u32 GetStepDirMStepRes(SpiCs moto);
u32 GetStepDirInterpolation(SpiCs moto);
u32 GetStepDirDoubleEdge(SpiCs moto);
void SetChopperBlankTime(SpiCs moto, u32 blankTime);
void SetChopperMode(SpiCs moto, u32 mode);
void SetChopperRandomTOff(SpiCs moto, u32 randomTOff);
void SetChopperHysteresisDecay(SpiCs moto, u32 hysteresisDecay);
void SetChopperHysteresisEnd(SpiCs moto, u32 hysteresisEnd);
void SetChopperHysteresisStart(SpiCs moto, u32 hysteresisStart);
void SetChopperTOff(SpiCs moto, u32 tOff);
u32 GetChopperBlankTime(SpiCs moto);
u32 GetChopperMode(SpiCs moto);
u32 GetChopperRandomTOff(SpiCs moto);
u32 GetChopperHysteresisDecay(SpiCs moto);
u32 GetChopperHysteresisEnd(SpiCs moto);
u32 GetChopperHysteresisStart(SpiCs moto);
u32 GetChopperTOff(SpiCs moto);
void SetSmartEnergyIMin(SpiCs moto, u32 smartIMin);
void SetSmartEnergyDownStep(SpiCs moto, u32 smartDownStep);
void SetSmartEnergyStallLevelMax(SpiCs moto, u32 stallLevelMax);
void SetSmartEnergyUpStep(SpiCs moto, u32 smartUpStep);
void SetSmartEnergyStallLevelMin(SpiCs moto, u32 stallLevelMin);
u32 GetSmartEnergyIMin(SpiCs moto);
u32 GetSmartEnergyDownStep(SpiCs moto);
u32 GetSmartEnergyStallLevelMax(SpiCs moto);
u32 GetSmartEnergyUpStep(SpiCs moto);
u32 GetSmartEnergyStallLevelMin(SpiCs moto);
void SetStallGuardFilter(SpiCs moto, u32 enable);
void SetStallGuardThreshold(SpiCs moto, s32 threshold);
void SetStallGuardCurrentScale(SpiCs moto, u32 currentScale);
u32 GetStallGuardFilter(SpiCs moto);
s32 GetStallGuardThreshold(SpiCs moto);
u32 GetStallGuardCurrentScale(SpiCs moto);
void SetDriverSlopeHighSide(SpiCs moto, u32 slopeHighSide);
void SetDriverSlopeLowSide(SpiCs moto, u32 slopeLowSide);
void SetDriverDisableProtection(SpiCs moto, u32 disableProtection);
void SetDriverProtectionTimer(SpiCs moto, u32 protectionTimer);
void SetDriverStepDirectionOff(SpiCs moto, u32 sDOff);
void SetDriverVSenseScale(SpiCs moto, u32 scale);
void SetDriverReadSelect(SpiCs moto, u32 readSelect);
void SetDriverTestMode(SpiCs moto, u32 testMode);
u32 GetDriverSlopeHighSide(SpiCs moto);
u32 GetDriverSlopeLowSide(SpiCs moto);
u32 GetDriverDisableProtection(SpiCs moto);
u32 GetDriverProtectionTimer(SpiCs moto);
u32 GetDriverStepDirectionOff(SpiCs moto);
u32 GetDriverVSenseScale(SpiCs moto);
u32 GetDriverReadSelect(SpiCs moto);
u32 GetDriverTestMode(SpiCs moto);

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

u32 GetPhases(SpiCs moto);
u32 GetMStepPos(SpiCs moto);
u32 GetStallGuard(SpiCs moto);
u32 GetSmartEnergy(SpiCs moto);
u32 GetDriverFlag(SpiCs moto);

void DriveDisable(SpiCs moto);
void DriveEnable(SpiCs moto);

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

void InitTmc260(void);

void SetAsDriver(void);

int GetResConfigFromLvnum(int subd);

#endif


