Files
bootloader/apps/KinetisFlashTool/KinetisFlashTool/KinetisFlashToolDlg.cpp
László Monda e6c1fce5b4 Add KBOOT.
2016-08-10 01:45:15 +02:00

948 lines
34 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.
*/
// KinetisFlashToolDlg.cpp : implementation file
//
#include "stdafx.h"
#include "KinetisFlashTool.h"
#include "KinetisFlashToolDlg.h"
#include "afxdialogex.h"
#include "SerialList.h"
#include "HistoryData.h"
#include "Bootloader.h"
#include "utility.h"
#include <WinUser.h>
#include <Dbt.h>
#include <cfgmgr32.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
CKinetisFlashToolDlg *g_pMainDlg;
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialogEx
{
public:
//! \brief Generated standard constructor.
CAboutDlg();
// Dialog Data
enum
{
IDD = IDD_ABOUTBOX
};
protected:
virtual void DoDataExchange(CDataExchange *pDX); // DDX/DDV support
// Implementation
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg()
: CDialogEx(CAboutDlg::IDD)
{
}
void CAboutDlg::DoDataExchange(CDataExchange *pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()
// CKinetisFlashToolDlg dialog
IMPLEMENT_DYNAMIC(CKinetisFlashToolDlg, CDialogEx);
// See CKinetisFlashToolDlg.h for documentation of this method.
CKinetisFlashToolDlg::CKinetisFlashToolDlg(CWnd *pParent /*=NULL*/)
: CDialogEx(CKinetisFlashToolDlg::IDD, pParent)
, m_log(_T(""))
, m_bootloaderVersion(_T(""))
, m_protoclVersion(_T(""))
, m_securityState(_T(""))
, m_flashSize(_T(""))
, m_flashSector(_T(""))
, m_ramSize(_T(""))
, m_rsvRgnFlashStart(_T(""))
, m_rsvRgnFlashEnd(_T(""))
, m_rsvRgnRamStart(_T(""))
, m_rsvRgnRamEnd(_T(""))
, m_devNotify(NULL)
{
m_hIcon = AfxGetApp()->LoadIcon(IDI_FREESCALE);
}
// See CKinetisFlashToolDlg.h for documentation of this method.
CKinetisFlashToolDlg::~CKinetisFlashToolDlg()
{
// If there is an automation proxy for this dialog, set
// its back pointer to this dialog to NULL, so it knows
// the dialog has been deleted.
// if (m_pAutoProxy != NULL)
// m_pAutoProxy->m_pDialog = NULL;
}
// See CKinetisFlashToolDlg.h for documentation of this method.
void CKinetisFlashToolDlg::DoDataExchange(CDataExchange *pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_TAB_FUNC, m_tabFunc);
DDX_Control(pDX, IDC_COMBO_PORT_VID, m_comboPortOrVID);
DDX_Control(pDX, IDC_COMBO_BAUD_PID, m_comboBaudOrPID);
DDX_Text(pDX, IDC_EDIT_LOG, m_log);
DDX_Control(pDX, IDC_EDIT_LOG, m_logCtrl);
DDX_Text(pDX, IDC_STATIC_BOOTLLOADER_VERSION, m_bootloaderVersion);
DDX_Text(pDX, IDC_STATIC_SERIAL_VERSION, m_protoclVersion);
DDX_Text(pDX, IDC_STATIC_SECURITY_STATE, m_securityState);
DDX_Text(pDX, IDC_STATIC_FLASH_SIZE, m_flashSize);
DDX_Text(pDX, IDC_STATIC_SECTOR_SIZE, m_flashSector);
DDX_Text(pDX, IDC_STATIC_RAM_SIZE, m_ramSize);
DDX_Text(pDX, IDC_STATIC_RESERVED_FLASH_START, m_rsvRgnFlashStart);
DDX_Text(pDX, IDC_STATIC_RESERVED_FLASH_END, m_rsvRgnFlashEnd);
DDX_Text(pDX, IDC_STATIC_RESERVED_RAM_START, m_rsvRgnRamStart);
DDX_Text(pDX, IDC_STATIC_RESERVED_RAM_END, m_rsvRgnRamEnd);
}
BEGIN_MESSAGE_MAP(CKinetisFlashToolDlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_CLOSE()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_RADIO_UART, &CKinetisFlashToolDlg::OnBnClickedRadio)
ON_BN_CLICKED(IDC_RADIO_USBHID, &CKinetisFlashToolDlg::OnBnClickedRadio)
ON_NOTIFY(TCN_SELCHANGE, IDC_TAB_FUNC, &CKinetisFlashToolDlg::OnTcnSelchangeTabFunc)
ON_CBN_SELCHANGE(IDC_COMBO_PORT_VID, &CKinetisFlashToolDlg::OnCbnSelchangeComboPortVid)
ON_CBN_SELCHANGE(IDC_COMBO_BAUD_PID, &CKinetisFlashToolDlg::OnCbnSelchangeComboBaudPid)
ON_CBN_KILLFOCUS(IDC_COMBO_PORT_VID, &CKinetisFlashToolDlg::OnKillfocusComboPortVid)
ON_CBN_KILLFOCUS(IDC_COMBO_BAUD_PID, &CKinetisFlashToolDlg::OnKillfocusComboBaudPid)
ON_BN_CLICKED(IDC_BUTTON_CNT_RESET, &CKinetisFlashToolDlg::OnClickedButtonCntReset)
ON_WM_TIMER()
ON_WM_DEVICECHANGE()
// User defined message
ON_MESSAGE(USER_MS_UPDATA_LOG, &CKinetisFlashToolDlg::OnUpdateLog)
ON_MESSAGE(USER_MS_CONNECTION_CHANGE, &CKinetisFlashToolDlg::OnChangeConnection)
ON_MESSAGE(USER_MS_UPDATA_STATUS, &CKinetisFlashToolDlg::OnUpdateStatus)
END_MESSAGE_MAP()
// CKinetisFlashToolDlg message handlers
// See CKinetisFlashToolDlg.h for documentation of this method.
BOOL CKinetisFlashToolDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu *pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// ShowWindow(SW_MAXIMIZE);
// TODO: Add extra initialization here
g_pMainDlg = this;
// Init COM port and baudrate list
RefreshComPortList();
RefreshBaudrateList();
// Init port button. uart is selected as default
((CButton *)GetDlgItem(IDC_RADIO_UART))->SetCheck(true);
((CButton *)GetDlgItem(IDC_RADIO_USBHID))->SetCheck(false);
((CEdit *)GetDlgItem(IDC_STATIC_PORT_VID))->SetWindowTextW(_T("Port:"));
((CEdit *)GetDlgItem(IDC_STATIC_BAUD_PID))->SetWindowTextW(_T("Baud:"));
// Register usb device notification.
RegisterUsbDeviceInterface();
// Init tab page.
// Add tab pages
m_tabFunc.InsertItem(0, _T("Update"));
m_tabFunc.InsertItem(1, _T("Flash Utilities"));
m_tabFunc.InsertItem(2, _T("BCA Utilities"));
// m_tabFunc.InsertItem(3, _T("IFR Utilities"));
// m_tabFunc.InsertItem(4, _T("Blhost Utilities"));
// Get tab page's size, and calculate child page's size.
CRect rc;
m_tabFunc.GetClientRect(&rc);
rc.top += 22; // add 20 more to discover the tab title.
rc.bottom -= 2;
rc.left += 2;
rc.right -= 2;
// Setup update page
m_updateDlg.Create(IDD_DIALOG_UPDATE, GetDlgItem(IDC_TAB_FUNC)); // create update page
m_updateDlg.SetWindowPos(NULL, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top,
SWP_SHOWWINDOW); // set window position
m_updateDlg.ShowWindow(true);
// Setup Flash utilities page
m_flashDlg.Create(IDD_DIALOG_FLASH, GetDlgItem(IDC_TAB_FUNC)); // create config page
m_flashDlg.SetWindowPos(NULL, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top,
SWP_SHOWWINDOW); // set window position
m_flashDlg.ShowWindow(false);
// Setup BCA utilities page
m_bootloaderConfigDLg.Create(IDD_DIALOG_CONFIG, GetDlgItem(IDC_TAB_FUNC)); // create config page
m_bootloaderConfigDLg.SetWindowPos(NULL, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top,
SWP_SHOWWINDOW); // set window position
m_bootloaderConfigDLg.ShowWindow(false);
m_tabFunc.SetCurSel(0); // set default tab page to page 0(Update page)
return TRUE; // return TRUE unless you set the focus to a control
}
// See CKinetisFlashToolDlg.h for documentation of this method.
void CKinetisFlashToolDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialogEx::OnSysCommand(nID, lParam);
}
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CKinetisFlashToolDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialogEx::OnPaint();
}
}
// The system calls this function to obtain the cursor to display while the user
// drags
// the minimized window.
HCURSOR CKinetisFlashToolDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
// Automation servers should not exit when a user closes the UI
// if a controller still holds on to one of its objects. These
// message handlers make sure that if the proxy is still in use,
// then the UI is hidden but the dialog remains around if it
// is dismissed.
void CKinetisFlashToolDlg::OnClose()
{
uint32_t address = 0;
if (cstringtoui(m_updateDlg.m_address, address))
{
g_pHistoryData->SetImageAddress(address);
}
g_pHistoryData->SetBackdoorKey(m_updateDlg.m_backdoorKey);
UnregisterDeviceNotification(m_devNotify);
/*
// Reset command will be sent when bootloader thread exits, not here.
if (g_pBootloader->m_isConneted)
{
Reset();
}*/
if (CanExit())
CDialogEx::OnClose();
}
// See CKinetisFlashToolDlg.h for documentation of this method.
void CKinetisFlashToolDlg::OnOK()
{
// if (CanExit())
// CDialogEx::OnOK();
}
// See CKinetisFlashToolDlg.h for documentation of this method.
void CKinetisFlashToolDlg::OnCancel()
{
if (CanExit())
CDialogEx::OnCancel();
}
// See CKinetisFlashToolDlg.h for documentation of this method.
BOOL CKinetisFlashToolDlg::CanExit()
{
// If the proxy object is still around, then the automation
// controller is still holding on to this application. Leave
// the dialog around, but hide its UI.
// if (m_pAutoProxy != NULL)
//{
// ShowWindow(SW_HIDE);
// return FALSE;
//}
return TRUE;
}
void CKinetisFlashToolDlg::RegisterUsbDeviceInterface()
{
/* The DBT_DEVICEARRIVAL and DBT_DEVICEREMOVECOMPLETE events are automatically broadcast
* to all top-level windows for port devices. Therefore, it is not necessary to call
* RegisterDeviceNotification for ports.
*/
DEV_BROADCAST_DEVICEINTERFACE notificationFilter;
ZeroMemory(&notificationFilter, sizeof(DEV_BROADCAST_DEVICEINTERFACE));
notificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
notificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
notificationFilter.dbcc_classguid = GUID_DEVINTERFACE_USB_DEVICE;
m_devNotify = RegisterDeviceNotification(this->GetSafeHwnd(), &notificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE);
if (m_devNotify == NULL)
{
AppendLog(_T("Error: Failed to register COM port device notification"));
}
}
// See CKinetisFlashToolDlg.h for documentation of this method.
void CKinetisFlashToolDlg::RefreshComPortList()
{
m_comboPortOrVID.ResetContent(); // Clear the content in the combox
// List all
for (size_t i = 0; i < g_pAllComDevices->GetDeviceCount(); i++)
{
m_comboPortOrVID.AddString(g_pAllComDevices->GetDevice(i).GetString());
}
if (m_comboPortOrVID.GetCount() == 0)
{
AppendLog(_T("Cannot find a COM port!"));
}
else
{
m_comboPortOrVID.SetCurSel(g_pHistoryData->GetCurrentDevice());
}
}
// See CKinetisFlashToolDlg.h for documentation of this method.
void CKinetisFlashToolDlg::RefreshBaudrateList()
{
m_comboBaudOrPID.ResetContent(); // Clear the content in the combox
// List all
for (size_t i = 0; i < g_pHistoryData->GetBaudRateCount(); i++)
{
m_comboBaudOrPID.AddString(format_cstring(_T("%d"), g_pHistoryData->GetBaudRate(i)));
}
m_comboBaudOrPID.SetCurSel(g_pHistoryData->GetCurrentBaudRate());
}
// See CKinetisFlashToolDlg.h for documentation of this method.
void CKinetisFlashToolDlg::RefreshPidList()
{
m_comboBaudOrPID.ResetContent(); // Clear the content in the combox
// List all
for (size_t i = 0; i < g_pHistoryData->GetPidCount(); i++)
{
m_comboBaudOrPID.AddString(format_cstring(_T("0x%04X"), g_pHistoryData->GetPid(i)));
}
m_comboBaudOrPID.SetCurSel(0);
}
// See CKinetisFlashToolDlg.h for documentation of this method.
void CKinetisFlashToolDlg::RefreshVidList()
{
m_comboPortOrVID.ResetContent(); // Clear the content in the combox
// List all
for (size_t i = 0; i < g_pHistoryData->GetVidCount(); i++)
{
m_comboPortOrVID.AddString(format_cstring(_T("0x%04X"), g_pHistoryData->GetVid(i)));
}
m_comboPortOrVID.SetCurSel(0);
}
// See CKinetisFlashToolDlg.h for documentation of this method.
void CKinetisFlashToolDlg::AppendLog(CString log)
{
m_log.Append(log);
m_log.Append(_T("\r\n"));
UpdateData(false);
::PostMessage(m_logCtrl.m_hWnd, WM_VSCROLL, SB_BOTTOM, 0); // Keep Log page always shows the bottom of the log.
}
// See CKinetisFlashToolDlg.h for documentation of this method.
void CKinetisFlashToolDlg::GetPeripheralConfig(blfwkdll::Updater::PeripheralConfig *config)
{
CString strW;
// TODO: Add your control notification handler code here
if (((CButton *)GetDlgItem(IDC_RADIO_UART))->GetCheck() == BST_CHECKED)
{
config->peripheralType = blfwkdll::Updater::HOST_PERIPHERAL_TYPE_TAG::kHostPeripheralType_UART;
m_comboPortOrVID.GetWindowTextW(strW);
CStringA strA(strW.GetBuffer());
strW.ReleaseBuffer(); // Change UCHAR string to CHAR string by these three
// steps.
config->comPortName = strA.GetBuffer();
strA.ReleaseBuffer();
m_comboBaudOrPID.GetWindowTextW(strW);
int32_t speed;
if (!cstringtoi(strW, speed))
{
AppendLog(_T("Error: Invalid Baudrate.(") + strW + _T(")"));
return;
}
config->comPortSpeed = speed;
}
else if (((CButton *)GetDlgItem(IDC_RADIO_USBHID))->GetCheck() == BST_CHECKED)
{
uint32_t id;
config->peripheralType = blfwkdll::Updater::HOST_PERIPHERAL_TYPE_TAG::kHostPeripheralType_USB_HID;
m_comboPortOrVID.GetWindowTextW(strW);
if (!cstringtoui(strW, id))
{
AppendLog(_T("Error: Invalid VID.(") + strW + _T(")"));
return;
}
config->usbHidVid = id & 0xFFFF;
m_comboBaudOrPID.GetWindowTextW(strW);
if (!cstringtoui(strW, id))
{
AppendLog(_T("Error: Invalid PID.(") + strW + _T(")"));
return;
}
config->usbHidPid = id & 0xFFFF;
}
config->ping = true;
config->packetTimeoutMs = 5000;
}
void CKinetisFlashToolDlg::Connect(void)
{
blfwkdll::Updater::PeripheralConfig config;
GetPeripheralConfig(&config);
g_pBootloader->Connect(&config);
// SetTimer(1, 1000, NULL);
}
// See CKinetisFlashToolDlg.h for documentation of this method.
void CKinetisFlashToolDlg::Reset(void)
{
// KillTimer(1);
g_pBootloader->Reset();
}
// See CKinetisFlashToolDlg.h for documentation of this method.
void CKinetisFlashToolDlg::OnBnClickedRadio()
{
// TODO: Add your control notification handler code here
KillTimer(1); // Peripheral configuration is changed, stop the ping timer.
if (g_pBootloader->m_isConneted)
{
Reset();
}
if (((CButton *)GetDlgItem(IDC_RADIO_UART))->GetCheck() == BST_CHECKED)
{
((CEdit *)GetDlgItem(IDC_STATIC_PORT_VID))->SetWindowTextW(_T("Port:"));
((CEdit *)GetDlgItem(IDC_STATIC_BAUD_PID))->SetWindowTextW(_T("Baud:"));
RefreshComPortList();
RefreshBaudrateList();
}
else if (((CButton *)GetDlgItem(IDC_RADIO_USBHID))->GetCheck() == BST_CHECKED)
{
((CEdit *)GetDlgItem(IDC_STATIC_PORT_VID))->SetWindowTextW(_T("VID:"));
((CEdit *)GetDlgItem(IDC_STATIC_BAUD_PID))->SetWindowTextW(_T("PID:"));
RefreshPidList();
RefreshVidList();
}
}
// See CKinetisFlashToolDlg.h for documentation of this method.
void CKinetisFlashToolDlg::OnCbnSelchangeComboPortVid()
{
// TODO: Add your control notification handler code here
KillTimer(1); // Peripheral configuration is changed, stop the ping timer.
if (g_pBootloader->m_isConneted)
{
Reset();
}
if (((CButton *)GetDlgItem(IDC_RADIO_UART))->GetCheck() == BST_CHECKED)
{
g_pHistoryData->SetCurrentDevice(m_comboPortOrVID.GetCurSel());
}
else if (((CButton *)GetDlgItem(IDC_RADIO_USBHID))->GetCheck() == BST_CHECKED)
{
g_pHistoryData->BubbleSelectedVid(m_comboPortOrVID.GetCurSel());
RefreshVidList();
}
}
// See CKinetisFlashToolDlg.h for documentation of this method.
void CKinetisFlashToolDlg::OnCbnSelchangeComboBaudPid()
{
// TODO: Add your control notification handler code here
KillTimer(1); // Peripheral configuration is changed, stop the ping timer.
if (g_pBootloader->m_isConneted)
{
Reset();
}
if (((CButton *)GetDlgItem(IDC_RADIO_UART))->GetCheck() == BST_CHECKED)
{
g_pHistoryData->SetCurrentBaudRate(m_comboBaudOrPID.GetCurSel());
}
else if (((CButton *)GetDlgItem(IDC_RADIO_USBHID))->GetCheck() == BST_CHECKED)
{
g_pHistoryData->BubbleSelectedPid(m_comboBaudOrPID.GetCurSel());
RefreshVidList();
}
}
// See CKinetisFlashToolDlg.h for documentation of this method.
void CKinetisFlashToolDlg::OnKillfocusComboPortVid()
{
if (m_comboPortOrVID.GetCurSel() >= 0)
{
// If no change in the textbox, then return;
return;
}
KillTimer(1); // Peripheral configuration is changed, stop the ping timer.
if (g_pBootloader->m_isConneted)
{
Reset();
}
CString text;
m_comboPortOrVID.GetWindowTextW(text);
if (((CButton *)GetDlgItem(IDC_RADIO_UART))->GetCheck() == BST_CHECKED)
{
// Find if there is the same COM port in the device list.
for (size_t i = 0; i < g_pAllComDevices->GetDeviceCount(); i++)
{
if (text.CompareNoCase(g_pAllComDevices->GetDevice(i).GetString()) == 0)
{
// If yes, then set it as current selected.
g_pHistoryData->SetCurrentDevice(i);
}
}
RefreshComPortList();
}
else if (((CButton *)GetDlgItem(IDC_RADIO_USBHID))->GetCheck() == BST_CHECKED)
{
uint32_t intVid;
if (!cstringtoui(text, intVid))
{
AppendLog(_T("Error: Invalid VID.(") + text + _T(")"));
}
else
{
g_pHistoryData->InsertVid(static_cast<uint16_t>(intVid));
}
RefreshVidList();
}
}
// See CKinetisFlashToolDlg.h for documentation of this method.
void CKinetisFlashToolDlg::OnKillfocusComboBaudPid()
{
if (m_comboBaudOrPID.GetCurSel() >= 0)
{
// If no change in the textbox, then return;
return;
}
KillTimer(1); // Peripheral configuration is changed, stop the ping timer.
if (g_pBootloader->m_isConneted)
{
Reset();
}
CString text;
m_comboBaudOrPID.GetWindowTextW(text);
if (((CButton *)GetDlgItem(IDC_RADIO_UART))->GetCheck() == BST_CHECKED)
{
int32_t intBaud;
if (!cstringtoi(text, intBaud))
{
AppendLog(_T("Error: Invalid Baud Rate.(") + text + _T(")"));
}
else
{
g_pHistoryData->InsertBaudRate(intBaud);
}
RefreshBaudrateList();
}
else if (((CButton *)GetDlgItem(IDC_RADIO_USBHID))->GetCheck() == BST_CHECKED)
{
uint32_t intPid;
if (!cstringtoui(text, intPid))
{
AppendLog(_T("Error: Invalid PID.(") + text + _T(")"));
}
else
{
g_pHistoryData->InsertPid(static_cast<uint16_t>(intPid));
}
RefreshPidList();
}
}
// See CKinetisFlashToolDlg.h for documentation of this method.
void CKinetisFlashToolDlg::OnClickedButtonCntReset()
{
if (!g_pBootloader->m_isConneted)
{
Connect();
SetTimer(1, 1000, NULL);
}
else
{
KillTimer(1);
Reset();
}
}
// See CKinetisFlashToolDlg.h for documentation of this method.
void CKinetisFlashToolDlg::OnTcnSelchangeTabFunc(NMHDR *pNMHDR, LRESULT *pResult)
{
// TODO: Add your control notification handler code here
*pResult = 0;
switch (m_tabFunc.GetCurSel())
{
case 0:
m_updateDlg.ShowWindow(true);
m_flashDlg.ShowWindow(false);
m_bootloaderConfigDLg.ShowWindow(false);
break;
case 1:
m_updateDlg.ShowWindow(false);
m_flashDlg.ShowWindow(true);
m_bootloaderConfigDLg.ShowWindow(false);
break;
case 2:
m_updateDlg.ShowWindow(false);
m_flashDlg.ShowWindow(false);
m_bootloaderConfigDLg.ShowWindow(true);
break;
/*
case 3:
m_updateDlg.ShowWindow(false);
m_flashDlg.ShowWindow(false);
m_bootloaderConfigDLg.ShowWindow(false);
break;
case 4:
m_updateDlg.ShowWindow(false);
m_flashDlg.ShowWindow(false);
m_bootloaderConfigDLg.ShowWindow(false);
break;
*/
default:
break;
}
}
// See CKinetisFlashToolDlg.h for documentation of this method.
void CKinetisFlashToolDlg::OnTimer(UINT_PTR nIDEvent)
{
// TODO: Add your control notification handler code here
g_pBootloader->Ping();
CDialogEx::OnTimer(nIDEvent);
}
BOOL CKinetisFlashToolDlg::OnDeviceChange(UINT nEventType, DWORD_PTR dwData)
{
#ifdef _DEBUG
AppendLog(_T("Device Change Event(") + format_cstring(_T("nEventType = %#x"), nEventType) + _T(")"));
#endif
PDEV_BROADCAST_HDR pHdr = (PDEV_BROADCAST_HDR)dwData;
switch (nEventType)
{
case DBT_DEVICEARRIVAL:
case DBT_DEVICEREMOVECOMPLETE:
{
#ifdef _DEBUG
AppendLog(_T("Device Change Event(") + format_cstring(_T("devicetype = %#x"), pHdr->dbch_devicetype) +
_T(")"));
#endif
if (pHdr->dbch_devicetype == DBT_DEVTYP_PORT)
{
#ifdef _DEBUG
AppendLog(_T("Device Change Event(") +
format_cstring(_T("dbcp_name = %s"), ((PDEV_BROADCAST_PORT)pHdr)->dbcp_name) + _T(")"));
#endif
// Backup previous selected device.
SerialDevice preDev;
if (g_pHistoryData->GetCurrentDevice() >= 0)
{
preDev = g_pAllComDevices->GetDevice(g_pHistoryData->GetCurrentDevice());
}
g_pAllComDevices->ScanSerialDevices(); // Rescan the serial com devices.
// If currently no device is selected, select the new device.
if ((g_pHistoryData->GetCurrentDevice() < 0) && (nEventType == DBT_DEVICEARRIVAL))
{
g_pHistoryData->SetCurrentDevice(
g_pAllComDevices->FindSerialDevice(((PDEV_BROADCAST_PORT)pHdr)->dbcp_name));
}
else if (g_pHistoryData->GetCurrentDevice() >= 0)
{
g_pHistoryData->SetCurrentDevice(g_pAllComDevices->FindSerialDevice(preDev));
}
if (((CButton *)GetDlgItem(IDC_RADIO_UART))->GetCheck() == BST_CHECKED)
{
RefreshComPortList();
}
}
/* For OpenSDA CDC device, DBT_DEVTYP_PORT event will not be broadcasted.
* Use DBT_DEVTYP_DEVICEINTERFACE event to handle the changes.
*/
else if (pHdr->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
{
#ifdef _DEBUG
AppendLog(_T("Device Change Event(") +
format_cstring(_T("dbcc_name = %s"), ((PDEV_BROADCAST_DEVICEINTERFACE)pHdr)->dbcc_name) +
_T(")"));
#endif
CString devPath = ((PDEV_BROADCAST_DEVICEINTERFACE)pHdr)->dbcc_name;
// Check whether the event is trigged by OpenSDA device.
// Only handle OpenSDA device, others will be handled by DBT_DEVTYP_PORT.
if (devPath.Find(format_cstring(_T("VID_%04x&PID_%04x"), 0x1357, 0x0089)) != -1)
{
// Backup previous selected device.
SerialDevice preDev;
if (g_pHistoryData->GetCurrentDevice() >= 0)
{
preDev = g_pAllComDevices->GetDevice(g_pHistoryData->GetCurrentDevice());
}
Sleep(500); // Wait for Windows Registry refresh
g_pAllComDevices->ScanSerialDevices(); // Rescan the serial com devices.
// If currently no device is selected, select the new device
if ((g_pHistoryData->GetCurrentDevice() < 0) && (nEventType == DBT_DEVICEARRIVAL))
{
HDEVINFO devInfo = SetupDiGetClassDevsW(&GUID_DEVINTERFACE_USB_DEVICE, NULL, 0,
DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);
CString devId = devPath.Left(devPath.ReverseFind(_T('#')));
devId = devId.Right(devId.GetLength() - devId.Find(_T("USB")));
devId.Replace(_T('#'), _T('\\'));
SP_DEVINFO_DATA devInfoData;
ZeroMemory(&devInfoData, sizeof(SP_DEVINFO_DATA));
devInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
SetupDiOpenDeviceInfo(devInfo, (PCTSTR)devId.GetString(), NULL,
DIOD_INHERIT_CLASSDRVS | DIOD_CANCEL_REMOVE, &devInfoData);
// The first child node of OpenSDA is the COM device node.
DEVINST portDevInst;
if (CM_Get_Child(&portDevInst, devInfoData.DevInst, 0) != CR_SUCCESS)
{
goto Refresh;
}
// Get COM device node's info.
ULONG idSize;
CString portDevId;
CM_Get_Device_ID_Size(&idSize, portDevInst, 0);
CM_Get_Device_ID(portDevInst, portDevId.GetBufferSetLength(idSize), idSize, 0);
portDevId.ReleaseBuffer();
SP_DEVINFO_DATA portDevInfoData;
ZeroMemory(&portDevInfoData, sizeof(SP_DEVINFO_DATA));
portDevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
SetupDiOpenDeviceInfo(devInfo, (PCTSTR)portDevId.GetString(), NULL,
DIOD_INHERIT_CLASSDRVS | DIOD_CANCEL_REMOVE, &portDevInfoData);
if (portDevInfoData.ClassGuid == GUID_DEVCLASS_PORTS)
{
// Get the com port from the friendly name.
ULONG bufSize = 0;
SetupDiGetDeviceRegistryProperty(devInfo, &portDevInfoData, SPDRP_FRIENDLYNAME, NULL, NULL,
0, &bufSize);
BYTE *pBuffer = (BYTE *)malloc(bufSize);
SetupDiGetDeviceRegistryProperty(devInfo, &portDevInfoData, SPDRP_FRIENDLYNAME, NULL,
pBuffer, bufSize, &bufSize);
CString friendlyName = CString((LPCWSTR)pBuffer);
CString comPort = friendlyName.Mid(friendlyName.ReverseFind(_T('(')) + 1);
comPort.TrimRight(_T(')'));
if (pBuffer != NULL)
{
free(pBuffer);
pBuffer = NULL;
}
g_pHistoryData->SetCurrentDevice(g_pAllComDevices->FindSerialDevice(SerialDevice(comPort)));
}
}
else if (g_pHistoryData->GetCurrentDevice() >= 0)
{
g_pHistoryData->SetCurrentDevice(g_pAllComDevices->FindSerialDevice(preDev));
}
Refresh:
if (((CButton *)GetDlgItem(IDC_RADIO_UART))->GetCheck() == BST_CHECKED)
{
RefreshComPortList();
}
}
}
#ifdef _DEBUG
else if (pHdr->dbch_devicetype == DBT_DEVTYP_VOLUME)
{
AppendLog(_T("Device Change Event(") +
format_cstring(_T("uintmask = %#x"), ((PDEV_BROADCAST_VOLUME)pHdr)->dbcv_unitmask) + _T(")"));
}
#endif
break;
}
default:
break;
}
return CDialog::OnDeviceChange(nEventType, dwData);
}
// See CKinetisFlashToolDlg.h for documentation of this method.
LRESULT CKinetisFlashToolDlg::OnUpdateLog(WPARAM wParam, LPARAM lParam)
{
LPWSTR log = (LPWSTR)wParam;
AppendLog(log);
return 0;
}
// See CKinetisFlashToolDlg.h for documentation of this method.
LRESULT CKinetisFlashToolDlg::OnUpdateStatus(WPARAM wParam, LPARAM lParam)
{
if (g_pBootloader->m_isConneted)
{
m_bootloaderVersion =
format_cstring(_T("%c%d.%d.%d"), (g_pBootloader->m_targetInfo.targetVersion & 0xff000000) >> 24,
(g_pBootloader->m_targetInfo.targetVersion & 0x00ff0000) >> 16,
(g_pBootloader->m_targetInfo.targetVersion & 0x0000ff00) >> 8,
g_pBootloader->m_targetInfo.targetVersion & 0x000000ff);
m_protoclVersion =
format_cstring(_T("%c%d.%d.%d"), (g_pBootloader->m_targetInfo.procotolVersion & 0xff000000) >> 24,
(g_pBootloader->m_targetInfo.procotolVersion & 0x00ff0000) >> 16,
(g_pBootloader->m_targetInfo.procotolVersion & 0x0000ff00) >> 8,
g_pBootloader->m_targetInfo.procotolVersion & 0x000000ff);
m_securityState =
format_cstring(_T("%s"), g_pBootloader->m_targetInfo.securityState ? _T("SECURE") : _T("UNSECURE"));
m_flashSize = format_cstring(_T("%s"), scale_bytes(g_pBootloader->m_targetInfo.flashSize));
m_flashSector = format_cstring(_T("%s"), scale_bytes(g_pBootloader->m_targetInfo.flashSectorSize));
m_ramSize = format_cstring(_T("%s"), scale_bytes(g_pBootloader->m_targetInfo.ramSize));
m_rsvRgnFlashStart = format_cstring(_T("0x%X"), g_pBootloader->m_targetInfo.rsvRgnFlashStart);
m_rsvRgnFlashEnd = format_cstring(_T("0x%X"), g_pBootloader->m_targetInfo.rsvRgnFlashEnd);
m_rsvRgnRamStart = format_cstring(_T("0x%X"), g_pBootloader->m_targetInfo.rsvRgnRamStart);
m_rsvRgnRamEnd = format_cstring(_T("0x%X"), g_pBootloader->m_targetInfo.rsvRgnRamEnd);
AppendLog(_T("Device information is updated!"));
}
return 0;
}
// See CKinetisFlashToolDlg.h for documentation of this method.
LRESULT CKinetisFlashToolDlg::OnChangeConnection(WPARAM wParam, LPARAM lParam)
{
if (g_pBootloader->m_isConneted)
{
AppendLog(_T("Connected to device successfully!"));
((CButton *)GetDlgItem(IDC_BUTTON_CNT_RESET))->SetWindowTextW(_T("Reset"));
AppendLog(_T("Collecting device information......"));
g_pBootloader->UpdateStatus();
}
else
{
m_bootloaderVersion.Empty();
m_protoclVersion.Empty();
m_securityState.Empty();
m_flashSize.Empty();
m_flashSector.Empty();
m_ramSize.Empty();
m_rsvRgnFlashStart.Empty();
m_rsvRgnFlashEnd.Empty();
m_rsvRgnRamStart.Empty();
m_rsvRgnRamEnd.Empty();
AppendLog(_T("Disconnected from device!\r\n"));
((CButton *)GetDlgItem(IDC_BUTTON_CNT_RESET))->SetWindowTextW(_T("Connect"));
}
::PostMessage(g_pMainDlg->m_updateDlg, USER_MS_CONNECTION_CHANGE, NULL, NULL);
return 0;
}