?? 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 + -