//总线宽度模式
typedef enum
{
SPIM_BITMODE_STANDARD = 0,//标准单线模式
SPIM_BITMODE_DUAL = 1,//双线模式
SPIM_BITMODE_QUAD = 2,//四线模式
}SPIM_BITMODE;
//功能模式
typedef enum
{
SPIM_FUN_IO = 0, //IO模式
SPIM_FUN_DMA_WRITE = 1, //DMA写模式
SPIM_FUN_DMA_READ = 2, //DMA读模式
SPIM_FUN_DIRECTMAP = 3, //直接内存映射模式
}SPIM_FUN_MODE;
//传输数据宽度定义
typedef enum
{
SPIM_DATA_8BIT = 0x7, //传输数据8bit
SPIM_DATA_16BIT = 0xF, //传输数据16bit
SPIM_DATA_24BIT = 0x17, //传输数据24bit
SPIM_DATA_32BIT = 0x1f, //传输数据32bit
}SPIM_DATA_BIT_WIDTH;
//突发传输事务数量定义
typedef enum
{
SPIM_BURST_NUM_1 = 0, //突发传输1次
SPIM_BURST_NUM_2 = 1, //突发传输2次
SPIM_BURST_NUM_3 = 2, //突发传输3次
SPIM_BURST_NUM_4 = 3, //突发传输4次
}SPIM_BURST_NUMBER;
//设置突发传输数据长度
void SPIM_SetBurstNumber(SPIM_BURST_NUMBER num)
{
SPIM->CTL0 &= ~(0x3 << 13);
SPIM->CTL0 |= (0x3 & num) << 13;
}
//设置传输数据宽度
void SPIM_SetDataBitWidth(SPIM_DATA_BIT_WIDTH width)
{
SPIM->CTL0 &= ~(0x1F << 8);
SPIM->CTL0 |= (0x1F & width) << 8;
}
//设置SPIM功能模式
void SPIM_SetFunMode(SPIM_FUN_MODE mode)
{
SPIM->CTL0 &= ~(0x3 << 22);
SPIM->CTL0 |= (0x3 & mode) << 22;
}
//设置总线宽度模式
void SPIM_SetIoMode(SPIM_BITMODE bitmode)
{
SPIM->CTL0 &= ~(0x3 << 20);
SPIM->CTL0 |= (0x3 & bitmode) << 20;
}
//等待传输完成
bool SPIM_WaitTransferComplete(u32 us)
{
if (us == 0) us = 1;
do
{
if ((SPIM->CTL1 & BIT0) == 0) return TRUE;
us--;
} while (us);
if ((SPIM->CTL1 & BIT0) == 0) return TRUE;
else return FALSE;
}
//发送一个命令,会完整的使能SS并结束SS使能
bool SPIM_SendCmd(u8 cmd)
{
bool status;
SPIM_OUT_EN(TRUE); //输出使能
SPIM_SetIoMode(SPIM_BITMODE_STANDARD); //标准IO模式
SPIM_SetFunMode(SPIM_FUN_IO); //IO读写模式
SPIM_SetDataBitWidth(SPIM_DATA_8BIT); //数据位宽8bit
SPIM_SetBurstNumber(SPIM_BURST_NUM_1); //突发传输1次
SPIM_SET_SS(0);
SPIM->TX[0] = cmd;
SPIM->CTL1 |= BIT0; //开始传输
status = SPIM_WaitTransferComplete(10); //等待传输完成
SPIM_SET_SS(1);
if (status == FALSE)
{
uart_printf("[SPIM]发送命令:0x%02X失败.\r\n", cmd);
}
return status;
}
//设置flash写使能
static bool SPIM_FLASH_WriteEnable(bool isWriteEnable)
{
return SPIM_SendCmd(isWriteEnable?OPCODE_WREN:OPCODE_WRDI);
}
//SPIM标准IO模式写入多个byte数据,不会使能SS
static bool SPIM_IoModeWriteBytes(const u8 *pData, u32 DataLen)
{
u32 Int4Cnt = DataLen / 4; //整数4字节数量
u32 Remainder = DataLen % 4; //不足4字节的余数数量
u32 i,index = 0;
bool status = TRUE;
SPIM_OUT_EN(TRUE); //输出使能
SPIM_SetFunMode(SPIM_FUN_IO); //IO读写模式
SPIM_SetIoMode(SPIM_BITMODE_STANDARD); //标准IO模式
SPIM_SetDataBitWidth(SPIM_DATA_8BIT); //数据位宽8bit
//先写整数4字节数据
if(Int4Cnt)
{
SPIM_SetBurstNumber(SPIM_BURST_NUM_4); //设置突发传输4次
for( i = 0;i < Int4Cnt;i ++)
{
SPIM->TX[0] = pData[index++];
SPIM->TX[1] = pData[index++];
SPIM->TX[2] = pData[index++];
SPIM->TX[3] = pData[index++];
SPIM->CTL1 |= BIT0; //开始传输
status = SPIM_WaitTransferComplete(40); //等待传输完成
if(status == FALSE) goto end_loop;
}
}
if(Remainder) //不足4字节的余数
{
SPIM_SetBurstNumber(SPIM_BURST_NUM_1); //设置突发传输1次
for( i = 0;i < Remainder;i ++)
{
SPIM->TX[0] = pData[index++];
SPIM->CTL1 |= BIT0; //开始传输
status = SPIM_WaitTransferComplete(10); //等待传输完成
if(status == FALSE) goto end_loop;
}
}
end_loop:
if (status == FALSE)
{
uart_printf("[SPIM]SPIM_IoModeWriteBytes:出错.\r\n");
}
return status;
}
|