📄 udisk.c
字号:
/****************************************Copyright (c)**************************************************
** Guangzou ZLG-MCU Development Co., LTD.
** graduate school
** http://www.zlgmcu.com
**
**--------------File Info-------------------------------------------------------------------------------
** File name: udisk.c
** Descriptions: LPC2300系列ARM控制U盘伴侣的串口驱动程序
**
**------------------------------------------------------------------------------------------------------
** Created by: Zhoulishan
** Created date: 2007-04-16
** Version: 1.0
** Descriptions: The original version
**
**------------------------------------------------------------------------------------------------------
** Modified by: Litiantian
** Modified date:
** Version:
** Descriptions: 大大改善代码可读性,并修正若干BUG。
********************************************************************************************************/
#include "config.h"
FileCB CurFileCB = {0xff, 0}; // 当前文件控制块初始化为:当前文件句柄空闲、当前文件大小为0
CONTR_DISK rwdisk; // 声明了一个文件操作的数据结构实体,通过该变量来完成文件的读写、删除操作
/********************************************************************************************************
** 函数名称:SendRequest
** 功能描述:请求帧发送函数
** 输入参数:buff: 待发送字符串的缓存区指针
** len: 待发送字符的长度
** 输出参数:无
**********************************************************************************************************/
void SendRequest(uint8 *buff, uint16 len)
{
uint16 i;
for (i = 0;i < len;i++)
{
while ((U0LSR & 0x20) == 0x00); // 等待字符发送完毕
U0THR = *(buff + i); // 发送一个字符
}
while ((U0LSR & 0x20) == 0x00);
}
/********************************************************************************************************
** 函数名称:ReceOneChar
** 功能描述:处理应答帧
** 输入参数:ReceCharacter: 接收的字符
** 输出参数:无
********************************************************************************************************/
void ReceOneChar(uint8 ReceChar)
{
static uint8 HFBuffer[6]; // 帧控制信息接收缓存,用于存储接收的帧的前6个字节,即帧的控制信息
static uint8 HFNumber = 0; // 帧控制信息接收缓存的位置“指针”
static uint16 DataLen; // 应答帧数据域长度
static uint8 state = 0; // 应答帧处理阶段标志,为0时指示正在处理应答帧的控制信息,为1时指示正在处理应答帧的数据域
/* 判断是否允许通讯,否则直接返回 */
if (rwdisk.state != 0)
{
return; // 不允许通讯,返回
}
/* 根据处理标志,对应答帧进行不同处理 */
switch (state)
{
/* 帧处理阶段1 */
case 0:
/* 将接收的帧控制信息存储到帧控制信息接收缓存 */
HFBuffer[HFNumber] = ReceChar;
HFNumber++;
/* 若接收的是无效帧,则复位HFNumber */
if (HFBuffer[0] != 'S')
{
if ( HFNumber == 2 )
{
if (HFBuffer[1] != ':')
{
HFNumber = 0;
}
}
}
/* 将接收帧的控制信息记录入rwdisk变量 */
if (HFNumber == 6)
{
HFNumber = 0;
/* 记录功能代码和功能代码执行状态信息 */
rwdisk.cmd = HFBuffer[2];
rwdisk.cmds = HFBuffer[3];
/* 记录需读出数据的长度 */
DataLen = HFBuffer[4] + HFBuffer[5]*0x100;
rwdisk.rlen = DataLen;
rwdisk.wlen = 0;
/* 若还要接收应答帧的数据域,进入帧处理阶段2,否则停止通讯,结束帧处理 */
if (DataLen != 0)
{
state = 1;
}
else
{
rwdisk.state = COMMNUNICATION_OFF;
}
}
break;
/* 帧处理阶段2, 接收应答帧数据域 */
case 1:
rwdisk.write_ptr[rwdisk.wlen] = ReceChar;
rwdisk.wlen++;
if (DataLen == rwdisk.wlen)
{
/* 接收数据域完毕,停止通讯,应答帧处理阶段标志复位 */
rwdisk.state = COMMNUNICATION_OFF;
state = 0;
}
break;
default:
break;
}
}
/*********************************************************************************************************
** 函数名称: UART0_Exception
** 功能描述: UART0中断服务程序,在中断里完成应答帧处理
** 输入参数: 无
** 输出参数: 无
********************************************************************************************************/
void __irq UART0_Exception(void)
{
uint8 IIR, temp;
VICIntEnClr |= 1 << UART0_INT;
while (((IIR = U0IIR) & 0x01) == 0) // 有中断发生
{
switch (IIR & 0x0e)
{
case 0x02: // THRE中断
break;
case 0x0c:
case 0x04: // 接收数据可用
ReceOneChar(U0RBR); // 应答帧处理
break; // 处理接收到的数据
case 0x06: // 线状态中断
temp = U0LSR;
break;
default :
break;
}
}
VICIntEnable |= 1 << UART0_INT; // 使能本中断
VICVectAddr = 0;
}
/*********************************************************************************************************
** 函数名称: UART0Init
** 功能描述: 初始化UART0
** 输入参数: bps: 波特率
** 输出参数: 无
********************************************************************************************************/
void UART0Init(uint32 bps)
{
uint16 Fdiv = 0;
PCONP |= 1 << 3; // 使能UART0
PINSEL0 = (0x01 << 4) | (0x01 << 6);// 设置P0.2和P0.3连接到UART0
U0LCR = 0x80; // 允许访问分频因子寄存器
Fdiv = (Fpclk / 16) / bps; // 设置波特率
U0DLM = Fdiv / 256;
U0DLL = Fdiv % 256;
U0LCR = 0x03; // 禁止访问分频因子寄存器, 且设置通讯帧格式为8个数据位, 1个停止位, 无奇偶校验
U0IER = 0x05; // 允许接收中断和线状态中断
U0FCR = 0x07; // 使能接收FIFO长度为1个字节
VICIntEnClr |= 1 << UART0_INT;
VICVectPri6 = 0x05; // 设置串口中断优先级为5
VICVectAddr6 = (uint32)UART0_Exception;
VICIntEnable |= 1 << UART0_INT;
IRQEnable();
}
void FreeFCB(void);
/********************************************************************************************************
** 函数名称:UDiskIni
** 功能描述:操作EasyUDisk功能模块之前需调用的初始化函数
** 输入参数:Baud 初始化使用的波特率
** 输出参数:无
********************************************************************************************************/
void UDiskIni(uint32 baud)
{
FreeFCB(); // 释放文件控制块
rwdisk.state = COMMNUNICATION_OFF; // 禁止主从机通讯
UART0Init(baud); // 串口0初始化
}
/*********************************************************************************************************
** 函数名称: Wait_Ack
** 功能描述: 等待从机处理完毕
** 输入参数: 无
** 输出参数: TRUE: 从机处理完毕
** FALSE: 超时
********************************************************************************************************/
uint8 Wait_Ack(void)
{
uint32 i = 0;
rwdisk.state = COMMNUNICATION_ON;
for (i = 0;i < WAIT_TIME_OUT;i++) // 软件延时等待
{
if (COMMNUNICATION_OFF == rwdisk.state)
{
return (TRUE);
}
}
return (FALSE);
}
/*********************************************************************************************************
** 函数名称: GetSysInfo
** 功能描述: 获取系统信息
** 输入参数: sysinfptr: 系统信息数据块变量的指针
** 输出参数: TRUE: 正常应答返回
** FALSE: 超时出错返回
********************************************************************************************************/
uint8 GetSysInfo(SYSINF *sysinfptr)
{
uint8 reqbuff[6]; // 请求帧缓存,未包括请求帧的数据域
uint8 framedat_rcvbuf[14]; // 应答帧数据域的接收缓存
reqbuff[0] = 'U';
reqbuff[1] = ':';
reqbuff[2] = 0x00;
reqbuff[3] = 0;
reqbuff[4] = 0;
reqbuff[5] = 0;
rwdisk.write_ptr = framedat_rcvbuf; // 设定接收应答帧数据域中数据的接收缓存
/* 发送系统信息查询请求帧 */
SendRequest(reqbuff, 6);
/* 接收返回的系统信息到系统信息接收块 */
if (TRUE == Wait_Ack())
{
if (rwdisk.cmds == 0)
{
sysinfptr->Baud = framedat_rcvbuf[0];
sysinfptr->Year = framedat_rcvbuf[1];
sysinfptr->Month = framedat_rcvbuf[2];
sysinfptr->Dom = framedat_rcvbuf[3];
sysinfptr->Hour = framedat_rcvbuf[4];
sysinfptr->Min = framedat_rcvbuf[5];
sysinfptr->Sec = framedat_rcvbuf[6];
sysinfptr->DiskIn = framedat_rcvbuf[7];
sysinfptr->FH.fh = framedat_rcvbuf[8];
sysinfptr->FH.fsize = framedat_rcvbuf[9]+framedat_rcvbuf[10]*0x100+framedat_rcvbuf[11]*0x10000+framedat_rcvbuf[12]*0x1000000;
sysinfptr->version = framedat_rcvbuf[13];
return (TRUE);
}
}
return (FALSE);
}
/*********************************************************************************************************
** 函数名称: SetUDiskSysInfo
** 功能描述: 设置EasyUDisk的系统信息
** 输入参数: sysinfptr: 系统信息数据块指针
** 输出参数: TRUE: 正常应答返回
** FALSE: 超时出错返回
********************************************************************************************************/
uint8 SetUDiskSysInfo(SYSINF *sysinfptr)
{
uint8 reqbuff[13]; // 请求帧缓存,存储系统信息设置请求帧的全部信息
uint8 framedat_rcvbuf[13]; // 应答帧数据域接收缓存
rwdisk.write_ptr = framedat_rcvbuf; // 设置用于接收应答帧数据域数据的接收缓存
/* 初始化请求帧 */
reqbuff[0] = 'U';
reqbuff[1] = ':';
reqbuff[2] = 0x01;
reqbuff[3] = 0;
reqbuff[4] = 7;
reqbuff[5] = 0;
reqbuff[6] = sysinfptr->Baud ;
reqbuff[7] = sysinfptr->Year ;
reqbuff[8] = sysinfptr->Month;
reqbuff[9] = sysinfptr->Dom;
reqbuff[10] = sysinfptr->Hour;
reqbuff[11] = sysinfptr->Min;
reqbuff[12] = sysinfptr->Sec;
SendRequest(reqbuff, 13);
/* 接收应答帧,若指令执行成功则返回TRUE */
if (Wait_Ack() == TRUE)
{
if (rwdisk.cmds == CMD_SUCCESS)
{
return (TRUE);
}
}
return (FALSE);
}
/*********************************************************************************************************
** 函数名称: MakeDir
** 功能描述: 建立目录
** 输入参数: Path: 绝对路径或相对路径或目录名
** 输出参数: 若接收到应答则返回指令的执行状态;若没有接收到回应, 则返回0xff
********************************************************************************************************/
uint8 MakeDir(char *Path)
{
uint8 reqbuff[6];
uint8 framedat_rcvbuf[6]; // 应答帧数据域接收缓存
uint8 ret;
reqbuff[0] = 'U';
reqbuff[1] = ':';
reqbuff[2] = 0x50;
reqbuff[3] = 0xff;
reqbuff[4] = strlen(Path); // 目录名长度
reqbuff[5] = 0;
/* 发送命令请求帧 */
SendRequest(reqbuff, 6);
SendRequest((uint8*)Path, strlen(Path));
rwdisk.write_ptr = framedat_rcvbuf;
/* 等待应答 */
if (Wait_Ack() == TRUE)
{
ret = rwdisk.cmds;
}
else
{
ret = 0xff;
}
return (ret);
}
/*********************************************************************************************************
** 函数名称: ChangeDirDir
** 功能描述: 设置当前目录
** 输入参数: DirName: 设置目录的路径
** 输出参数: 为0表示正常,
** 非零值为失败
********************************************************************************************************/
uint8 ChangeDir(char *DirName)
{
uint8 reqbuff[6];
uint8 framedat_rcvbuf[6]; // 应答帧数据域接收缓存
uint8 namelen;
uint8 ret;
rwdisk.write_ptr = framedat_rcvbuf;
reqbuff[0] = 'U';
reqbuff[1] = ':';
reqbuff[2] = 0x52;
reqbuff[3] = 0x00;
namelen = strlen(DirName);
reqbuff[4] = namelen;
reqbuff[5] = 0;
SendRequest(reqbuff, 6);
SendRequest((uint8*)DirName, namelen);
if (Wait_Ack() == TRUE)
{
if (rwdisk.cmds == CMD_SUCCESS)
{
ret = 0;
}
else
{
ret = rwdisk.cmds;
}
}
else
{
ret = 0xff; // 设备没响应
}
return (ret);
}
/*********************************************************************************************************
** 函数名称: RemoveDir
** 功能描述: 删除指定的目录
** 输入参数: DirName: 被删除目录的名字或路径
** 输出参数: 为0表示正常删除目录,
** 非零值为删除目录失败
********************************************************************************************************/
uint8 RemoveDir(char *DirName)
{
uint8 reqbuff[6];
uint8 framedat_rcvbuf[6]; // 应答帧数据域接收缓存
uint8 namelen;
uint8 ret;
reqbuff[0] = 'U';
reqbuff[1] = ':';
reqbuff[2] = 0x53;
reqbuff[3] = 0x00;
namelen = strlen(DirName); // 获取文件名字符串长度
reqbuff[4] = namelen;
reqbuff[5] = 0;
SendRequest(reqbuff, 6);
SendRequest((uint8*)DirName, namelen);
rwdisk.write_ptr = framedat_rcvbuf;
if (Wait_Ack() == TRUE) // 等待应答
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -