📄 usb_demo.cpp
字号:
// Stop event was set
CloseHandle(hDevice);
CloseHandle(ol.hEvent);
return 0;
}
}
}
if (!bRet)
{
sprintf(errorMsg, "Connection to board lost.");
mainForm->btConnectClick(NULL);
CloseHandle(hDevice);
CloseHandle(ol.hEvent);
return 0;
}
// Update LCD display mirror
int bufIndex = report[1];
int nBytes = INPUT_REPORT_SIZE - 1;
if (bufIndex + nBytes > LCD_BUFFER_SIZE) // this is to protect from buffer overflow
nBytes = LCD_BUFFER_SIZE - bufIndex;
if (nBytes < 0)
nBytes = 0;
memcpy(lcdBuffer + bufIndex, report + 2, nBytes);
UpdateDisplay(lcdBuffer);
}
}
//---------------------------------------------------------------------------
/////////////////// CreateInputThread()
//
// Creates input thread to poll for LCD mirror input reports.
// The function returns handle to the created thread.
HANDLE CreateInputThread()
{
ResetEvent(g_hStopEvent); // set the state of the specified event object to nonsignaled
DWORD dwThreadID;
HANDLE hThread = CreateThread(NULL, 0, InputThreadProc, NULL, 0, &dwThreadID);
if (!hThread)
{
OnError("Failed to create input thread.");
}
return hThread;
}
//---------------------------------------------------------------------------
/////////////////// ConnectDevice()
//
// Establishes the connection to the target device.
//
// Function returns 1 if connection attempt succeeded or 0 if failed.
// device_path_buffer is the data space for storing of the device path variable
int ConnectDevice(char *device_path_buffer){
if (IsConnected())
return 2;
else
{
// Open handle to device
if (OpenDeviceHandle())
{
strcpy(device_path_buffer,g_devicePath);
// Create thread to manage LCD mirror
hInputThread = CreateInputThread();
if (!hInputThread)
{
CloseHandle(g_hDevice);
g_hDevice = INVALID_HANDLE_VALUE;
}
}
else
{
return 0;
}
}
return 1;
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// MISCELLANEOUS IAP-RELATIVE FUNCTIONS
//---------------------------------------------------------------------------
/////////////////// OffsetToAddress()
//
// Converts an offset within a flash sector to the xdata address
// used to program the sector.
uint16 OffsetToAddress(uchar flash, uchar sector, uint16 offset)
{
if (flash == PRIMARY_FLASH)
{
#ifdef UPSD_2MB
return (0x8000 + offset);
#else
return (0x8000 + (sector & 1) * 0x4000 + offset);
#endif
}
else
{
return (0x8000 + sector * 0x2000 + offset);
}
}
//---------------------------------------------------------------------------
/////////////////// SectorSize()
//
// Returns the size (in bytes) of a primary or secondary flash sector.
uint16 SectorSize(uchar flash, uchar sector)
{
#ifdef UPSD_2MB
return (flash == SECONDARY_FLASH) ? 0x2000 : 0x8000;
#else
return (flash == SECONDARY_FLASH) ? 0x2000 : 0x4000;
#endif
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// MAIN IAP DEMO COMMANDS IMPLEMENTATION
//---------------------------------------------------------------------------
/////////////////// SetPage()
//
// Sets the page register.
//
// The function takes one argument - value which will be set to PAGE register of uPSD.
// Function returns TRUE if successful, FALSE on error.
BOOL SetPage(BYTE page)
{
REPORT_BUF reportBuf;
memset(&reportBuf, 0, sizeof(REPORT_BUF));
// Send command
reportBuf.reportID = 0;
reportBuf.report.u.setRegs.cmd = CMD_SET_PAGE;
reportBuf.report.u.setRegs.page = page;
DWORD cbWritten;
if (!WriteFile(g_hDevice, &reportBuf, sizeof(REPORT_BUF), &cbWritten, NULL))
{
OnError("Error sending CMD_SET_PAGE command.");
return FALSE;
}
return TRUE;
}
//---------------------------------------------------------------------------
/////////////////// SetVM()
//
// Sets the VM register.
//
// The function takes one argument - value which will be set to VM register of uPSD.
// Function returns TRUE if successful, FALSE on error.
BOOL SetVM(BYTE vm)
{
REPORT_BUF reportBuf;
memset(&reportBuf, 0, sizeof(REPORT_BUF));
// Send command
reportBuf.reportID = 0;
reportBuf.report.u.setRegs.cmd = CMD_SET_VM;
reportBuf.report.u.setRegs.vm = vm;
DWORD cbWritten;
if (!WriteFile(g_hDevice, &reportBuf, sizeof(REPORT_BUF), &cbWritten, NULL))
{
OnError("Error sending CMD_SET_VM command.");
return FALSE;
}
return TRUE;
}
//---------------------------------------------------------------------------
/////////////////// SelectFlash()
//
// Selects primary or secondary flash for manipulation in data space.
//
// list and meaning of parameters:
// uchar flash - flash selector, 0 = Main Flash (primary), 1 = Boot Flash (secondary)
// uchar sector - sector selector, 0..7 for Main Flash, 0..3 for Boot flash
//
// Function returns TRUE if successful, FALSE on error.
BOOL SelectFlash(int flash, BYTE sector)
{
if (flash == PRIMARY_FLASH)
{
// Put primary in data space; secondary/boot in code space
if(!SetVM(PRIMARY_FLASH_VM))return false;
#ifdef UPSD_2MB
if(!SetPage(sector))return false;
#else
if(!SetPage(sector/2))return false;
#endif
}
else if (flash == SECONDARY_FLASH)
{
if (sector >= 4)
{
OnError("Secondary/boot flash sector can not be > 3.");
return FALSE;
}
// Put secondary/boot flash in data space
if(!SetVM(SECONDARY_FLASH_VM))return false;
if(!SetPage(0))return false;
}
return TRUE;
}
//---------------------------------------------------------------------------
/////////////////// GetStatus()
//
// Returns status from firmware.
//
// Returns TRUE if successful; FALSE on error.
BOOL GetStatus(PREPORT_BUF pStatusBuf)
{
REPORT_BUF reportBuf;
memset(&reportBuf, 0, sizeof(REPORT_BUF));
// Send command
reportBuf.reportID = 0;
reportBuf.report.u.cmd = CMD_STATUS;
DWORD cbWritten;
if (!WriteFile(g_hDevice, &reportBuf, sizeof(REPORT_BUF), &cbWritten, NULL))
{
OnError("Error sending CMD_STATUS command.");
return FALSE;
}
// Get status reply
memset(pStatusBuf, 0, sizeof(REPORT_BUF));
if (!(HidD_GetFeature)(g_hDevice, pStatusBuf, sizeof(REPORT_BUF)))
{
OnError("Error reading CMD_GET_STATUS reply.");
return FALSE;
}
return TRUE;
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// FLASH READ/WRITE/ERASE ROUTINES IMPLEMENTATION
//---------------------------------------------------------------------------
/////////////////// ReadFlash()
//
// Reads and returns a number of bytes from the
// selected flash sector starting at a specified offset.
//
// list and meaning of parameters:
// uchar flash - flash selector, 0 = Main Flash (primary), 1 = Boot Flash (secondary)
// uchar sector - sector selector, 0..7 for Main Flash, 0..3 for Boot flash
// uint16 offset - offset address where to write the data, valid values are
// 0x0000-0x7fff for Main Flash, 0x0000-0x1fff for Boot Flash
// uchar *buffer - destination buffer where the read data will be stored
// uint16 nBytes - amount of data to read
//
// Function returns TRUE on success, FALSE on error.
BOOL ReadFlash(uchar flash, uchar sector, uint16 offset, uchar *buffer, uint16 nBytes)
{
static char str[256];
REPORT_BUF reportBuf;
memset(&reportBuf, 0, sizeof(REPORT_BUF));
if (!nBytes)
{
OnError("Invalid count of bytes to read.");
return FALSE;
}
// Convert sector offset to xdata address
uint16 address = OffsetToAddress(flash, sector, offset);
// Send command
reportBuf.reportID = 0;
reportBuf.report.u.cmd = CMD_READ;
reportBuf.report.u.rw.flash = flash;
reportBuf.report.u.rw.address = SWAP_UINT16(address);
reportBuf.report.u.rw.nBytes = SWAP_UINT16(nBytes);
// Hold off LCD monitor thread while we read
EnterCriticalSection(&g_crSection);
DWORD cbWritten;
if (!WriteFile(g_hDevice, &reportBuf, sizeof(REPORT_BUF), &cbWritten, NULL))
{
OnError("Error sending CMD_READ command.");
LeaveCriticalSection(&g_crSection);
return FALSE;
}
t1 = Now();
// Read data
uint16 cbRemaining = nBytes;
uint16 cbTemp = cbRemaining;
while (cbRemaining)
{
if (!(HidD_GetFeature)(g_hDevice, &reportBuf, sizeof(REPORT_BUF)))
{
OnError("Error reading CMD_READ reply.");
LeaveCriticalSection(&g_crSection);
return FALSE;
}
// Skip 0 command byte at start of report buffer
uint16 cbData = min(cbRemaining, CMD_SIZE - 1);
memcpy(buffer, reportBuf.report.u.buffer + 1, cbData);
buffer += cbData;
cbRemaining -= cbData;
// Update display on every 100 byte boundary
if ((cbTemp/100) != (cbRemaining/100))
{
sprintf(str, "Reading flash: %d bytes remaining", (cbTemp/100)*100);
mainForm->sbStatus->Panels->Items[0]->Text = AnsiString(str);// update text in status bar
mainForm->Repaint(); // refresh the texts displayed on the main form
cbTemp = cbRemaining;
}
}
LeaveCriticalSection(&g_crSection);
t2 = Now();
time_consumed_for_ReadFlash = MilliSecondsBetween(t1, t2);
mainForm->sbStatus->Panels->Items[0]->Text = "Reading Flash is done.";// update text in status bar
mainForm->sbStatus->Panels->Items[0]->Text += " Time consumed " + AnsiString(time_consumed_for_ReadFlash) +" ms.";
mainForm->Repaint(); // refresh the texts displayed on the main form
return TRUE;
}
//---------------------------------------------------------------------------
/////////////////// WriteFlash()
//
// Writes a number of bytes to the selected flash sector,
// starting at a specified offset.
//
// list and meaning of parameters:
// uchar flash - flash selector, 0 = Main Flash (primary), 1 = Boot Flash (secondary)
// uchar sector - sector selector, 0..7 for Main Flash, 0..3 for Boot flash
// uint16 offset - offset address where to write the data, valid values are
// 0x0000-0x7fff for Main Flash, 0x0000-0x1fff for Boot Flash
// uchar *buffer - source buffer containing data
// uint16 nBytes - amount of data to write
//
// Function returns TRUE on success, FALSE on error.
BOOL WriteFlash(uchar flash, uchar sector, uint16 offset, uchar *buffer, uint16 nBytes)
{
static char str[256];
REPORT_BUF reportBuf;
memset(&reportBuf, 0, sizeof(REPORT_BUF));
if (!nBytes)
{
OnError("Invalid count of bytes to write.");
return FALSE;
}
// Hold off LCD monitor thread while we write
EnterCriticalSection(&g_crSection);
// Calculate checksum
uchar checkSum = 0;
for (int i = 0; i < nBytes; i++)
{
checkSum += buffer[i];
}
// Convert sector offset to xdata address
uint16 address = OffsetToAddress(flash, sector, offset);
// Send command
reportBuf.reportID = 0;
reportBuf.report.u.cmd = CMD_WRITE;
reportBuf.report.u.rw.flash = flash;
reportBuf.report.u.rw.address = SWAP_UINT16(address);
reportBuf.report.u.rw.nBytes = SWAP_UINT16(nBytes);
DWORD cbWritten;
if (!WriteFile(g_hDevice, &reportBuf, sizeof(REPORT_BUF), &cbWritten, NULL))
{
OnError("Error sending CMD_WRITE command.");
LeaveCriticalSection(&g_crSection);
return FALSE;
}
// Write data
uint16 cbRemaining = nBytes;
uint16 cbTemp = cbRemaining;
while (cbRemaining)
{
uint16 cbData = min(cbRemaining, CMD_SIZE - 1);
reportBuf.reportID = 0;
reportBuf.report.u.cmd = 0;
memcpy(reportBuf.report.u.buffer + 1, buffer, cbData);
if (!WriteFile(g_hDevice, &reportBuf, sizeof(REPORT_BUF), &cbWritten, NULL))
{
OnError("Error writing data.");
LeaveCriticalSection(&g_crSection);
return FALSE;
}
buffer += cbData;
cbRemaining -= cbData;
// Update display on every 100 byte boundary
if ((cbTemp/100) != (cbRemaining/100))
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -