#include "includes.h"
#include "KungFu8_SPI.h"

/********************************************************************************************
*								SPI
*

*
**********************************************************************************************/



/***********************************************************************************
 * 函数名     	：SPI_SendData
 * 函数功能	：SPI发送单个字节数据 （主模式）
 * 入口参数	：待发送的单字节数据Data
 * 返回         ：
 *
 * SPI发送单个字节数据
 **********************************************************************************/
void SPI_SendData(uint8 Sendbyte)
{
//	uint8 RecVar;
	P2LR4=0;
	// 清除收溢出信号，写是主动行为，正常逻辑不会写失败
	SSCI1OV=0;
	// 清除可能的写失败信息，写冲突标志位清零
	SSCI1WCFL=0;

//	// 历史读取并 送数据到发送缓存区并硬件启动脉冲发送
////：：	RecVar = SSCI1BUFR;  // 该语句因RecVar无实际作用会被优化，因此不需要同步接收值进行为了状态更新进行嵌汇编的读取
//	BANKSEL_Read_SDI();
//	Read_NoUse_SDI();	// 建立在前面操作对象与SSCIBUFR在一个区的直接嵌汇编读取

	SSCI1BUFR=Sendbyte;
	// 等待发送完毕中断信号
	while(!SSCI1IF);
	SSCI1IF=0;
//	RecVar = SSCI1BUFR; // 无效语句被优化的不能读取会影响后续的接收
	BANKSEL_Read_SDI();
	Read_NoUse_SDI();   // 嵌汇编的读取语句
	P2LR4=0;

}

/***********************************************************************************
 * 函数名     	：SPI_ReceiveData
 * 函数功能	：SPI接收单个字节数据（主模式）
 * 入口参数	：无
 * 返回         ：
 * SPI接收单个字节数据
 **********************************************************************************/
uint8 SPI_ReceiveData(void)
{
	// 清除收溢出信号，写是主动行为，正常逻辑不会写失败
	SSCI1OV=0;
	// 清除可能的写失败信息
	SSCI1WCFL=0;

//	// 历史读取
//	BANKSEL_Read_SDI();
//	Read_NoUse_SDI();	// 建立在前面操作对象与SSCIBUFR在一个区的直接签汇编读取

	// 送数据到发送缓存区并硬件启动脉冲发送
	SSCI1BUFR=0x00;
	// 等待发送完毕的中断信号到来
	while(!SSCI1IF);
	SSCI1IF=0;

	return (SSCI1BUFR);  // 实现的是读取  ->R0
}

/***********************************************************************************
 * 函数名     	：SPI_SendAndReceive_Data
 * 函数功能	：SPI发送并接收单个字节数据（主模式）
 * 入口参数	：待发送的单字节数据Sendbyte
 * 返回         ：RecVar 	返回接收的单字节数据
 *
 * SPI发送并接收单个字节数据
 **********************************************************************************/
uint8 SPI_SendAndReceive_Data(uint8 Sendbyte)
{
volatile	uint8 RecVar=Sendbyte;
	// 清除收溢出信号，写是主动行为，正常逻辑不会写失败
	SSCI1OV=0;
	// 清除可能的写失败信息
	SSCI1WCFL=0;

	//	// 历史读取
	//	BANKSEL_Read_SDI();
	//	Read_NoUse_SDI();	// 建立在前面操作对象与SSCIBUFR在一个区的直接签汇编读取

	// 送数据到发送缓存区并硬件启动脉冲发送
	SSCI1BUFR=RecVar;              // 注：变量中转，避免优化的发送被提前到SSCIOV=0和SSCIWCFL=0;之前运行的非设计顺序
	// 等待发送完毕的中断信号到来
	while(!SSCI1IF);
	SSCI1IF=0;

	return (SSCI1BUFR);  // 实现的是读取  ->R0
}

/***********************************************************************************
 * 函数名     	：SPI_Mode_Configuration  主机配置
 * 函数功能	：设置SPI模式
 * 入口参数	：无
 * 返回         ：无
 * 主控模式采用3/4线：SCK,SDI,SDO,SS
 **********************************************************************************/
void SPI_Master_Mode_Configuration(void)
{
	//关闭SPI模块，初始化完之后再打开
	SSCI1EN=0;
	// SPI功能引脚配置对应数字输入或输出


//    APFCTL6=0X13;   //SDO1:P70;   SCK1:P72
//    APFCTL7=0X14;   //SS1:P33     SDI1:P71
//	// 根据配置进行对应引脚的输入输出的数字配置，SS仅为从机的功能引脚，主机控制从机需主动io控制，
//	ANS2&=0xF0;	 // P20 P21 P22
//	P1LR&=0xFC;  // 输出脚初始默认电平
//	TR1&=0xF4;   // TR20 TR21 输出 (SCK SDO)
//	TR22=1;		 // TR22(SDI)

	APFCTL10 &= 0x03;
    APFCTL10 |= 0xF4;   //SDO1:P24   SCK1:P72  SS1:P17     SDI1:P71
	// 根据配置进行对应引脚的输入输出的数字配置，SS1仅为从机的功能引脚，主机控制从机需主动io控制，
    P7LR =0;	//必要，否则可能会导致信息右移一位。
	ANS7=0xF0;	//数字输出口
	ANS24=0;	ANS17=0;
	TR24=0;     //SDO TRxx清0
	TR72=0;     //SCK TRxx主动模式清0
	TR71=1;     //SDI TRxx置1
	TR17=0;     //SS  TRxx置1


	// 配置极性 采样点 发送沿
	SAMPLE1=0;			//SPI数据输入采样相位

	// 配置空闲电平极性 0x00低 0x10高   |  选择主机工作及时钟或配置从机模式     默认高位进行 清零写错误 或溢出错误，即 SSCIWCFL  和   SSCIOV  并此时不使能
	SSCI1CTL0	=  0x00 |	SPI_Master_Mode_SCLK_Div64;		//16m:250k
	CKEGE1=0;		 	//SPI数据输出沿,时钟空闲电平SSCI1CKP先配置


	// 使能模块
	SSCI1EN=1;	//同步串行端口使能

	//中断配置,主机不需要使用中断(逻辑更加复杂),从机一般使用中断,慢速设计也可以软件查询，从机支持唤醒
	SSCI1IE=0;//关闭SPI中断
	SSCI1IF=0;
}
/***********************************************************************************
 * 函数名     	：SPI_Mode_Configuration  从机配置
 * 函数功能	：设置SPI模式
 * 入口参数	：无
 * 返回         ：无
 * 主控模式采用3/4线：SCK,SDI,SDO,SS
 **********************************************************************************/
void SPI_Slave_Mode_Configuration(void)
{
	//关闭SPI模块，初始化完之后再打开
	SSCI1EN=0;

	APFCTL10 &= 0x03;
    APFCTL10 |= 0xF4;   //SDO1:P24   SCK1:P72  SS1:P17     SDI1:P71

    ANS24=0;	ANS72=0;	ANS17=0;	ANS71=0;
    // SS1，同步从动模式下需要配置

	TR24=0;		//SDO TRxx清零
	TR72=1;		//SCK TRxx从动模式置1
	TR71=1;		//SDI TRxx置1
	TR17=1;		//SS  TRxx置1


	// 配置极性 采样点 发送沿
	SAMPLE1=0;			//SPI数据输出时间中间采样输入数据(下一波数据)，SPI从动模式必须为0

	//  配置空闲电平极性   | 选择主机工作及时钟或配置从机模式     高位进行 清零写错误 或溢出错误，即 SSCIWCFL  和   SSCIOV
	SSCI1CTL0	=	 0x00 | SPI_Slave_Mode_SCK_SS ;  // SPI_Slave_Mode_SCK SPI_Slave_Mode_SCK_SS
	CKEGE1=0;		 	//SPI数据输出沿

	// 使能模块
	SSCI1EN=1;	//同步串行端口使能
	SSCI1BUFR=0x55; //  仅样例的应答，默认或0均可，即值不限，先有主机发起命令
	//中断配置,主机不需要使用中断(逻辑更加复杂),从机一般使用中断,慢速设计也可以软件查询，从机支持唤醒
	PSSCI1=1;    //高优先级配置
	SSCI1IF=0;
	SSCI1IE=1;
}


