scsi2sd-monitor.cc 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. // Copyright (C) 2015 Michael McMaster <michael@codesrc.com>
  2. //
  3. // This file is part of SCSI2SD.
  4. //
  5. // SCSI2SD is free software: you can redistribute it and/or modify
  6. // it under the terms of the GNU General Public License as published by
  7. // the Free Software Foundation, either version 3 of the License, or
  8. // (at your option) any later version.
  9. //
  10. // SCSI2SD is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. // GNU General Public License for more details.
  14. //
  15. // You should have received a copy of the GNU General Public License
  16. // along with SCSI2SD. If not, see <http://www.gnu.org/licenses/>.
  17. // For compilers that support precompilation, includes "wx/wx.h".
  18. #include <wx/wxprec.h>
  19. #ifndef WX_PRECOMP
  20. #include <wx/wx.h>
  21. #endif
  22. #include <wx/filedlg.h>
  23. #include <wx/filefn.h>
  24. #include <wx/filename.h>
  25. #include <wx/log.h>
  26. #include <wx/notebook.h>
  27. #include <wx/progdlg.h>
  28. #include <wx/utils.h>
  29. #include <wx/windowptr.h>
  30. #include <wx/thread.h>
  31. #include <zipper.hh>
  32. #include "ConfigUtil.hh"
  33. #include "TargetPanel.hh"
  34. #include "SCSI2SD_Bootloader.hh"
  35. #include "SCSI2SD_HID.hh"
  36. #include "Firmware.hh"
  37. #include <algorithm>
  38. #include <iomanip>
  39. #include <vector>
  40. #include <set>
  41. #include <sstream>
  42. #if __cplusplus >= 201103L
  43. #include <cstdint>
  44. #include <memory>
  45. using std::shared_ptr;
  46. #else
  47. #include <stdint.h>
  48. #include <tr1/memory>
  49. using std::tr1::shared_ptr;
  50. #endif
  51. #define MIN_FIRMWARE_VERSION 0x0400
  52. using namespace SCSI2SD;
  53. namespace
  54. {
  55. static uint8_t sdCrc7(uint8_t* chr, uint8_t cnt, uint8_t crc)
  56. {
  57. uint8_t a;
  58. for(a = 0; a < cnt; a++)
  59. {
  60. uint8_t data = chr[a];
  61. uint8_t i;
  62. for(i = 0; i < 8; i++)
  63. {
  64. crc <<= 1;
  65. if ((data & 0x80) ^ (crc & 0x80))
  66. {
  67. crc ^= 0x09;
  68. }
  69. data <<= 1;
  70. }
  71. }
  72. return crc & 0x7F;
  73. }
  74. class TimerLock
  75. {
  76. public:
  77. TimerLock(wxTimer* timer) :
  78. myTimer(timer),
  79. myInterval(myTimer->GetInterval())
  80. {
  81. myTimer->Stop();
  82. };
  83. virtual ~TimerLock()
  84. {
  85. if (myTimer && myInterval > 0)
  86. {
  87. myTimer->Start(myInterval);
  88. }
  89. }
  90. private:
  91. wxTimer* myTimer;
  92. int myInterval;
  93. };
  94. class AppFrame : public wxFrame
  95. {
  96. public:
  97. AppFrame() :
  98. wxFrame(NULL, wxID_ANY, "scsi2sd-monitor", wxPoint(50, 50), wxSize(250, 150))
  99. {
  100. wxFlexGridSizer *fgs = new wxFlexGridSizer(3, 2, 9, 25);
  101. fgs->Add(new wxStaticText(this, wxID_ANY, wxT("SCSI2SD Device:")));
  102. myBoardText = new wxStaticText(this, wxID_ANY, wxT(""));
  103. fgs->Add(myBoardText);
  104. fgs->Add(new wxStaticText(this, wxID_ANY, wxT("SD Test:")));
  105. mySDText = new wxStaticText(this, wxID_ANY, wxT(""));
  106. fgs->Add(mySDText);
  107. fgs->Add(new wxStaticText(this, wxID_ANY, wxT("SCSI Test:")));
  108. mySCSIText = new wxStaticText(this, wxID_ANY, wxT(""));
  109. fgs->Add(mySCSIText);
  110. wxBoxSizer* hbox = new wxBoxSizer(wxHORIZONTAL);
  111. hbox->Add(fgs, 1, wxALL | wxEXPAND, 15);
  112. this->SetSizer(hbox);
  113. Centre();
  114. //Fit(); // Needed to reduce window size on Windows
  115. //FitInside(); // Needed on Linux to prevent status bar overlap
  116. myTimer = new wxTimer(this, ID_Timer);
  117. myTimer->Start(1000);
  118. }
  119. private:
  120. wxTimer* myTimer;
  121. shared_ptr<HID> myHID;
  122. shared_ptr<Bootloader> myBootloader;
  123. wxStaticText* myBoardText;
  124. wxStaticText* mySDText;
  125. wxStaticText* mySCSIText;
  126. enum
  127. {
  128. ID_ConfigDefaults = wxID_HIGHEST + 1,
  129. ID_Timer
  130. };
  131. void evaluate()
  132. {
  133. if (myHID)
  134. {
  135. std::stringstream msg;
  136. msg << "Ready, " <<
  137. myHID->getFirmwareVersionStr();
  138. myBoardText->SetLabelText(msg.str());
  139. std::vector<uint8_t> csd(myHID->getSD_CSD());
  140. std::vector<uint8_t> cid(myHID->getSD_CID());
  141. bool sdGood = false;
  142. for (size_t i = 0; i < 16; ++i)
  143. {
  144. if (csd[i] != 0)
  145. {
  146. sdGood = true;
  147. //break;
  148. }
  149. }
  150. sdGood = sdGood &&
  151. (sdCrc7(&csd[0], 15, 0) == (csd[15] >> 1)) &&
  152. (sdCrc7(&cid[0], 15, 0) == (cid[15] >> 1));
  153. if (sdGood)
  154. {
  155. mySDText->SetLabelText("OK");
  156. }
  157. else
  158. {
  159. mySDText->SetLabelText("FAIL");
  160. }
  161. if (myHID->scsiSelfTest())
  162. {
  163. mySCSIText->SetLabelText("OK");
  164. }
  165. else
  166. {
  167. mySCSIText->SetLabelText("FAIL");
  168. }
  169. }
  170. else
  171. {
  172. if (myBootloader)
  173. {
  174. myBoardText->SetLabelText("Bootloader");
  175. }
  176. else
  177. {
  178. myBoardText->SetLabelText("Missing");
  179. }
  180. mySDText->SetLabelText("-");
  181. mySCSIText->SetLabelText("-");
  182. }
  183. }
  184. void OnID_Timer(wxTimerEvent& event)
  185. {
  186. // Check if we are connected to the HID device.
  187. // AND/or bootloader device.
  188. try
  189. {
  190. if (myBootloader)
  191. {
  192. // Verify the USB HID connection is valid
  193. if (!myBootloader->ping())
  194. {
  195. myBootloader.reset();
  196. }
  197. }
  198. if (!myBootloader)
  199. {
  200. myBootloader.reset(Bootloader::Open());
  201. }
  202. if (myHID && !myHID->ping())
  203. {
  204. // Verify the USB HID connection is valid
  205. std::cerr << "RESET!" << std::endl;
  206. myHID.reset();
  207. }
  208. if (!myHID)
  209. {
  210. myHID.reset(HID::Open());
  211. }
  212. }
  213. catch (std::runtime_error& e)
  214. {
  215. std::cerr << e.what() << std::endl;
  216. }
  217. evaluate();
  218. }
  219. // Note: Don't confuse this with the wxApp::OnExit virtual method
  220. void OnExitEvt(wxCommandEvent& event)
  221. {
  222. Close(true);
  223. }
  224. wxDECLARE_EVENT_TABLE();
  225. };
  226. wxBEGIN_EVENT_TABLE(AppFrame, wxFrame)
  227. EVT_MENU(wxID_EXIT, AppFrame::OnExitEvt)
  228. EVT_TIMER(AppFrame::ID_Timer, AppFrame::OnID_Timer)
  229. wxEND_EVENT_TABLE()
  230. class App : public wxApp
  231. {
  232. public:
  233. virtual bool OnInit()
  234. {
  235. AppFrame* frame = new AppFrame();
  236. frame->Show(true);
  237. SetTopWindow(frame);
  238. return true;
  239. }
  240. };
  241. } // namespace
  242. // Main Method
  243. wxIMPLEMENT_APP(App);