请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
器件型号:TMS320F28377S Thread 中讨论的其他器件: controlSUITE、 C2000WARE
我使用的是 Launchpad XL TMS320F28377S 板。 晶振频率为10.00MHz。 我将修改 USB 主机 MSC 示例、将 UART 代码放入其中。 但这不起作用。 我认为这是一个时钟问题、因为数据被传输、但 数据在 PC 软件(Docklight)上是无用的、这通常是由于波特率不匹配而发生的。 因此、请查看此代码并帮助我解决问题。 硬件经过良好测试、TTL 到 USB 转换器工作正常。
//######################################################################################################################
//
//文件:USB_host_msc.c
//
标题:USB Host MSC 示例的主例程。
//
//##########################################################################################################################
//$TI 发行版:F2837xS 支持库 V210 $//
$发行 日期:星期二11月1日15:35:23 CDT 2016 $//
版权所有:版权所有(C) 2014-2016德州仪器(TI)公司-//
http://www.ti.com/ 保留所有权利$
//############################################################################################################
//
//包含的文件
//
#include "F28x_Project.h"
#include
#include
#include
include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "inc/hw_ints.h"
#include "driverlib/interrupt.h"
#include "driverlib/sysclib.h"
#include "driverlib/sysblib.h"
#include "driverlib/usb.usb.usb.usb/include
"usb.usb.usb.usb/usb.usb"
#include "usb.usb.usb.us.us.us.usb.us.us.us.us.us.us.usb.mdio"#include "#include "#include "usb.usb.us.usb.us.us.us.usb.us.us.us.us.us"#include "#include "usb.usb.us.usb.us.us.us.us.us.us.usb.us.us.us.us.us.us.us.us.usb.us.us.us.us.us.us.us.
//
//! addtogroup cpu01_example_list
//! USB 海量存储类主机(USB_host_msc)
//!
//! 此示例应用演示了如何从 USB 海量
//! 存储类设备。 它使用 FatFs,一种 FAT 文件系统驱动程序。 IT
//! 通过 UART 提供一个简单的命令控制台、用于发出查看
//! 并在大容量存储设备上导航文件系统。
//!
//! 第一个 UART 连接到
//!上的 FTDI 虚拟串行端口 controlCARD 板、配置为每秒115、200位、以及8-N-1
//! 模式。 程序启动后,将向
//! 终端。 键入``help ''可获得命令帮助。
//!
//! 加载并运行示例后、使用
//! 以上设置可打开命令提示符。 然后连接 USB MSC 设备
//! 连接到 controlCARD 顶部的 microUSB 端口。
//!
//! 有关 FatFs 的更多详细信息,请参阅以下站点:
//! elm-chan.org/.../00index_e.html
///*********
//
//
//定义保存路径的缓冲区的大小,或
来自//存储卡的临时数据的大小。 分配了两个具有此大小的缓冲区。 缓冲
区//大小必须足够大,以容纳预期的最长完整路径名,
//包括文件名和尾随的空字符。
////
*****************
#define PATH_BUF_SIZE 80
//*********
//
//定义保存命令行的缓冲区的大小。
////
*****************
#define CMD_BUF_SIZE 64
//*********
//
//此缓冲区保存到当前工作目录的完整路径。 最初
//它是根("/")。
////
*****************
静态 char g_cCwdBuf[path_BUF_size]="/";
//*********
//
//操作文件路径或从
存储卡读取数据时使用的临时数据缓冲区//。
////
*****************
静态 char g_cTmpBuf[path_BUF_size];
//*********
//
//保存命令行的缓冲区。
////
*****************
静态 char g_cCmdbuf[CMD_BUF_SIZE];
//*********
//
//当前 FAT FS 状态。
////
*****************
静态 FATFS g_sFatFs;
静态 DIR g_sDirObject;
静态 FILINFO g_sFileInfo;
静态 FIL g_sFileObject;
//*********
//
//保持 FRESULT 数字代码、
//和字符串表示之间映射的结构。 从 FatFs
// FAT 文件系统驱动程序返回 FRESULT 代码。
////
*****************
typedef 结构
{
FRESULT 结果;
char * pcResultStr;
}
tFresultString;
//*************
//
//一个宏,可以轻松地将结果代码添加到表中。
////
*****************
#define FRESULT_Entry (f) {(f)、(#f)}
//*********
//
//保存数字 FRESULT 代码与
//它的名称作为字符串之间映射的表。 这用于查找
//打印到控制台的错误代码。
////
*****************
tFresultString g_sFresultStrings[]=
{
FRESULT_Entry (FR_OK)、
FRESULT_Entry (FR_NOT _READY)、
FRESULT_Entry (FR_NO_FILE)、
FRESULT_Entry (FR_NO_PATH)、
FRESULT_Entry (FR_INVALID_NAME)、
FRESULT_Entry (FR_INVALID_DRIVE)、
FRESULT_Entry (FR_Denied)、
FRESULT_Entry (FR_Exists)、
FRESULT_Entry (FR_RW_ERROR)、
FRESULT_Entry (FR_WRITE_PROTECTED)、
FRESULT_Entry (FR_NOT _ENABLED)、
FRESULT_Entry (FR_NO_filesystem)、
FRESULT_Entry (FR_INVALID_OBJECT)、
FRESULT_Entry (FR_mkfs_aborted)
};
//*********
//
//保存结果代码数的宏。
////
*****************
#define NUM_FRESULT_CODES (sizeof (g_sFresultStrings)/ sizeof (tFresultString))
//*********
//
//主机控制器内存池的大小(以字节为单位)。
////
*****************
#define HCD_MEMORY_SIZE 128
//*************
//
//提供给主机控制器驱动程序的内存池。
////
*****************
uint8_t g_pHCPool [hcd_memory_size];
//*********
//
// MSC 驱动程序的实例数据。
////
*****************
tUSBHMSCInstance * g_psMSCInstance = 0;
//*********
//
//声明 USB 事件驱动程序接口。
////
*****************
Declate_event_driver (g_sUSBEventDriver、0、0、USBHCEDents);
//***************
//
//包含应用程序中使用的所有主机驱动程序的全局变量。
//在本例中,仅加载 MSC 类。
////
*****************
静态 tUSBHostClassDriver const * const g_ppHostClassDriver[]=
{
&g_sUSBHostMSCClassDriver、
&g_sUSBEventDriver
};
//*********
//
//此全局变量保存 g_ppHostClassDrivers
//列表中的类驱动程序数。
////
*****************
#define NUM_CLASS_DRIVERS (sizeof (g_ppHostClassDrivers)/ \
sizeof (g_ppHostClassDrivers[0])
//*************
//
//保持应用程序的当前状态。
////
*****************
typedef 枚举
{
//
//不存在设备。
//
State_no_device、
//
//正在枚举大容量存储设备。
//
State_device_enum、
//
//大容量存储设备就绪。
//
State_DEVICE_READY、
//
//连接了不受支持的设备。
//
State_unknown_device、
//
//发生电源故障。
//
State_POWER_FAULT
}
tState;
volatile tState g_Estate;
volatile tState g_eUIState;
//*********
//
//当前 USB 操作模式-主机、设备或未知。
////
*****************
tUSBMode g_eCurrentUSBMode;
//*********
//
//如果驱动程序库遇到错误,则调用的错误例程。
////
*****************
#ifdef debug
void
__error__(char *pcFilename,unsigned long ulLine)
{
}
#endif
//*************
//
// USB 模式回调
//
//\param ulIndex 是 USB 控制器的基于零的索引,组成
// 回调。
//\param eMode 表示新的操作模式。
//
//每当 OTG 模式发生更改
时,USB 库就会调用此函数//如果已建立连接,则会通知我们
是要//作为主机还是设备运行。
//
//\返回无。
////
*****************
void
modeCallback (unsigned long ulIndex、tUSBMode eMode)
{
//
//保存新模式。
//
G_eCurrentUSBMode = eMode;
}
//*********
//
//此函数返回错误代码的字符串表示,该错误代码是
//从对 FatFs 的函数调用返回的。 它可用于打印人工
//可读错误消息。
////
*****************
const char *
StringFromFresult (FRESULT fresult)
{
unsigned int uIdx;
//
//输入循环,在错误代码表中搜索匹配的错误代码。
//
对于(uIdx = 0;uIdx < NUM_FRESULT_CODES;uIdx++)
{
//
//如果找到匹配项,则返回错误代码的字符串名称。
//
if (g_sFresultStrings[uIdx].fresult=fresult)
{
return (g_sFresultStrings[uIdx].pcResultStr);
}
}
//
//此时未找到匹配的代码,因此返回一个字符串,指示
//未知错误。
//
return ("未知错误代码");
}
//*********
//
//此函数实现"ls"命令。 它打开当前目录
//并枚举内容,并为它
//找到的每个项目打印一行。 它显示文件属性、时间和日期、
//文件大小以及名称等详细信息。 它显示末
尾的文件大小摘要//以及可用空间。
////
*****************
int
Cmd_ls (int argc、char * argv[])
{
无符号超长整型 TotalSize;
unsigned long ulFileCount;
unsigned long ulDirCount;
FRESULT 结果;
FATFS * pFatFs;
//
//如果未连接驱动器,请勿尝试执行任何操作。
//
if (g_Estate!= State_device_ready)
{
return (FR_NOT _READY);
}
//
//打开当前目录进行访问。
//
fresult = f_opendir (&g_sDirObject、g_cCwdBuf);
//
//检查错误,如果有问题,则返回。
//
if (fresult!= FR_OK)
{
return (fresult);
}
ulTotalSize = 0;
ulFileCount = 0;
ulDirCount = 0;
//
//输入循环以枚举所有目录条目。
//
while (1)
{
//
//从目录中读取条目。
//
fresult = f_readdir (&g_sDirObject、&g_sFileInfo);
//
//检查错误,如果有问题,则返回。
//
if (fresult!= FR_OK)
{
return (fresult);
}
//
//如果文件名为空,则这是列表的末尾。
//
if (!g_sFileInfo.fname[0])
{
中断;
}
//
//如果属性是目录,则增加目录计数。
//
if (g_sFileInfo.fattrib 和 am_DIR)
{
ulDirCount++;
}
//
//否则,它是一个文件。 递增文件计数、并添加
//将文件大小设置为总计。
//
其他
{
ulFileCount++;
ulTotalSize += g_sFileInfo.fsize;
}
//
//将条目信息打印在一行上,并显示格式
//属性、日期、时间、大小和名称。
//
UARTprintf ("%c%c%c%c%c %u/%02u/%02u %02u:%02u %9U %s\n"、
(G_sFileInfo.fattrib & AM_DIR)? (uint32_t)'D':(uint32_t)'-'、
(G_sFileInfo.fattrib 和 AM_RDO)? (uint32_t)'R':(uint32_t)'-'、
(G_sFileInfo.fattrib 和 AM_HID)? (uint32_t)'h':(uint32_t)'-'、
(G_sFileInfo.fattrib 和 AM_SYS)? (uint32_t)'s':(uint32_t)'-'、
(G_sFileInfo.fattrib & AM_ARC)? (uint32_t)'a':(uint32_t)'-'、
(uint32_t)((g_sFileInfo.fdate >> 9)+ 1980)、
(uint32_t)((g_sFileInfo.fdate >> 5)和15)、
(uint32_t)(g_t_filt32_t
)(uint32_t)
(uint32_t)(uint32_t)、
(uint32_t)(uint32_t)(uint32_t)(uint32_t)、(uFileInfo.t)(uint32_t)(uint32_t)、(uint32_t (uint32_t)(uinteg_t)(uinteg_t)、(
g_sFileInfo.fname);
}
//
//打印显示文件、目录和大小总计的摘要行。
//
UARTprintf ("\n%4U 文件、总共%10U 字节\n%4U 目录"、
ulFileCount、ulTotalSize、ulDirCount);
//
//获得可用空间。
//
fresult=f_getfree("/",&ulTotalSize,&pFatFs);
//
//检查错误,如果有问题,则返回。
//
if (fresult!= FR_OK)
{
return (fresult);
}
//
//显示计算出的可用空间量。
//
UARTprintf ("、%10uK 字节空闲\n"、ulTotalSize * pFatFs->ischions_clust / 2);
//
//将其添加到这里,返回时没有错误。
//
退货(0);
}
//*********
//
//此函数实现“CD”命令。 它采用
//指定目录的参数来创建当前工作目录。 路径
//分隔符必须使用正斜杠"/"。 CD 的参数可以是
//以下之一:
//
////* root ("/")
//*完全指定的路径("/my/path/to/mydir)
//*当前目录("mydir")中的单个目录名
//*父目录("..")
//
////它不了解相对路径,所以不要尝试这样的操作:
//("../my/new/path)
//
//指定新目录后,它会尝试打开该目录//
确保它存在。 如果新路径已成功打开,则
//当前工作目录(cwd)将更改为新路径。
////
*****************
int
Cmd_cd (int argc、char * argv[])
{
unsigned int uIdx;
FRESULT 结果;
//
//如果未连接驱动器,请勿尝试执行任何操作。
//
if (g_Estate!= State_device_ready)
{
return (FR_NOT _READY);
}
//
//将当前工作路径复制到临时缓冲区中,这样就可以了
//操作。
//
strcpy (g_cTmpBuf、g_cCwdBuf);
//
//如果第一个字符是/,则这是完全指定的路径,然后是
//应按原样使用。
//
if (argv[1][0]='/')
{
//
//确保新路径不大于 cwd 缓冲区。
//
if (strlen (argv[1])+ 1 > sizeof (g_cCwdBuf))
{
UARTprintf ("生成的路径名太长\n"\n);
返回(0);
}
//
//如果新路径名(在 argv[1]中)不是太长,则复制该路径名
//进入临时缓冲区,以便可以对其进行检查。
//
其他
{
strncpy (g_cTmpBuf、argv[1]、sizeof (g_cTmpBuf));
}
}
//
//如果参数是. 然后尝试删除上的最低级别
// CWD。
//
否则、如果(!strcmp (argv[1]、".."))
{
//
//获取当前路径中最后一个字符的索引。
//
uIdx = strlen (g_cTmpBuf)- 1;
//
//从路径名末尾备份,直到分隔符(/)
//找到,或者直到我们到达路径的开头。
//
while (((g_cTmpBuf[uIdx]!='/')&&(uIdx > 1))
{
//
//备份一个字符。
//
uIdx--;
}
//
//现在我们要么处于当前路径中的最低级别分隔符,
//或字符串开头(根)。 因此、请设置新的结束
//字符串,有效地删除路径的最后一部分。
//
G_cTmpBuf[uIdx]= 0;
}
//
//否则,这只是当前目录中的常规路径名,
//并且需要将其附加到当前路径。
//
其他
{
//
//测试以确保在添加新的附加路径时
//当前路径,缓冲区中有空间用于完整的新路径。
//它需要包含一个新的分隔符和一个尾随的空字符。
//
if (strlen (g_cTmpBuf)+ strlen (argv[1])+ 1 + 1 > sizeof (g_cCwdBuf))
{
UARTprintf ("生成的路径名太长\n"\n);
返回(0);
}
//
//新路径是可以的,所以添加分隔符,然后附加新路径
//目录到路径。
//
其他
{
//
//如果尚未位于根级别,则追加/
//
if (strcmp (g_cTmpBuf、"/"))
{
strcat (g_cTmpBuf、"/");
}
//
//将新目录附加到路径。
//
strcat (g_cTmpBuf、argv[1]);
}
}
//
//此时,候选新目录路径位于 chTmpBuf 中。 尝试
//打开它以确保它有效。
//
fresult = f_opendir (&g_sDirObject、g_cTmpBuf);
//
//如果无法打开,则是一条错误的路径。 通知用户并返回。
//
if (fresult!= FR_OK)
{
UARTprintf ("CD:%s\n"、g_cTmpBuf);
return (fresult);
}
//
//否则,它是一个有效的新路径,所以将其复制到 CWD 中。
//
其他
{
strncpy (g_cCwdBuf、g_cTmpBuf、sizeof (g_cCwdBuf));
}
//
//返回成功。
//
退货(0);
}
//*********
//
//此函数实现"pwd"命令。 它只需打印当前
//工作目录。
////
*****************
int
Cmd_pwd (int argc、char * argv[])
{
//
//如果未连接驱动器,请勿尝试执行任何操作。
//
if (g_Estate!= State_device_ready)
{
return (FR_NOT _READY);
}
//
//将 CWD 打印到控制台。
//
UARTprintf ("%s\n"、g_cCwdBuf);
//
//返回成功。
//
退货(0);
}
//*********
//
//此函数实现"cat"命令。 它读取文件//的内容
并将其打印到控制台。 这只能用于文本文件。 如果
//它用于二进制文件,则可能会在
//控制台上打印一堆垃圾。
////
*****************
int
Cmd_cat (int argc、char * argv[])
{
FRESULT 结果;
unsigned short usBytesRead;
//
//如果未连接驱动器,请勿尝试执行任何操作。
//
if (g_Estate!= State_device_ready)
{
return (FR_NOT _READY);
}
//
//首先,检查以确保当前路径(CWD)加上文件
//名称加上分隔符和尾随空,都适合临时
//将用于保存文件名的缓冲区。 文件名必须为
//完整指定,带路径,到 FatFs。
//
if (strlen (g_cCwdBuf)+ strlen (argv[1])+ 1 + 1 > sizeof (g_cTmpBuf))
{
UARTprintf ("生成的路径名太长\n"\n);
返回(0);
}
//
//将当前路径复制到临时缓冲区,以便对其进行操作。
//
strcpy (g_cTmpBuf、g_cCwdBuf);
//
//如果尚未位于根级别,则追加分隔符。
//
if (strcmp ("/"、g_cCwdBuf))
{
strcat (g_cTmpBuf、"/");
}
//
//最后,附加文件名以生成完全指定的文件。
//
strcat (g_cTmpBuf、argv[1]);
//
//打开文件进行读取。
//
fresult = f_open (&g_sFileObject、g_ctmpBuf、fa_read);
//
//如果打开文件时出现问题,则返回错误。
//
if (fresult!= FR_OK)
{
return (fresult);
}
//
//输入循环从文件中重复读取数据并显示数据,直到
//文件的末尾已到达。
//
操作
{
//
//从文件中读取数据块。 读取尽可能多的数据
//临时缓冲区,包括尾部空的空间。
//
fresult = f_read (&g_sFileObject、g_cTmpBuf、sizeof (g_cTmpBuf)- 1、
usBytesRead (&U);
//
//如果读取错误,则打印换行符并返回
//用户错误。
//
if (fresult!= FR_OK)
{
UARTprintf ("\n");
return (fresult);
}
//
// Null 终止最后一个被读取的块,使其成为空
//可与 printf 一起使用的终止字符串。
//
G_cTmpBuf[usBytesRad]= 0;
//
//打印接收到的文件的最后一个块。
//
UARTprintf ("%s"、g_cTmpBuf);
//
//继续读取,直到读取的字节数小于完整的字节数。
//这意味着已到达缓冲区的末尾。
//
}
while (usBytesRead = sizeof (g_cTmpBuf)- 1);
//
//返回成功。
//
退货(0);
}
//*********
//
//此函数实现“帮助”命令。 它打印
一个简单的//可用命令列表,并附有简要说明。
////
*****************
int
Cmd_help (int argc、char * argv[])
{
tCmdLineEntry *pentrry;
//
//打印一些标题文本。
//
UARTprintf ("\n 可用命令\n");
UARTprintf ("------------------ \n");
//
//指向命令表的开头。
//
pentrry =&g_psCmdTable[0];
//
//输入循环以从命令表中读取每个条目。 结束时
//命令名称为 NULL 时已到达表。
//
while (preme->pcCmd)
{
//
//打印命令名称和简短说明。
//
UARTprintf ("%s%s%s\n"、pentry -> pcCmd、pentry -> pcHelp);
//
//前进到表中的下一个条目。
//
pentry++;
}
//
//返回成功。
//
退货(0);
}
//*********
//
//这是保存命令名称、实现函数和
//简要说明的表。
////
*****************
tCmdLineEntry g_psCmdTable[]=
{
{"help"、Cmd_help、 ":显示命令列表"},
{"h"、 CMD_help、":帮助别名"}、
{"?"、 CMD_help、":帮助别名"}、
{"ls"、 CMD_ls、 ":显示文件列表"},
{"chdir"、cmd_cd、 ":更改目录"}、
{"CD"、 CMD_CD、 “: chdir 的别名”},
{"pwd"、Cmd_pwd、 ":显示当前工作目录"},
{"cat"、cmd_cat、 ":显示文本文件的内容"},
{0、0、0}
};
//*********
//
//这是 MSC 驱动程序的回调。
//
//\param ulInstance 是
与驱动程序通信//时所需的驱动程序实例。
//\param ulEvent 是驱动程序定义的事件之一。
//\param pvData 是传递到寄存器初始调用
中的数据的指针//回调。
//
//此函数处理 MSC 驱动程序的回调事件。
当前处理的唯一事件//是 MSC_EVENT_OPEN 和 MSC_EVENT_CLOSE。 这使
//主例程能够知道何时检测到 MSC 设备并
枚举//以及何时从系统中删除 MSC 设备。
//
//返回成功时返回\e true,失败时返回\e false。
////
*****************
void
MSCCallback (tUSBHMSCInstance * psMSCInstance、uint32_t ui32Event、void * pvEventData)
{
//
//确定事件。
//
switch (ui32event)
{
//
//设备驱动程序已成功枚举 MSC 时调用
//器件。
//
案例 MSC_EVENT_OPEN:
{
//
//继续到枚举状态。
//
g_Estate = State_device_enum;
中断;
}
//
//由于错误或而卸载设备驱动程序时调用
//设备不再存在。
//
案例 MSC_EVENT_CLOSE:
{
//
//返回到“无设备”状态并等待新连接。
//
g_Estate = State_no_device;
中断;
}
默认值:
{
中断;
}
}
//*********
//
//这是来自主机堆栈的通用回调。
//
//\param pvData 实际上是 tEventInfo 结构的指针。
//
//将调用此函数,以便在发生与
大容量存储设备相关的 USB 事件之外的//时通知应用程序。 此时
//此选项用于检测插入和删除的不受支持的设备。
//它还用于在发生电源故障时通知应用程序。
//
将 g_USBGenericEventDriver 包含在//主机控制器驱动程序数组中时,需要此函
数,该数将传递到// USBHCDRegisterDrivers()函数。
//
//\返回无。
////
*****************
void
USBHCEDEvents (void *pvData)
{
tEventInfo *pEventInfo;
//
//将此指针投射到其实际类型。
//
pEventInfo =(tEventInfo *) pvData;
switch (pEventInfo->ui32Event)
{
//
//检测到新键盘。
//
案例 USB_EVENT_UNKNOWN_Connected:
{
//
//检测到未知设备。
//
g_Estate = State_unknown_device;
中断;
}
//
//键盘已拔下。
//
案例 USB_EVENT_DISCONNECTED:
{
//
//已删除未知设备。
//
g_Estate = State_no_device;
中断;
}
案例 USB_EVENT_POWER_FAULT:
{
//
//不能通电表示没有设备。
//
G_ARRAT = State_Power_FAULT;
中断;
}
默认值:
{
中断;
}
}
//*********
//
//此函数从 UART 控制台读取一行文本。 在
整个过程中调用 USB 主机 MAIN //函数、以使 USB 保持活动状态并保持正常。
////
*****************
void
ReadLine (void)
{
unsigned long ulIdx、ulPrompt;
unsigned char ucchar;
tState eStateCopy;
//
//在命令缓冲区的开头开始读取并打印提示符。
//
G_cCmdBuf[0]='\0';
ulIdx = 0;
ulPrompt = 1;
//
//永久循环。 该循环将在何时明确地断开
//已完全读取。
//
while (1)
{
//
//查看是否已枚举大容量存储设备。
//
if (g_Estate = State_device_enum)
{
//
//如果大容量存储设备速度慢,请在该设备上轻松操作
//连接后启动。
//
if (USBHMSCDriveReady (g_psMSCInstance)!= 0)
{
//
//在尝试检查是否为之前等待大约100ms
//设备已就绪。
//
SysCtlDelay (SysCtlClockGet (system_clock_speed)/30);
中断;
}
//
//将工作目录重置为 root。
//
G_cCwdBuf[0]='/';
G_cCwdBuf[1]='\0';
//
//尝试打开目录。 某些驱动器需要更长的时间
//比其他人启动,这可能会失败(即使是 USB
//设备已枚举)。
//
f_mount (0、&g_sFatFs);
if (f_opendir (&g_sDirObject、g_cCwdBuf)== FR_OK)
{
//
//驱动器已完全就绪,因此进入该状态。
//
g_Estate = State_device_ready;
}
}
//
//查看状态是否已更改。 我们将 g_eUIState 的副本复制到
//防止编译器警告未定义的易失性顺序
//访问。
//
eStateCopy = g_eUIState;
if (g_Estate!= eStateCopy)
{
//
//确定新状态。
//
switch (g_Estate)
{
//
//先前连接的设备已断开连接。
//
案例 State_no_device:
{
if (g_eUIState = State_unknown_device)
{
UARTprintf ("\n 未知设备已断开连接。\n");
}
其他
{
UARTprintf ("\n 大容量存储设备已断开连接。\n");
}
ulPrompt = 1;
中断;
}
//
//正在枚举大容量存储设备。
//
实例 State_device_enum:
{
中断;
}
//
//已枚举并初始化大容量存储设备。
//
案例 State_device_ready:
{
UARTprintf ("\n 已连接大容量存储设备。\n");
ulPrompt = 1;
中断;
}
//
//已连接未知设备。
//
案例 State_UNKNOWN_DEVICE:
{
UARTprintf ("\n 已连接未知设备。\n");
ulPrompt = 1;
中断;
}
//
//发生电源故障。
//
案例 State_Power_FAULT:
{
UARTprintf ("\n 电源故障。\n"\});
ulPrompt = 1;
中断;
}
}
//
//保存当前状态。
//
G_eUIState = g_Estate;
}
//
//如有必要,打印提示。
//
if (ulPrompt)
{
//
//根据当前状态打印提示。
//
if (g_Estate = State_device_ready)
{
UARTprintf ("%s>%s"、g_cCwdBuf、g_cCmdBuf);
}
否则、如果(g_Estate = State_unknown_device)
{
UARTprintf ("未知>%s"、g_cCmdBuf);
}
其他
{
UARTprintf ("nodev>%s"、g_cCmdbf);
}
//
//不再需要打印提示。
//
ulPrompt = 0;
}
//
//循环,此时已从接收到字符
// UART。
//
//while (UARTCharsAvail (UARTA_BASE))
while (UARTCharsAvail (UARTC_BASE))
{
//
//从 UART 读取下一个字符。
//
ucchar = UARTgetc();
//
//查看此字符是否为退格,并且至少有一个
//输入行中的字符。
//
if ((ucchar ='\b')&&(ulIdx!= 0))
{
//
//删除输入行中的最后一个字符。
//
UARTprintf ("\b\b\b");
ulIdx--;
g_cCmdBuf[ulIdx]='\0';
}
//
//查看此字符是否为换行符。
//
否则、如果((ucChar ='\r\n')||(ucChar ='\n'))
{
//
//返回给呼叫者。
//
UARTprintf ("\n");
返回;
}
//
//查看此字符是转义还是 Ctrl-U
//
否则、如果((ucChar =0x1b)||(ucChar =0x15))
{
//
//擦除输入缓冲区中的所有字符。
//
while (ulIdx)
{
UARTprintf ("\b\b\b");
ulIdx--;
}
G_cCmdbuf[0]='\0';
}
//
//查看这是否是可打印的 ASCII 字符。
//
否则、如果((ucchar >=')&&(ucchar <='~')&&
(ulIdx <(sizeof (g_cCmdBuf)- 1)))
{
//
//将此字符添加到输入缓冲区。
//
g_cCmdBuf[ulIdx++]= ucChar;
g_cCmdBuf[ulIdx]='\0';
UARTprintf ("%c"、(无符号长整型) ucChar);
}
}
//
//告诉 OTG 状态机经过了多少时间
//自上次调用以来的毫秒数。
//
USBHCDMain();
// USBOTGMain (GetTickms());
}
}
//*********
//
//配置 UART 及其引脚。 这必须在 UARTprintf()之前调用。
////
*****************
void
ConfigureUART (void)
{
//
//启用 UART0
//
// SysCtlPeripheralEnable (SYSCTL_Periph_SCI1);
SysCtlPeripheralEnable (SYSCTL_Periph_SCI3);
GPIO_SetupPinMux (90、GPIO_MUX_CPU1、6); //rx
GPIO_SetupPinOptions (90、GPIO_INPUT、GPIO_PushPull);//Rx
GPIO_SetupPinMux (89、GPIO_MUX_CPU1、6);//Tx
GPIO_SetupPinOptions (89、GPIO_OUTPUT、GPIO_异 步);//Tx
//
//为 UART 模式配置 GPIO 引脚。
//
EALLOW;
// GpioCtrlRegs.GPAMUX2.bit.GPIO28 = 1;
// GpioCtrlRegs.GPAPUD.bit.GPIO28 = 0;
// GpioRegs.GPO28=0;// GpioRegs.GPADL.GPIO28 = 3;
// GpioRegs.GPO2.bit.GPIO2.GPOS=GP0.GPIO2.Gpio2.GPIO2.GPIO2.bit.GPIO2.GPIO2.GPIO2.GPIO2.9/GPIO2.GPIO2.GPIO1.bit.GPIO2.GPIO2.GPIO2.GPIO2.GPIO2.GPIO2.GPIO2.GPIO2.GPIO2.GPIO2.GPIO2.GPIO2.GPIOR.GPIOR.GPIO2.GPIOR.GPIO2.GPIO2.GPIOR.GPIO2.GPIO2.GPIOR.GPIO2.
//
//初始化控制台 I/O 的 UART
//
UARTStdioConfig (2、115200、SysCtlLowSpeedClockGet (system_clock_speed));
}
//*********
//
//这是运行应用程序的主循环。
////
*****************
int
main (void)
{
int iStatus;
#ifdef _flash
//将时间关键代码和闪存设置代码复制到 RAM
//其中包括以下函数:InitFlash_BANK0 ();
// RamfuncsLoadStart、RamfuncsLoadSize 和 RamfuncsRunStart
//符号由链接器创建。 请参阅器件.cmd 文件。
memcpy (&RamfuncsRunStart、&RamfuncsLoadStart、(size_t)&RamfuncsLoadSize);
#endif
//
//将时钟设置为以50MHz 的频率从 PLL 运行
//
SysCtlClockSet (SYSCTL_OSCSRC_XTAL | SYSCTL_PLL_ENABLE | SYSCTL_IMULT (20)| SYSCTL_SYSDIV (2));
SysCtlAuxClockSet (SYSCTL_OSCSRC_XTAL | SYSCTL_PLL_ENABLE | SYSCTL_IMULT (12)| SYSCTL_SYSDIV (4));
#ifdef _FLASH
//调用闪存初始化以设置闪存等待状态
//此函数必须驻留在 RAM 中
InitFlash_BANK0 ();
#endif
//
//最初等待设备连接。
//
g_Estate = State_no_device;
G_eUIState = State_no_device;
//
//初始化 PIE 和矢量表
InitPieCtrl();
InitPieVectTable();
USBGPIOEnable();
USBIntRegister (USB0_BASE、F28x_USB0HostIntHandler);
//
//为调试输出配置 UART0。
//
ConfigureUART();
UARTprintf ("\n\nUSB 大容量存储主机程序\n");
UARTprintf ("键入\'help\'以获取帮助。\n\n");
//
//启用中断
//
IntMasterEnable();
//
//初始化 USB 堆栈模式并传入模式回调。
//
USBStackModeSet (0、eUSBModeForceHost、ModeCallback);
//
//注册主机类驱动程序。
//
USBHCDRegisterDrivers (0、g_ppHostClassDrivers、NUM_CLASS_DRIVERS);
//
//打开海量存储类驱动程序的实例。
//
G_psMSCInstance = USBHMSCDriveOpen (0、(tUSBHMSCCallback) MSCCallback);
//
//初始化电源配置。 这将设置电源使能信号
//为高电平有效且不使能电源故障。
//
USBHCDPowerConfigInit (0、USBHCD_VBUS_AUTO_HIGH | USBHCD_VBUS_FILTER);
//
//使用2ms 轮询初始化 USB 控制器以进行 OTG 操作
//速率。
//
USBHCDInit (0、g_pHCPool、HCD_MEMORY_SIZE);
//
//初始化文件系统。
//
f_mount (0、&g_sFatFs);
//
//输入一个无限循环来读取和处理来自的命令
//用户。
//
while (1)
{
//
//从用户获取一行文本。
//
readline();
if (g_cCmdBuf[0]='\0')
{
继续;
}
//
//将线路从用户传递到命令处理器。
//将对其进行解析并执行有效的命令。
//
iStatus = CmdLineProcess (g_cCmdBuf);
//
//处理命令错误的情况。
//
if (iStatus = CMDLINE_BAD_CMD)
{
UARTprintf ("命令错误!\n");
}
//
//处理过多参数的情况。
//
否则、如果(iStatus = CMDLINE_TOW_LOAD_ARGs)
{
UARTprintf ("命令处理器的参数太多!\n");
}
//
//否则命令被执行。 打印错误
//如果返回一个,则编码。
//
否则(iStatus!= 0)
{
UARTprintf ("命令返回错误代码%s\n"、
StringFromResult((FRESULT)iStatus));
}
}
//
////文件结束
//




