⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usb_demo.cpp

📁 ST公司upsd34XX评估板上位机源程序
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/////////////////////////////////////////////////////////////////////////////
// USB_Demo.cpp
//
// Main source for Mirror example application.
//
// Author: Jon Moore, Marian Ilecko
//
// Revision History:
//
// 06/12/02 (JAM) V1.0.0 - Initial coding.
// 08/29/02 (JAM) V1.0.1 - Use second device handle for LCD mirror input thread.
// 08/30/02 (JAM) V1.0.2 - Use ST vendor ID and 0x8000 sector size for 2MB part.
// 10/21/02 (JAM) V1.0.3 - Fixed hex file format bug; added critical section to
//                         synch monitor thread and main thread.
// 11/02/02 (JAM) V1.0.5 - Minor message changes; fixed boot flash page register
//                         bug; flash radio buttons immediately switch to selected
//                         flash.
// 11/04/02 (JAM) V1.0.6 - Change to erase flash sector rather than entire flash.
//
// 22/09/03 (MI)  V1.0.7 - Auto-detection feature
// 25/09/03 (MI)  V1.0.7 - Port to Borland C++ Builder in progress
// 29/09/03 (MI)  V1.0.7 - Porting finalized
// 01/10/03 (MI)  V1.0.7 - Some bugfixes and improvements
// 10/10/03 (MI)  V1.0.7 - Rearrangements, commenting
// 11/25/03 (MI)  V1.0.9 - Memory leakage bug fixed
// 11/26/03 (MI)  V1.1.0 - Some improvements and adjustments
// 11/26/03 (MI)  V1.1.1 - Some fixes, added Alt-? keys on some buttons
//
// Copyright (c)2003 ST Microelecronics
// All rights reserved.
//
//---------------------------------------------------------------------------
// This example demo code is provided as is and has no warranty,
// implied or otherwise.  You are free to use/modify any of the provided
// code at your own risk in your applications with the expressed limitation
// of liability (see below) so long as your product using the code contains
// at least one uPSD products (device).
//
// LIMITATION OF LIABILITY:   NEITHER STMicroelectronics NOR ITS VENDORS OR
// AGENTS SHALL BE LIABLE FOR ANY LOSS OF PROFITS, LOSS OF USE, LOSS OF DATA,
// INTERRUPTION OF BUSINESS, NOR FOR INDIRECT, SPECIAL, INCIDENTAL OR
// CONSEQUENTIAL DAMAGES OF ANY KIND WHETHER UNDER THIS AGREEMENT OR
// OTHERWISE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
//---------------------------------------------------------------------------

#include <vcl.h>
#include <setupapi.h>
#include <stdio.h>
#include <DateUtils.hpp>
#pragma hdrstop

#define WIN32 YES
//app_intr.h file needs to know whether it's included into Win32 or 8051 app.
//this is very important 'cause there are certain differences in data types used
//also be careful with compiler options, do not use other data alignments then single-byte!
//we will ensure of this using following directive:
#pragma pack(1)

#include "app_intr.h"
#include "USB_demo.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TmainForm *mainForm;
//---------------------------------------------------------------------------

/////////////////// Macros

#define min(x,y) (((x)<(y))?(x):(y))
#define SELECTED_FLASH ((mainForm->rbMain->Checked==TRUE)?(PRIMARY_FLASH):(SECONDARY_FLASH))
#define SELECTED_SECTOR ((BYTE) mainForm->cbSector->ItemIndex)

// For converting 8051 big endian to x86 little endian format
#define SWAP_UINT16(x) ((((x)&0xff00)>>8) | (((x)&0x00ff)<<8))
#define SWAP_UINT32(x) ((((x)&0xff000000)>>24) | (((x)&0x00ff0000)>>8) | (((x)&0x0000ff00)<<8) | (((x)&0x000000ff)<<24))

/////////////////// Constants

#define MAX_NUM_MMF_ENTRIES 32
#define MAX_SECTOR_SIZE 0x8000

#define VERSION_STR			"(v1.1.1)"
#define UPSD_2MB

#define ST_VENDOR_ID        0x0483
#define ST_PRODUCT_ID       0x0000
#define PRIMARY_FLASH_VM    0x92
#define SECONDARY_FLASH_VM  0x8C

/////////////////// Typedefs

typedef struct _HIDD_ATTRIBUTES
{
    ULONG   Size; // = sizeof (struct _HIDD_ATTRIBUTES)

    USHORT  VendorID;
    USHORT  ProductID;
    USHORT  VersionNumber;

} HIDD_ATTRIBUTES, *PHIDD_ATTRIBUTES;

typedef VOID (__stdcall *PHidD_GetProductString)(HANDLE, PVOID, ULONG);
typedef VOID (__stdcall *PHidD_GetHidGuid)(LPGUID);
typedef BOOLEAN (__stdcall *PHidD_GetAttributes)(HANDLE, PHIDD_ATTRIBUTES);
typedef BOOLEAN (__stdcall *PHidD_SetFeature)(HANDLE, PVOID, ULONG);
typedef BOOLEAN (__stdcall *PHidD_GetFeature)(HANDLE, PVOID, ULONG);

typedef struct
{
    // The Microsoft HID driver expects a prefix report ID byte
    unsigned char reportID;
    MCU_CMD report;

} REPORT_BUF, *PREPORT_BUF;

typedef struct
{
    int regValue;
    int regMask;
    int start;
    int end;
    int length;
    int swapValue;
    int swapMask;
    BOOL swappable;
    int swapStart;
    int swapEnd;

} MMF_ENTRY, *PMMF_ENTRY;

/////////////////// Globals

HANDLE           g_hDevice              = INVALID_HANDLE_VALUE;
char             g_devicePath[MAX_PATH] = {0};
HANDLE           g_hStopEvent           = NULL;
CRITICAL_SECTION g_crSection;

MMF_ENTRY        g_mmfEntries[MAX_NUM_MMF_ENTRIES];
int              g_nMmfEntries = 0;

PHidD_GetProductString     HidD_GetProductString   = NULL;
PHidD_GetHidGuid           HidD_GetHidGuid         = NULL;
PHidD_GetAttributes        HidD_GetAttributes      = NULL;
PHidD_SetFeature           HidD_SetFeature         = NULL;
PHidD_GetFeature           HidD_GetFeature         = NULL;

HINSTANCE         hHID;
TCHAR             displayBuffer[LCD_BUFFER_SIZE];
static HANDLE     hInputThread = NULL;

int test_runs,stop_test,time_consumed_for_ReadFlash;
TDateTime t1,t2; // used for measurement of operation's time consumption

//---------------------------------------------------------------------------


/////////////////// OnError()
//
// Generic error handler.

void OnError(char *pszMsg)
{
   Application->MessageBox(pszMsg, "Error", MB_OK|MB_ICONEXCLAMATION);
}

//---------------------------------------------------------------------------
//              MAIN FORM CONSTRUCTOR, DESTRUCTOR AND MISCELLANEOUS FUNCTIONS
//---------------------------------------------------------------------------


/////////////////// TmainForm()
//
// Most of the initializations are done in mainForm's constructor
//
__fastcall TmainForm::TmainForm(TComponent* Owner)
        : TForm(Owner)
{
   int sizeof_REPORT_BUF; // we will test if size of output report structure is correct
   sizeof_REPORT_BUF = sizeof(REPORT_BUF);
   if (sizeof_REPORT_BUF != 65){
      Application->MessageBox("Warning: the program has been compiled using data alignment different then single-byte.\nThis affects data structures and prevents the program from correct operation.\nPlease re-compile the program using correct compiler options.","Error",MB_OK|MB_ICONEXCLAMATION);
      Application->Terminate();
   }
   else
   {
      // The LoadLibrary function maps the specified executable module
      // into the address space of the calling process.
      hHID = LoadLibrary("HID.DLL");   // assign the handle to variable hHID

      // If the function succeeds, the return value is a handle to the module.
      // If the function fails, the return value is NULL.
      if (!hHID) // Then the error message is generated.
      {
         OnError("Failed to load HID.DLL.");
      }

      // The GetProcAddress function returns the address of the specified
      // exported dynamic-link library (DLL) function.
      // We export only those functions which we need.
      HidD_GetProductString = (PHidD_GetProductString)
         GetProcAddress(hHID, "HidD_GetProductString");
      HidD_GetHidGuid = (PHidD_GetHidGuid)
         GetProcAddress(hHID, "HidD_GetHidGuid");
      HidD_GetAttributes = (PHidD_GetAttributes)
         GetProcAddress(hHID, "HidD_GetAttributes");
      HidD_SetFeature = (PHidD_SetFeature)
         GetProcAddress(hHID, "HidD_SetFeature");
      HidD_GetFeature = (PHidD_GetFeature)
         GetProcAddress(hHID, "HidD_GetFeature");

      if ( !HidD_GetHidGuid
         || !HidD_GetAttributes
         || !HidD_GetProductString
         || !HidD_SetFeature
         || !HidD_GetFeature )
      {
         OnError("Couldn't find one or more HID entry points.");
         FreeLibrary(hHID);
      }
      g_hStopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
      InitializeCriticalSection(&g_crSection);
      Timer1->Enabled = 1; // enable the auto-detection timer
      mainForm->BringToFront();
   }
}
//---------------------------------------------------------------------------


/////////////////// FormDestroy()
//
// When closing the form, we close StopEvent handle and free HID library
//
void __fastcall TmainForm::FormDestroy(TObject *Sender)
{
   CloseHandle(g_hStopEvent);
   FreeLibrary(hHID);
}
//---------------------------------------------------------------------------


/////////////////// FormClose()
//
// Before closing the form, we must stop the LCD-display mirroring thread
//
void __fastcall TmainForm::FormClose(TObject *Sender, TCloseAction &Action)
{
   // 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
}
//---------------------------------------------------------------------------


/////////////////// UpdateDisplay()
//
// Displays mirrored data to panel at mainForm.

void __fastcall UpdateDisplay(char *src)
{
   src[LCD_BUFFER_SIZE-1] = 0;
   mainForm->lbDisplayMirror->Caption = AnsiString(src);
}
//---------------------------------------------------------------------------


//---------------------------------------------------------------------------
//              CONNECTION AND INPUT THREAD MANAGING ROUTINES
//---------------------------------------------------------------------------


/////////////////// IsConnected()
//
// Checks if connection to the board exists.
//
// Function returns TRUE if the board is connected, or FALSE if it isn't.

BOOL IsConnected()
{
   return g_hDevice != INVALID_HANDLE_VALUE;
}
//---------------------------------------------------------------------------


/////////////////// Disconnect()
//
// Closes handle to device and stops LCD mirror input thread.
//
// The function requires one argument - the handle to the thread to close.

void Disconnect(HANDLE hInputThread)
{
   if (g_hDevice != INVALID_HANDLE_VALUE)
   {
      CloseHandle(g_hDevice);
      g_hDevice = INVALID_HANDLE_VALUE;
   }

   // Close handle to input thread
   if (hInputThread)
   {
      // Tell input thread to exit
      SetEvent(g_hStopEvent); // set the state of the specified event object to signaled
      if (WaitForSingleObject(hInputThread, 3000) != WAIT_OBJECT_0)
      {
//         OnError("Input thread not exiting in 3 seconds.");
      }
      CloseHandle(hInputThread); // close the input thread's handle
   }
}
//---------------------------------------------------------------------------


/////////////////// OpenDeviceHandle()
//
// Attempts to open a handle to a ST HID device.
//
// If successful, OpenDeviceHandle returns 1 and stores the
// device path in g_devicePath; else OpenDeviceHandle returns 0.

   SP_DEVICE_INTERFACE_DATA devData;
   SP_INTERFACE_DEVICE_DETAIL_DATA DetailData;

int OpenDeviceHandle()
{
   // Get HID GUID
   GUID guid;                // GUID structure holds a globally unique identifier (GUID),
   (HidD_GetHidGuid)(&guid); // which identifies a particular object class and interface.

   // Open handle to the set of all HID devices
   HDEVINFO hDevInfo = SetupDiGetClassDevs(&guid, NULL, NULL, DIGCF_PRESENT|DIGCF_INTERFACEDEVICE);

   if (hDevInfo == INVALID_HANDLE_VALUE)
   {
      OnError("Failed to open handle to HID device set.");
      return 0;
   }

   devData.cbSize = sizeof(devData);

   // For each HID device...
   DWORD dwIndex = 0;
   bool success;
   while (1)
   {
      success = SetupDiEnumDeviceInterfaces(hDevInfo, 0, &guid, dwIndex, &devData);
      if (success == FALSE) // no more devices found
      {  // destroy a device information set and free all associated memory
         SetupDiDestroyDeviceInfoList(hDevInfo);
         return 0;
      }
      dwIndex++;

      DetailData.cbSize = 5;
      unsigned long BytesReturned;
      success = SetupDiGetDeviceInterfaceDetail(hDevInfo, &devData, &DetailData, 256, &BytesReturned, NULL);

      if (success)
      {
         // Open handle to device
         HANDLE hDevice = CreateFile(DetailData.DevicePath, GENERIC_READ|GENERIC_WRITE,
                           FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);

         if (hDevice != INVALID_HANDLE_VALUE)
         {
            // Get vendor and product ID values
            HIDD_ATTRIBUTES attr;
            attr.Size = sizeof(attr);
            if ((HidD_GetAttributes)(hDevice, &attr))
            {
               if ((attr.VendorID == ST_VENDOR_ID) && (attr.ProductID == ST_PRODUCT_ID))
               {
                  // Found our device! Store handle and device path.
                  g_hDevice = hDevice;
                  strcpy(g_devicePath, DetailData.DevicePath);
                  // destroy a device information set and free all associated memory
                  SetupDiDestroyDeviceInfoList(hDevInfo);
                  return 1;
               }
            }
            // otherwise close the handle and continue with next device in list
            CloseHandle(hDevice);
         }
      }
   }
}
//---------------------------------------------------------------------------


/////////////////// InputThreadProc()
//
// Thread procedure for input thread.
//
// The input thread reads input reports from the device. The input
// reports contain the data for the LCD mirror buffer. The LCD
// mirror buffer data is posted to the dialog box procedure and the
// dialog procedure updates the display edit field.
//
// The device can't send the whole mirror buffer at once. Multiple
// consecutive reports are used to pass the data for the buffer. Each
// input report has a mirror buffer index byte at the start and is
// then followed by the 7 bytes of data at the specified index in the
// LCD mirror buffer.

DWORD WINAPI InputThreadProc(LPVOID pParameter)
{
   static TCHAR errorMsg[256];

   // Open another handle to the HID device

   HANDLE hDevice = CreateFile(g_devicePath, GENERIC_READ|GENERIC_WRITE,
                           FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
                           FILE_FLAG_OVERLAPPED, NULL);

   if (hDevice == INVALID_HANDLE_VALUE)
	{
      sprintf(errorMsg, "CreateFile failed (Error %d)", GetLastError());
      OnError(errorMsg);
      return 0;
	}

	OVERLAPPED ol;
	memset(&ol, 0, sizeof(ol));
	ol.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

	static char lcdBuffer[LCD_BUFFER_SIZE + 1];
	memset(lcdBuffer, 0, sizeof(lcdBuffer));

	while (TRUE)
	{
		// Report buffer (Windows will put a report ID byte at the start)
		char report[INPUT_REPORT_SIZE + 1];

		// Read input report from device
      EnterCriticalSection(&g_crSection);
		DWORD cbRet;
		ResetEvent(ol.hEvent);
		BOOL bRet;
      bRet = ReadFile(hDevice, report, sizeof(report), &cbRet, &ol);
      LeaveCriticalSection(&g_crSection);

		if (!bRet)
      {
         if (GetLastError() == ERROR_IO_PENDING)
         {
				// OK - Wait for data to come in or stop event to be set
				HANDLE handles[2] = {ol.hEvent, g_hStopEvent};
				DWORD waitRet = WaitForMultipleObjects(2, handles, FALSE, INFINITE);
				if (waitRet == WAIT_OBJECT_0)
				{
               // Data came in
					bRet = GetOverlappedResult(hDevice, &ol, &cbRet, TRUE);
				}
				else if (waitRet == (WAIT_OBJECT_0 + 1))
				{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -