📄 usb_demo.cpp
字号:
leave_cycle = 1;
}
if (((0x100 - sum) & 0xFF) != temp)
{
bRet = false;
leave_cycle = 1;
}
if ((addr + cbData) > cbSector)
{
Application->MessageBox("Warning: hex file address exceeds selected sector size.\nData past the last sector address will be ignored.",
"Warning", MB_ICONEXCLAMATION|MB_OK);
bRet = TRUE;
leave_cycle = 1;
}
}
}
fclose(file);
// If the hex file was valid, write the data to flash
if (!bRet)
{
OnError("Invalid syntax in hex file.");
}
else
{
if (verify)
{
uchar buffer2[MAX_SECTOR_SIZE];
memset(buffer2, 0xFF, sizeof(buffer2));
if (ReadFlash(flash, sector, 0, buffer2, cbSector))
{
for (i = 0; i < cbSector; i++)
{
if (buffer[i] != buffer2[i])
{
if ((i & 0xFFF) == 0x555)
{
// Work around flash write bug
}
else
{
Application->MessageBox("File contents do not match.", "Verify", MB_OK);
return TRUE;
}
}
}
Application->MessageBox("File contents match.", "Verify", MB_OK);
return TRUE;
}
}
else
{
bRet = WriteFlash(flash, sector, 0, buffer, cbSector);
}
}
return bRet;
}
//---------------------------------------------------------------------------
/////////////////// ResetBoard()
//
// Sends a command to reset the chip.
//
// Function has no parameters.
// Function returns TRUE on success, FALSE on error.
BOOL ResetBoard()
{
// Hack: get display monitor thread thread to exit
HANDLE hDevice = g_hDevice;
g_hDevice = INVALID_HANDLE_VALUE;
Sleep(1000);
REPORT_BUF reportBuf;
memset(&reportBuf, 0, sizeof(REPORT_BUF));
// Send command
reportBuf.reportID = 0;
reportBuf.report.u.cmd = CMD_RESET;
DWORD cbWritten;
if (!WriteFile(hDevice, &reportBuf, sizeof(REPORT_BUF), &cbWritten, NULL))
{
OnError("Error sending CMD_RESET command.");
return FALSE;
}
CloseHandle(hDevice);
Disconnect(hInputThread);
hInputThread = NULL; // clear the handle variable
Sleep(1000);
return TRUE;
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// BUTTON FUNCTIONALITY IMPLEMENTATION
//---------------------------------------------------------------------------
// In this section is code which is executed after user pressed some of
// the controll buttons.
/////////////////// btConnectClick()
//
// Creates or cancels the connection to the board
void __fastcall TmainForm::btConnectClick(TObject *Sender)
{
char path[MAX_PATH];
if (btConnect->Caption == "Connect") // check if the board is already connected...
{ // if not, we will try to establish a connection.
if (Sender != NULL)
{
Timer1->Enabled = 1; // enable the auto-detection timer
lbAutodetect->Visible = 0; // notify the user that plug/unplug detection feature is ON
}
if (ConnectDevice(path)) // if connection process resulted in success...
{
Label2->Caption = AnsiString(path+4);
btConnect->Caption = "Disconnect";
btRead->Enabled = 1; // enable all IAP buttons and other controls
btWrite->Enabled = 1;
btErase->Enabled = 1;
btVerify->Enabled = 1;
btProgram->Enabled = 1;
btBlankCheck->Enabled = 1;
btUpload->Enabled = 1;
btReset->Enabled = 1;
btStopMirror->Enabled = 1;
rbMain->Enabled = 1;
rbBoot->Enabled = 1;
cbSector->Enabled = 1;
edOffset->Enabled = 1;
edCount->Enabled = 1;
edData->Enabled = 1;
mainForm->sbStatus->Panels->Items[0]->Text = "Connected to the board, ready...";
}
else
OnError("Failed to open connection to ST demo board.\n\n"
"Please un-plug the uPSD demo board from the PC "
"(USB cable), \nwait, and then re-plug the device "
"back in and try to connect.");
}
else
{ // if the board is connected, we will disconnect it.
if (Sender != NULL)
{
Timer1->Enabled = 0; // stop the auto-detection timer
mainForm->sbStatus->Panels->Items[0]->Text = "Board has been disconnected by software...";
lbAutodetect->Visible = 1; // notify the user that plug/unplug detection feature is OFF
}
else
{ // if mirroring thread lost the response from the board, display status message
mainForm->sbStatus->Panels->Items[0]->Text = "Connection to the board lost...";
}
btConnect->Caption = "Connect";
btRead->Enabled = 0; // disable all IAP buttons and other controls
btWrite->Enabled = 0;
btErase->Enabled = 0;
btVerify->Enabled = 0;
btProgram->Enabled = 0;
btBlankCheck->Enabled = 0;
btUpload->Enabled = 0;
btStopMirror->Enabled = 0;
btReset->Enabled = 0;
rbMain->Enabled = 0;
rbBoot->Enabled = 0;
cbSector->Enabled = 0;
edOffset->Enabled = 0;
edCount->Enabled = 0;
edData->Enabled = 0;
lbDisplayMirror->Caption = "";
Disconnect(hInputThread);
}
btStopMirror->Caption = "Stop Mirror";
}
//---------------------------------------------------------------------------
/////////////////// btStopMirrorClick()
//
// Stops or restarts the mirroring of LCD display content.
void __fastcall TmainForm::btStopMirrorClick(TObject *Sender)
{
if (hInputThread)
{ // Stop LCD-display mirroring thread
btStopMirror->Caption = "Start Mirror";
SetEvent(g_hStopEvent); // set the state of the specified event object to signaled
CloseHandle(hInputThread); // close the input thread's handle
hInputThread = NULL; // clear the handle variable
Timer1->Enabled = 1; // enable the auto-detection timer
lbAutodetect->Visible = 1; // notify the user that plug/unplug detection feature is OFF
}
else
{ // Create thread to manage LCD mirror
btStopMirror->Caption = "Stop Mirror";
hInputThread = CreateInputThread();
if (!hInputThread)
{
CloseHandle(g_hDevice);
g_hDevice = INVALID_HANDLE_VALUE;
}
lbAutodetect->Visible = 0; // notify the user that plug/unplug detection feature is ON
}
}
//---------------------------------------------------------------------------
/////////////////// btReadClick()
//
// Reads data of given length from specified offset of selected
// flash sector and displays it in edit controls.
void __fastcall TmainForm::btReadClick(TObject *Sender)
{
if (ReadData())
mainForm->sbStatus->Panels->Items[0]->Text = "Read Flash done.";
}
//---------------------------------------------------------------------------
/////////////////// btWriteClick()
//
// Reads data and length from edit controls and writes it
// to selected flash sector at specified offset.
void __fastcall TmainForm::btWriteClick(TObject *Sender)
{
if (WriteData())
mainForm->sbStatus->Panels->Items[0]->Text = "Write Flash done.";
}
//---------------------------------------------------------------------------
/////////////////// btEraseClick()
//
// Erases the selected flash sector.
void __fastcall TmainForm::btEraseClick(TObject *Sender)
{
if(SELECTED_SECTOR==0){
if(Application->MessageBox("The IAP firmware resides in sector number zero.\nDo you really want to erase this sector ?\n","Warning",MB_YESNO|MB_ICONEXCLAMATION)==IDYES){
if (SectorErase(SELECTED_FLASH, SELECTED_SECTOR))
mainForm->sbStatus->Panels->Items[0]->Text = "Erase Sector done.";
} else mainForm->sbStatus->Panels->Items[0]->Text = "Sector was not erased.";
} else if (SectorErase(SELECTED_FLASH, SELECTED_SECTOR))
mainForm->sbStatus->Panels->Items[0]->Text = "Erase Sector done.";
}
//---------------------------------------------------------------------------
/////////////////// btBlankCheckClick()
//
// Checks the selected flash sector whether it is blank or not.
// Being blank means to have all bytes set to 0xFF.
void __fastcall TmainForm::btBlankCheckClick(TObject *Sender)
{
if (BlankCheck(SELECTED_FLASH, SELECTED_SECTOR))
mainForm->sbStatus->Panels->Items[0]->Text = "Blank Check done.";
}
//---------------------------------------------------------------------------
/////////////////// btUploadClick()
//
// Reads data from the selected flash sector and saves it to file.
void __fastcall TmainForm::btUploadClick(TObject *Sender)
{
if (UploadToFile(SELECTED_FLASH, SELECTED_SECTOR))
mainForm->sbStatus->Panels->Items[0]->Text = "Upload done.";
else mainForm->sbStatus->Panels->Items[0]->Text = "Upload cancelled.";
}
//---------------------------------------------------------------------------
/////////////////// btProgramClick()
//
// Loads data from file and writes it to selected flash sector.
void __fastcall TmainForm::btProgramClick(TObject *Sender)
{
// Prompt user for file
mainForm->sbStatus->Panels->Items[0]->Text = "Program Sector...";
if (OpenDialog1->Execute())
{
t1 = Now();
if (ProgramOrVerify(SELECTED_FLASH, SELECTED_SECTOR, FALSE, OpenDialog1->FileName.c_str())){
mainForm->sbStatus->Panels->Items[0]->Text = "Program Sector done.";
t2 = Now();
mainForm->sbStatus->Panels->Items[0]->Text += " Time consumed is " + AnsiString(MilliSecondsBetween(t1, t2)) +" ms.";
}
}
else mainForm->sbStatus->Panels->Items[0]->Text = "Program Sector cancelled.";
}
//---------------------------------------------------------------------------
/////////////////// btVerifyClick()
//
// Verifies the content of selected flash sector with data from given file.
void __fastcall TmainForm::btVerifyClick(TObject *Sender)
{
// Prompt user for file
mainForm->sbStatus->Panels->Items[0]->Text = "Verify Sector...";
if (OpenDialog1->Execute())
{
if (ProgramOrVerify(SELECTED_FLASH, SELECTED_SECTOR, TRUE, OpenDialog1->FileName.c_str()))
mainForm->sbStatus->Panels->Items[0]->Text = "Verify Sector done.";
}
else mainForm->sbStatus->Panels->Items[0]->Text = "Verify Sector cancelled.";
}
//---------------------------------------------------------------------------
/////////////////// btResetClick()
//
// Resets the board.
void __fastcall TmainForm::btResetClick(TObject *Sender)
{
mainForm->sbStatus->Panels->Items[0]->Text = "Board reset...";
mainForm->Repaint(); // refresh the texts displayed on the main form
ResetBoard();
Application->MessageBox("Please check if you have Disconnect-on-Demand feature\nimplemented and enabled in your demo FW.\nIf not, please unplug and replug the USB connector now.","Reset in progress");
}
//---------------------------------------------------------------------------
/////////////////// btCloseClick()
//
// Closes the program.
void __fastcall TmainForm::btCloseClick(TObject *Sender)
{
// Stop LCD-display mirroring thread
SetEvent(g_hStopEvent); // set the state of the specified event object to signaled
CloseHandle(hInputThread); // close the input thread's handle
hInputThread = NULL; // clear the handle variable
// Terminate the application
Application->Terminate();
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// AUTO-DETECTION ROUTINES
//---------------------------------------------------------------------------
// In this section there is code for the device plug/unplug detection.
/////////////////// CheckIfDeviceIsPresent()
//
// Checks if our device is present
int CheckIfDeviceIsPresent(){
if (OpenDeviceHandle()){
char path[256];
strcpy(path,g_devicePath+4);
CloseHandle(g_hDevice);
g_hDevice = INVALID_HANDLE_VALUE;
return 1;
}
else return 0;
}
//---------------------------------------------------------------------------
/////////////////// Timer1Timer()
//
// Periodically searches for the device if it is present
void __fastcall TmainForm::Timer1Timer(TObject *Sender)
{
Timer1->Enabled = 0; // Disable the timer to prevent event overlap
if (!IsConnected()){
if (CheckIfDeviceIsPresent()){
btConnectClick(NULL);
}
}
Timer1->Enabled = 1; // Re-enable the timer
}
//---------------------------------------------------------------------------
/////////////////// btAboutClick()
//
// Displays the About Program info.
void __fastcall TmainForm::btAboutClick(TObject *Sender)
{
Application->MessageBox("USB In-Application-Programming Demo v.1.1.1\n\n(c)2003 ST Microelectronics\n\nMemory Products Group, Design & Application Center, Prague\n\nMembers of the team are:\nMarian Ilecko (responsible for Windows SW)\nPetr Pfeifer (responsible for uPSD FW)\n\nIf you have any questions, contact us on our addresses:\nmarian.ilecko@st.com\npetr.pfeifer@st.com","About the program",MB_OK);
}
//---------------------------------------------------------------------------
/////////////////// rbMainClick()
//
// This control changes execution page between primary and secondary flash.
// While the program is executed from primary, it can access secondary flash
// mapped in data space. On the contrary, when executing from secondary, the
// primary flash can be accessed for reading and writing.
// This method is also attached to ComboBox control, which selects among
// flash sectors. After changing these options, the command to the board is
// sent immediately. You can see the result on the LCD display.
void __fastcall TmainForm::rbMainClick(TObject *Sender)
{
if(rbMain->Checked)
{
if(cbSector->Items->Count==4){
cbSector->Items->Add("4");
cbSector->Items->Add("5");
cbSector->Items->Add("6");
cbSector->Items->Add("7");
}
}
else {
if(cbSector->ItemIndex>3)
cbSector->ItemIndex=3;
if(cbSector->Items->Count==8)
for(int i=0;i<4;i++)
cbSector->Items->Delete(4);
}
// Select the target sector
if (!SelectFlash(SELECTED_FLASH, SELECTED_SECTOR))
mainForm->sbStatus->Panels->Items[0]->Text = "Error changing the execution page...";
else
mainForm->sbStatus->Panels->Items[0]->Text = "Execution page changed...";
}
//---------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -