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

📄 unit1.cpp

📁 PSOCbootloader电脑端控制程序代码
💻 CPP
字号:
//---------------------------------------------------------------------------

#include <vcl.h>
#include <windows.h>
#include <string.h>
#include <stdio.h>
#include <io.h>
#include <fcntl.h>

#pragma hdrstop
#include "Unit1.h"
#include "Unit2.h"


//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;

#define CONNECTED 1
#define WAITING   2
#define HEX_BLOCK_LEN 141

int  LAST_BLOCK=215;   // for 27th family
//     LAST_BLOCK=463;   // for 29th family

// declarations for RS-232 API's
HANDLE hCom,hThread;
BOOL fSuccess;
COMMTIMEOUTS CommTimeOuts;
OVERLAPPED ovr;
TStringList *CommPortsList = new TStringList;

int HexFileHandle;        // handle for HEX file
char buffer[50],Error,Status=0;
char dataBuffer[HEX_BLOCK_LEN],dataFromPSoC[HEX_BLOCK_LEN];
char* FilePath="";  // Path of HEX file selected
DWORD bytesRead,bytesWritten;
//int Result;

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------

void __fastcall TForm1::btnConnectClick(TObject *Sender)
{
      DCB *dcb;
      char x='S',i;
      char *strConnect="CONNECT", *strAnswer="OK!";
      char *CommName;

//        COMMCONFIG comm;
//	CommConfigDialog("COM1",NULL,&comm);

      if ((Status & CONNECTED)||(Status & WAITING)) return;

      CommName=CommPortsList->Strings[CommPortsBox->ItemIndex].c_str();
      hCom= CreateFile(CommName,GENERIC_WRITE | GENERIC_READ,
                        0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);
      if (hCom == INVALID_HANDLE_VALUE) {
            Application->MessageBox("Port is busy and cann't be opened.","I/O Error!", MB_OK);
            hCom=0;
            return;
      }
// Configure COM-port
      dcb=(DCB*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(DCB));
      dcb->DCBlength=sizeof(DCB);
      BuildCommDCB("baud=115200 parity=N data=8 stop=1",dcb);
      dcb->fNull=TRUE;
      SetCommState(hCom,dcb);
      HeapFree(GetProcessHeap(),0,dcb);
/*
      fSuccess = GetCommState(hCom, &dcb);
      dcb.BaudRate = CBR_115200; // set the baud rate
      dcb.ByteSize = 8;          // data size, xmit, and rcv
      dcb.Parity = NOPARITY;     // no parity bit
      dcb.StopBits = ONESTOPBIT; // one stop bit
      fSuccess = SetCommState(hCom, &dcb);
      if (!fSuccess) {
          Application->MessageBox("Cann't configurate COM-port","Configuration Error!", MB_OK);
          CloseHandle(hCom); hCom=0;
          return ;
      }
*/
      // Connecting to device
      GetCommTimeouts(hCom,&CommTimeOuts);    // Timeout for questioning device
      CommTimeOuts.ReadTotalTimeoutConstant=100;
      SetCommTimeouts(hCom,&CommTimeOuts);
      PurgeComm(hCom,PURGE_RXCLEAR);

      WriteFile(hCom, strConnect, 7, &bytesWritten, &ovr);
      GetOverlappedResult(hCom,&ovr,&bytesWritten,true);

      i=0; Error=0;
      for (i=0;i<3;i++){
        ReadFile(hCom, &x, 1, &bytesRead, &ovr);
        GetOverlappedResult(hCom,&ovr,&bytesWritten,true);
        if (x!=*(strAnswer+i)) Error=1;
        buffer[i]=x;
      }
      if (Error){
        lblConnect->SetTextBuf("Not Connected");
        Application->MessageBox("Device doesn't answer! May be it is not connected or unpowered.","Communication Error!", MB_OK);
        CloseHandle(hCom); hCom=0;
        return;
      }
      buffer[i]=0;

      WriteFile(hCom, strAnswer, 3, &bytesWritten, &ovr);
      GetOverlappedResult(hCom,&ovr,&bytesWritten,true);

      lblConnect->SetTextBuf("Connected");
      lblConnect->Font->Color=clRed;
      lblValue->SetTextBuf("000");
      CheckBox1->Enabled=false;

      Status|= CONNECTED;
      ProgressBar->Position=0;
}
//---------------------------------------------------------------------------

void GetCommPorts(){
  HKEY KeyHandle;
  int ErrCode, Index;
  char ValueName[100], Data[100];
  DWORD ValueLen=100, DataLen=100, ValueType;

  ErrCode = RegOpenKeyEx(
    HKEY_LOCAL_MACHINE,
    "HARDWARE\\DEVICEMAP\\SERIALCOMM",
    0,
    KEY_READ,
    &KeyHandle);

  if (ErrCode != ERROR_SUCCESS){
    Application->MessageBox("Cann't open registry!","Regisry Error!",MB_OK);
    return;
  }
  try{
    Index = 0;
    do{
      ValueLen=DataLen=100;
      ErrCode = RegEnumValue(
        KeyHandle,
        Index,
        ValueName,
        &ValueLen,
        NULL,
        &ValueType,
        Data,
        &DataLen);

      if (ErrCode == ERROR_SUCCESS){
        CommPortsList->Add(Data);
        Index++;
      }
    }while (ErrCode == ERROR_SUCCESS);
    CommPortsList->Sort();
   }
   __finally{
    RegCloseKey(KeyHandle);
   }
}

void __fastcall TForm1::FormCreate(TObject *Sender)
{
      DCB dcb;
      HDC  DC;
      GetCommPorts();           // Obtain all COM ports List
      CommPortsBox->Items = CommPortsList; //Set List in ComboBox
      CommPortsBox->ItemIndex=0; // Set first item in ComboBox, ussually COM1

      memset(&ovr,0,sizeof(ovr));// get memory for overlapped structure
      ovr.hEvent=CreateEvent(NULL,false,false,NULL);

      ProgressBar->Position=0;
      ProgressBar->Brush->Color = clAqua;
      lblValue->SetTextBuf("000");
                  /*
      DC=GetDC(0);
      Result=(GetDeviceCaps(DC, LOGPIXELSX) == 96);
      ReleaseDC(0, DC);
      */
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
        delete CommPortsList;// destroy List Object;
        if (hCom) CloseHandle(hCom); // close port if opened
        if (HexFileHandle) FileClose(HexFileHandle);
}
//---------------------------------------------------------------------------


void __fastcall TForm1::btnSelectClick(TObject *Sender)
{
       char SelectedFileName[30],*p;
       int len,handle;
       if (OpenDialog->Execute()){
           p = FilePath = OpenDialog->FileName.c_str();
           len = strlen(p);
           p+=len;
           while ((*p) != '\\') p--;
           p++;
           strcpy(SelectedFileName,p);

           lblSelect->SetTextBuf(SelectedFileName);
           lblSelect->Font->Color=clRed;

           handle = open(FilePath,O_RDONLY);
           if (filelength(handle)==72538){
               LAST_BLOCK=463;
           }else LAST_BLOCK=215;
           close(handle);

           Form1->ProgressBar->Max=LAST_BLOCK;
       };
}
//---------------------------------------------------------------------------

void __fastcall TForm1::btnExitClick(TObject *Sender)
{
           Form1->Close();
}
//---------------------------------------------------------------------------

int SendReadControlBlock(){
  char k,s='S',f='F'; // start and last symbols of data frame
  int i,repeatCount;
  DWORD bytesRead,bytesWritten;

  //Send start frame symbol - 'S'
  WriteFile(hCom,&s, 1, &bytesWritten, &ovr);
  GetOverlappedResult(hCom,&ovr,&bytesWritten,true);
  // Send all bytes without CheckSum
  for (i=1; i<137; i++){
      if ((dataBuffer[i]>'f')||(dataBuffer[i]<'0')||
         ((dataBuffer[i]>'9')&&(dataBuffer[i]<'a'))){ // detecting non-Hex symbols
         Application->MessageBox("Hex files contains non-hex symbols","HEX file Error!",MB_OK);
         return 0;
      }
      WriteFile(hCom,dataBuffer+i, 1, &bytesWritten, &ovr);
      GetOverlappedResult(hCom,&ovr,&bytesWritten,true);
  }
  //Send last frame symbol - 'F'
  WriteFile(hCom,&f, 1, &bytesWritten, &ovr);
  GetOverlappedResult(hCom,&ovr,&bytesWritten,true);

  GetCommTimeouts(hCom,&CommTimeOuts); // Set timeout for Flash Write operation
  CommTimeOuts.ReadTotalTimeoutConstant=1000;
  SetCommTimeouts(hCom,&CommTimeOuts);
  //Reading Back Info

  ReadFile(hCom, &k, 1, &bytesRead, &ovr);
  GetOverlappedResult(hCom,&ovr,&bytesWritten,true);
  if (k!=s) return 0;
  GetCommTimeouts(hCom,&CommTimeOuts);
  CommTimeOuts.ReadTotalTimeoutConstant=25; // Set timeout between characters
  SetCommTimeouts(hCom,&CommTimeOuts);

  //ReadFile(hCom, dataFromPSoC+1, 136, &bytesRead, &ovr);
  //GetOverlappedResult(hCom,&ovr,&bytesWritten,true);

  for (i=1;i<137;i++){
     ReadFile(hCom, &k, 1, &bytesRead, &ovr);
     GetOverlappedResult(hCom,&ovr,&bytesWritten,true);
     dataFromPSoC[i]=k;
  }

  ReadFile(hCom, &k, 1, &bytesRead, &ovr);
  GetOverlappedResult(hCom,&ovr,&bytesWritten,true);
  if (k!=f) return 0;
  // Control written data in Flash symbol by symbol
  for (i=1;i<137;i++){
     if (dataBuffer[i]!=dataFromPSoC[i]){
    //    Application->MessageBox("Data written in Flash incorrectly!","Error Data!",MB_OK);
        return 0;
     }
  }
  return 1;
}

DWORD WINAPI ProgrammingThread(LPVOID lpParam)
{
  char s,k,str[5],Error=0;
  int i,RepeatWriteCount;
  long fl; char sss[20];
  DWORD bytesRead,bytesWritten;

  if (!(Status & CONNECTED)) {
      Application->MessageBox("Device is not connected!","Error!",MB_OK);
      return 0;
  }
  if ((HexFileHandle=FileOpen(FilePath,fmOpenRead))==-1){
      Application->MessageBox("File Is Not Selected or Can not Be Opened!","Error!",MB_OK);
      return 0;
  };
//  if (fl=filelength(HexFileHandle)) {
//      LAST_BLOCK=455;
//      Form1->ProgressBar->Max=LAST_BLOCK;
//  }
 // Form1->Cursor=crHourGlass;   // Change mouse cursor
  Form1->Enabled=false;
  dataBuffer[HEX_BLOCK_LEN]=0;
  FileSeek(HexFileHandle,HEX_BLOCK_LEN,0);// Start from Second Block
  for (i=1; i<=LAST_BLOCK; i++){ // For All blocks without 3 last ones
    if (FileRead(HexFileHandle,dataBuffer,HEX_BLOCK_LEN)<HEX_BLOCK_LEN) {
       Application->MessageBox("File Sructure Is Incorrect","Error!",MB_OK);
       break;
    };
    // Try to write data for 3 times
    for (RepeatWriteCount=0; RepeatWriteCount<3; RepeatWriteCount++){
       if (SendReadControlBlock()) break;
       if (RepeatWriteCount==2){
          Application->MessageBox("Data cann't be written in Flash correctly!","Error Data!",MB_OK);
          Error=1;
          goto Finish;
       }
    }
    // Informate about writing progress in the form
    Form1->ProgressBar->Position=i;
    sprintf(str,"%03u",i);
    Form1->lblValue->SetTextBuf(str);
    Form1->lblValue->Font->Color=clRed;
    Form1->lblValue->Update();
  }
  // Send Terminate Write Info - 'S' 'S' (2 bytes)
  k='S';
  WriteFile(hCom,&k, 1, &bytesWritten, &ovr);
  GetOverlappedResult(hCom,&ovr,&bytesWritten,true);
  WriteFile(hCom,&k, 1, &bytesWritten, &ovr);
  GetOverlappedResult(hCom,&ovr,&bytesWritten,true);
Finish: // Close HEX File Handler
  FileClose(HexFileHandle); HexFileHandle=0;
  CloseHandle(hCom);hCom=0;   // Close Port
  Status &= (~CONNECTED);     // Disconnect from Device
  if (Error)
     Form1->lblConnect->SetTextBuf("Programming Failed!");
  else Form1->lblConnect->SetTextBuf("Programmed and Disconnected");

  Form1->lblConnect->Font->Color=clNavy;
  Form1->CheckBox1->Font->Color=clNavy;

//  Form1->Cursor=crDefault;   // Change mouse cursor
  Form1->Enabled=true;
  Form1->CheckBox1->Enabled=true;
  return 0;
}

void __fastcall TForm1::btnProgramClick(TObject *Sender)
{
   DWORD thread, thread_param=0;
   hThread = CreateThread(NULL, 0,
                         ProgrammingThread,
                         &thread_param,
                         0,
                         &thread);
   CloseHandle(hThread);
}

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

void __fastcall TForm1::Button2Click(TObject *Sender)
{
        FormAbout->Left=Form1->Left+Form1->Width/2-FormAbout->Width/2;
        FormAbout->Top=Form1->Top+Form1->Height/2-FormAbout->Height/2;
        FormAbout->ShowModal();
}
//---------------------------------------------------------------------------

DWORD WINAPI WaitForConnectionThread(LPVOID lpParam)
{
      DCB          *dcb;
      char x='S',i;
      char *strConnect="CONNECT", *strAnswer="OK!";
      char *CommName;

      Status|=WAITING;
      CommName=CommPortsList->Strings[Form1->CommPortsBox->ItemIndex].c_str();

      hCom= CreateFile(CommName,GENERIC_WRITE | GENERIC_READ,
                        0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);
      if (hCom == INVALID_HANDLE_VALUE) {
            Application->MessageBox("Port is busy and cann't be opened.","I/O Error!", MB_OK);
            hCom=0;
            Form1->CheckBox1->Font->Color=clNavy;
            Form1->CheckBox1->Checked=false;
            Status&=(~WAITING);
            CloseHandle(hThread);
            return 0;
      }

      dcb=(DCB*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(DCB));
      dcb->DCBlength=sizeof(DCB);
      BuildCommDCB("baud=115200 parity=N data=8 stop=1",dcb);
      dcb->fNull=TRUE;
      SetCommState(hCom,dcb);
      HeapFree(GetProcessHeap(),0,dcb);

      GetCommTimeouts(hCom,&CommTimeOuts);
      CommTimeOuts.ReadTotalTimeoutMultiplier=0; // No TimeOut
      CommTimeOuts.ReadTotalTimeoutConstant=0; // No TimeOut
      SetCommTimeouts(hCom,&CommTimeOuts);

      i=0;Error=1;
      while (Error){
         PurgeComm(hCom,PURGE_RXCLEAR);
         Error=0;
         for (i=0;i<7;i++){
           ReadFile(hCom, &x, 1, &bytesRead, &ovr);
           GetOverlappedResult(hCom,&ovr,&bytesRead,true);
           if (x!=*(strConnect+i)) {Error=1;i++;break;}
         }
         if (Error) continue;
         WriteFile(hCom, strAnswer, 3, &bytesWritten, &ovr);
         GetOverlappedResult(hCom,&ovr,&bytesWritten,true);
         Sleep(10);
//         Application->MessageBox("Read CONNECT and send OK!","info", MB_OK);
         for (i=0;i<3;i++){
           ReadFile(hCom, &x, 1, &bytesRead, &ovr);
           GetOverlappedResult(hCom,&ovr,&bytesRead,true);
           if (x!=*(strAnswer+i)) {Error=1;break;}
         }
      }
      Status&=(~WAITING);
      Status|= CONNECTED;

      Form1->lblConnect->SetTextBuf("Connected");
      Form1->lblConnect->Font->Color=clRed;
      Form1->lblValue->SetTextBuf("000");

      Form1->CheckBox1->Font->Color=clNavy;
      Form1->CheckBox1->Checked=false;
      Form1->ProgressBar->Position=0;
      Form1->CheckBox1->Enabled=false;

      CloseHandle(hThread);
      return 0;
}


void __fastcall TForm1::CheckBox1Click(TObject *Sender)
{
   DWORD thread, thread_param=0;
   if (Status & CONNECTED) return;

   if (CheckBox1->Checked==true){
       hThread = CreateThread(NULL, 0,
                         WaitForConnectionThread,
                         &thread_param,
                         0,
                         &thread);
       CheckBox1->Font->Color=clRed;
   }else {
         TerminateThread(hThread,0);
         if (hCom!=0) {CloseHandle(hCom);hCom=0;}
         CloseHandle(hThread);
         CheckBox1->Font->Color=clNavy;
         Status&=(~WAITING);
   }
}
//---------------------------------------------------------------------------

⌨️ 快捷键说明

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