C# Cypress EEPROM Utility with interop calls to deviceIoControl for access to USB driver.


/ Published in: C#
Save to your folder(s)

Cypress FX2 EEPROM utility implemented in C#.net with interop calls to deviceIoControl for access to the USB driver. This utility reads, writes, verifies and erases the EEPROM. It embeds the vend_ax.hex firmware in a byte array and automatically downloads the firmware if it isn't detected in internal RAM. Some of the code was borrowed from the EzUsb or CyConsole utility. Some code was taken from the EzUsbSys.h file and re-defined for use in c#.


Copy this code and paste it in your HTML
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Linq; // for SequenceEqual (array comparison).
  7. using System.Text;
  8. using System.Windows.Forms;
  9. using System.Runtime.InteropServices; // for DllImport
  10. using System.Diagnostics; // for Assert
  11. using System.Threading; // for Thread.Sleep
  12.  
  13.  
  14. namespace CypressEepromUtility
  15. {
  16. public partial class MainForm : Form
  17. {
  18. // This is the main form for a utility to read, write, verify and erase the EEPROM on a Cypress FX2 processor board.
  19. // Some of the code was taken from the EzMr (CyConsole) utility which used the EzUsb driver.
  20. // Calls are made to deviceIoControl to access the EzUsb driver.
  21.  
  22. #region Vend_AX firmware array.
  23. // This array was generated from C:\Cypress\USB\Examples\FX2LP\Vend_ax\Vend_Ax.hex.
  24. // The .hex was was reconstituted into a binary buffer and then written to a text file and its contents included here.
  25. // The code used to create the text file is testIntelHexToByteArray().
  26. // The AA bytes are gaps that are untouched by the .hex contents.
  27. // The original VendAx array taken from Vend_Ax.h in the EzMr project
  28. // caused random Windows driver errors, crashes and PC lock-ups when coming out of reset.
  29. // It would fail about 1 out of 5 startups and would otherwise run normally.
  30.  
  31. public static byte[] VendAxCode = new byte[]
  32. {
  33. #region fwCode
  34. 0x02, 0x07, 0xF3, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
  35. 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
  36. 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x02, 0x0D, 0x60, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
  37. 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x02, 0x08, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
  38. 0xAA, 0xAA, 0xAA, 0x02, 0x08, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
  39. 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
  40. 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x90, 0xE6, 0xB9, 0xE0, 0x24, 0x5E, 0xB4, 0x0B, 0x00, 0x40, 0x03, 0x02,
  41. 0x03, 0x98, 0x90, 0x00, 0x9C, 0x75, 0xF0, 0x03, 0xA4, 0xC5, 0x83, 0x25, 0xF0, 0xC5, 0x83, 0x73, 0x02, 0x01, 0x92, 0x02,
  42. 0x01, 0x92, 0x02, 0x01, 0x0D, 0x02, 0x00, 0xBD, 0x02, 0x00, 0xD7, 0x02, 0x00, 0xF3, 0x02, 0x01, 0x3C, 0x02, 0x01, 0x8C,
  43. 0x02, 0x01, 0x16, 0x02, 0x01, 0x29, 0x02, 0x01, 0x62, 0x90, 0xE7, 0x40, 0xE5, 0x19, 0xF0, 0xE4, 0x90, 0xE6, 0x8A, 0xF0,
  44. 0x90, 0xE6, 0x8B, 0x04, 0xF0, 0x90, 0xE6, 0xA0, 0xE0, 0x44, 0x80, 0xF0, 0x02, 0x03, 0x98, 0x90, 0xE6, 0x0A, 0xE0, 0x90,
  45. 0xE7, 0x40, 0xF0, 0xE4, 0x90, 0xE6, 0x8A, 0xF0, 0x90, 0xE6, 0x8B, 0x04, 0xF0, 0x90, 0xE6, 0xA0, 0xE0, 0x44, 0x80, 0xF0,
  46. 0x02, 0x03, 0x98, 0x90, 0xE7, 0x40, 0x74, 0x0F, 0xF0, 0xE4, 0x90, 0xE6, 0x8A, 0xF0, 0x90, 0xE6, 0x8B, 0x04, 0xF0, 0x90,
  47. 0xE6, 0xA0, 0xE0, 0x44, 0x80, 0xF0, 0x02, 0x03, 0x98, 0x90, 0xE6, 0xBA, 0xE0, 0xF5, 0x17, 0x02, 0x03, 0x98, 0x90, 0xE6,
  48. 0x7A, 0xE0, 0x54, 0xFE, 0xF0, 0xE4, 0x90, 0xE6, 0x8A, 0xF0, 0x90, 0xE6, 0x8B, 0xF0, 0x02, 0x03, 0x98, 0x90, 0xE6, 0x7A,
  49. 0xE0, 0x44, 0x01, 0xF0, 0xE4, 0x90, 0xE6, 0x8A, 0xF0, 0x90, 0xE6, 0x8B, 0xF0, 0x02, 0x03, 0x98, 0x90, 0xE7, 0x40, 0x74,
  50. 0x07, 0xF0, 0xE4, 0x90, 0xE6, 0x8A, 0xF0, 0x90, 0xE6, 0x8B, 0x04, 0xF0, 0x90, 0xE6, 0xA0, 0xE0, 0x44, 0x80, 0xF0, 0x7F,
  51. 0xE8, 0x7E, 0x03, 0x12, 0x07, 0xAD, 0xD2, 0x04, 0x12, 0x0B, 0x87, 0x02, 0x03, 0x98, 0x90, 0xE6, 0xB5, 0xE0, 0x54, 0xFE,
  52. 0xF0, 0x90, 0xE6, 0xBF, 0xE0, 0x90, 0xE6, 0x8A, 0xF0, 0x90, 0xE6, 0xBE, 0xE0, 0x90, 0xE6, 0x8B, 0xF0, 0x90, 0xE6, 0xBB,
  53. 0xE0, 0x90, 0xE6, 0xB3, 0xF0, 0x90, 0xE6, 0xBA, 0xE0, 0x90, 0xE6, 0xB4, 0xF0, 0x02, 0x03, 0x98, 0x75, 0x19, 0x01, 0x43,
  54. 0x17, 0x01, 0x90, 0xE6, 0xBA, 0xE0, 0x75, 0x31, 0x00, 0xF5, 0x32, 0xA3, 0xE0, 0xFE, 0xE4, 0xEE, 0x42, 0x31, 0x90, 0xE6,
  55. 0xBE, 0xE0, 0x75, 0x33, 0x00, 0xF5, 0x34, 0xA3, 0xE0, 0xFE, 0xE4, 0xEE, 0x42, 0x33, 0x90, 0xE6, 0xB8, 0xE0, 0x64, 0xC0,
  56. 0x60, 0x03, 0x02, 0x02, 0x82, 0xE5, 0x34, 0x45, 0x33, 0x70, 0x03, 0x02, 0x03, 0x98, 0x90, 0xE6, 0xA0, 0xE0, 0x20, 0xE1,
  57. 0xF9, 0xC3, 0xE5, 0x34, 0x94, 0x40, 0xE5, 0x33, 0x94, 0x00, 0x50, 0x08, 0x85, 0x33, 0x35, 0x85, 0x34, 0x36, 0x80, 0x06,
  58. 0x75, 0x35, 0x00, 0x75, 0x36, 0x40, 0x90, 0xE6, 0xB9, 0xE0, 0xB4, 0xA3, 0x35, 0xE4, 0xF5, 0x37, 0xF5, 0x38, 0xC3, 0xE5,
  59. 0x38, 0x95, 0x36, 0xE5, 0x37, 0x95, 0x35, 0x50, 0x60, 0xE5, 0x32, 0x25, 0x38, 0xF5, 0x82, 0xE5, 0x31, 0x35, 0x37, 0xF5,
  60. 0x83, 0xE0, 0xFF, 0x74, 0x40, 0x25, 0x38, 0xF5, 0x82, 0xE4, 0x34, 0xE7, 0xF5, 0x83, 0xEF, 0xF0, 0x05, 0x38, 0xE5, 0x38,
  61. 0x70, 0x02, 0x05, 0x37, 0x80, 0xD0, 0xE4, 0xF5, 0x37, 0xF5, 0x38, 0xC3, 0xE5, 0x38, 0x95, 0x36, 0xE5, 0x37, 0x95, 0x35,
  62. 0x50, 0x18, 0x74, 0x40, 0x25, 0x38, 0xF5, 0x82, 0xE4, 0x34, 0xE7, 0xF5, 0x83, 0x74, 0xCD, 0xF0, 0x05, 0x38, 0xE5, 0x38,
  63. 0x70, 0x02, 0x05, 0x37, 0x80, 0xDD, 0xAD, 0x36, 0x7A, 0xE7, 0x79, 0x40, 0x7E, 0xE7, 0x7F, 0x40, 0xAB, 0x07, 0xAF, 0x32,
  64. 0xAE, 0x31, 0x12, 0x08, 0xB8, 0xE4, 0x90, 0xE6, 0x8A, 0xF0, 0x90, 0xE6, 0x8B, 0xE5, 0x36, 0xF0, 0x25, 0x32, 0xF5, 0x32,
  65. 0xE5, 0x35, 0x35, 0x31, 0xF5, 0x31, 0xC3, 0xE5, 0x34, 0x95, 0x36, 0xF5, 0x34, 0xE5, 0x33, 0x95, 0x35, 0xF5, 0x33, 0x02,
  66. 0x01, 0xBD, 0x90, 0xE6, 0xB8, 0xE0, 0x64, 0x40, 0x60, 0x03, 0x02, 0x03, 0x98, 0xE5, 0x1A, 0x70, 0x05, 0x12, 0x09, 0x67,
  67. 0x8F, 0x1A, 0xE5, 0x34, 0x45, 0x33, 0x70, 0x03, 0x02, 0x03, 0x98, 0xE4, 0x90, 0xE6, 0x8A, 0xF0, 0x90, 0xE6, 0x8B, 0xF0,
  68. 0x90, 0xE6, 0xA0, 0xE0, 0x20, 0xE1, 0xF9, 0x90, 0xE6, 0x8B, 0xE0, 0x75, 0x35, 0x00, 0xF5, 0x36, 0x90, 0xE6, 0xB9, 0xE0,
  69. 0xB4, 0xA3, 0x38, 0xE4, 0xF5, 0x37, 0xF5, 0x38, 0xC3, 0xE5, 0x38, 0x95, 0x36, 0xE5, 0x37, 0x95, 0x35, 0x40, 0x03, 0x02,
  70. 0x03, 0x7C, 0x74, 0x40, 0x25, 0x38, 0xF5, 0x82, 0xE4, 0x34, 0xE7, 0xF5, 0x83, 0xE0, 0xFF, 0xE5, 0x32, 0x25, 0x38, 0xF5,
  71. 0x82, 0xE5, 0x31, 0x35, 0x37, 0xF5, 0x83, 0xEF, 0xF0, 0x05, 0x38, 0xE5, 0x38, 0x70, 0x02, 0x05, 0x37, 0x80, 0xCD, 0xE4,
  72. 0xF5, 0x37, 0xF5, 0x38, 0xC3, 0xE5, 0x38, 0x95, 0x36, 0xE5, 0x37, 0x95, 0x35, 0x50, 0x75, 0x85, 0x1A, 0x39, 0xE5, 0x1A,
  73. 0x64, 0x01, 0x60, 0x44, 0xE5, 0x32, 0x25, 0x38, 0xFF, 0xE5, 0x31, 0x35, 0x37, 0xFE, 0xE5, 0x1A, 0x24, 0xFF, 0xFD, 0xE4,
  74. 0x34, 0xFF, 0x5E, 0xFE, 0xEF, 0x5D, 0x4E, 0x60, 0x10, 0xE5, 0x32, 0x25, 0x38, 0xFF, 0xE5, 0x1A, 0x14, 0x5F, 0xFF, 0xC3,
  75. 0xE5, 0x1A, 0x9F, 0xF5, 0x39, 0xC3, 0xE5, 0x36, 0x95, 0x38, 0xFF, 0xE5, 0x35, 0x95, 0x37, 0xFE, 0xC3, 0xEF, 0x95, 0x39,
  76. 0xEE, 0x94, 0x00, 0x50, 0x07, 0xC3, 0xE5, 0x36, 0x95, 0x38, 0xF5, 0x39, 0xE5, 0x32, 0x25, 0x38, 0xFF, 0xE5, 0x31, 0x35,
  77. 0x37, 0xFE, 0x74, 0x40, 0x25, 0x38, 0xF5, 0x82, 0xE4, 0x34, 0xE7, 0xAD, 0x82, 0xFC, 0xAB, 0x39, 0x12, 0x0A, 0x9C, 0xE5,
  78. 0x39, 0x25, 0x38, 0xF5, 0x38, 0xE4, 0x35, 0x37, 0xF5, 0x37, 0x80, 0x80, 0xE5, 0x36, 0x25, 0x32, 0xF5, 0x32, 0xE5, 0x35,
  79. 0x35, 0x31, 0xF5, 0x31, 0xC3, 0xE5, 0x34, 0x95, 0x36, 0xF5, 0x34, 0xE5, 0x33, 0x95, 0x35, 0xF5, 0x33, 0x02, 0x02, 0x96,
  80. 0xC3, 0x22, 0x90, 0xE6, 0xB9, 0xE0, 0x70, 0x03, 0x02, 0x04, 0x85, 0x14, 0x70, 0x03, 0x02, 0x05, 0x2E, 0x24, 0xFE, 0x70,
  81. 0x03, 0x02, 0x05, 0xC4, 0x24, 0xFB, 0x70, 0x03, 0x02, 0x04, 0x7F, 0x14, 0x70, 0x03, 0x02, 0x04, 0x79, 0x14, 0x70, 0x03,
  82. 0x02, 0x04, 0x6D, 0x14, 0x70, 0x03, 0x02, 0x04, 0x73, 0x24, 0x05, 0x60, 0x03, 0x02, 0x06, 0x39, 0x12, 0x0D, 0x68, 0x40,
  83. 0x03, 0x02, 0x06, 0x45, 0x90, 0xE6, 0xBB, 0xE0, 0x24, 0xFE, 0x60, 0x3B, 0x14, 0x60, 0x56, 0x24, 0xFD, 0x60, 0x16, 0x14,
  84. 0x60, 0x40, 0x24, 0x06, 0x70, 0x75, 0xE5, 0x0A, 0x90, 0xE6, 0xB3, 0xF0, 0xE5, 0x0B, 0x90, 0xE6, 0xB4, 0xF0, 0x02, 0x06,
  85. 0x45, 0x12, 0x0D, 0x33, 0x50, 0x0F, 0xE5, 0x12, 0x90, 0xE6, 0xB3, 0xF0, 0xE5, 0x13, 0x90, 0xE6, 0xB4, 0xF0, 0x02, 0x06,
  86. 0x45, 0x90, 0xE6, 0xA0, 0xE0, 0x44, 0x01, 0xF0, 0x02, 0x06, 0x45, 0xE5, 0x0C, 0x90, 0xE6, 0xB3, 0xF0, 0xE5, 0x0D, 0x90,
  87. 0xE6, 0xB4, 0xF0, 0x02, 0x06, 0x45, 0xE5, 0x0E, 0x90, 0xE6, 0xB3, 0xF0, 0xE5, 0x0F, 0x90, 0xE6, 0xB4, 0xF0, 0x02, 0x06,
  88. 0x45, 0x90, 0xE6, 0xBA, 0xE0, 0xFF, 0x12, 0x0B, 0xE2, 0xAA, 0x06, 0xA9, 0x07, 0x7B, 0x01, 0xEA, 0x49, 0x4B, 0x60, 0x0D,
  89. 0xEE, 0x90, 0xE6, 0xB3, 0xF0, 0xEF, 0x90, 0xE6, 0xB4, 0xF0, 0x02, 0x06, 0x45, 0x90, 0xE6, 0xA0, 0xE0, 0x44, 0x01, 0xF0,
  90. 0x02, 0x06, 0x45, 0x90, 0xE6, 0xA0, 0xE0, 0x44, 0x01, 0xF0, 0x02, 0x06, 0x45, 0x12, 0x0C, 0xF1, 0x02, 0x06, 0x45, 0x12,
  91. 0x0D, 0x50, 0x02, 0x06, 0x45, 0x12, 0x0D, 0x48, 0x02, 0x06, 0x45, 0x12, 0x0C, 0xDF, 0x02, 0x06, 0x45, 0x12, 0x0D, 0x6A,
  92. 0x40, 0x03, 0x02, 0x06, 0x45, 0x90, 0xE6, 0xB8, 0xE0, 0x24, 0x7F, 0x60, 0x2B, 0x14, 0x60, 0x3C, 0x24, 0x02, 0x60, 0x03,
  93. 0x02, 0x05, 0x24, 0xA2, 0x00, 0xE4, 0x33, 0xFF, 0x25, 0xE0, 0xFF, 0xA2, 0x02, 0xE4, 0x33, 0x4F, 0x90, 0xE7, 0x40, 0xF0,
  94. 0xE4, 0xA3, 0xF0, 0x90, 0xE6, 0x8A, 0xF0, 0x90, 0xE6, 0x8B, 0x74, 0x02, 0xF0, 0x02, 0x06, 0x45, 0xE4, 0x90, 0xE7, 0x40,
  95. 0xF0, 0xA3, 0xF0, 0x90, 0xE6, 0x8A, 0xF0, 0x90, 0xE6, 0x8B, 0x74, 0x02, 0xF0, 0x02, 0x06, 0x45, 0x90, 0xE6, 0xBC, 0xE0,
  96. 0x54, 0x7E, 0xFF, 0x7E, 0x00, 0xE0, 0xD3, 0x94, 0x80, 0x40, 0x06, 0x7C, 0x00, 0x7D, 0x01, 0x80, 0x04, 0x7C, 0x00, 0x7D,
  97. 0x00, 0xEC, 0x4E, 0xFE, 0xED, 0x4F, 0x24, 0x3E, 0xF5, 0x82, 0x74, 0x0D, 0x3E, 0xF5, 0x83, 0xE4, 0x93, 0xFF, 0x33, 0x95,
  98. 0xE0, 0xFE, 0xEF, 0x24, 0xA1, 0xFF, 0xEE, 0x34, 0xE6, 0x8F, 0x82, 0xF5, 0x83, 0xE0, 0x54, 0x01, 0x90, 0xE7, 0x40, 0xF0,
  99. 0xE4, 0xA3, 0xF0, 0x90, 0xE6, 0x8A, 0xF0, 0x90, 0xE6, 0x8B, 0x74, 0x02, 0xF0, 0x02, 0x06, 0x45, 0x90, 0xE6, 0xA0, 0xE0,
  100. 0x44, 0x01, 0xF0, 0x02, 0x06, 0x45, 0x12, 0x0D, 0x6C, 0x40, 0x03, 0x02, 0x06, 0x45, 0x90, 0xE6, 0xB8, 0xE0, 0x24, 0xFE,
  101. 0x60, 0x1D, 0x24, 0x02, 0x60, 0x03, 0x02, 0x06, 0x45, 0x90, 0xE6, 0xBA, 0xE0, 0xB4, 0x01, 0x05, 0xC2, 0x00, 0x02, 0x06,
  102. 0x45, 0x90, 0xE6, 0xA0, 0xE0, 0x44, 0x01, 0xF0, 0x02, 0x06, 0x45, 0x90, 0xE6, 0xBA, 0xE0, 0x70, 0x59, 0x90, 0xE6, 0xBC,
  103. 0xE0, 0x54, 0x7E, 0xFF, 0x7E, 0x00, 0xE0, 0xD3, 0x94, 0x80, 0x40, 0x06, 0x7C, 0x00, 0x7D, 0x01, 0x80, 0x04, 0x7C, 0x00,
  104. 0x7D, 0x00, 0xEC, 0x4E, 0xFE, 0xED, 0x4F, 0x24, 0x3E, 0xF5, 0x82, 0x74, 0x0D, 0x3E, 0xF5, 0x83, 0xE4, 0x93, 0xFF, 0x33,
  105. 0x95, 0xE0, 0xFE, 0xEF, 0x24, 0xA1, 0xFF, 0xEE, 0x34, 0xE6, 0x8F, 0x82, 0xF5, 0x83, 0xE0, 0x54, 0xFE, 0xF0, 0x90, 0xE6,
  106. 0xBC, 0xE0, 0x54, 0x80, 0xFF, 0x13, 0x13, 0x13, 0x54, 0x1F, 0xFF, 0xE0, 0x54, 0x0F, 0x2F, 0x90, 0xE6, 0x83, 0xF0, 0xE0,
  107. 0x44, 0x20, 0xF0, 0x02, 0x06, 0x45, 0x90, 0xE6, 0xA0, 0xE0, 0x44, 0x01, 0xF0, 0x02, 0x06, 0x45, 0x12, 0x0D, 0x6E, 0x50,
  108. 0x7C, 0x90, 0xE6, 0xB8, 0xE0, 0x24, 0xFE, 0x60, 0x20, 0x24, 0x02, 0x70, 0x5B, 0x90, 0xE6, 0xBA, 0xE0, 0xB4, 0x01, 0x04,
  109. 0xD2, 0x00, 0x80, 0x65, 0x90, 0xE6, 0xBA, 0xE0, 0x64, 0x02, 0x60, 0x5D, 0x90, 0xE6, 0xA0, 0xE0, 0x44, 0x01, 0xF0, 0x80,
  110. 0x54, 0x90, 0xE6, 0xBC, 0xE0, 0x54, 0x7E, 0xFF, 0x7E, 0x00, 0xE0, 0xD3, 0x94, 0x80, 0x40, 0x06, 0x7C, 0x00, 0x7D, 0x01,
  111. 0x80, 0x04, 0x7C, 0x00, 0x7D, 0x00, 0xEC, 0x4E, 0xFE, 0xED, 0x4F, 0x24, 0x3E, 0xF5, 0x82, 0x74, 0x0D, 0x3E, 0xF5, 0x83,
  112. 0xE4, 0x93, 0xFF, 0x33, 0x95, 0xE0, 0xFE, 0xEF, 0x24, 0xA1, 0xFF, 0xEE, 0x34, 0xE6, 0x8F, 0x82, 0xF5, 0x83, 0xE0, 0x44,
  113. 0x01, 0xF0, 0x80, 0x15, 0x90, 0xE6, 0xA0, 0xE0, 0x44, 0x01, 0xF0, 0x80, 0x0C, 0x12, 0x00, 0x80, 0x50, 0x07, 0x90, 0xE6,
  114. 0xA0, 0xE0, 0x44, 0x01, 0xF0, 0x90, 0xE6, 0xA0, 0xE0, 0x44, 0x80, 0xF0, 0x22, 0xE4, 0xF5, 0x2C, 0xF5, 0x2B, 0xF5, 0x2A,
  115. 0xF5, 0x29, 0xC2, 0x03, 0xC2, 0x00, 0xC2, 0x02, 0xC2, 0x01, 0x12, 0x0C, 0x6C, 0x7E, 0x0A, 0x7F, 0x00, 0x8E, 0x0A, 0x8F,
  116. 0x0B, 0x75, 0x12, 0x0A, 0x75, 0x13, 0x12, 0x75, 0x08, 0x0A, 0x75, 0x09, 0x1C, 0x75, 0x10, 0x0A, 0x75, 0x11, 0x4A, 0x75,
  117. 0x14, 0x0A, 0x75, 0x15, 0x78, 0xEE, 0x54, 0xC0, 0x70, 0x03, 0x02, 0x07, 0x52, 0x75, 0x2D, 0x00, 0x75, 0x2E, 0x80, 0x8E,
  118. 0x2F, 0x8F, 0x30, 0xC3, 0x74, 0x9A, 0x9F, 0xFF, 0x74, 0x0A, 0x9E, 0xCF, 0x24, 0x02, 0xCF, 0x34, 0x00, 0xFE, 0xE4, 0x8F,
  119. 0x28, 0x8E, 0x27, 0xF5, 0x26, 0xF5, 0x25, 0xF5, 0x24, 0xF5, 0x23, 0xF5, 0x22, 0xF5, 0x21, 0xAF, 0x28, 0xAE, 0x27, 0xAD,
  120. 0x26, 0xAC, 0x25, 0xAB, 0x24, 0xAA, 0x23, 0xA9, 0x22, 0xA8, 0x21, 0xC3, 0x12, 0x0D, 0x03, 0x50, 0x37, 0xE5, 0x30, 0x25,
  121. 0x24, 0xF5, 0x82, 0xE5, 0x2F, 0x35, 0x23, 0xF5, 0x83, 0xE0, 0xFF, 0xE5, 0x2E, 0x25, 0x24, 0xF5, 0x82, 0xE5, 0x2D, 0x35,
  122. 0x23, 0xF5, 0x83, 0xEF, 0xF0, 0xE4, 0xFA, 0xF9, 0xF8, 0xE5, 0x24, 0x24, 0x01, 0xF5, 0x24, 0xEA, 0x35, 0x23, 0xF5, 0x23,
  123. 0xE9, 0x35, 0x22, 0xF5, 0x22, 0xE8, 0x35, 0x21, 0xF5, 0x21, 0x80, 0xB3, 0x85, 0x2D, 0x0A, 0x85, 0x2E, 0x0B, 0x74, 0x00,
  124. 0x24, 0x80, 0xFF, 0x74, 0x0A, 0x34, 0xFF, 0xFE, 0xC3, 0xE5, 0x13, 0x9F, 0xF5, 0x13, 0xE5, 0x12, 0x9E, 0xF5, 0x12, 0xC3,
  125. 0xE5, 0x0D, 0x9F, 0xF5, 0x0D, 0xE5, 0x0C, 0x9E, 0xF5, 0x0C, 0xC3, 0xE5, 0x0F, 0x9F, 0xF5, 0x0F, 0xE5, 0x0E, 0x9E, 0xF5,
  126. 0x0E, 0xC3, 0xE5, 0x09, 0x9F, 0xF5, 0x09, 0xE5, 0x08, 0x9E, 0xF5, 0x08, 0xC3, 0xE5, 0x11, 0x9F, 0xF5, 0x11, 0xE5, 0x10,
  127. 0x9E, 0xF5, 0x10, 0xC3, 0xE5, 0x15, 0x9F, 0xF5, 0x15, 0xE5, 0x14, 0x9E, 0xF5, 0x14, 0xD2, 0xE8, 0x43, 0xD8, 0x20, 0x90,
  128. 0xE6, 0x68, 0xE0, 0x44, 0x09, 0xF0, 0x90, 0xE6, 0x5C, 0xE0, 0x44, 0x3D, 0xF0, 0xD2, 0xAF, 0x90, 0xE6, 0x80, 0xE0, 0x54,
  129. 0xF7, 0xF0, 0x53, 0x8E, 0xF8, 0xC2, 0x03, 0x12, 0x07, 0xFF, 0x30, 0x01, 0x05, 0x12, 0x03, 0x9A, 0xC2, 0x01, 0x30, 0x03,
  130. 0xF2, 0x12, 0x0D, 0x64, 0x50, 0xED, 0xC2, 0x03, 0x12, 0x0C, 0x0D, 0x20, 0x00, 0x16, 0x90, 0xE6, 0x82, 0xE0, 0x30, 0xE7,
  131. 0x04, 0xE0, 0x20, 0xE1, 0xEF, 0x90, 0xE6, 0x82, 0xE0, 0x30, 0xE6, 0x04, 0xE0, 0x20, 0xE0, 0xE4, 0x12, 0x0B, 0xB6, 0x12,
  132. 0x0D, 0x66, 0x80, 0xC7, 0x22, 0x8E, 0x3A, 0x8F, 0x3B, 0x90, 0xE6, 0x00, 0xE0, 0x54, 0x18, 0x70, 0x12, 0xE5, 0x3B, 0x24,
  133. 0x01, 0xFF, 0xE4, 0x35, 0x3A, 0xC3, 0x13, 0xF5, 0x3A, 0xEF, 0x13, 0xF5, 0x3B, 0x80, 0x15, 0x90, 0xE6, 0x00, 0xE0, 0x54,
  134. 0x18, 0xFF, 0xBF, 0x10, 0x0B, 0xE5, 0x3B, 0x25, 0xE0, 0xF5, 0x3B, 0xE5, 0x3A, 0x33, 0xF5, 0x3A, 0xE5, 0x3B, 0x15, 0x3B,
  135. 0xAE, 0x3A, 0x70, 0x02, 0x15, 0x3A, 0x4E, 0x60, 0x05, 0x12, 0x0C, 0x21, 0x80, 0xEE, 0x22, 0x78, 0x7F, 0xE4, 0xF6, 0xD8,
  136. 0xFD, 0x75, 0x81, 0x41, 0x02, 0x06, 0x4D, 0x22, 0x02, 0x0C, 0x32, 0x00, 0x02, 0x0C, 0xB3, 0x00, 0x02, 0x0C, 0x9D, 0x00,
  137. 0x02, 0x0C, 0x85, 0x00, 0x02, 0x0B, 0x19, 0x00, 0x02, 0x0B, 0x50, 0x00, 0x02, 0x09, 0xFF, 0x00, 0x02, 0x0D, 0x70, 0x00,
  138. 0x02, 0x0D, 0x71, 0x00, 0x02, 0x0D, 0x72, 0x00, 0x02, 0x0D, 0x73, 0x00, 0x02, 0x0D, 0x74, 0x00, 0x02, 0x0D, 0x75, 0x00,
  139. 0x02, 0x0D, 0x76, 0x00, 0x02, 0x0D, 0x77, 0x00, 0x02, 0x0D, 0x78, 0x00, 0x02, 0x0D, 0x79, 0x00, 0x02, 0x0D, 0x70, 0x00,
  140. 0x02, 0x0D, 0x7A, 0x00, 0x02, 0x0D, 0x7B, 0x00, 0x02, 0x0D, 0x7C, 0x00, 0x02, 0x0D, 0x7D, 0x00, 0x02, 0x0D, 0x7E, 0x00,
  141. 0x02, 0x0D, 0x7F, 0x00, 0x02, 0x0D, 0x80, 0x00, 0x02, 0x0D, 0x70, 0x00, 0x02, 0x0D, 0x70, 0x00, 0x02, 0x0D, 0x70, 0x00,
  142. 0x02, 0x0D, 0x81, 0x00, 0x02, 0x0D, 0x82, 0x00, 0x02, 0x0D, 0x83, 0x00, 0x02, 0x0D, 0x84, 0x00, 0x02, 0x0D, 0x85, 0x00,
  143. 0x02, 0x0D, 0x86, 0x00, 0x02, 0x0D, 0x87, 0x00, 0x02, 0x0D, 0x88, 0x00, 0x02, 0x0D, 0x89, 0x00, 0x02, 0x0D, 0x8A, 0x00,
  144. 0x02, 0x0D, 0x8B, 0x00, 0x02, 0x0D, 0x8C, 0x00, 0x02, 0x0D, 0x8D, 0x00, 0x02, 0x0D, 0x8E, 0x00, 0x02, 0x0D, 0x8F, 0x00,
  145. 0x02, 0x0D, 0x90, 0x00, 0x02, 0x0D, 0x91, 0x00, 0x02, 0x0D, 0x92, 0x00, 0x8E, 0x3C, 0x8F, 0x3D, 0x8D, 0x3E, 0x8A, 0x3F,
  146. 0x8B, 0x40, 0x12, 0x0D, 0x58, 0x12, 0x0D, 0x24, 0x12, 0x0C, 0xC9, 0x50, 0x01, 0x22, 0xE5, 0x19, 0x60, 0x0C, 0xE5, 0x3C,
  147. 0x90, 0xE6, 0x79, 0xF0, 0x12, 0x0C, 0xC9, 0x50, 0x01, 0x22, 0xE5, 0x3D, 0x90, 0xE6, 0x79, 0xF0, 0x12, 0x0C, 0xC9, 0x50,
  148. 0x01, 0x22, 0x90, 0xE6, 0x78, 0x74, 0x80, 0xF0, 0xE5, 0x17, 0x25, 0xE0, 0x44, 0x01, 0x90, 0xE6, 0x79, 0xF0, 0x12, 0x0D,
  149. 0x14, 0x50, 0x01, 0x22, 0x90, 0xE6, 0x79, 0xE0, 0xF5, 0x41, 0x12, 0x0D, 0x14, 0x50, 0x01, 0x22, 0xE4, 0xF5, 0x41, 0xE5,
  150. 0x3E, 0x14, 0xFF, 0xE5, 0x41, 0xC3, 0x9F, 0x50, 0x1C, 0x90, 0xE6, 0x79, 0xE0, 0xFF, 0xE5, 0x40, 0x25, 0x41, 0xF5, 0x82,
  151. 0xE4, 0x35, 0x3F, 0xF5, 0x83, 0xEF, 0xF0, 0x12, 0x0D, 0x14, 0x50, 0x01, 0x22, 0x05, 0x41, 0x80, 0xDA, 0x90, 0xE6, 0x78,
  152. 0x74, 0x20, 0xF0, 0x12, 0x0D, 0x14, 0x50, 0x01, 0x22, 0x90, 0xE6, 0x79, 0xE0, 0xFF, 0xE5, 0x40, 0x25, 0x41, 0xF5, 0x82,
  153. 0xE4, 0x35, 0x3F, 0xF5, 0x83, 0xEF, 0xF0, 0x12, 0x0D, 0x14, 0x50, 0x01, 0x22, 0x90, 0xE6, 0x78, 0x74, 0x40, 0xF0, 0x90,
  154. 0xE6, 0x79, 0xE0, 0xF5, 0x41, 0xC3, 0x22, 0xE5, 0x19, 0x70, 0x03, 0x7F, 0x01, 0x22, 0x7A, 0x10, 0x7B, 0x40, 0x7D, 0x40,
  155. 0xE4, 0xFF, 0xFE, 0x12, 0x08, 0xB8, 0xE4, 0xF5, 0x3A, 0x74, 0x00, 0x25, 0x3A, 0xF5, 0x82, 0xE4, 0x34, 0x10, 0xF5, 0x83,
  156. 0xE5, 0x3A, 0xF0, 0x05, 0x3A, 0xE5, 0x3A, 0xB4, 0x40, 0xEB, 0x7C, 0x10, 0x7D, 0x00, 0x7B, 0x40, 0xE4, 0xFF, 0xFE, 0x12,
  157. 0x0A, 0x9C, 0xE4, 0xF5, 0x3A, 0xE5, 0x3A, 0xF4, 0xFF, 0x74, 0x00, 0x25, 0x3A, 0xF5, 0x82, 0xE4, 0x34, 0x10, 0xF5, 0x83,
  158. 0xEF, 0xF0, 0x05, 0x3A, 0xE5, 0x3A, 0xB4, 0x40, 0xE8, 0x7A, 0x10, 0x7B, 0x00, 0x7D, 0x40, 0xE4, 0xFF, 0xFE, 0x12, 0x08,
  159. 0xB8, 0x90, 0x10, 0x00, 0xE0, 0xF5, 0x3A, 0xE5, 0x3A, 0x30, 0xE0, 0x05, 0x75, 0x3B, 0x01, 0x80, 0x08, 0x63, 0x3A, 0x3F,
  160. 0x05, 0x3A, 0x85, 0x3A, 0x3B, 0xE4, 0xF5, 0x3A, 0xE5, 0x3A, 0xC3, 0x94, 0x40, 0x50, 0x15, 0xAF, 0x3A, 0x7E, 0x00, 0x7C,
  161. 0x10, 0x7D, 0x40, 0xAB, 0x3B, 0x12, 0x0A, 0x9C, 0xE5, 0x3B, 0x25, 0x3A, 0xF5, 0x3A, 0x80, 0xE4, 0xAF, 0x3B, 0x22, 0x32,
  162. 0x12, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40, 0xB4, 0x04, 0x04, 0x10, 0x00, 0x00, 0x01, 0x02, 0x00, 0x01, 0x0A, 0x06,
  163. 0x00, 0x02, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x09, 0x02, 0x2E, 0x00, 0x01, 0x01, 0x00, 0x80, 0x32, 0x09, 0x04, 0x00,
  164. 0x00, 0x04, 0xFF, 0x00, 0x00, 0x00, 0x07, 0x05, 0x02, 0x02, 0x00, 0x02, 0x00, 0x07, 0x05, 0x04, 0x02, 0x00, 0x02, 0x00,
  165. 0x07, 0x05, 0x86, 0x02, 0x00, 0x02, 0x00, 0x07, 0x05, 0x88, 0x02, 0x00, 0x02, 0x00, 0x09, 0x02, 0x2E, 0x00, 0x01, 0x01,
  166. 0x00, 0x80, 0x32, 0x09, 0x04, 0x00, 0x00, 0x04, 0xFF, 0x00, 0x00, 0x00, 0x07, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00, 0x07,
  167. 0x05, 0x04, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x86, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x88, 0x02, 0x40, 0x00, 0x00,
  168. 0x04, 0x03, 0x09, 0x04, 0x10, 0x03, 0x43, 0x00, 0x79, 0x00, 0x70, 0x00, 0x72, 0x00, 0x65, 0x00, 0x73, 0x00, 0x73, 0x00,
  169. 0x0E, 0x03, 0x45, 0x00, 0x5A, 0x00, 0x2D, 0x00, 0x55, 0x00, 0x53, 0x00, 0x42, 0x00, 0x00, 0x00, 0x8E, 0x3C, 0x8F, 0x3D,
  170. 0x8C, 0x3E, 0x8D, 0x3F, 0x8B, 0x40, 0xC2, 0x87, 0x43, 0xB2, 0x80, 0x12, 0x0D, 0x58, 0x12, 0x0D, 0x24, 0x12, 0x0C, 0xC9,
  171. 0x50, 0x04, 0xD2, 0x04, 0x80, 0x59, 0xE5, 0x19, 0x60, 0x0F, 0xE5, 0x3C, 0x90, 0xE6, 0x79, 0xF0, 0x12, 0x0C, 0xC9, 0x50,
  172. 0x04, 0xD2, 0x04, 0x80, 0x46, 0xE5, 0x3D, 0x90, 0xE6, 0x79, 0xF0, 0x12, 0x0C, 0xC9, 0x50, 0x04, 0xD2, 0x04, 0x80, 0x37,
  173. 0xE4, 0xF5, 0x41, 0xE5, 0x41, 0xC3, 0x95, 0x40, 0x50, 0x21, 0x05, 0x3F, 0xE5, 0x3F, 0xAE, 0x3E, 0x70, 0x02, 0x05, 0x3E,
  174. 0x14, 0xF5, 0x82, 0x8E, 0x83, 0xE0, 0x90, 0xE6, 0x79, 0xF0, 0x12, 0x0D, 0x14, 0x50, 0x04, 0xD2, 0x04, 0x80, 0x10, 0x05,
  175. 0x41, 0x80, 0xD8, 0x90, 0xE6, 0x78, 0xE0, 0x44, 0x40, 0xF0, 0x12, 0x0C, 0x51, 0xC2, 0x04, 0x53, 0xB2, 0x7F, 0xA2, 0x04,
  176. 0x22, 0xC0, 0xE0, 0xC0, 0x83, 0xC0, 0x82, 0x90, 0xE6, 0x80, 0xE0, 0x30, 0xE7, 0x0E, 0x85, 0x08, 0x0C, 0x85, 0x09, 0x0D,
  177. 0x85, 0x10, 0x0E, 0x85, 0x11, 0x0F, 0x80, 0x0C, 0x85, 0x10, 0x0C, 0x85, 0x11, 0x0D, 0x85, 0x08, 0x0E, 0x85, 0x09, 0x0F,
  178. 0x53, 0x91, 0xEF, 0x90, 0xE6, 0x5D, 0x74, 0x10, 0xF0, 0xD0, 0x82, 0xD0, 0x83, 0xD0, 0xE0, 0x32, 0xC0, 0xE0, 0xC0, 0x83,
  179. 0xC0, 0x82, 0x90, 0xE6, 0x80, 0xE0, 0x30, 0xE7, 0x0E, 0x85, 0x08, 0x0C, 0x85, 0x09, 0x0D, 0x85, 0x10, 0x0E, 0x85, 0x11,
  180. 0x0F, 0x80, 0x0C, 0x85, 0x10, 0x0C, 0x85, 0x11, 0x0D, 0x85, 0x08, 0x0E, 0x85, 0x09, 0x0F, 0x53, 0x91, 0xEF, 0x90, 0xE6,
  181. 0x5D, 0x74, 0x20, 0xF0, 0xD0, 0x82, 0xD0, 0x83, 0xD0, 0xE0, 0x32, 0x30, 0x04, 0x09, 0x90, 0xE6, 0x80, 0xE0, 0x44, 0x0A,
  182. 0xF0, 0x80, 0x07, 0x90, 0xE6, 0x80, 0xE0, 0x44, 0x08, 0xF0, 0x7F, 0xDC, 0x7E, 0x05, 0x12, 0x07, 0xAD, 0x90, 0xE6, 0x5D,
  183. 0x74, 0xFF, 0xF0, 0x90, 0xE6, 0x5F, 0xF0, 0x53, 0x91, 0xEF, 0x90, 0xE6, 0x80, 0xE0, 0x54, 0xF7, 0xF0, 0x22, 0x90, 0xE6,
  184. 0x82, 0xE0, 0x30, 0xE0, 0x04, 0xE0, 0x20, 0xE6, 0x0B, 0x90, 0xE6, 0x82, 0xE0, 0x30, 0xE1, 0x19, 0xE0, 0x30, 0xE7, 0x15,
  185. 0x90, 0xE6, 0x80, 0xE0, 0x44, 0x01, 0xF0, 0x7F, 0x14, 0x7E, 0x00, 0x12, 0x07, 0xAD, 0x90, 0xE6, 0x80, 0xE0, 0x54, 0xFE,
  186. 0xF0, 0x22, 0xA9, 0x07, 0xAE, 0x14, 0xAF, 0x15, 0x8F, 0x82, 0x8E, 0x83, 0xA3, 0xE0, 0x64, 0x03, 0x70, 0x17, 0xAD, 0x01,
  187. 0x19, 0xED, 0x70, 0x01, 0x22, 0x8F, 0x82, 0x8E, 0x83, 0xE0, 0x7C, 0x00, 0x2F, 0xFD, 0xEC, 0x3E, 0xFE, 0xAF, 0x05, 0x80,
  188. 0xDF, 0xE4, 0xFE, 0xFF, 0x22, 0x90, 0xE6, 0x82, 0xE0, 0x44, 0xC0, 0xF0, 0x90, 0xE6, 0x81, 0xF0, 0x43, 0x87, 0x01, 0x00,
  189. 0x00, 0x00, 0x00, 0x00, 0x22, 0x74, 0x00, 0xF5, 0x86, 0x90, 0xFD, 0xA5, 0x7C, 0x05, 0xA3, 0xE5, 0x82, 0x45, 0x83, 0x70,
  190. 0xF9, 0x22, 0xC0, 0xE0, 0xC0, 0x83, 0xC0, 0x82, 0x90, 0xE6, 0xB5, 0xE0, 0x44, 0x01, 0xF0, 0xD2, 0x01, 0x53, 0x91, 0xEF,
  191. 0x90, 0xE6, 0x5D, 0x74, 0x01, 0xF0, 0xD0, 0x82, 0xD0, 0x83, 0xD0, 0xE0, 0x32, 0x12, 0x0D, 0x58, 0x12, 0x0D, 0x24, 0x12,
  192. 0x0D, 0x14, 0x90, 0xE6, 0x78, 0xE0, 0x44, 0x40, 0xF0, 0x12, 0x0D, 0x58, 0x90, 0xE6, 0x78, 0xE0, 0x30, 0xE1, 0xE9, 0x22,
  193. 0xD2, 0x00, 0xE4, 0xF5, 0x1A, 0x90, 0xE6, 0x78, 0xE0, 0x54, 0x10, 0xFF, 0xC4, 0x54, 0x0F, 0x44, 0x50, 0xF5, 0x17, 0x13,
  194. 0xE4, 0x33, 0xF5, 0x19, 0x22, 0xC0, 0xE0, 0xC0, 0x83, 0xC0, 0x82, 0xD2, 0x03, 0x53, 0x91, 0xEF, 0x90, 0xE6, 0x5D, 0x74,
  195. 0x08, 0xF0, 0xD0, 0x82, 0xD0, 0x83, 0xD0, 0xE0, 0x32, 0xC0, 0xE0, 0xC0, 0x83, 0xC0, 0x82, 0x53, 0x91, 0xEF, 0x90, 0xE6,
  196. 0x5D, 0x74, 0x04, 0xF0, 0xD0, 0x82, 0xD0, 0x83, 0xD0, 0xE0, 0x32, 0xC0, 0xE0, 0xC0, 0x83, 0xC0, 0x82, 0x53, 0x91, 0xEF,
  197. 0x90, 0xE6, 0x5D, 0x74, 0x02, 0xF0, 0xD0, 0x82, 0xD0, 0x83, 0xD0, 0xE0, 0x32, 0x90, 0xE6, 0x78, 0xE0, 0xFF, 0x30, 0xE0,
  198. 0xF8, 0xEF, 0x30, 0xE2, 0x02, 0xD3, 0x22, 0xEF, 0x20, 0xE1, 0x02, 0xD3, 0x22, 0xC3, 0x22, 0x90, 0xE7, 0x40, 0xE5, 0x18,
  199. 0xF0, 0xE4, 0x90, 0xE6, 0x8A, 0xF0, 0x90, 0xE6, 0x8B, 0x04, 0xF0, 0xD3, 0x22, 0x90, 0xE7, 0x40, 0xE5, 0x16, 0xF0, 0xE4,
  200. 0x90, 0xE6, 0x8A, 0xF0, 0x90, 0xE6, 0x8B, 0x04, 0xF0, 0xD3, 0x22, 0xEB, 0x9F, 0xF5, 0xF0, 0xEA, 0x9E, 0x42, 0xF0, 0xE9,
  201. 0x9D, 0x42, 0xF0, 0xE8, 0x9C, 0x45, 0xF0, 0x22, 0x90, 0xE6, 0x78, 0xE0, 0xFF, 0x30, 0xE0, 0xF8, 0xEF, 0x30, 0xE2, 0x02,
  202. 0xD3, 0x22, 0xC3, 0x22, 0x90, 0xE6, 0x78, 0x74, 0x80, 0xF0, 0xE5, 0x17, 0x25, 0xE0, 0x90, 0xE6, 0x79, 0xF0, 0x22, 0x90,
  203. 0xE5, 0x0D, 0xE0, 0x30, 0xE4, 0x02, 0xC3, 0x22, 0xD3, 0x22, 0x00, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05,
  204. 0x90, 0xE6, 0xBA, 0xE0, 0xF5, 0x18, 0xD3, 0x22, 0x90, 0xE6, 0xBA, 0xE0, 0xF5, 0x16, 0xD3, 0x22, 0x90, 0xE6, 0x78, 0xE0,
  205. 0x20, 0xE6, 0xF9, 0x22, 0x53, 0xD8, 0xEF, 0x32, 0xD3, 0x22, 0xD3, 0x22, 0xD3, 0x22, 0xD3, 0x22, 0xD3, 0x22, 0xD3, 0x22,
  206. 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
  207. 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0xAA,
  208. // The original array was padded to a size divisible by 16 but apparently that is not required.
  209. #endregion
  210. };
  211.  
  212. #endregion
  213.  
  214. #region DLL APIs
  215.  
  216. // CreateFile - Used to get access to a USB device
  217. [DllImport("kernel32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
  218. public static extern Microsoft.Win32.SafeHandles.SafeFileHandle CreateFile(
  219. string lpFileName,
  220. uint dwDesiredAccess,
  221. uint dwShareMode,
  222. IntPtr SecurityAttributes,
  223. uint dwCreationDisposition,
  224. uint dwFlagsAndAttributes,
  225. IntPtr hTemplateFile
  226. );
  227.  
  228. // public const uint FILE_ATTRIBUTE_NORMAL = 0x80; // not used
  229. // public const uint FILE_INVALID_HANDLE_VALUE = -1; // not used
  230. // Taken from WinNt.h. These could be enum-ized for type-safety.
  231. public const uint FILE_GENERIC_READ = 0x80000000;
  232. public const uint FILE_GENERIC_WRITE = 0x40000000;
  233. public const uint FILE_SHARE_WRITE = 0x00000002;
  234. public const uint FILE_CREATE_NEW = 1;
  235. public const uint FILE_CREATE_ALWAYS = 2;
  236. public const uint FILE_OPEN_EXISTING = 3;
  237.  
  238. #region multiple DeviceIoControl definitions
  239.  
  240. // DeviceIoControl. outbuf as IntPtr
  241. [return: MarshalAs(UnmanagedType.Bool)]
  242. [DllImport("Kernel32.dll", ExactSpelling = true, SetLastError = true, CharSet = CharSet.Auto)]
  243. public static extern bool DeviceIoControl(
  244. [In] Microsoft.Win32.SafeHandles.SafeFileHandle hDevice,
  245. [In] uint dwIoControlCode, // EIOControlCode
  246. ref EzUsbSys.VENDOR_REQUEST_IN lpInBuffer,
  247. [In] int nInBufferSize,
  248. IntPtr lpOutBuffer,
  249. int nOutBufferSize,
  250. ref int pBytesReturned,
  251. IntPtr Overlapped
  252. );
  253.  
  254. // DeviceIoControl. outbuf as byte []
  255. [return: MarshalAs(UnmanagedType.Bool)]
  256. [DllImport("Kernel32.dll", ExactSpelling = true, SetLastError = true, CharSet = CharSet.Auto)]
  257. public static extern bool DeviceIoControl(
  258. [In] Microsoft.Win32.SafeHandles.SafeFileHandle hDevice,
  259. [In] uint dwIoControlCode, // EIOControlCode
  260. ref EzUsbSys.VENDOR_REQUEST_IN lpInBuffer,
  261. [In] int nInBufferSize,
  262. byte[] lpOutBuffer,
  263. int nOutBufferSize,
  264. ref int pBytesReturned,
  265. IntPtr Overlapped
  266. );
  267.  
  268. // DeviceIoControl. outbuf as byte []
  269. [return: MarshalAs(UnmanagedType.Bool)]
  270. [DllImport("Kernel32.dll", ExactSpelling = true, SetLastError = true, CharSet = CharSet.Auto)]
  271. public static extern bool DeviceIoControl(
  272. [In] Microsoft.Win32.SafeHandles.SafeFileHandle hDevice,
  273. [In] uint dwIoControlCode, // EIOControlCode
  274. ref EzUsbSys.ANCHOR_DOWNLOAD_CONTROL lpInBuffer,
  275. [In] int nInBufferSize,
  276. byte[] lpOutBuffer,
  277. int nOutBufferSize,
  278. ref int pBytesReturned,
  279. IntPtr Overlapped
  280. );
  281.  
  282. // DeviceIoControl. outbuf as byte []
  283. [return: MarshalAs(UnmanagedType.Bool)]
  284. [DllImport("Kernel32.dll", ExactSpelling = true, SetLastError = true, CharSet = CharSet.Auto)]
  285. public static extern bool DeviceIoControl(
  286. [In] Microsoft.Win32.SafeHandles.SafeFileHandle hDevice,
  287. [In] uint dwIoControlCode, // EIOControlCode
  288. ref EzUsbSys.VENDOR_OR_CLASS_REQUEST_CONTROL lpInBuffer,
  289. [In] int nInBufferSize,
  290. byte[] lpOutBuffer,
  291. int nOutBufferSize,
  292. ref int pBytesReturned,
  293. IntPtr Overlapped
  294. );
  295.  
  296. // DeviceIoControl. intbuf and outbuf as Usb_Device_Descriptor
  297. [return: MarshalAs(UnmanagedType.Bool)]
  298. [DllImport("Kernel32.dll", ExactSpelling = true, SetLastError = true, CharSet = CharSet.Auto)]
  299. public static extern bool DeviceIoControl(
  300. [In] Microsoft.Win32.SafeHandles.SafeFileHandle hDevice,
  301. [In] uint dwIoControlCode, // EIOControlCode
  302. ref EzUsbSys.Usb_Device_Descriptor lpInBuffer,
  303. [In] int nInBufferSize,
  304. ref EzUsbSys.Usb_Device_Descriptor lpOutBuffer,
  305. int nOutBufferSize,
  306. ref int pBytesReturned,
  307. IntPtr Overlapped
  308. );
  309.  
  310. // DeviceIoControl. outbuf as byte []
  311. [return: MarshalAs(UnmanagedType.Bool)]
  312. [DllImport("Kernel32.dll", ExactSpelling = true, SetLastError = true, CharSet = CharSet.Auto)]
  313. public static extern bool DeviceIoControl(
  314. [In] Microsoft.Win32.SafeHandles.SafeFileHandle hDevice,
  315. [In] uint dwIoControlCode, // EIOControlCode
  316. byte[] lpInBuffer,
  317. [In] int nInBufferSize,
  318. byte[] lpOutBuffer,
  319. int nOutBufferSize,
  320. ref int pBytesReturned,
  321. IntPtr Overlapped
  322. );
  323.  
  324. #endregion
  325.  
  326. /*
  327.   // since I'm using SafeFileHandle, don't call CloseHandle(hOut);
  328.   [DllImport("kernel32.dll", CallingConvention = CallingConvention.StdCall, SetLastError = true)]
  329.   [return: MarshalAs(UnmanagedType.Bool)]
  330.   public static extern bool CloseHandle(Microsoft.Win32.SafeHandles.SafeFileHandle hObject);
  331.   */
  332.  
  333. #endregion
  334.  
  335. #region Other Interop defines
  336.  
  337. // Taken from EzUsbSys.h
  338. public class EzUsbSys
  339. {
  340. // These values were taken from EzUsbSys.h which were defined using the CTL_CODE macro defined in WinIoCtl.h
  341. // lic static uint IOCTL_Ezusb_GET_PIPE_INFO = CTL_CODE(FileDevice.UNKNOWN, Ezusb_IOCTL_INDEX + 0, Method.BUFFERED, FileAccess.ANY );
  342. public static uint IOCTL_Ezusb_GET_DEVICE_DESCRIPTOR = CTL_CODE(FileDevice.UNKNOWN, Ezusb_IOCTL_INDEX + 1, Method.BUFFERED, FileAccess.ANY );
  343. public static uint IOCTL_Ezusb_VENDOR_REQUEST = CTL_CODE(FileDevice.UNKNOWN, Ezusb_IOCTL_INDEX + 5, Method.BUFFERED, FileAccess.ANY );
  344. // lic static uint IOCTL_Ezusb_ANCHOR_DOWNLOAD = CTL_CODE(FileDevice.UNKNOWN, Ezusb_IOCTL_INDEX + 7, Method.BUFFERED, FileAccess.ANY );
  345. public static uint IOCTL_EZUSB_ANCHOR_DOWNLOAD = CTL_CODE(FileDevice.UNKNOWN, Ezusb_IOCTL_INDEX + 27, Method.IN_DIRECT, FileAccess.ANY );
  346. public static uint IOCTL_EZUSB_VENDOR_OR_CLASS_REQUEST = CTL_CODE(FileDevice.UNKNOWN, Ezusb_IOCTL_INDEX + 22, Method.IN_DIRECT, FileAccess.ANY );
  347.  
  348. enum FileDevice : uint
  349. {
  350. UNKNOWN = 0x00000022, // taken from FILE_DEVICE_UNKNOWN in WinIoCtl.h
  351. };
  352.  
  353. enum Method : uint
  354. {
  355. BUFFERED = 0, // METHOD_BUFFERED in WinIoCtl.h
  356. IN_DIRECT = 1,
  357. OUT_DIRECT = 2,
  358. NEITHER = 3,
  359. };
  360.  
  361. enum FileAccess : uint
  362. {
  363. ANY = 0, // FILE_ANY_ACCESS in WinIoCtl.h
  364. };
  365.  
  366. // CTL_CODE macro defined in WinIoCtl.h
  367. // c# does not allow macros with parameters therefore this function was created.
  368. // For improved type-safety, the parameters are defined as enums based on uint.
  369. private static uint CTL_CODE(FileDevice deviceType, uint function, Method method, FileAccess access)
  370. {
  371. return ((uint)deviceType << 16) | ((uint)access << 14) | ((uint)function << 2) | (uint)method;
  372. }
  373.  
  374. private const uint Ezusb_IOCTL_INDEX = 0x0800; // taken from Ezusb_IOCTL_INDEX in EzUsbSys.h.
  375.  
  376. private static bool testOk = TestOk(); // Run test at startup.
  377.  
  378. static bool TestOk()
  379. {
  380. // Make sure that this implementation results in the same values seen in EzUsb.
  381. Debug.Assert(
  382. IOCTL_Ezusb_VENDOR_REQUEST == 0x00222014 &&
  383. IOCTL_EZUSB_ANCHOR_DOWNLOAD == 0x0022206D &&
  384. IOCTL_EZUSB_VENDOR_OR_CLASS_REQUEST == 0x00222059
  385. );
  386. return true;
  387. }
  388.  
  389. public enum VendAxCmd : byte
  390. {
  391. ANCHOR_LOAD_INTERNAL = 0xA0, // ANCHOR_LOAD_INTERNAL in EzUsbSys.h. R+W internal memory. Executed by USB core rather than firmware.
  392. RwEepromSmall = 0xA2, // Couldn't find A2 in EzUsbSys.h. It R&W small EEPROM.
  393. ANCHOR_LOAD_EXTERNAL = 0xA3, // ANCHOR_LOAD_EXTERNAL
  394. GetEepromSize = 0xA5, // Couldn't find this in EzUsbSys.h. Consider using this to check EEPROM size.
  395. RwEepromBig = 0xA9, // R&W a 'large' EEPROM. I'm assuming that we'll use only the large EEPROM.
  396. };
  397.  
  398. public enum RequestType : byte
  399. {
  400. Class = 1,
  401. Vendor = 2
  402. };
  403.  
  404. public enum Recipient : byte
  405. {
  406. Device = 0,
  407. Interface = 1,
  408. Endpoint = 2,
  409. Other = 3
  410. };
  411.  
  412. public enum Direction : byte
  413. {
  414. HostToDevice = 0,
  415. DeviceToHost = 1
  416. }
  417.  
  418. // structs taken from EzUsbSys.h
  419. // I'll keep the structure definitions as close as possible to the original definitions.
  420. // A constructor is added for better type-safety.
  421.  
  422. public struct VENDOR_REQUEST_IN // from EzUsbSys.h
  423. {
  424. public byte bRequest;
  425. public UInt16 wValue;
  426. public UInt16 wIndex;
  427. public UInt16 wLength;
  428. public byte direction;
  429. public byte bData;
  430.  
  431. public VENDOR_REQUEST_IN(
  432. VendAxCmd bRequest,
  433. int offset,
  434. UInt16 wIndex,
  435. int wLength,
  436. Direction direction,
  437. byte bData)
  438. {
  439. this.bRequest = (byte)bRequest;
  440. this.wValue = (UInt16)offset;
  441. this.wIndex = wIndex;
  442. this.wLength = (UInt16)wLength;
  443. this.direction = (byte)direction;
  444. this.bData = bData;
  445. }
  446.  
  447. };
  448.  
  449. // Structure used with IOCTL_EZUSB_ANCHOR_DOWNLOAD (but not IOCTL_Ezusb_ANCHOR_DOWNLOAD).
  450. public struct ANCHOR_DOWNLOAD_CONTROL // From EzUsbSys.h
  451. {
  452. UInt16 offset;
  453.  
  454. public ANCHOR_DOWNLOAD_CONTROL(UInt16 offset)
  455. {
  456. this.offset = offset;
  457. }
  458. };
  459.  
  460.  
  461. public struct VENDOR_OR_CLASS_REQUEST_CONTROL // From EzUsbSys.h
  462. {
  463. public byte direction; // transfer direction (0=host to device, 1=device to host)
  464. public byte requestType; // request type (1=class, 2=vendor)
  465. public byte recepient; // recipient (0=device,1=interface,2=endpoint,3=other)
  466. public byte requestTypeReservedBits;
  467. public byte request;
  468. public UInt16 value;
  469. public UInt16 index;
  470.  
  471. public VENDOR_OR_CLASS_REQUEST_CONTROL(
  472. Direction direction,
  473. RequestType requestType,
  474. Recipient recepient,
  475. VendAxCmd request,
  476. int value,
  477. UInt16 index)
  478. {
  479. Debug.Assert(value < 0x100000);
  480.  
  481. this.direction = (byte)direction;
  482. this.requestType = (byte)requestType;
  483. this.recepient = (byte)recepient;
  484. this.request = (byte)request;
  485. this.value = (UInt16)value;
  486. this.index = index;
  487. this.requestTypeReservedBits = 0;
  488. }
  489. };
  490.  
  491. public struct Usb_Device_Descriptor // Taken from usb100.h
  492. {
  493. public byte bLength;
  494. public byte bDescriptorType;
  495. public ushort bcdUSB;
  496. public byte bDeviceClass;
  497. public byte bDeviceSubClass;
  498. public byte bDeviceProtocol;
  499. public byte bMaxPacketSize0;
  500. public ushort idVendor;
  501. public ushort idProduct;
  502. public ushort bcdDevice;
  503. public byte iManufacturer;
  504. public byte iProduct;
  505. public byte iSerialNumber;
  506. public byte bNumConfigurations;
  507. };
  508.  
  509. } // EzUsbSys
  510.  
  511.  
  512. #endregion
  513.  
  514. public const int EepromSizeBytes = 0x8000; // The size of a 32 kB EEPROM.
  515. public const int UsbMaxPacketSize = 0x1000;
  516.  
  517. static Microsoft.Win32.SafeHandles.SafeFileHandle hDevice;
  518. string iicFilename;
  519. EzUsbSys.Usb_Device_Descriptor deviceDescriptor = new EzUsbSys.Usb_Device_Descriptor();
  520. bool deviceOnline = false;
  521. bool vendAxLoaded = false;
  522.  
  523. public MainForm()
  524. {
  525. InitializeComponent();
  526. }
  527.  
  528. private void timer1_Tick(object sender, EventArgs e)
  529. {
  530. try
  531. {
  532. timer1.Stop();
  533.  
  534. // This should be modififed to dynamically update a list of devices.
  535. if (txtDeviceName.Text.Length==0)
  536. {
  537. string[] list = GetUnopenedDevices();
  538.  
  539. cmboDeviceList.Items.Clear();
  540. cmboDeviceList.Items.AddRange(list);
  541.  
  542. txtQtyDevices.Text = string.Format("{0} device{1} available", list.Length, list.Length != 1 ? "s" : "");
  543.  
  544. if (list.Length == 1)
  545. {
  546. cmboDeviceList.SelectedIndex = 0;
  547. }
  548. }
  549. ping();
  550. }
  551. finally
  552. {
  553. timer1.Start();
  554. }
  555. }
  556.  
  557. private void ping()
  558. {
  559. bool deviceOnlineNow = false;
  560. byte [] eeFirst8Bytes = null;
  561. try
  562. {
  563. Open();
  564. GetDeviceDescriptorDevIoCtl(ref deviceDescriptor);
  565. deviceOnlineNow = true;
  566.  
  567. if (vendAxLoaded)
  568. {
  569. eeFirst8Bytes = EepromRead(8);
  570. }
  571.  
  572. hDevice.Close();
  573.  
  574. if (!vendAxLoaded)
  575. {
  576. downloadVendAx(); // FirmwareDownloadDevIoCtl(VendAxCode);
  577. }
  578.  
  579. }
  580. catch
  581. {
  582. deviceOnlineNow = false;
  583. }
  584.  
  585. // change in status.
  586. if (deviceOnline != deviceOnlineNow)
  587. {
  588. deviceOnline = deviceOnlineNow;
  589.  
  590. txtIdVendor.Text = !deviceOnline ? "" :
  591. deviceDescriptor.idVendor.ToString("X04") + ( deviceDescriptor.idVendor==0x04B4 ?
  592. " (Cypress default)" : deviceDescriptor.idVendor==0x08b1 ? " (DCT)" : "" )
  593. ;
  594.  
  595. txtDeviceName.Text = deviceOnline ? cmboDeviceList.Text : "";
  596. txtProductId.Text = deviceOnline ? deviceDescriptor.idProduct.ToString("X04") : "";
  597. txtDeviceId.Text = deviceOnline ? deviceDescriptor.bcdDevice.ToString("X04") : "";
  598.  
  599. ProgressDone(deviceOnline ? "Connected" : "Disconnected");
  600.  
  601. }
  602.  
  603. if (!deviceOnline)
  604. {
  605. vendAxLoaded = false;
  606. }
  607.  
  608. txtVendAxLoaded.Text = vendAxLoaded ? "Yes" : "No";
  609.  
  610. if (deviceOnline && vendAxLoaded && eeFirst8Bytes != null)
  611. {
  612. txtEeFirst8Bytes.Text = BitConverter.ToString(eeFirst8Bytes).Replace("-", " "); ;
  613. }
  614. else
  615. {
  616. txtEeFirst8Bytes.Text = "";
  617. }
  618.  
  619. btnDeviceToIicFile.Enabled = deviceOnline;
  620. btnEraseEeAfter8.Enabled = deviceOnline;
  621. IicDownload.Enabled = deviceOnline;
  622. btnVerifyIicFile.Enabled = deviceOnline;
  623. btnEraseEeprom.Enabled = deviceOnline;
  624. cmboDeviceToIicFileSize.Enabled = deviceOnline;
  625.  
  626. cmboDeviceList.Visible = cmboDeviceList.Items.Count > 1;
  627.  
  628. }
  629.  
  630.  
  631. void GetDeviceDescriptorDevIoCtl(ref EzUsbSys.Usb_Device_Descriptor arg)
  632. {
  633.  
  634. Debug.Assert(hDevice != null);
  635.  
  636. int pBytesReturned = 0;
  637. bool bOk;
  638.  
  639. bOk = DeviceIoControl(
  640. hDevice,
  641. (uint)EzUsbSys.IOCTL_Ezusb_GET_DEVICE_DESCRIPTOR,
  642. ref arg,
  643. Marshal.SizeOf(arg),
  644. ref arg,
  645. Marshal.SizeOf(arg),
  646. ref pBytesReturned,
  647. IntPtr.Zero);
  648.  
  649. if (!bOk || pBytesReturned != Marshal.SizeOf(arg)) { throw new Exception(); }
  650.  
  651. }
  652.  
  653.  
  654. // taken from CEzMrView::Ezusb_DownloadIntelHex in EzMrView
  655. void downloadVendAx()
  656. {
  657. try
  658. {
  659. // EzMr had some sleeps that apparently are not necessary.
  660. // I'll parameterize the duration as a reminder that it might need to be revisited.
  661. int sleepDuration = 0; // 400
  662.  
  663. ProgressInit(3, "Downloading FW");
  664. Open();
  665. SendOpReset();
  666. hDevice.Close();
  667. ProgressUpdate(1);
  668.  
  669. Thread.Sleep(sleepDuration); // Sleep durations may not be necessary.
  670.  
  671. Debug.Assert(VendAxCode.Length == 3476);
  672. ProgressUpdate(2);
  673.  
  674. Open();
  675. vendAxLoaded = VendAxCode.SequenceEqual(IntRamRead(0, VendAxCode.Length));
  676.  
  677. if (!vendAxLoaded)
  678. {
  679. FirmwareDownloadDevIoCtl(VendAxCode);
  680. vendAxLoaded = VendAxCode.SequenceEqual(IntRamRead(0, VendAxCode.Length));
  681. if (!vendAxLoaded) { throw new Exception("VendAx Verify Failed"); }
  682. }
  683. Thread.Sleep(sleepDuration);
  684. SendOpRun();
  685. hDevice.Close();
  686. ProgressUpdate(3);
  687. Thread.Sleep(sleepDuration);
  688. ProgressDone( "FW downloaded and verified" );
  689. }
  690. catch ( Exception ex )
  691. {
  692. ProgressDone( "FW downloaded Failed" );
  693. }
  694. }
  695.  
  696. // Open a handle for the Cypress device.
  697. // The result is stored in this->hDevice.
  698. void Open()
  699. {
  700. hDevice = CreateFile(
  701. cmboDeviceList.Text,
  702. FILE_GENERIC_WRITE,
  703. FILE_SHARE_WRITE,
  704. IntPtr.Zero,
  705. FILE_OPEN_EXISTING,
  706. 0,
  707. IntPtr.Zero);
  708.  
  709. if (hDevice.IsInvalid ) throw( new Exception( "Open failed") );
  710. }
  711.  
  712. byte[] EepromRead( int qty)
  713. {
  714. Debug.Assert(qty <= EepromSizeBytes);
  715.  
  716. if (qty <= UsbMaxPacketSize)
  717. {
  718. return EepromReadDevIoCtl(0, qty);
  719. }
  720.  
  721. byte[] buffer = new byte[qty];
  722.  
  723. ProgressInit(buffer.Length, "Reading EEPROM");
  724.  
  725. for (int remaining = qty, offset=0; remaining>0; )
  726. {
  727. int len = Math.Min(remaining, UsbMaxPacketSize);
  728.  
  729. // Append smaller buffer onto larger buffer.
  730. Array.Copy(EepromReadDevIoCtl(offset, len), 0, buffer, offset, len);
  731.  
  732. ProgressUpdate(offset);
  733.  
  734. offset += len;
  735. remaining -= len;
  736. } // for
  737.  
  738. ProgressDone("Done reading");
  739.  
  740. return buffer;
  741.  
  742. } // EepromRead
  743.  
  744. byte[] EepromReadDevIoCtl(int offset, int qty)
  745. {
  746. Debug.Assert(qty <= UsbMaxPacketSize);
  747. Debug.Assert(offset <= EepromSizeBytes);
  748.  
  749. byte[] buffer = new byte[qty];
  750.  
  751. EzUsbSys.VENDOR_OR_CLASS_REQUEST_CONTROL myRequest = new EzUsbSys.VENDOR_OR_CLASS_REQUEST_CONTROL(
  752. EzUsbSys.Direction.DeviceToHost,
  753. EzUsbSys.RequestType.Vendor,
  754. EzUsbSys.Recipient.Device,
  755. EzUsbSys.VendAxCmd.RwEepromBig,
  756. offset,
  757. 0 );
  758.  
  759. Debug.Assert(hDevice != null);
  760.  
  761. int pBytesReturned = 0;
  762.  
  763. bool bOk = DeviceIoControl(
  764. hDevice,
  765. (uint)EzUsbSys.IOCTL_EZUSB_VENDOR_OR_CLASS_REQUEST,
  766. ref myRequest,
  767. Marshal.SizeOf(myRequest),
  768. buffer,
  769. buffer.Length,
  770. ref pBytesReturned,
  771. IntPtr.Zero);
  772.  
  773. if (!bOk) { throw new Exception("DeviceIoControl failed"); }
  774. if (!(pBytesReturned == qty)) { throw new Exception("DeviceIoControl failed"); }
  775.  
  776. return buffer;
  777.  
  778. } // EepromReadDevIoCtl
  779.  
  780. void EepromWrite( byte[] buffer)
  781. {
  782. EepromWriteDevIoCtl(0, buffer);
  783. }
  784.  
  785. void EepromWriteDevIoCtl(int offset, byte[] buffer )
  786. {
  787.  
  788. Debug.Assert(offset <= EepromSizeBytes );
  789. Debug.Assert(buffer.Length <= UsbMaxPacketSize);
  790.  
  791. EzUsbSys.VENDOR_OR_CLASS_REQUEST_CONTROL myRequest = new EzUsbSys.VENDOR_OR_CLASS_REQUEST_CONTROL(
  792. EzUsbSys.Direction.HostToDevice,
  793. EzUsbSys.RequestType.Vendor,
  794. EzUsbSys.Recipient.Device,
  795. EzUsbSys.VendAxCmd.RwEepromBig,
  796. offset,
  797. 0);
  798.  
  799. Debug.Assert(hDevice != null);
  800.  
  801. int pBytesReturned = 0;
  802.  
  803. bool bOk = DeviceIoControl(
  804. hDevice,
  805. (uint)EzUsbSys.IOCTL_EZUSB_VENDOR_OR_CLASS_REQUEST,
  806. ref myRequest,
  807. Marshal.SizeOf(myRequest),
  808. buffer,
  809. buffer.Length,
  810. ref pBytesReturned,
  811. IntPtr.Zero);
  812.  
  813. if (!bOk) { throw new Exception("DeviceIoControl failed"); }
  814. if (!(pBytesReturned == buffer.Length)) { throw new Exception("DeviceIoControl failed"); }
  815. if (!buffer.SequenceEqual(EepromReadDevIoCtl(offset, buffer.Length))) { throw new Exception("Verify failed"); }
  816.  
  817. }
  818.  
  819.  
  820. // Write a single byte to ram location specified.
  821. // To download firmware, see FirmwareDownloadDevIoCtl
  822. // Typical usage:
  823. // IntRamWrite(0xE600, 1); // write a 1 to address 0xE600 to enter reset.
  824. // IntRamWrite(0xE600, 0); // write a 1 to address 0xE600 to enter reset.
  825. void IntRamWriteByteDevIoCtl(UInt16 offset, byte data)
  826. {
  827.  
  828. EzUsbSys.VENDOR_REQUEST_IN myRequest = new EzUsbSys.VENDOR_REQUEST_IN(
  829. EzUsbSys.VendAxCmd.ANCHOR_LOAD_INTERNAL,
  830. offset,
  831. 0x00,
  832. 0x01, // length of data.
  833. EzUsbSys.Direction.HostToDevice,
  834. data);
  835.  
  836. Debug.Assert(hDevice != null);
  837.  
  838. int pBytesReturned = 0;
  839.  
  840. bool bOk = DeviceIoControl(
  841. hDevice,
  842. (uint)EzUsbSys.IOCTL_Ezusb_VENDOR_REQUEST,
  843. ref myRequest,
  844. Marshal.SizeOf(myRequest),
  845. IntPtr.Zero,
  846. 0,
  847. ref pBytesReturned,
  848. IntPtr.Zero);
  849.  
  850. if (!bOk) { throw new Exception("DeviceIoControl failed"); }
  851. if (!(pBytesReturned == 0)) { throw new Exception("DeviceIoControl failed"); }
  852.  
  853. } // IntRamWriteByteDevIoCtl
  854.  
  855.  
  856. // Read internal memory. Used to determine if Vend_Ax is downloaded.
  857. byte[] IntRamRead(int offset, int qty)
  858. {
  859. byte data=0;
  860.  
  861. EzUsbSys.VENDOR_REQUEST_IN myRequest = new EzUsbSys.VENDOR_REQUEST_IN(
  862. EzUsbSys.VendAxCmd.ANCHOR_LOAD_INTERNAL,
  863. offset,
  864. 0x00,
  865. qty, // length of data.
  866. EzUsbSys.Direction.DeviceToHost,
  867. data);
  868.  
  869. Debug.Assert(hDevice != null);
  870.  
  871. byte[] buffer = new byte[qty];
  872.  
  873. int pBytesReturned = 0;
  874.  
  875. bool bOk = DeviceIoControl(
  876. hDevice,
  877. (uint)EzUsbSys.IOCTL_Ezusb_VENDOR_REQUEST,
  878. ref myRequest,
  879. Marshal.SizeOf(myRequest),
  880. buffer,
  881. buffer.Length,
  882. ref pBytesReturned,
  883. IntPtr.Zero);
  884.  
  885. if (!bOk) { throw new Exception("DeviceIoControl failed"); }
  886. Debug.Assert(pBytesReturned == qty);
  887.  
  888. return buffer;
  889.  
  890. }
  891.  
  892. // Hold CPU in reset.
  893. void SendOpReset()
  894. {
  895. IntRamWriteByteDevIoCtl(0xE600, 1); // write a 1 to address 0xE600 to enter reset.
  896. return;
  897. }
  898.  
  899. // Let CPU run.
  900. void SendOpRun()
  901. {
  902. IntRamWriteByteDevIoCtl(0xE600, 0); // write a 1 to address 0xE600 to enter reset.
  903. return;
  904. }
  905.  
  906. // Download firmware.
  907. // See downloadVendAx for usage.
  908. // Typical usage:
  909. // SendOpReset();
  910. // FirmwareDownload(VendAxCode);
  911. // SendOpRun();
  912. void FirmwareDownloadDevIoCtl( byte [] buffer )
  913. {
  914. Debug.Assert(buffer.Length < 7 * 1024); // The driver spec says the size must be less than 7 kB.
  915.  
  916. EzUsbSys.ANCHOR_DOWNLOAD_CONTROL myRequest = new EzUsbSys.ANCHOR_DOWNLOAD_CONTROL(0);
  917. Debug.Assert(hDevice != null);
  918.  
  919. int pBytesReturned = 0;
  920. bool bOk;
  921.  
  922. bOk = DeviceIoControl(
  923. hDevice,
  924. (uint)EzUsbSys.IOCTL_EZUSB_ANCHOR_DOWNLOAD,
  925. ref myRequest,
  926. Marshal.SizeOf(myRequest),
  927. buffer,
  928. buffer.Length,
  929. ref pBytesReturned,
  930. IntPtr.Zero);
  931.  
  932. if (!bOk) { throw new Exception("DeviceIoControl failed"); }
  933. Debug.Assert(pBytesReturned == 0);
  934.  
  935. }
  936.  
  937.  
  938. // Find all un-opened devices.
  939. // Check the ezusb driver, and the TsUsb.sys driver, for a list of available devices.
  940. // Typically, there would be a qty of 0 or 1. Rarely, there would be more.
  941. // It's assumed that there would be few devices.
  942. static string[] GetUnopenedDevices()
  943. {
  944. string [] driverList = new string[]{ "Tsusb2", "ezusb" };
  945. List<string> deviceList = new List<string>();
  946.  
  947. foreach (string driverName in driverList)
  948. {
  949. // I didn't test this fully with the ezusb driver.
  950. // The Tsusb driver used 'funny' characters and didn't seem to work with character '\'.
  951. // I might be able to use characters > '\' but didn't think this would be very common.
  952. for (char c = '0'; c < '\\'; c++)
  953. {
  954. string deviceName = @"\\.\" + driverName + "-" + c;
  955.  
  956. Microsoft.Win32.SafeHandles.SafeFileHandle hOut = CreateFile(
  957. deviceName,
  958. FILE_GENERIC_READ | FILE_GENERIC_WRITE,
  959. 0,
  960. IntPtr.Zero,
  961. FILE_OPEN_EXISTING,
  962. 0,
  963. IntPtr.Zero);
  964.  
  965. if (hOut.IsInvalid)
  966. {
  967. hOut.Close();
  968. continue;
  969. }
  970. else
  971. {
  972. deviceList.Add(deviceName);
  973. hOut.Close();
  974. // if using SafeFileHandle, don't call CloseHandle(hOut);
  975. // Why? hOut was getting closed 'safely' yet again which resulted in odd behavior.
  976. }
  977. } // for each device letter
  978. } // for each device driver
  979.  
  980.  
  981. return deviceList.ToArray();
  982.  
  983. }
  984.  
  985. // Download a .IIC file.
  986. // Prompt for the file to download.
  987. private void IicDownload_Click(object sender, EventArgs e)
  988. {
  989. try
  990. {
  991. OpenFileDialog dlg = new OpenFileDialog();
  992. dlg.FileName = iicFilename;
  993. dlg.Title = "Select .IIC file to load into EEPROM";
  994. dlg.CheckFileExists = true;
  995. dlg.Filter = "IIC files (*.iic)|*.iic|All files (*.*)|*.*";
  996. DialogResult result = dlg.ShowDialog();
  997.  
  998. if (result != DialogResult.OK)
  999. {
  1000. return;
  1001. }
  1002.  
  1003. iicFilename = dlg.FileName;
  1004.  
  1005. byte [] buffer = System.IO.File.ReadAllBytes(iicFilename);
  1006.  
  1007. const int packetSize = 0x100;
  1008.  
  1009. ProgressInit( buffer.Length, "Writing EEPROM");
  1010.  
  1011. Open();
  1012.  
  1013. for ( int offset=0, remaining=buffer.Length; remaining>0; )
  1014. {
  1015. int length = Math.Min( packetSize, remaining );
  1016.  
  1017. byte [] x = new byte[length];
  1018.  
  1019. ProgressUpdate(buffer.Length - remaining);
  1020.  
  1021. // extract smaller buffer from large buffer
  1022. Array.Copy( buffer, offset, x, 0, length );
  1023.  
  1024. EepromWriteDevIoCtl( offset, x );
  1025.  
  1026. remaining -= length;
  1027. offset += length;
  1028.  
  1029.  
  1030. }
  1031.  
  1032. Debug.Assert(buffer.SequenceEqual(EepromRead( buffer.Length)));
  1033.  
  1034. hDevice.Close();
  1035.  
  1036. ProgressDone( string.Format( "{0} bytes downloaded and verified", buffer.Length ));
  1037. }
  1038. catch (Exception ex)
  1039. {
  1040. ProgressDone( string.Format( "Download Error" ));
  1041. }
  1042. }
  1043.  
  1044. private void btnEraseEeprom_Click(object sender, EventArgs e)
  1045. {
  1046. EraseEe( false );
  1047. }
  1048.  
  1049. private void btnDeviceToIicFile_Click(object sender, EventArgs e)
  1050. {
  1051. int size = 0;
  1052.  
  1053. try
  1054. {
  1055. string s = cmboDeviceToIicFileSize.Text;
  1056. s = s.Split(' ')[0];
  1057.  
  1058. size = ( s.StartsWith("0x", StringComparison.OrdinalIgnoreCase)) ?
  1059. Int32.Parse(s.Substring(2), System.Globalization.NumberStyles.HexNumber):
  1060. Int32.Parse(s);
  1061.  
  1062. size = Math.Min(size, EepromSizeBytes);
  1063. }
  1064. catch
  1065. {
  1066. MessageBox.Show("Invalid file size");
  1067. return; // TODO:
  1068. }
  1069.  
  1070. SaveFileDialog dlg = new SaveFileDialog();
  1071. dlg.Title = "Select .IIC file to write from EEPROM";
  1072. dlg.RestoreDirectory = true;
  1073. dlg.FileName = iicFilename;
  1074. dlg.Filter = "IIC files (*.iic)|*.iic|All files (*.*)|*.*";
  1075. DialogResult result = dlg.ShowDialog();
  1076.  
  1077. if (result != DialogResult.OK)
  1078. {
  1079. return;
  1080. }
  1081.  
  1082. iicFilename = dlg.FileName;
  1083.  
  1084. byte [] buffer = new byte[size];
  1085.  
  1086. Open();
  1087.  
  1088. ProgressInit(size, "Reading EEPROM");
  1089.  
  1090. for ( int offset = 0; offset < size; offset += Math.Min( size, UsbMaxPacketSize))
  1091. {
  1092. ProgressUpdate(offset);
  1093.  
  1094. byte[] x = EepromReadDevIoCtl(offset, Math.Min(size, UsbMaxPacketSize));
  1095.  
  1096. x.CopyTo(buffer, offset);
  1097. }
  1098.  
  1099. hDevice.Close();
  1100.  
  1101. ProgressDone( string.Format( "{0} bytes saved", size ) );
  1102.  
  1103. System.IO.File.WriteAllBytes(iicFilename, buffer);
  1104.  
  1105. }
  1106.  
  1107.  
  1108.  
  1109. private void EraseEe( bool keepFirst8Bytes )
  1110. {
  1111. try
  1112. {
  1113. const int eraseSize = 0x100;
  1114. const int eraseSizeTotal = EepromSizeBytes;
  1115.  
  1116. byte[] buffer = new byte[eraseSize];
  1117. for (int i = 0; i < buffer.Length; i++)
  1118. {
  1119. buffer[i] = 0xFF;
  1120. }
  1121.  
  1122. Open();
  1123.  
  1124. ProgressInit(eraseSizeTotal, "Erasing EEPROM");
  1125.  
  1126. for (int offset = 0; offset < eraseSizeTotal; offset += eraseSize)
  1127. {
  1128. ProgressUpdate(offset);
  1129. EepromWriteDevIoCtl(offset == 0 && keepFirst8Bytes ? 8 : offset, buffer);
  1130. }
  1131.  
  1132. hDevice.Close();
  1133.  
  1134. ProgressDone("EEPROM erased");
  1135. }
  1136. catch (Exception ex)
  1137. {
  1138. ProgressDone("EEPROM erase failed");
  1139. }
  1140. }
  1141.  
  1142. private void btnEraseEeAfter8_Click(object sender, EventArgs e)
  1143. {
  1144. EraseEe( true );
  1145. }
  1146.  
  1147.  
  1148.  
  1149. private void ProgressInit(int maxArg, string txtArg)
  1150. {
  1151. // Initialize the progress bar on the statusbar for operations that might take a long time.
  1152. toolStripStatusLabel1.Text = txtArg;
  1153. toolStripStatusLabel1.Visible = true;
  1154. toolStripProgressBar1.Maximum = maxArg; //
  1155. toolStripProgressBar1.Visible = true;
  1156. }
  1157.  
  1158. private void ProgressUpdate(int offsetArg )
  1159. {
  1160. toolStripProgressBar1.Value = offsetArg;
  1161. statusStrip1.Update();
  1162. }
  1163.  
  1164. private void ProgressDone( string txt )
  1165. {
  1166. toolStripProgressBar1.Visible = false;
  1167. toolStripStatusLabel1.Text = txt;
  1168. }
  1169.  
  1170. private void cmboDeviceList_SelectedIndexChanged(object sender, EventArgs e)
  1171. {
  1172. // If there a multiple devices found, and the selection changes, disconnect the current device.
  1173. deviceOnline = false;
  1174. }
  1175.  
  1176. private void btnVerifyIicFile_Click(object sender, EventArgs e)
  1177. {
  1178. OpenFileDialog dlg = new OpenFileDialog();
  1179. dlg.FileName = iicFilename;
  1180. dlg.Title = "Select .IIC file to compare with EEPROM";
  1181. dlg.CheckFileExists = true;
  1182. dlg.Filter = "IIC files (*.iic)|*.iic|All files (*.*)|*.*";
  1183. DialogResult result = dlg.ShowDialog();
  1184.  
  1185. if (result != DialogResult.OK)
  1186. {
  1187. return;
  1188. }
  1189.  
  1190. iicFilename = dlg.FileName;
  1191.  
  1192. byte[] buffer = System.IO.File.ReadAllBytes(iicFilename);
  1193.  
  1194. try
  1195. {
  1196. Open();
  1197. if (!buffer.SequenceEqual(EepromRead(buffer.Length)))
  1198. {
  1199. throw new Exception();
  1200. }
  1201. hDevice.Close();
  1202. ProgressDone("Verify OK");
  1203. }
  1204. catch
  1205. {
  1206. ProgressDone("Verify failed");
  1207. }
  1208. }
  1209.  
  1210.  
  1211. private void MainForm_Load(object sender, EventArgs e)
  1212. {
  1213. //testIntelHexToByteArray();
  1214. timer1.Start();
  1215. cmboDeviceToIicFileSize.SelectedIndex = 0;
  1216. } // btnVerifyIicFile_Click
  1217.  
  1218. /*
  1219.   // Test/development code used to generate data to initialize the VendAxCode array.
  1220.   // It has one-time usage during development and isn't expected to be used unless the Vend_AX firmware should change.
  1221.   // This leaves a trail to re-create the data and is commented-out to reduce program size.
  1222.   void testIntelHexToByteArray()
  1223.   {
  1224.   // See http://en.wikipedia.org/wiki/.hex for .HEX record structure.
  1225.   // I'm assuming that the .hex file is simple, loads internal memory only.
  1226.  
  1227.   string[] hex = System.IO.File.ReadAllLines("vend_ax.hex");
  1228.  
  1229.   int maxAddress=0;
  1230.  
  1231.   // find max memory used.
  1232.   foreach (string record in hex )
  1233.   {
  1234.   Debug.Assert(record[0] == ':');
  1235.  
  1236.   byte recordType = byte.Parse(record.Substring(7, 2), System.Globalization.NumberStyles.HexNumber);
  1237.   if (recordType == 1)
  1238.   {
  1239.   break;
  1240.   }
  1241.  
  1242.   UInt16 recByteCount = UInt16.Parse(record.Substring(1, 2), System.Globalization.NumberStyles.HexNumber);
  1243.   UInt16 recAddress = UInt16.Parse(record.Substring(3, 4), System.Globalization.NumberStyles.HexNumber);
  1244.  
  1245.   Debug.Assert(recAddress < 0x2000); // If this fails, re-visit assumptions.
  1246.  
  1247.   byte checkSum = byte.Parse(record.Substring(9 + recByteCount * 2, 2), System.Globalization.NumberStyles.HexNumber);
  1248.  
  1249.   Debug.Assert(record.Length == 11 + recByteCount * 2);
  1250.  
  1251.   maxAddress = Math.Max( maxAddress, recAddress+recByteCount );
  1252.  
  1253.   }
  1254.  
  1255.   byte[] bin = new byte[maxAddress+1]; // allocate buffer to reconstitute .hex file into. +1 should result in an extra AA at the end.
  1256.   for ( int i=0; i<bin.Length; i++ ) { bin[i]=0xAA; } // Initialize buffer with 0xAA, just because the original Vend_Ax array did this.
  1257.  
  1258.   // For each record read from the .hex file,
  1259.   foreach (string record in hex)
  1260.   {
  1261.   Debug.Assert(record[0] == ':');
  1262.  
  1263.   byte recordType = byte.Parse(record.Substring(7, 2), System.Globalization.NumberStyles.HexNumber);
  1264.   if (recordType == 1)
  1265.   {
  1266.   break;
  1267.   }
  1268.  
  1269.   UInt16 recByteCount = UInt16.Parse(record.Substring(1, 2), System.Globalization.NumberStyles.HexNumber);
  1270.   UInt16 recAddress = UInt16.Parse(record.Substring(3, 4), System.Globalization.NumberStyles.HexNumber);
  1271.  
  1272.   byte checkSum = byte.Parse(record.Substring(9 + recByteCount * 2, 2), System.Globalization.NumberStyles.HexNumber);
  1273.   // TODO: validate checksum.
  1274.   // In my tests, the firmware ran.
  1275.  
  1276.   Debug.Assert(record.Length == 11 + recByteCount * 2); // make sure the length is ok.
  1277.  
  1278.   // For each byte, represented as a 2-character hex number, store the byte in the binary buffer.
  1279.   for (int i = 0; i < recByteCount; i++)
  1280.   {
  1281.   byte b = byte.Parse(record.Substring(9 + i * 2, 2), System.Globalization.NumberStyles.HexNumber);
  1282.   bin[recAddress + i] = b;
  1283.   }
  1284.   } // foreach record in hex.
  1285.  
  1286.   // write to file
  1287.   // Create records of the form: 0x02, 0x07, 0xF3, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
  1288.  
  1289.   // This resulting text will be used to initialize an array.
  1290.   System.IO.StreamWriter file = new System.IO.StreamWriter("vend_ax.txt");
  1291.  
  1292.   for (int i = 0; i < bin.Length; i++)
  1293.   {
  1294.   string s = string.Format( "0x{0:X02}, {1}", bin[i], i%10==9 ? "
  1295. " : "" );
  1296.   file.Write(s);
  1297.   }
  1298.  
  1299.   file.Close();
  1300.  
  1301.   return;
  1302.   }
  1303.   */
  1304.  
  1305.  
  1306. private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
  1307. {
  1308. // Add a convenience link to the app to start the device manager in the control panel.
  1309. System.Diagnostics.Process.Start("devmgmt.msc");
  1310. }
  1311.  
  1312. private void linkLabel2_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
  1313. {
  1314. // Add a convenience link to open the current working directoy.
  1315. System.Diagnostics.Process.Start(System.IO.Directory.GetCurrentDirectory());
  1316. }
  1317.  
  1318. } // MainForm.
  1319. } // namespace CypressEepromUtility
  1320. // End of file

Report this snippet


Comments

RSS Icon Subscribe to comments

You need to login to post a comment.