📄 unit1.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 + -