cdc_acm_protocol.h 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. /*
  2. * cdc_acm_protocol.h
  3. *
  4. * Greaseweazle protocol over CDC ACM streams.
  5. *
  6. * Written & released by Keir Fraser <keir.xen@gmail.com>
  7. *
  8. * This is free and unencumbered software released into the public domain.
  9. * See the file COPYING for more details, or visit <http://unlicense.org>.
  10. */
  11. /*
  12. * GREASEWEAZLE COMMAND SET
  13. *
  14. * NOTE: Commands cannot be pipelined. Do not issue a new command until the
  15. * previous command is completed with all expected bytes received by the host.
  16. */
  17. /* CMD_GET_INFO, length=3, idx. Returns 32 bytes after ACK. */
  18. #define CMD_GET_INFO 0
  19. /* [BOOTLOADER] CMD_UPDATE, length=6, <update_len>.
  20. * Host follows after a successful ACK response with <update_len> bytes.
  21. * Bootloader finally returns a status byte, 0 on success. */
  22. /* [MAIN FIRMWARE] CMD_UPDATE, length=10, <update_len>, 0xdeafbee3.
  23. * Host follows after a successful ACK response with <update_len> bytes.
  24. * Main firmware finally returns a status byte, 0 on success. */
  25. #define CMD_UPDATE 1
  26. /* CMD_SEEK, length=3-4, cyl#. Seek to cyl# on selected drive.
  27. * cyl# is signed: length=3 => int8_t cyl#; length=4 => int16_t cyl# */
  28. #define CMD_SEEK 2
  29. /* CMD_HEAD, length=3, head# (0=bottom) */
  30. #define CMD_HEAD 3
  31. /* CMD_SET_PARAMS, length=3+nr, idx, <nr bytes> */
  32. #define CMD_SET_PARAMS 4
  33. /* CMD_GET_PARAMS, length=4, idx, nr_bytes. Returns nr_bytes after ACK. */
  34. #define CMD_GET_PARAMS 5
  35. /* CMD_MOTOR, length=4, drive#, on/off. Turn on/off a drive motor. */
  36. #define CMD_MOTOR 6
  37. /* CMD_READ_FLUX, length=8-12. Argument is gw_read_flux; optional fields
  38. * may be omitted. Returns flux readings terminating with EOStream (NUL). */
  39. #define CMD_READ_FLUX 7
  40. /* CMD_WRITE_FLUX, length=4. Argument is gw_write_flux.
  41. * Host follows the ACK with flux values terminating with EOStream (NUL).
  42. * Device finally returns a status byte, 0 on success.
  43. * No further commands should be issued until the status byte is received. */
  44. #define CMD_WRITE_FLUX 8
  45. /* CMD_GET_FLUX_STATUS, length=2. Last read/write status returned in ACK. */
  46. #define CMD_GET_FLUX_STATUS 9
  47. /* CMD_SWITCH_FW_MODE, length=3, <mode>. No response on success: The device
  48. * resets into the requested mode, and the USB connection also resets. */
  49. #define CMD_SWITCH_FW_MODE 11
  50. /* CMD_SELECT, length=3, drive#. Select drive# as current unit. */
  51. #define CMD_SELECT 12
  52. /* CMD_DESELECT, length=2. Deselect current unit (if any). */
  53. #define CMD_DESELECT 13
  54. /* CMD_SET_BUS_TYPE, length=3, bus_type. Set the bus type. */
  55. #define CMD_SET_BUS_TYPE 14
  56. /* CMD_SET_PIN, length=4, pin#, level. */
  57. #define CMD_SET_PIN 15
  58. /* CMD_RESET, length=2. Reset all state to initial (power on) values. */
  59. #define CMD_RESET 16
  60. /* CMD_ERASE_FLUX, length=6. Argument is gw_erase_flux.
  61. * Device returns a status byte when erasure is completed, 0 on success.
  62. * No further commands should be issued until the status byte is received. */
  63. #define CMD_ERASE_FLUX 17
  64. /* CMD_SOURCE_BYTES, length=6. Argument is gw_sink_source_bytes. */
  65. #define CMD_SOURCE_BYTES 18
  66. /* CMD_SINK_BYTES, length=6. Argument is gw_sink_source_bytes. */
  67. #define CMD_SINK_BYTES 19
  68. /* CMD_GET_PIN, length=3, pin#. Successful ACK is followed by pin-level byte
  69. * (1=High, 0=Low). Unsupported pin returns ACK_BAD_PIN and no pin level. */
  70. #define CMD_GET_PIN 20
  71. /* CMD_TEST_MODE, length=10, 0x6e504b4e, 0x382910d3
  72. * Responds ACK_OKAY and then switches to board test mode until reset. */
  73. #define CMD_TEST_MODE 21
  74. /* CMD_NOCLICK_STEP, length=2
  75. * Steps outward from cylinder 0. This is expected to be ignored by the drive,
  76. * but will reset the Disk Change signal if a disk has been inserted.
  77. * On successful return the drive is always at cylinder 0. */
  78. #define CMD_NOCLICK_STEP 22
  79. #define CMD_MAX 22
  80. /*
  81. * CMD_SET_BUS CODES
  82. */
  83. #define BUS_NONE 0
  84. #define BUS_IBMPC 1
  85. #define BUS_SHUGART 2
  86. /*#define BUS_APPLE2 3*/ /* reserved for Adafruit_Floppy */
  87. /*
  88. * ACK RETURN CODES
  89. */
  90. #define ACK_OKAY 0
  91. #define ACK_BAD_COMMAND 1
  92. #define ACK_NO_INDEX 2
  93. #define ACK_NO_TRK0 3
  94. #define ACK_FLUX_OVERFLOW 4
  95. #define ACK_FLUX_UNDERFLOW 5
  96. #define ACK_WRPROT 6
  97. #define ACK_NO_UNIT 7
  98. #define ACK_NO_BUS 8
  99. #define ACK_BAD_UNIT 9
  100. #define ACK_BAD_PIN 10
  101. #define ACK_BAD_CYLINDER 11
  102. #define ACK_OUT_OF_SRAM 12
  103. #define ACK_OUT_OF_FLASH 13
  104. /*
  105. * CONTROL-CHANNEL COMMAND SET:
  106. * We abuse SET_LINE_CODING requests over endpoint 0, stashing a command
  107. * in the baud-rate field.
  108. */
  109. #define BAUD_NORMAL 9600
  110. #define BAUD_CLEAR_COMMS 10000
  111. /*
  112. * Flux stream opcodes. Preceded by 0xFF byte.
  113. *
  114. * Argument types:
  115. * N28: 28-bit non-negative integer N, encoded as 4 bytes b0,b1,b2,b3:
  116. * b0 = (uint8_t)(1 | (N << 1))
  117. * b1 = (uint8_t)(1 | (N >> 6))
  118. * b2 = (uint8_t)(1 | (N >> 13))
  119. * b3 = (uint8_t)(1 | (N >> 20))
  120. */
  121. /* FLUXOP_INDEX [CMD_READ_FLUX]
  122. * Args:
  123. * +4 [N28]: ticks to index, relative to sample cursor.
  124. * Signals an index pulse in the read stream. Sample cursor is unaffected. */
  125. #define FLUXOP_INDEX 1
  126. /* FLUXOP_SPACE [CMD_READ_FLUX, CMD_WRITE_FLUX]
  127. * Args:
  128. * +4 [N28]: ticks to increment the sample cursor.
  129. * Increments the sample cursor with no intervening flux transitions. */
  130. #define FLUXOP_SPACE 2
  131. /* FLUXOP_ASTABLE [CMD_WRITE_FLUX]
  132. * Args:
  133. * +4 [N28]: astable period.
  134. * Generate regular flux transitions at specified astable period.
  135. * Duration is specified by immediately preceding FLUXOP_SPACE opcode(s). */
  136. #define FLUXOP_ASTABLE 3
  137. /*
  138. * COMMAND PACKETS
  139. */
  140. /* CMD_GET_INFO, index 0 */
  141. #define GETINFO_FIRMWARE 0
  142. struct packed gw_info {
  143. uint8_t fw_major;
  144. uint8_t fw_minor;
  145. uint8_t is_main_firmware; /* == 0 -> update bootloader */
  146. uint8_t max_cmd;
  147. uint32_t sample_freq;
  148. uint8_t hw_model, hw_submodel;
  149. uint8_t usb_speed;
  150. uint8_t mcu_id;
  151. uint16_t mcu_mhz;
  152. uint16_t mcu_sram_kb;
  153. uint16_t usb_buf_kb;
  154. };
  155. extern struct gw_info gw_info;
  156. /* CMD_GET_INFO, index 1 */
  157. #define GETINFO_BW_STATS 1
  158. struct packed gw_bw_stats {
  159. struct packed {
  160. uint32_t bytes;
  161. uint32_t usecs;
  162. } min_bw, max_bw;
  163. };
  164. #define GETINFO_CURRENT_DRIVE 7
  165. #define GETINFO_DRIVE(unit) (8+(unit))
  166. struct packed gw_drive_info {
  167. #define _GW_DF_cyl_valid 0
  168. #define _GW_DF_motor_on 1
  169. #define _GW_DF_is_flippy 2
  170. uint32_t flags;
  171. int32_t cyl;
  172. };
  173. /* CMD_READ_FLUX */
  174. struct packed gw_read_flux {
  175. /** MANDATORY FIELDS: **/
  176. /* Maximum ticks to read for (or 0, for no limit). */
  177. uint32_t ticks;
  178. /* Maximum index pulses to read (or 0, for no limit). */
  179. uint16_t max_index;
  180. /** OPTIONAL FIELDS: **/
  181. /* Linger time, in ticks, to continue reading after @max_index pulses. */
  182. uint32_t max_index_linger; /* default: 500 microseconds */
  183. };
  184. /* CMD_WRITE_FLUX */
  185. struct packed gw_write_flux {
  186. /* If non-zero, start the write at the index pulse. */
  187. uint8_t cue_at_index;
  188. /* If non-zero, terminate the write at the next index pulse. */
  189. uint8_t terminate_at_index;
  190. };
  191. /* CMD_ERASE_FLUX */
  192. struct packed gw_erase_flux {
  193. uint32_t ticks;
  194. };
  195. /* CMD_SINK_SOURCE_BYTES */
  196. struct packed gw_sink_source_bytes {
  197. uint32_t nr_bytes;
  198. uint32_t seed;
  199. };
  200. /* CMD_{GET,SET}_PARAMS, index 0 */
  201. #define PARAMS_DELAYS 0
  202. struct packed gw_delay {
  203. uint16_t select_delay; /* usec */
  204. uint16_t step_delay; /* usec */
  205. uint16_t seek_settle; /* msec */
  206. uint16_t motor_delay; /* msec */
  207. uint16_t watchdog; /* msec */
  208. };
  209. /* CMD_SWITCH_FW_MODE */
  210. #define FW_MODE_BOOTLOADER 0
  211. #define FW_MODE_NORMAL 1
  212. /*
  213. * Local variables:
  214. * mode: C
  215. * c-file-style: "Linux"
  216. * c-basic-offset: 4
  217. * tab-width: 4
  218. * indent-tabs-mode: nil
  219. * End:
  220. */