400 lines
12 KiB
C++
400 lines
12 KiB
C++
/*
|
|
* Copyright (c) 2013-15, Freescale Semiconductor, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without modification,
|
|
* are permitted provided that the following conditions are met:
|
|
*
|
|
* o Redistributions of source code must retain the above copyright notice, this list
|
|
* of conditions and the following disclaimer.
|
|
*
|
|
* o Redistributions in binary form must reproduce the above copyright notice, this
|
|
* list of conditions and the following disclaimer in the documentation and/or
|
|
* other materials provided with the distribution.
|
|
*
|
|
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
|
* contributors may be used to endorse or promote products derived from this
|
|
* software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
#include "stdafx.h"
|
|
#include "KinetisFlashTool.h"
|
|
#include "ConfigDlg.h"
|
|
#include "afxdialogex.h"
|
|
|
|
#include "HistoryData.h"
|
|
#include "utility.h"
|
|
#include "BootloaderConfigDlg.h"
|
|
|
|
extern void PrintLog(const wchar_t *format, ...);
|
|
// ConfigDlg dialog
|
|
|
|
IMPLEMENT_DYNAMIC(ConfigDlg, CDialogEx)
|
|
|
|
// See ConfigDlg.h for documentation of this method.
|
|
ConfigDlg::ConfigDlg(CWnd *pParent /*=NULL*/)
|
|
: CDialogEx(IDD_DIALOG_CONFIG, pParent)
|
|
, m_bcaData(NULL)
|
|
, m_bcaBinaries(_T(""))
|
|
{
|
|
}
|
|
|
|
// See ConfigDlg.h for documentation of this method.
|
|
ConfigDlg::~ConfigDlg()
|
|
{
|
|
if (m_bcaData != NULL)
|
|
{
|
|
free(m_bcaData);
|
|
}
|
|
}
|
|
|
|
// See ConfigDlg.h for documentation of this method.
|
|
void ConfigDlg::DoDataExchange(CDataExchange *pDX)
|
|
{
|
|
CDialogEx::DoDataExchange(pDX);
|
|
DDX_Control(pDX, IDC_COMBO_FILE2, m_ctrlImageFile);
|
|
DDX_Text(pDX, IDC_EDIT_BCA_BINARY, m_bcaBinaries);
|
|
}
|
|
|
|
BEGIN_MESSAGE_MAP(ConfigDlg, CDialogEx)
|
|
ON_BN_CLICKED(IDC_BUTTON_BROWSE2, &ConfigDlg::OnBnClickedButtonBrowse)
|
|
ON_CBN_SELCHANGE(IDC_COMBO_FILE2, &ConfigDlg::OnSelchangeComboFile)
|
|
ON_BN_CLICKED(IDC_BUTTON_SAVE_BCA, &ConfigDlg::OnBnClickedButtonSaveBca)
|
|
ON_EN_CHANGE(IDC_EDIT_BCA_BINARY, &ConfigDlg::OnChangeEditBcaData)
|
|
ON_WM_SHOWWINDOW()
|
|
ON_BN_CLICKED(IDC_BUTTON_CONFIG_BCA, &ConfigDlg::OnBnClickedButtonConfigBca)
|
|
ON_CBN_KILLFOCUS(IDC_COMBO_FILE2, &ConfigDlg::OnKillfocusComboFile)
|
|
END_MESSAGE_MAP()
|
|
|
|
// See ConfigDlg.h for documentation of this method.
|
|
void ConfigDlg::OnOK()
|
|
{
|
|
// CDialogEx::OnOK();
|
|
}
|
|
|
|
// See ConfigDlg.h for documentation of this method.
|
|
void ConfigDlg::OnCancel()
|
|
{
|
|
// CDialogEx::OnCancel();
|
|
}
|
|
|
|
// See ConfigDlg.h for documentation of this method.
|
|
BOOL ConfigDlg::OnInitDialog()
|
|
{
|
|
CDialogEx::OnInitDialog();
|
|
|
|
// TODO: Add extra initialization here
|
|
if (m_bcaData == NULL)
|
|
{
|
|
m_bcaData = (char *)malloc(64);
|
|
FillMemory(m_bcaData, 64, 0xFF);
|
|
}
|
|
// 128 for BCA characters,
|
|
// There are four lines of BCA characters
|
|
// 2*4 for four "\r\n" pairs.
|
|
((CEdit *)GetDlgItem(IDC_EDIT_BCA_BINARY))->SetLimitText(128 + 2 * 4);
|
|
|
|
// RefreshImageFileList();
|
|
|
|
UpdateData(FALSE);
|
|
return TRUE; // return TRUE unless you set the focus to a control
|
|
}
|
|
|
|
// See ConfigDlg.h for documentation of this method.
|
|
void ConfigDlg::RefreshImageFileList()
|
|
{
|
|
// Clear the contents
|
|
m_ctrlImageFile.ResetContent();
|
|
|
|
for (size_t i = 0; i < g_pHistoryData->GetFileCount(); i++)
|
|
{
|
|
m_ctrlImageFile.AddString(g_pHistoryData->GetFilePath(i));
|
|
}
|
|
|
|
bool enableSave = false;
|
|
if (g_pHistoryData->GetFileCount() > 0)
|
|
{
|
|
m_ctrlImageFile.SetCurSel(0);
|
|
if (g_pHistoryData->GetFileType(0) != HistoryData::FileType::kBinary)
|
|
{
|
|
PrintLog(_T("Warning: Currently, only binary file is supported!\r\n"));
|
|
enableSave = false;
|
|
}
|
|
else if (ReadBootloaderConfigureArea())
|
|
{
|
|
enableSave = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
enableSave = false;
|
|
}
|
|
if (!enableSave)
|
|
{
|
|
ResetBootloaderConfigureArea();
|
|
}
|
|
GetDlgItem(IDC_BUTTON_SAVE_BCA)->EnableWindow(enableSave);
|
|
}
|
|
|
|
// See ConfigDlg.h for documentation of this method.
|
|
BOOL ConfigDlg::ReadBootloaderConfigureArea()
|
|
{
|
|
CString filePath;
|
|
m_ctrlImageFile.GetWindowTextW(filePath);
|
|
CFile *cFile = new CFile(filePath.GetBuffer(), CFile::modeReadWrite | CFile::typeBinary);
|
|
filePath.ReleaseBuffer();
|
|
|
|
ULONGLONG length = cFile->GetLength();
|
|
if (length < 0x400)
|
|
{
|
|
PrintLog(_T("Warning: File(%s) is smaller than 1K bytes, fill 0xFFs to extend it to 1K bytes."), filePath);
|
|
cFile->SeekToEnd();
|
|
while (length < 0x400)
|
|
{
|
|
cFile->Write("\xFF", 1);
|
|
length++;
|
|
}
|
|
cFile->Flush(); // Flush the 0xFFs to file.
|
|
}
|
|
|
|
cFile->Seek(0x3C0, CFile::begin);
|
|
cFile->Read(m_bcaData, 64);
|
|
|
|
PrintLog(_T("Read BCA data from image file."));
|
|
|
|
delete cFile;
|
|
|
|
UpdateDataOfBootloaderConfigureArea(FALSE);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
// See ConfigDlg.h for documentation of this method.
|
|
void ConfigDlg::UpdateDataOfBootloaderConfigureArea(BOOL direction)
|
|
{
|
|
if (direction)
|
|
{
|
|
UpdateData(TRUE); // Update UI to CString m_bcaBinaries
|
|
|
|
int length = m_bcaBinaries.GetLength();
|
|
LPWSTR buffer = m_bcaBinaries.GetBuffer();
|
|
|
|
char tempHigh, tempLow;
|
|
int posBin = 0, posChar = 0;
|
|
while ((posBin < 64) && (posChar < length))
|
|
{
|
|
// Only convert legal characters.
|
|
if (isxdigit(buffer[posChar * 2]) && isxdigit(buffer[posChar * 2 + 1]))
|
|
{
|
|
tempHigh = buffer[posChar * 2] & 0xFF; // change TCHAR to char, abandon the high bits.
|
|
tempLow = buffer[posChar * 2 + 1] & 0xFF; // change TCHAR to char, abandon the high bits.
|
|
m_bcaData[posBin] = ((hex_to_int(tempHigh) & 0xFF) << 4) | (hex_to_int(tempLow) & 0xFF);
|
|
posBin++;
|
|
posChar++;
|
|
}
|
|
else
|
|
{
|
|
// Skip the illegal character pairs.
|
|
posChar++;
|
|
}
|
|
}
|
|
m_bcaBinaries.ReleaseBuffer();
|
|
}
|
|
else
|
|
{
|
|
LPTSTR buffer = m_bcaBinaries.GetBuffer(128 + 2 * 4 + 1); // 128 for 128 BCA characters
|
|
// 2 * 4 for enter characters("\r\n") each line
|
|
// 1 byte more for for terminator("\0")
|
|
int posBin = 0, posChar = 0;
|
|
for (; posBin < 64; posChar++, posBin++)
|
|
{
|
|
// 32 characters each line.
|
|
if ((!(posBin % 0x10)) && (posBin != 0))
|
|
{
|
|
// Add "\r\n" at the end of each line
|
|
buffer[posChar * 2] = '\r';
|
|
buffer[posChar * 2 + 1] = '\n';
|
|
posChar++;
|
|
}
|
|
buffer[posChar * 2] = int_to_hex(m_bcaData[posBin] >> 4);
|
|
buffer[posChar * 2 + 1] = int_to_hex(m_bcaData[posBin]);
|
|
}
|
|
buffer[posChar * 2] = '\0';
|
|
m_bcaBinaries.ReleaseBuffer();
|
|
|
|
UpdateData(FALSE); // Update CString m_bcaBinaries to UI
|
|
}
|
|
}
|
|
|
|
// See ConfigDlg.h for documentation of this method.
|
|
void ConfigDlg::WriteBootloaderConfigureArea()
|
|
{
|
|
UpdateDataOfBootloaderConfigureArea(TRUE);
|
|
|
|
CString filePath;
|
|
m_ctrlImageFile.GetWindowTextW(filePath);
|
|
CFile *cFile = new CFile(filePath.GetBuffer(), CFile::modeWrite | CFile::typeBinary);
|
|
filePath.ReleaseBuffer();
|
|
|
|
cFile->Seek(0x3C0, CFile::begin);
|
|
cFile->Write(m_bcaData, 64);
|
|
cFile->Flush();
|
|
|
|
PrintLog(_T("Write new BCA data to image file."));
|
|
delete (cFile);
|
|
}
|
|
|
|
// See ConfigDlg.h for documentation of this method.
|
|
void ConfigDlg::ResetBootloaderConfigureArea()
|
|
{
|
|
if (m_bcaData == NULL)
|
|
{
|
|
m_bcaData = (char *)malloc(64);
|
|
}
|
|
FillMemory(m_bcaData, 64, 0xFF);
|
|
UpdateDataOfBootloaderConfigureArea(FALSE);
|
|
}
|
|
|
|
// See ConfigDlg.h for documentation of this method.
|
|
void ConfigDlg::OnShowWindow(BOOL bShow, UINT nStatus)
|
|
{
|
|
CDialogEx::OnShowWindow(bShow, nStatus);
|
|
|
|
// Image file list might be changed at other tab page.
|
|
// Refresh it when showing this tab page.
|
|
if (bShow)
|
|
{
|
|
RefreshImageFileList();
|
|
}
|
|
}
|
|
|
|
// See ConfigDlg.h for documentation of this method.
|
|
void ConfigDlg::OnBnClickedButtonBrowse()
|
|
{
|
|
CFileDialog cFileDlg(TRUE);
|
|
|
|
cFileDlg.m_ofn.lpstrTitle = _T("Select the image file");
|
|
cFileDlg.m_ofn.lpstrFilter = _T("Supported files(*.bin)\0*.bin;\0All files(*.*)\0*.*\0\0");
|
|
if (IDOK == cFileDlg.DoModal())
|
|
{
|
|
CString fullPath = cFileDlg.GetPathName();
|
|
if (file_exists(fullPath))
|
|
{
|
|
g_pHistoryData->InsertFile(fullPath);
|
|
RefreshImageFileList();
|
|
}
|
|
else
|
|
{
|
|
PrintLog(_T("Invalid full path filename, or file doesn't exist.(%s)"), fullPath);
|
|
}
|
|
}
|
|
}
|
|
|
|
// See ConfigDlg.h for documentation of this method.
|
|
void ConfigDlg::OnChangeEditBcaData()
|
|
{
|
|
// Update UI to string variable;
|
|
UpdateData(TRUE);
|
|
}
|
|
|
|
// See ConfigDlg.h for documentation of this method.
|
|
void ConfigDlg::OnSelchangeComboFile()
|
|
{
|
|
// If a file is selected, bubble it to the head of a file list.
|
|
g_pHistoryData->BubbleSelectedFile(m_ctrlImageFile.GetCurSel());
|
|
RefreshImageFileList();
|
|
}
|
|
|
|
void ConfigDlg::OnKillfocusComboFile()
|
|
{
|
|
if (m_ctrlImageFile.GetCurSel() >= 0)
|
|
{
|
|
// If no change in the textbox, then return;
|
|
return;
|
|
}
|
|
|
|
CString filePath;
|
|
m_ctrlImageFile.GetWindowTextW(filePath);
|
|
|
|
// Test if the file exists
|
|
if (file_exists(filePath))
|
|
{
|
|
// File exists, add it to history file list, and refresh commbo box.
|
|
g_pHistoryData->InsertFile(filePath);
|
|
RefreshImageFileList();
|
|
}
|
|
else
|
|
{
|
|
// File doesn't exist.
|
|
if (!filePath.IsEmpty())
|
|
{
|
|
PrintLog(_T("Invalid full path filename, or file doesn't exist.(%s)"), filePath);
|
|
}
|
|
m_ctrlImageFile.SetCurSel(-1); // Set invalid selection.
|
|
ResetBootloaderConfigureArea(); // Reset configureArea to 0xFFs.
|
|
GetDlgItem(IDC_BUTTON_SAVE_BCA)->EnableWindow(false); // Disable save button.
|
|
}
|
|
}
|
|
|
|
// See ConfigDlg.h for documentation of this method.
|
|
void ConfigDlg::OnBnClickedButtonConfigBca()
|
|
{
|
|
// BCA data in the UI page might be changed.
|
|
// Update it to memory region.
|
|
UpdateDataOfBootloaderConfigureArea(TRUE);
|
|
|
|
CString filePath;
|
|
m_ctrlImageFile.GetWindowTextW(filePath);
|
|
|
|
CFile *cFile = new CFile;
|
|
if (!cFile->Open(filePath, CFile::modeRead | CFile::typeBinary, NULL))
|
|
{
|
|
// If cannot open this file, transfer NULL to bootloader config dlg.
|
|
delete cFile;
|
|
cFile = NULL;
|
|
}
|
|
else
|
|
{
|
|
// Check if this file is binary file.
|
|
CString extension = PathFindExtension(filePath);
|
|
if (extension.CompareNoCase(_T(".bin")) != 0)
|
|
{
|
|
// If not binary file, close it and transfer NULL to bootloader config dlg.
|
|
cFile->Close();
|
|
delete cFile;
|
|
cFile = NULL;
|
|
}
|
|
}
|
|
|
|
BootloaderConfigDlg dlg((blfwkdll::BootloaderConfigureAreaData *)m_bcaData, cFile, this);
|
|
|
|
dlg.DoModal();
|
|
|
|
// Update the new BCA to UI page.
|
|
UpdateDataOfBootloaderConfigureArea(FALSE);
|
|
|
|
if (cFile != NULL)
|
|
{
|
|
cFile->Close();
|
|
delete cFile;
|
|
cFile = NULL;
|
|
}
|
|
}
|
|
|
|
// See ConfigDlg.h for documentation of this method.
|
|
void ConfigDlg::OnBnClickedButtonSaveBca()
|
|
{
|
|
WriteBootloaderConfigureArea();
|
|
}
|