📄 usb.c
字号:
#include <msp430x14x.h>
#include <string.h>
#define USB_RESET_ALL 0x05 /* 等40ms,执行硬件复位 */
#define USB_CHECK_EXIST 0x06 /* 输入:任意数据 输出:按位取反 测试工作状态 */
#define SET_USB_MODE 0x15 /* 输入:模式代码 输出:操作状态(等20us) 设置工作模式 */
#define USB_GET_STATUS 0x22 /* 输出:中断状态 获取中断状态并取消请求 */
#define USB_SET_BAUDRATE 0x02 /* 输入:分频系数和分频常数 输出:操作状态(等1ms) 设置串口通讯波特率 */
#define RD_USB_DATA 0x28 /* 输出:数据长度和数据流 从当前USB中断的端点缓冲区读取数据块 */
#define WR_USB_DATA7 0x2B /* 输入:数据长度和数据流 向USB主机端点的输出缓冲器写入数据块 */
#define USB_ABORT_NAK 0x17 /* 放弃当前NAK的重试 */
#define USB_DISK_INIT 0x51 /* 初始化USB存储设备 (产生中断) */
#define USB_DISK_SIZE 0x53 /* 获取USB存储设备的容量 (产生中断) */
#define USB_DISK_READ 0x54 /* 输入:LBA地址和扇区数 从USB存储设备读数据块 (产生中断) */
#define USB_DISK_RD_GO 0x55 /* 继续USB存储设备的读操作 (产生中断) */
#define USB_DISK_WRITE 0x56 /* 输入:LBA地址和扇区数 向USB存储设备写数据块 (产生中断) */
#define USB_DISK_WR_GO 0x57 /* 继续USB存储设备的写操作 (产生中断) */
#define USB_GET_IC_VER 0x01 /* 输出:版本号 获取芯片及固件版本 */
#define USB_ENTER_SLEEP 0x03 /* 进入低功耗睡眠挂起状态 */
#define USB_SET_DISK_LUN 0x0B /* 输入:数据34H和逻辑单元号 设置USB存储设备的当前逻辑单元号 */
#define USB_DISK_INQUIRY 0x58 /* 查询USB存储设备的特性 (产生中断) */
#define USB_DISK_READY 0x59 /* 检查USB存储设备是否就绪 (产生中断) */
#define USB_DISK_R_SENSE 0x5A /* 检查USB存储设备的错误 (产生中断) */
#define USB_DISK_MAX_LUN 0x5D /* 获取USB存储设备的最大单元号 (产生中断) */
/* 操作状态 */
#define CMD_RET_SUCCESS 0x51 /* 操作成功 */
#define CMD_RET_ABORT 0x5F /* 操作失败 */
/* 中断状态 */
#define USB_INT_SUCCESS 0x14 /* 主机方式:USB事务或传输操作成功 */
#define USB_INT_CONNECT 0x15 /* 主机方式:检测到USB设备连接事件 */
#define USB_INT_DISCONNECT 0x16 /* 主机方式:检测到USB设备断开事件 */
#define USB_INT_BUF_OVER 0x17 /* 主机方式:USB控制传输的数据太多,缓冲区溢出 */
#define USB_INT_DISK_READ 0x1D /* 主机方式:USB存储设备读操作,请求数据读出 */
#define USB_INT_DISK_WRITE 0x1E /* 主机方式:USB存储设备写操作,请求数据写入 */
#define USB_INT_DISK_ERR 0x1F /* 主机方式:USB存储设备操作失败 */
/* 其他 */
#define USB_SUCCESS 0x00 /* USB函数操作成功 */
#define USB_ABORT 0xFF /* USB函数操作失败 */
#define USB_CS 0x01 /* 片选控制输入(低电平有效) */
#define USB_INT 0x02 /* 中断请求输出(低电平有效) */
#define USB_WR 0x04 /* 写选通输入(低电平有效) */
#define USB_RD 0x08 /* 读选通输入(低电平有效) */
#define USB_A0 0x10 /* 地址线输入:A0 = 0写命令;A0 = 1读写数据 */
#define USB_CTL_INIT() {P2OUT = (P2OUT | 0x0F) & 0xEF;\
P2DIR = (P2DIR | 0x1D) & 0xFD;}
#define USB_DB_INIT() {P1DIR = 0x00;}
#define USB_CLRB(BIT) {P2OUT &= ~BIT;}
#define USB_SETB(BIT) {P2OUT |= BIT;}
#define USB_CTL_RESET() {P2OUT = (P2OUT | 0x0F) & 0xEF;}
#define USB_RD_INT() (P2IN & USB_INT)
#define USB_DB_SET(DATA) {P1OUT = (DATA); P1DIR = 0xFF;}
#define USB_DB_READ() (P1DIR = 0x00 , P1IN & 0xFF)
#define USB_DB_RESET() {P1DIR = 0x00;}
void USB_SendCmd(char cmd)
{
USB_DB_SET(cmd); /* cmd -> D[0-7] */
USB_CLRB(USB_CS); /* CS:L, WR:L, A0:H, RD:H */
USB_CLRB(USB_WR); /* 写命令 */
USB_SETB(USB_A0);
USB_SETB(USB_RD);
_NOP();
_NOP();
_NOP();
USB_CTL_RESET(); /* CS:H, WR:H, A0:L, RD:H */
USB_DB_RESET(); /* D[0-7]: input */
}
void USB_SendData(char data)
{
USB_DB_SET(data); /* data -> D[0-7] */
USB_CLRB(USB_CS); /* CS:L, WR:L, A0:L, RD:H */
USB_CLRB(USB_WR); /* 写数据 */
USB_CLRB(USB_A0);
USB_SETB(USB_RD);
_NOP();
_NOP();
_NOP();
USB_CTL_RESET(); /* CS:H, WR:H, A0:L, RD:H */
USB_DB_RESET(); /* D[0-7]: input */
}
char USB_ReadData(void)
{
char DB_Temp;
USB_CLRB(USB_CS); /* CS:L, WR:H, A0:L, RD:L */
USB_SETB(USB_WR); /* 读数据 */
USB_CLRB(USB_A0);
USB_CLRB(USB_RD);
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
DB_Temp = USB_DB_READ(); /* D[0-7] -> DB_Temp */
_NOP();
_NOP();
USB_CTL_RESET(); /* CS:H, WR:H, A0:L, RD:H */
USB_DB_RESET(); /* D[0-7]: input */
return DB_Temp;
}
void USB_Delayms(unsigned int ms)
{
/*
适用于8MHz的时钟,不精确
*/
while(ms--)
{
for(int i = 2000;i != 0;i--);
}
}
char USB_WaitInt(void)
{
char status;
while(USB_RD_INT() != 0x00);
USB_SendCmd(USB_GET_STATUS);
status = USB_ReadData();
return status;
}
char USB_Init(void)
{
USB_CTL_INIT(); /* USB控制端初始化 */
USB_DB_INIT(); /* USB数据端初始化 */
USB_SendCmd(USB_RESET_ALL); /* CH375芯片复位 */
USB_Delayms(40);
USB_SendCmd(USB_CHECK_EXIST); /* 检查芯片是否可以正常工作 */
USB_SendData(0xAA);
if(USB_ReadData() != 0x55)
{
return USB_ABORT;
}
USB_SendCmd(SET_USB_MODE); /* 设置USB模式 */
USB_SendData(0x06); /* 已启动的主机模式,自动产生SOF包 */
USB_Delayms(1);
if(USB_ReadData() != CMD_RET_SUCCESS)
{
return USB_ABORT;
}
return USB_SUCCESS;
}
char USB_ReadSec(unsigned long LBA, char *secBuffer)
{
char status;
USB_SendCmd(USB_DISK_READ); /* 发出读扇区指令并指明目的扇区 */
USB_SendData(LBA & 0xFF);
USB_SendData((LBA >> 8) & 0xFF);
USB_SendData((LBA >> 16) & 0xFF);
USB_SendData((LBA >> 24) & 0xFF);
USB_SendData(1);
/*
读出指定扇区的数据并存入secBuff
*/
int index = 0;
do
{
status = USB_WaitInt();
if(status == USB_INT_DISK_READ)
{
/*
一次读64个字节的数据
*/
int length;
USB_SendCmd(RD_USB_DATA);
length = USB_ReadData();
while(length--)
{
secBuffer[index++] = USB_ReadData();
}
/*
这里需要延时一段时间,否则之后的操作会出现无法预知的行为!
*/
USB_Delayms(1);
USB_SendCmd(USB_DISK_RD_GO); /* 发出继续读取的指令 */
}
else
{
break;
}
}while(1);
if(status == USB_INT_SUCCESS)
{
return USB_SUCCESS;
}
else
{
return USB_ABORT;
}
}
char USB_WriteSec(unsigned long LBA, char *secBuffer)
{
char status;
USB_SendCmd(USB_DISK_WRITE); /* 发出写扇区指令并指明目的扇区 */
USB_SendData(LBA & 0xFF);
USB_SendData((LBA >> 8) & 0xFF);
USB_SendData((LBA >> 16) & 0xFF);
USB_SendData((LBA >> 24) & 0xFF);
USB_SendData(1);
int index = 0;
do{
status = USB_WaitInt();
if(status == USB_INT_DISK_WRITE)
{
/*
一次写64个字节的数据
*/
USB_SendCmd(WR_USB_DATA7);
USB_SendData(64);
for(int i = 0;i < 64;i++)
{
USB_SendData(secBuffer[index++]);
}
/*
这里不能延时,否则之后的操作会出现无法预知的行为!
*/
USB_SendCmd(USB_DISK_WR_GO);
}
else
{
break;
}
}while(1);
if(status == USB_INT_SUCCESS)
{
return USB_SUCCESS;
}
else
{
return USB_ABORT;
}
}
typedef struct _DIRDATA{
char DIR_Name[11];
char DIR_Attr;
char DIR_NTRes;
char DIR_CrtTimeTenth;
int DIR_CrtTime;
int DIR_CrtDate;
int DIR_LstAccDate;
int DIR_FstClusHI;
int DIR_WrtTime;
int DIR_WrtDate;
int DIR_FstClusLO;
long DIR_FileSize;
}DIRDATA;
#define INT_TO_DATE(i) ((long)((i) & 0x1F) + \
(long)(((i) >> 5) & 0x0F) * 100 + \
(long)((((i) >> 9) & 0x7F) + 1980) * 10000)
#define INT_TO_TIME(i) ((long)((i) & 0x1F) * 2 + \
(long)(((i) >> 5) & 0x3F) * 100 + \
(long)(((i) >> 11) & 0x1F) * 10000)
int DATE_TO_INT(long date)
{
int i = 0;
i += (int)((date / 10000 - 1980) << 9);
date %= 10000;
i += (int)((date / 100) << 5);
date %= 100;
i += (int)(date);
return i;
}
int TIME_TO_INT(long time)
{
int i = 0;
i += (int)((time / 10000) << 11);
time %= 10000;
i += (int)((time / 100) << 5);
time %= 100;
i += (int)(time / 2);
return i;
}
char secData[512];
void main(void)
{
WDTCTL = WDTPW+WDTHOLD;
USB_Init();
while(USB_WaitInt() != USB_INT_CONNECT);
USB_SendCmd(USB_DISK_INIT);
while(USB_WaitInt() != USB_INT_SUCCESS);
_NOP();
USB_ReadSec(0x00000790, secData);
_NOP();
char data[] = "Hello!";
memset((void *)secData, 0, 512);
memcpy((void *)secData, (void *)data, strlen(data));
USB_WriteSec(0x00000792, secData);
USB_ReadSec(0x00000792, secData);
_NOP();
DIRDATA dData;
USB_ReadSec(0x00000790, secData);
_NOP();
char name[11] = {'A', 'L', 'B', 'E', 'R', 'T', ' ', ' ', 'T', 'X', 'T'};
memcpy((void *)(dData.DIR_Name), (void *)name, 11);
dData.DIR_Attr = 0x20;
dData.DIR_NTRes = 0x18;
dData.DIR_CrtTimeTenth = 0x00;
dData.DIR_CrtTime = TIME_TO_INT(133500);
dData.DIR_CrtDate = DATE_TO_INT(20080307);
dData.DIR_LstAccDate = DATE_TO_INT(20080307);
dData.DIR_FstClusHI = 0x0000;
dData.DIR_WrtTime = TIME_TO_INT(133500);
dData.DIR_WrtDate = DATE_TO_INT(20080307);
dData.DIR_FstClusLO = 0x0003;
dData.DIR_FileSize = (long)strlen(data);
int free = 0;
for(free = 0;(secData[free] != 0xEB && secData[free] != 0x00) && (free < 512);
free += 32);
if(free < 512)
{
memcpy((void *)(&secData[free]), (void *)(&dData), sizeof(dData));
USB_WriteSec(0x00000790, secData);
}
_NOP();
USB_ReadSec(0x00000020, secData);
_NOP();
long link = 0x0FFFFFFF;
memcpy((void *)(&secData[12]), (void *)(&link), 4);
USB_WriteSec(0x00000020, secData);
_NOP();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -