floppy.c 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269
  1. /*
  2. * floppy.c
  3. *
  4. * Floppy interface control.
  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. #define m(bitnr) (1u<<(bitnr))
  12. #define get_index() gpio_read_pin(gpio_index, pin_index)
  13. #define get_trk0() gpio_read_pin(gpio_trk0, pin_trk0)
  14. #define get_wrprot() gpio_read_pin(gpio_wrprot, pin_wrprot)
  15. #define configure_pin(pin, type) \
  16. gpio_configure_pin(gpio_##pin, pin_##pin, type)
  17. #define SAMPLE_MHZ 72
  18. #define TIM_PSC (SYSCLK_MHZ / SAMPLE_MHZ)
  19. #define sample_ns(x) (((x) * SAMPLE_MHZ) / 1000)
  20. #define sample_us(x) ((x) * SAMPLE_MHZ)
  21. #define time_from_samples(x) ((x) * TIME_MHZ / SAMPLE_MHZ)
  22. #define write_pin(pin, level) \
  23. gpio_write_pin(gpio_##pin, pin_##pin, level ? O_TRUE : O_FALSE)
  24. static int bus_type = -1;
  25. static int unit_nr = -1;
  26. static struct {
  27. int cyl;
  28. bool_t motor;
  29. } unit[3];
  30. static struct gw_delay delay_params;
  31. static const struct gw_delay factory_delay_params = {
  32. .select_delay = 10,
  33. .step_delay = 5000,
  34. .seek_settle = 15,
  35. .motor_delay = 750,
  36. .auto_off = 10000
  37. };
  38. #if STM32F == 1
  39. #include "f1/floppy.c"
  40. #elif STM32F == 7
  41. #include "f7/floppy.c"
  42. #endif
  43. static struct index {
  44. /* Main code can reset this at will. */
  45. volatile unsigned int count;
  46. /* For synchronising index pulse reporting to the RDATA flux stream. */
  47. volatile unsigned int rdata_cnt;
  48. /* Last time at which ISR fired. */
  49. time_t isr_time;
  50. /* Timer structure for index_timer() calls. */
  51. struct timer timer;
  52. } index;
  53. /* Timer to clean up stale index.isr_time. */
  54. #define INDEX_TIMER_PERIOD time_ms(5000)
  55. static void index_timer(void *unused);
  56. /* A DMA buffer for running a timer associated with a floppy-data I/O pin. */
  57. static struct dma_ring {
  58. /* Indexes into the buf[] ring buffer. */
  59. uint16_t cons; /* dma_rd: our consumer index for flux samples */
  60. union {
  61. uint16_t prod; /* dma_wr: our producer index for flux samples */
  62. timcnt_t prev_sample; /* dma_rd: previous CCRx sample value */
  63. };
  64. /* DMA ring buffer of timer values (ARR or CCRx). */
  65. timcnt_t buf[512];
  66. } dma;
  67. static struct {
  68. time_t deadline;
  69. bool_t armed;
  70. } auto_off;
  71. static enum {
  72. ST_inactive,
  73. ST_command_wait,
  74. ST_zlp,
  75. ST_read_flux,
  76. ST_read_flux_drain,
  77. ST_write_flux_wait_data,
  78. ST_write_flux_wait_index,
  79. ST_write_flux,
  80. ST_write_flux_drain,
  81. ST_erase_flux,
  82. ST_source_bytes,
  83. ST_sink_bytes,
  84. ST_update_bootloader,
  85. } floppy_state = ST_inactive;
  86. static uint32_t u_cons, u_prod;
  87. #define U_MASK(x) ((x)&(U_BUF_SZ-1))
  88. static void step_one_out(void)
  89. {
  90. write_pin(dir, FALSE);
  91. delay_us(10);
  92. write_pin(step, TRUE);
  93. delay_us(10);
  94. write_pin(step, FALSE);
  95. delay_us(delay_params.step_delay);
  96. }
  97. static void step_one_in(void)
  98. {
  99. write_pin(dir, TRUE);
  100. delay_us(10);
  101. write_pin(step, TRUE);
  102. delay_us(10);
  103. write_pin(step, FALSE);
  104. delay_us(delay_params.step_delay);
  105. }
  106. static void _set_bus_type(uint8_t type)
  107. {
  108. int i;
  109. bus_type = type;
  110. unit_nr = -1;
  111. for (i = 0; i < ARRAY_SIZE(unit); i++) {
  112. unit[i].cyl = -1;
  113. unit[i].motor = FALSE;
  114. }
  115. reset_bus();
  116. }
  117. static bool_t set_bus_type(uint8_t type)
  118. {
  119. if (type == bus_type)
  120. return TRUE;
  121. if (type > BUS_SHUGART)
  122. return FALSE;
  123. _set_bus_type(type);
  124. return TRUE;
  125. }
  126. static uint8_t floppy_seek(unsigned int cyl)
  127. {
  128. int cur_cyl;
  129. if (unit_nr < 0)
  130. return ACK_NO_UNIT;
  131. cur_cyl = unit[unit_nr].cyl;
  132. if ((cyl == 0) || (cur_cyl < 0)) {
  133. unsigned int i;
  134. for (i = 0; i < 256; i++) {
  135. if (get_trk0() == LOW)
  136. break;
  137. step_one_out();
  138. }
  139. cur_cyl = 0;
  140. if (get_trk0() == HIGH) {
  141. unit[unit_nr].cyl = -1;
  142. return ACK_NO_TRK0;
  143. }
  144. }
  145. if (cur_cyl < 0) {
  146. } else if (cur_cyl <= cyl) {
  147. unsigned int nr = cyl - cur_cyl;
  148. while (nr--)
  149. step_one_in();
  150. } else {
  151. unsigned int nr = cur_cyl - cyl;
  152. while (nr--)
  153. step_one_out();
  154. }
  155. delay_ms(delay_params.seek_settle);
  156. unit[unit_nr].cyl = cyl;
  157. return ACK_OKAY;
  158. }
  159. static void floppy_flux_end(void)
  160. {
  161. /* Turn off write pins. */
  162. write_pin(wgate, FALSE);
  163. configure_pin(wdata, GPO_bus);
  164. /* Turn off timers. */
  165. tim_rdata->ccer = 0;
  166. tim_rdata->cr1 = 0;
  167. tim_rdata->sr = 0; /* dummy, drains any pending DMA */
  168. tim_wdata->ccer = 0;
  169. tim_wdata->cr1 = 0;
  170. tim_wdata->sr = 0; /* dummy, drains any pending DMA */
  171. /* Turn off DMA. */
  172. dma_rdata.cr &= ~DMA_CR_EN;
  173. dma_wdata.cr &= ~DMA_CR_EN;
  174. while ((dma_rdata.cr & DMA_CR_EN) || (dma_wdata.cr & DMA_CR_EN))
  175. continue;
  176. }
  177. static void floppy_reset(void)
  178. {
  179. floppy_state = ST_inactive;
  180. auto_off.armed = FALSE;
  181. floppy_flux_end();
  182. drive_deselect();
  183. act_led(FALSE);
  184. }
  185. void floppy_init(void)
  186. {
  187. floppy_mcu_init();
  188. /* Output pins, unbuffered. */
  189. configure_pin(dir, GPO_bus);
  190. configure_pin(step, GPO_bus);
  191. configure_pin(wgate, GPO_bus);
  192. configure_pin(side, GPO_bus);
  193. configure_pin(wdata, GPO_bus);
  194. /* Input pins. */
  195. configure_pin(index, GPI_bus);
  196. configure_pin(trk0, GPI_bus);
  197. configure_pin(wrprot, GPI_bus);
  198. /* Configure INDEX-changed IRQs and timer. */
  199. timer_init(&index.timer, index_timer, NULL);
  200. index_timer(NULL);
  201. exti->rtsr = 0;
  202. exti->imr = exti->ftsr = m(pin_index);
  203. IRQx_set_prio(irq_index, INDEX_IRQ_PRI);
  204. IRQx_enable(irq_index);
  205. delay_params = factory_delay_params;
  206. _set_bus_type(BUS_NONE);
  207. }
  208. struct gw_info gw_info = {
  209. .is_main_firmware = 1,
  210. .max_cmd = CMD_MAX,
  211. .sample_freq = 72000000u,
  212. .hw_model = STM32F
  213. };
  214. static void auto_off_arm(void)
  215. {
  216. auto_off.armed = TRUE;
  217. auto_off.deadline = time_now() + time_ms(delay_params.auto_off);
  218. }
  219. static void floppy_end_command(void *ack, unsigned int ack_len)
  220. {
  221. auto_off_arm();
  222. usb_write(EP_TX, ack, ack_len);
  223. u_cons = u_prod = 0;
  224. if (floppy_state == ST_command_wait)
  225. act_led(FALSE);
  226. if (ack_len == usb_bulk_mps) {
  227. ASSERT(floppy_state == ST_command_wait);
  228. floppy_state = ST_zlp;
  229. }
  230. }
  231. /*
  232. * READ PATH
  233. */
  234. static struct {
  235. union {
  236. time_t start; /* read, write: Time at which read/write started. */
  237. time_t end; /* erase: Time at which to end the erasure. */
  238. };
  239. uint8_t status;
  240. uint8_t idx, nr_idx;
  241. bool_t packet_ready;
  242. bool_t write_finished;
  243. bool_t terminate_at_index;
  244. bool_t no_flux_area;
  245. unsigned int packet_len;
  246. uint32_t ticks_since_flux;
  247. uint8_t packet[USB_HS_MPS];
  248. } rw;
  249. static always_inline void _write_28bit(uint32_t x)
  250. {
  251. u_buf[U_MASK(u_prod++)] = 1 | (x << 1);
  252. u_buf[U_MASK(u_prod++)] = 1 | (x >> 6);
  253. u_buf[U_MASK(u_prod++)] = 1 | (x >> 13);
  254. u_buf[U_MASK(u_prod++)] = 1 | (x >> 20);
  255. }
  256. static void rdata_encode_flux(void)
  257. {
  258. const uint16_t buf_mask = ARRAY_SIZE(dma.buf) - 1;
  259. uint16_t cons = dma.cons, prod;
  260. timcnt_t prev = dma.prev_sample, curr, next;
  261. uint32_t ticks;
  262. ASSERT(rw.idx < rw.nr_idx);
  263. /* We don't want to race the Index IRQ handler. */
  264. IRQ_global_disable();
  265. /* Find out where the DMA engine's producer index has got to. */
  266. prod = ARRAY_SIZE(dma.buf) - dma_rdata.ndtr;
  267. if (rw.idx != index.count) {
  268. /* We have just passed the index mark: Record information about
  269. * the just-completed revolution. */
  270. unsigned int partial_flux = (timcnt_t)(index.rdata_cnt - prev);
  271. u_buf[U_MASK(u_prod++)] = 0xff;
  272. u_buf[U_MASK(u_prod++)] = FLUXOP_INDEX;
  273. _write_28bit(partial_flux);
  274. rw.idx = index.count;
  275. }
  276. IRQ_global_enable();
  277. /* Process the flux timings into the raw bitcell buffer. */
  278. for (; cons != prod; cons = (cons+1) & buf_mask) {
  279. next = dma.buf[cons];
  280. curr = next - prev;
  281. prev = next;
  282. ticks = curr;
  283. if (ticks == 0) {
  284. /* 0: Skip. */
  285. } else if (ticks < 250) {
  286. /* 1-249: One byte. */
  287. u_buf[U_MASK(u_prod++)] = ticks;
  288. } else {
  289. unsigned int high = (ticks-250) / 255;
  290. if (high < 5) {
  291. /* 250-1524: Two bytes. */
  292. u_buf[U_MASK(u_prod++)] = 250 + high;
  293. u_buf[U_MASK(u_prod++)] = 1 + ((ticks-250) % 255);
  294. } else {
  295. /* 1525-(2^28-1): Seven bytes. */
  296. u_buf[U_MASK(u_prod++)] = 0xff;
  297. u_buf[U_MASK(u_prod++)] = FLUXOP_NOFLUX;
  298. _write_28bit(ticks - 249);
  299. u_buf[U_MASK(u_prod++)] = 249;
  300. }
  301. }
  302. }
  303. /* If it has been a long time since the last flux timing, transfer some of
  304. * the accumulated time to the host in a "long gap" sample. This avoids
  305. * timing overflow and, because we take care to keep @prev well behind the
  306. * sample clock, we cannot race the next flux timestamp. */
  307. curr = tim_rdata->cnt - prev;
  308. if (unlikely(curr > sample_us(400))) {
  309. ticks = sample_us(200);
  310. u_buf[U_MASK(u_prod++)] = 0xff;
  311. u_buf[U_MASK(u_prod++)] = FLUXOP_NOFLUX;
  312. _write_28bit(ticks);
  313. prev += ticks;
  314. }
  315. /* Save our progress for next time. */
  316. dma.cons = cons;
  317. dma.prev_sample = prev;
  318. }
  319. static uint8_t floppy_read_prep(const struct gw_read_flux *rf)
  320. {
  321. if (rf->nr_idx == 0)
  322. return ACK_BAD_COMMAND;
  323. /* Prepare Timer & DMA. */
  324. dma_rdata.mar = (uint32_t)(unsigned long)dma.buf;
  325. dma_rdata.ndtr = ARRAY_SIZE(dma.buf);
  326. rdata_prep();
  327. /* DMA soft state. */
  328. dma.cons = 0;
  329. dma.prev_sample = tim_rdata->cnt;
  330. /* Start Timer. */
  331. tim_rdata->cr1 = TIM_CR1_CEN;
  332. index.count = 0;
  333. floppy_state = ST_read_flux;
  334. memset(&rw, 0, sizeof(rw));
  335. rw.nr_idx = rf->nr_idx;
  336. rw.start = time_now();
  337. rw.status = ACK_OKAY;
  338. return ACK_OKAY;
  339. }
  340. static void make_read_packet(unsigned int n)
  341. {
  342. unsigned int c = U_MASK(u_cons);
  343. unsigned int l = U_BUF_SZ - c;
  344. if (l < n) {
  345. memcpy(rw.packet, &u_buf[c], l);
  346. memcpy(&rw.packet[l], u_buf, n-l);
  347. } else {
  348. memcpy(rw.packet, &u_buf[c], n);
  349. }
  350. u_cons += n;
  351. rw.packet_ready = TRUE;
  352. }
  353. static void floppy_read(void)
  354. {
  355. unsigned int avail = (uint32_t)(u_prod - u_cons);
  356. if (floppy_state == ST_read_flux) {
  357. rdata_encode_flux();
  358. avail = (uint32_t)(u_prod - u_cons);
  359. if (avail > U_BUF_SZ) {
  360. /* Overflow */
  361. printk("OVERFLOW %u %u %u %u\n", u_cons, u_prod,
  362. rw.packet_ready, ep_tx_ready(EP_TX));
  363. floppy_flux_end();
  364. rw.status = ACK_FLUX_OVERFLOW;
  365. floppy_state = ST_read_flux_drain;
  366. u_cons = u_prod = avail = 0;
  367. } else if (rw.idx >= rw.nr_idx) {
  368. /* Read all requested revolutions. */
  369. floppy_flux_end();
  370. floppy_state = ST_read_flux_drain;
  371. } else if ((index.count == 0)
  372. && (time_since(rw.start) > time_ms(2000))) {
  373. /* Timeout */
  374. printk("NO INDEX\n");
  375. floppy_flux_end();
  376. rw.status = ACK_NO_INDEX;
  377. floppy_state = ST_read_flux_drain;
  378. u_cons = u_prod = avail = 0;
  379. }
  380. } else if ((avail < usb_bulk_mps)
  381. && !rw.packet_ready
  382. && ep_tx_ready(EP_TX)) {
  383. /* Final packet, including ACK byte (NUL). */
  384. memset(rw.packet, 0, usb_bulk_mps);
  385. make_read_packet(avail);
  386. floppy_state = ST_command_wait;
  387. floppy_end_command(rw.packet, avail+1);
  388. return; /* FINISHED */
  389. }
  390. if (!rw.packet_ready && (avail >= usb_bulk_mps))
  391. make_read_packet(usb_bulk_mps);
  392. if (rw.packet_ready && ep_tx_ready(EP_TX)) {
  393. usb_write(EP_TX, rw.packet, usb_bulk_mps);
  394. rw.packet_ready = FALSE;
  395. }
  396. }
  397. /*
  398. * WRITE PATH
  399. */
  400. static always_inline uint32_t _read_28bit(void)
  401. {
  402. uint32_t x;
  403. x = (u_buf[U_MASK(u_cons++)] ) >> 1;
  404. x |= (u_buf[U_MASK(u_cons++)] & 0xfe) << 6;
  405. x |= (u_buf[U_MASK(u_cons++)] & 0xfe) << 13;
  406. x |= (u_buf[U_MASK(u_cons++)] & 0xfe) << 20;
  407. return x;
  408. }
  409. static unsigned int _wdata_decode_flux(timcnt_t *tbuf, unsigned int nr)
  410. {
  411. unsigned int todo = nr;
  412. uint32_t x, ticks = rw.ticks_since_flux;
  413. if (todo == 0)
  414. return 0;
  415. if (rw.no_flux_area) {
  416. unsigned int nfa_pulse = sample_ns(1250);
  417. while (ticks >= nfa_pulse) {
  418. *tbuf++ = nfa_pulse - 1;
  419. ticks -= nfa_pulse;
  420. if (!--todo)
  421. goto out;
  422. }
  423. rw.no_flux_area = FALSE;
  424. }
  425. while (u_cons != u_prod) {
  426. x = u_buf[U_MASK(u_cons)];
  427. if (x == 0) {
  428. /* 0: Terminate */
  429. u_cons++;
  430. rw.write_finished = TRUE;
  431. goto out;
  432. } else if (x < 250) {
  433. /* 1-249: One byte */
  434. u_cons++;
  435. } else if (x < 255) {
  436. /* 250-254: Two bytes */
  437. if ((uint32_t)(u_prod - u_cons) < 2)
  438. goto out;
  439. u_cons++;
  440. x = 250 + (x - 250) * 255;
  441. x += u_buf[U_MASK(u_cons++)] - 1;
  442. } else {
  443. /* 255: Six bytes */
  444. if ((uint32_t)(u_prod - u_cons) < 6)
  445. goto out;
  446. u_cons += 2; /* skip 255, FLUXOP_NOFLUX */
  447. ticks += _read_28bit();
  448. continue;
  449. }
  450. ticks += x;
  451. if (ticks < sample_ns(800))
  452. continue;
  453. if (ticks > sample_us(150)) {
  454. rw.no_flux_area = TRUE;
  455. goto out;
  456. }
  457. *tbuf++ = ticks - 1;
  458. ticks = 0;
  459. if (!--todo)
  460. goto out;
  461. }
  462. out:
  463. rw.ticks_since_flux = ticks;
  464. return nr - todo;
  465. }
  466. static void wdata_decode_flux(void)
  467. {
  468. const uint16_t buf_mask = ARRAY_SIZE(dma.buf) - 1;
  469. uint16_t nr_to_wrap, nr_to_cons, nr, dmacons;
  470. /* Find out where the DMA engine's consumer index has got to. */
  471. dmacons = ARRAY_SIZE(dma.buf) - dma_wdata.ndtr;
  472. /* Find largest contiguous stretch of ring buffer we can fill. */
  473. nr_to_wrap = ARRAY_SIZE(dma.buf) - dma.prod;
  474. nr_to_cons = (dmacons - dma.prod - 1) & buf_mask;
  475. nr = min(nr_to_wrap, nr_to_cons);
  476. /* Now attempt to fill the contiguous stretch with flux data calculated
  477. * from buffered bitcell data. */
  478. dma.prod += _wdata_decode_flux(&dma.buf[dma.prod], nr);
  479. dma.prod &= buf_mask;
  480. }
  481. static void floppy_process_write_packet(void)
  482. {
  483. int len = ep_rx_ready(EP_RX);
  484. if ((len >= 0) && !rw.packet_ready) {
  485. usb_read(EP_RX, rw.packet, len);
  486. rw.packet_ready = TRUE;
  487. rw.packet_len = len;
  488. }
  489. if (rw.packet_ready) {
  490. unsigned int avail = U_BUF_SZ - (uint32_t)(u_prod - u_cons);
  491. unsigned int n = rw.packet_len;
  492. if (avail >= n) {
  493. unsigned int p = U_MASK(u_prod);
  494. unsigned int l = U_BUF_SZ - p;
  495. if (l < n) {
  496. memcpy(&u_buf[p], rw.packet, l);
  497. memcpy(u_buf, &rw.packet[l], n-l);
  498. } else {
  499. memcpy(&u_buf[p], rw.packet, n);
  500. }
  501. u_prod += n;
  502. rw.packet_ready = FALSE;
  503. }
  504. }
  505. }
  506. static uint8_t floppy_write_prep(const struct gw_write_flux *wf)
  507. {
  508. if (get_wrprot() == LOW)
  509. return ACK_WRPROT;
  510. wdata_prep();
  511. /* WDATA DMA setup: From a circular buffer into the WDATA Timer's ARR. */
  512. dma_wdata.par = (uint32_t)(unsigned long)&tim_wdata->arr;
  513. dma_wdata.mar = (uint32_t)(unsigned long)dma.buf;
  514. /* Initialise DMA ring indexes (consumer index is implicit). */
  515. dma_wdata.ndtr = ARRAY_SIZE(dma.buf);
  516. dma.prod = 0;
  517. floppy_state = ST_write_flux_wait_data;
  518. memset(&rw, 0, sizeof(rw));
  519. rw.status = ACK_OKAY;
  520. rw.terminate_at_index = wf->terminate_at_index;
  521. return ACK_OKAY;
  522. }
  523. static void floppy_write_wait_data(void)
  524. {
  525. bool_t write_finished;
  526. unsigned int u_buf_threshold;
  527. floppy_process_write_packet();
  528. wdata_decode_flux();
  529. /* We don't wait for the massive F7 u_buf[] to fill at Full Speed. */
  530. u_buf_threshold = ((U_BUF_SZ > 16384) && !usb_is_highspeed())
  531. ? 16384 - 512 : U_BUF_SZ - 512;
  532. /* Wait for DMA and input buffers to fill, or write stream to end. We must
  533. * take care because, since we are not yet draining the DMA buffer, the
  534. * write stream may end without us noticing and setting rw.write_finished.
  535. * Hence we peek for a NUL byte in the input buffer if it's non-empty. */
  536. write_finished = ((u_prod == u_cons)
  537. ? rw.write_finished
  538. : (u_buf[U_MASK(u_prod-1)] == 0));
  539. if (((dma.prod != (ARRAY_SIZE(dma.buf)-1))
  540. || ((uint32_t)(u_prod - u_cons) < u_buf_threshold))
  541. && !write_finished)
  542. return;
  543. floppy_state = ST_write_flux_wait_index;
  544. rw.start = time_now();
  545. /* Enable DMA only after flux values are generated. */
  546. dma_wdata_start();
  547. /* Preload timer with first flux value. */
  548. tim_wdata->egr = TIM_EGR_UG;
  549. tim_wdata->sr = 0; /* dummy write, gives h/w time to process EGR.UG=1 */
  550. barrier(); /* Trigger timer update /then/ wait for next index pulse */
  551. index.count = 0;
  552. }
  553. static void floppy_write_wait_index(void)
  554. {
  555. if (index.count == 0) {
  556. if (time_since(rw.start) > time_ms(2000)) {
  557. /* Timeout */
  558. floppy_flux_end();
  559. rw.status = ACK_NO_INDEX;
  560. floppy_state = ST_write_flux_drain;
  561. }
  562. return;
  563. }
  564. /* Start timer. */
  565. tim_wdata->cr1 = TIM_CR1_CEN;
  566. /* Enable output. */
  567. configure_pin(wdata, AFO_bus);
  568. write_pin(wgate, TRUE);
  569. index.count = 0;
  570. floppy_state = ST_write_flux;
  571. }
  572. static void floppy_write_check_underflow(void)
  573. {
  574. uint32_t avail = u_prod - u_cons;
  575. if (/* We've run the input buffer dry. */
  576. (avail == 0)
  577. /* The input buffer is nearly dry, and doesn't contain EOStream. */
  578. || ((avail < 16) && (u_buf[U_MASK(u_prod-1)] != 0))) {
  579. /* Underflow */
  580. printk("UNDERFLOW %u %u %u %u\n", u_cons, u_prod,
  581. rw.packet_ready, ep_rx_ready(EP_RX));
  582. floppy_flux_end();
  583. rw.status = ACK_FLUX_UNDERFLOW;
  584. floppy_state = ST_write_flux_drain;
  585. }
  586. }
  587. static void floppy_write(void)
  588. {
  589. uint16_t dmacons, todo, prev_todo;
  590. floppy_process_write_packet();
  591. wdata_decode_flux();
  592. /* Early termination on index pulse? */
  593. if (rw.terminate_at_index && (index.count != 0))
  594. goto terminate;
  595. if (!rw.write_finished) {
  596. floppy_write_check_underflow();
  597. return;
  598. }
  599. /* Wait for DMA ring to drain. */
  600. todo = ~0;
  601. do {
  602. /* Check for early termination on index pulse. */
  603. if (rw.terminate_at_index && (index.count != 0))
  604. goto terminate;
  605. /* Check progress of draining the DMA ring. */
  606. prev_todo = todo;
  607. dmacons = ARRAY_SIZE(dma.buf) - dma_wdata.ndtr;
  608. todo = (dma.prod - dmacons) & (ARRAY_SIZE(dma.buf) - 1);
  609. } while ((todo != 0) && (todo <= prev_todo));
  610. terminate:
  611. floppy_flux_end();
  612. floppy_state = ST_write_flux_drain;
  613. }
  614. static void floppy_write_drain(void)
  615. {
  616. /* Drain the write stream. */
  617. if (!rw.write_finished) {
  618. floppy_process_write_packet();
  619. (void)_wdata_decode_flux(dma.buf, ARRAY_SIZE(dma.buf));
  620. return;
  621. }
  622. /* Wait for space to write ACK packet. */
  623. if (!ep_tx_ready(EP_TX))
  624. return;
  625. /* ACK with Status byte. */
  626. u_buf[0] = rw.status;
  627. floppy_state = ST_command_wait;
  628. floppy_end_command(u_buf, 1);
  629. }
  630. /*
  631. * ERASE PATH
  632. */
  633. static uint8_t floppy_erase_prep(const struct gw_erase_flux *ef)
  634. {
  635. if (get_wrprot() == LOW)
  636. return ACK_WRPROT;
  637. write_pin(wgate, TRUE);
  638. floppy_state = ST_erase_flux;
  639. memset(&rw, 0, sizeof(rw));
  640. rw.status = ACK_OKAY;
  641. rw.end = time_now() + time_from_samples(ef->erase_ticks);
  642. return ACK_OKAY;
  643. }
  644. static void floppy_erase(void)
  645. {
  646. if (time_since(rw.end) < 0)
  647. return;
  648. write_pin(wgate, FALSE);
  649. /* ACK with Status byte. */
  650. u_buf[0] = rw.status;
  651. floppy_state = ST_command_wait;
  652. floppy_end_command(u_buf, 1);
  653. }
  654. /*
  655. * SINK/SOURCE
  656. */
  657. static struct {
  658. unsigned int todo;
  659. unsigned int min_delta;
  660. unsigned int max_delta;
  661. } ss;
  662. static void sink_source_prep(const struct gw_sink_source_bytes *ssb)
  663. {
  664. ss.min_delta = INT_MAX;
  665. ss.max_delta = 0;
  666. ss.todo = ssb->nr_bytes;
  667. }
  668. static void ss_update_deltas(int len)
  669. {
  670. uint32_t *u_times = (uint32_t *)u_buf;
  671. time_t delta, now = time_now();
  672. unsigned int p = u_prod;
  673. /* Every four bytes we store a timestamp in a u_buf[]-sized ring buffer.
  674. * We then record min/max time taken to overwrite a previous timestamp. */
  675. while (len--) {
  676. if (p++ & 3)
  677. continue;
  678. delta = time_diff(u_times[U_MASK(p)>>2], now);
  679. u_times[U_MASK(p)>>2] = now;
  680. if ((delta > ss.max_delta) && (p >= U_BUF_SZ))
  681. ss.max_delta = delta;
  682. if ((delta < ss.min_delta) && (p >= U_BUF_SZ))
  683. ss.min_delta = delta;
  684. }
  685. u_prod = p;
  686. }
  687. static void source_bytes(void)
  688. {
  689. if (!ep_tx_ready(EP_TX))
  690. return;
  691. if (ss.todo < usb_bulk_mps) {
  692. floppy_state = ST_command_wait;
  693. floppy_end_command(rw.packet, ss.todo);
  694. return; /* FINISHED */
  695. }
  696. usb_write(EP_TX, rw.packet, usb_bulk_mps);
  697. ss.todo -= usb_bulk_mps;
  698. ss_update_deltas(usb_bulk_mps);
  699. }
  700. static void sink_bytes(void)
  701. {
  702. int len;
  703. if (ss.todo == 0) {
  704. /* We're done: Wait for space to write the ACK byte. */
  705. if (!ep_tx_ready(EP_TX))
  706. return;
  707. u_buf[0] = ACK_OKAY;
  708. floppy_state = ST_command_wait;
  709. floppy_end_command(u_buf, 1);
  710. return; /* FINISHED */
  711. }
  712. /* Packet ready? */
  713. len = ep_rx_ready(EP_RX);
  714. if (len < 0)
  715. return;
  716. /* Read it and adjust byte counter. */
  717. usb_read(EP_RX, rw.packet, len);
  718. ss.todo = (ss.todo <= len) ? 0 : ss.todo - len;
  719. ss_update_deltas(len);
  720. }
  721. /*
  722. * BOOTLOADER UPDATE
  723. */
  724. #define BL_START 0x08000000
  725. #define BL_END ((uint32_t)_stext)
  726. #define BL_SIZE (BL_END - BL_START)
  727. static struct {
  728. uint32_t len;
  729. uint32_t cur;
  730. } update;
  731. static void erase_old_bootloader(void)
  732. {
  733. uint32_t p;
  734. for (p = BL_START; p < BL_END; p += FLASH_PAGE_SIZE)
  735. fpec_page_erase(p);
  736. }
  737. static void update_prep(uint32_t len)
  738. {
  739. fpec_init();
  740. erase_old_bootloader();
  741. floppy_state = ST_update_bootloader;
  742. update.cur = 0;
  743. update.len = len;
  744. printk("Update Bootloader: %u bytes\n", len);
  745. }
  746. static void update_continue(void)
  747. {
  748. int len;
  749. if ((len = ep_rx_ready(EP_RX)) >= 0) {
  750. usb_read(EP_RX, &u_buf[u_prod], len);
  751. u_prod += len;
  752. }
  753. if ((len = u_prod) >= 2) {
  754. int nr = len & ~1;
  755. fpec_write(u_buf, nr, BL_START + update.cur);
  756. update.cur += nr;
  757. u_prod -= nr;
  758. memcpy(u_buf, &u_buf[nr], u_prod);
  759. }
  760. if ((update.cur >= update.len) && ep_tx_ready(EP_TX)) {
  761. uint16_t crc = crc16_ccitt((void *)BL_START, update.len, 0xffff);
  762. printk("Final CRC: %04x (%s)\n", crc, crc ? "FAIL" : "OK");
  763. u_buf[0] = !!crc;
  764. floppy_state = ST_command_wait;
  765. floppy_end_command(u_buf, 1);
  766. }
  767. }
  768. static void process_command(void)
  769. {
  770. uint8_t cmd = u_buf[0];
  771. uint8_t len = u_buf[1];
  772. uint8_t resp_sz = 2;
  773. auto_off_arm();
  774. act_led(TRUE);
  775. switch (cmd) {
  776. case CMD_GET_INFO: {
  777. uint8_t idx = u_buf[2];
  778. if (len != 3)
  779. goto bad_command;
  780. memset(&u_buf[2], 0, 32);
  781. switch(idx) {
  782. case GETINFO_FIRMWARE: /* gw_info */
  783. gw_info.fw_major = fw_major;
  784. gw_info.fw_minor = fw_minor;
  785. memcpy(&u_buf[2], &gw_info, sizeof(gw_info));
  786. break;
  787. case GETINFO_BW_STATS: /* gw_bw_stats */ {
  788. struct gw_bw_stats bw;
  789. bw.min_bw.bytes = U_BUF_SZ;
  790. bw.min_bw.usecs = ss.max_delta / time_us(1);
  791. bw.max_bw.bytes = U_BUF_SZ;
  792. bw.max_bw.usecs = ss.min_delta / time_us(1);
  793. memcpy(&u_buf[2], &bw, sizeof(bw));
  794. break;
  795. }
  796. default:
  797. goto bad_command;
  798. }
  799. resp_sz += 32;
  800. break;
  801. }
  802. case CMD_UPDATE: {
  803. uint32_t u_len = *(uint32_t *)&u_buf[2];
  804. uint32_t signature = *(uint32_t *)&u_buf[6];
  805. if (len != 10) goto bad_command;
  806. if (u_len & 3) goto bad_command;
  807. if (u_len > BL_SIZE) goto bad_command;
  808. if (signature != 0xdeafbee3) goto bad_command;
  809. update_prep(u_len);
  810. break;
  811. }
  812. case CMD_SEEK: {
  813. uint8_t cyl = u_buf[2];
  814. if ((len != 3) || (cyl > 85))
  815. goto bad_command;
  816. u_buf[1] = floppy_seek(cyl);
  817. goto out;
  818. }
  819. case CMD_SIDE: {
  820. uint8_t side = u_buf[2];
  821. if ((len != 3) || (side > 1))
  822. goto bad_command;
  823. write_pin(side, side);
  824. break;
  825. }
  826. case CMD_SET_PARAMS: {
  827. uint8_t idx = u_buf[2];
  828. if ((len < 3) || (idx != PARAMS_DELAYS)
  829. || (len > (3 + sizeof(delay_params))))
  830. goto bad_command;
  831. memcpy(&delay_params, &u_buf[3], len-3);
  832. break;
  833. }
  834. case CMD_GET_PARAMS: {
  835. uint8_t idx = u_buf[2];
  836. uint8_t nr = u_buf[3];
  837. if ((len != 4) || (idx != PARAMS_DELAYS)
  838. || (nr > sizeof(delay_params)))
  839. goto bad_command;
  840. memcpy(&u_buf[2], &delay_params, nr);
  841. resp_sz += nr;
  842. break;
  843. }
  844. case CMD_MOTOR: {
  845. uint8_t unit = u_buf[2], on_off = u_buf[3];
  846. if ((len != 4) || (on_off & ~1))
  847. goto bad_command;
  848. u_buf[1] = drive_motor(unit, on_off & 1);
  849. goto out;
  850. }
  851. case CMD_READ_FLUX: {
  852. struct gw_read_flux rf = { .nr_idx = 2 };
  853. if ((len < 2) || (len > (2 + sizeof(rf))))
  854. goto bad_command;
  855. memcpy(&rf, &u_buf[2], len-2);
  856. u_buf[1] = floppy_read_prep(&rf);
  857. goto out;
  858. }
  859. case CMD_WRITE_FLUX: {
  860. struct gw_write_flux wf = { 0 };
  861. if ((len < 2) || (len > (2 + sizeof(wf))))
  862. goto bad_command;
  863. memcpy(&wf, &u_buf[2], len-2);
  864. u_buf[1] = floppy_write_prep(&wf);
  865. goto out;
  866. }
  867. case CMD_GET_FLUX_STATUS: {
  868. if (len != 2)
  869. goto bad_command;
  870. u_buf[1] = rw.status;
  871. goto out;
  872. }
  873. case CMD_SELECT: {
  874. uint8_t unit = u_buf[2];
  875. if (len != 3)
  876. goto bad_command;
  877. u_buf[1] = drive_select(unit);
  878. goto out;
  879. }
  880. case CMD_DESELECT: {
  881. if (len != 2)
  882. goto bad_command;
  883. drive_deselect();
  884. break;
  885. }
  886. case CMD_SET_BUS_TYPE: {
  887. uint8_t type = u_buf[2];
  888. if ((len != 3) || !set_bus_type(type))
  889. goto bad_command;
  890. break;
  891. }
  892. case CMD_SET_PIN: {
  893. uint8_t pin = u_buf[2];
  894. uint8_t level = u_buf[3];
  895. if ((len != 4) || (level & ~1))
  896. goto bad_command;
  897. u_buf[1] = set_user_pin(pin, level);
  898. goto out;
  899. }
  900. case CMD_RESET: {
  901. if (len != 2)
  902. goto bad_command;
  903. delay_params = factory_delay_params;
  904. _set_bus_type(BUS_NONE);
  905. reset_user_pins();
  906. break;
  907. }
  908. case CMD_ERASE_FLUX: {
  909. struct gw_erase_flux ef;
  910. if (len != (2 + sizeof(ef)))
  911. goto bad_command;
  912. memcpy(&ef, &u_buf[2], len-2);
  913. u_buf[1] = floppy_erase_prep(&ef);
  914. goto out;
  915. }
  916. case CMD_SOURCE_BYTES:
  917. case CMD_SINK_BYTES: {
  918. struct gw_sink_source_bytes ssb;
  919. if (len != (2 + sizeof(ssb)))
  920. goto bad_command;
  921. memcpy(&ssb, &u_buf[2], len-2);
  922. floppy_state = (cmd == CMD_SOURCE_BYTES)
  923. ? ST_source_bytes : ST_sink_bytes;
  924. sink_source_prep(&ssb);
  925. break;
  926. }
  927. #if STM32F == 7
  928. case CMD_SWITCH_FW_MODE: {
  929. uint8_t mode = u_buf[2];
  930. if ((len != 3) || (mode & ~1))
  931. goto bad_command;
  932. if (mode == FW_MODE_BOOTLOADER) {
  933. usb_deinit();
  934. delay_ms(500);
  935. /* Poke a flag in SRAM1, picked up by the bootloader. */
  936. *(volatile uint32_t *)0x20010000 = 0xdeadbeef;
  937. dcache_disable();
  938. system_reset();
  939. }
  940. break;
  941. }
  942. #endif
  943. default:
  944. goto bad_command;
  945. }
  946. u_buf[1] = ACK_OKAY;
  947. out:
  948. floppy_end_command(u_buf, resp_sz);
  949. return;
  950. bad_command:
  951. u_buf[1] = ACK_BAD_COMMAND;
  952. goto out;
  953. }
  954. static void floppy_configure(void)
  955. {
  956. auto_off_arm();
  957. floppy_flux_end();
  958. floppy_state = ST_command_wait;
  959. u_cons = u_prod = 0;
  960. act_led(FALSE);
  961. }
  962. void floppy_process(void)
  963. {
  964. int i, len;
  965. if (auto_off.armed && (time_since(auto_off.deadline) >= 0)) {
  966. floppy_flux_end();
  967. for (i = 0; i < ARRAY_SIZE(unit); i++) {
  968. if (unit[i].motor)
  969. drive_motor(i, FALSE);
  970. }
  971. drive_deselect();
  972. auto_off.armed = FALSE;
  973. }
  974. switch (floppy_state) {
  975. case ST_command_wait:
  976. len = ep_rx_ready(EP_RX);
  977. if ((len >= 0) && (len < (U_BUF_SZ-u_prod))) {
  978. usb_read(EP_RX, &u_buf[u_prod], len);
  979. u_prod += len;
  980. }
  981. if ((u_prod >= 2) && (u_prod >= u_buf[1]) && ep_tx_ready(EP_TX)) {
  982. process_command();
  983. }
  984. break;
  985. case ST_zlp:
  986. if (ep_tx_ready(EP_TX)) {
  987. usb_write(EP_TX, NULL, 0);
  988. floppy_state = ST_command_wait;
  989. }
  990. break;
  991. case ST_read_flux:
  992. case ST_read_flux_drain:
  993. floppy_read();
  994. break;
  995. case ST_write_flux_wait_data:
  996. floppy_write_wait_data();
  997. break;
  998. case ST_write_flux_wait_index:
  999. floppy_write_wait_index();
  1000. break;
  1001. case ST_write_flux:
  1002. floppy_write();
  1003. break;
  1004. case ST_write_flux_drain:
  1005. floppy_write_drain();
  1006. break;
  1007. case ST_erase_flux:
  1008. floppy_erase();
  1009. break;
  1010. case ST_source_bytes:
  1011. source_bytes();
  1012. break;
  1013. case ST_sink_bytes:
  1014. sink_bytes();
  1015. break;
  1016. case ST_update_bootloader:
  1017. update_continue();
  1018. break;
  1019. default:
  1020. break;
  1021. }
  1022. }
  1023. const struct usb_class_ops usb_cdc_acm_ops = {
  1024. .reset = floppy_reset,
  1025. .configure = floppy_configure
  1026. };
  1027. /*
  1028. * INTERRUPT HANDLERS
  1029. */
  1030. static void IRQ_INDEX_changed(void)
  1031. {
  1032. unsigned int cnt = tim_rdata->cnt;
  1033. time_t now = time_now(), prev = index.isr_time;
  1034. /* Clear INDEX-changed flag. */
  1035. exti->pr = m(pin_index);
  1036. index.isr_time = now;
  1037. if (time_diff(prev, now) < time_us(50))
  1038. return;
  1039. index.count++;
  1040. index.rdata_cnt = cnt;
  1041. }
  1042. static void index_timer(void *unused)
  1043. {
  1044. time_t now = time_now();
  1045. IRQ_global_disable();
  1046. /* index.isr_time mustn't get so old that the time_diff() test in
  1047. * IRQ_INDEX_changed() overflows. To prevent this, we ensure that,
  1048. * at all times,
  1049. * time_diff(index.isr_time, time_now()) < 2*INDEX_TIMER_PERIOD + delta,
  1050. * where delta is small. */
  1051. if (time_diff(index.isr_time, now) > INDEX_TIMER_PERIOD)
  1052. index.isr_time = now - INDEX_TIMER_PERIOD;
  1053. IRQ_global_enable();
  1054. timer_set(&index.timer, now + INDEX_TIMER_PERIOD);
  1055. }
  1056. /*
  1057. * Local variables:
  1058. * mode: C
  1059. * c-file-style: "Linux"
  1060. * c-basic-offset: 4
  1061. * tab-width: 4
  1062. * indent-tabs-mode: nil
  1063. * End:
  1064. */