floppy.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968
  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. #if STM32F == 1
  18. #include "floppy_f1.c"
  19. #elif STM32F == 7
  20. #include "floppy_f7.c"
  21. #endif
  22. /* Track and modify states of output pins. */
  23. static struct {
  24. bool_t densel;
  25. bool_t sel0;
  26. bool_t mot0;
  27. bool_t dir;
  28. bool_t step;
  29. bool_t wgate;
  30. bool_t side;
  31. } pins;
  32. #define read_pin(pin) pins.pin
  33. #define write_pin(pin, level) ({ \
  34. gpio_write_pin(gpio_##pin, pin_##pin, level ? O_TRUE : O_FALSE); \
  35. pins.pin = level; })
  36. static struct index {
  37. /* Main code can reset this at will. */
  38. volatile unsigned int count;
  39. /* For synchronising index pulse reporting to the RDATA flux stream. */
  40. volatile unsigned int rdata_cnt;
  41. /* Following fields are for delayed-index writes. */
  42. unsigned int delay;
  43. struct timer delay_timer;
  44. time_t timestamp;
  45. } index;
  46. static void index_delay_timer(void *unused);
  47. /* A DMA buffer for running a timer associated with a floppy-data I/O pin. */
  48. static struct dma_ring {
  49. /* Indexes into the buf[] ring buffer. */
  50. uint16_t cons; /* dma_rd: our consumer index for flux samples */
  51. union {
  52. uint16_t prod; /* dma_wr: our producer index for flux samples */
  53. timcnt_t prev_sample; /* dma_rd: previous CCRx sample value */
  54. };
  55. /* DMA ring buffer of timer values (ARR or CCRx). */
  56. timcnt_t buf[512];
  57. } dma;
  58. static struct {
  59. time_t deadline;
  60. bool_t armed;
  61. } auto_off;
  62. static enum {
  63. ST_inactive,
  64. ST_command_wait,
  65. ST_zlp,
  66. ST_read_flux,
  67. ST_read_flux_drain,
  68. ST_write_flux_wait_data,
  69. ST_write_flux_wait_index,
  70. ST_write_flux,
  71. ST_write_flux_drain,
  72. } floppy_state = ST_inactive;
  73. static uint8_t u_buf[8192];
  74. static uint32_t u_cons, u_prod;
  75. #define U_MASK(x) ((x)&(sizeof(u_buf)-1))
  76. static struct gw_delay delay_params = {
  77. .select_delay = 10,
  78. .step_delay = 3000,
  79. .seek_settle = 15,
  80. .motor_delay = 750,
  81. .auto_off = 10000
  82. };
  83. static void step_one_out(void)
  84. {
  85. write_pin(dir, FALSE);
  86. delay_us(10);
  87. write_pin(step, TRUE);
  88. delay_us(10);
  89. write_pin(step, FALSE);
  90. delay_us(delay_params.step_delay);
  91. }
  92. static void step_one_in(void)
  93. {
  94. write_pin(dir, TRUE);
  95. delay_us(10);
  96. write_pin(step, TRUE);
  97. delay_us(10);
  98. write_pin(step, FALSE);
  99. delay_us(delay_params.step_delay);
  100. }
  101. static int cur_cyl = -1;
  102. static void drive_select(bool_t on)
  103. {
  104. if (read_pin(sel0) == on)
  105. return;
  106. write_pin(sel0, on);
  107. if (on)
  108. delay_us(delay_params.select_delay);
  109. }
  110. static bool_t floppy_seek(unsigned int cyl)
  111. {
  112. if ((cyl == 0) || (cur_cyl < 0)) {
  113. unsigned int i;
  114. for (i = 0; i < 256; i++) {
  115. if (get_trk0() == LOW)
  116. break;
  117. step_one_out();
  118. }
  119. cur_cyl = 0;
  120. if (get_trk0() == HIGH) {
  121. cur_cyl = -1;
  122. return FALSE;
  123. }
  124. }
  125. if (cur_cyl < 0) {
  126. } else if (cur_cyl <= cyl) {
  127. unsigned int nr = cyl - cur_cyl;
  128. while (nr--)
  129. step_one_in();
  130. } else {
  131. unsigned int nr = cur_cyl - cyl;
  132. while (nr--)
  133. step_one_out();
  134. }
  135. delay_ms(delay_params.seek_settle);
  136. cur_cyl = cyl;
  137. return TRUE;
  138. }
  139. static void drive_motor(bool_t on)
  140. {
  141. if (read_pin(mot0) == on)
  142. return;
  143. write_pin(mot0, on);
  144. if (on)
  145. delay_ms(delay_params.motor_delay);
  146. }
  147. static void floppy_flux_end(void)
  148. {
  149. /* Turn off write pins. */
  150. write_pin(wgate, FALSE);
  151. configure_pin(wdata, GPO_bus);
  152. /* Turn off DMA. */
  153. dma_rdata.cr &= ~DMA_CR_EN;
  154. dma_wdata.cr &= ~DMA_CR_EN;
  155. while ((dma_rdata.cr & DMA_CR_EN) || (dma_wdata.cr & DMA_CR_EN))
  156. continue;
  157. /* Turn off timers. */
  158. tim_rdata->ccer = 0;
  159. tim_rdata->cr1 = 0;
  160. tim_rdata->sr = 0; /* dummy, drains any pending DMA */
  161. tim_wdata->ccer = 0;
  162. tim_wdata->cr1 = 0;
  163. tim_wdata->sr = 0; /* dummy, drains any pending DMA */
  164. }
  165. static void floppy_reset(void)
  166. {
  167. floppy_state = ST_inactive;
  168. auto_off.armed = FALSE;
  169. floppy_flux_end();
  170. /* Turn off all output pins. */
  171. write_pin(densel, FALSE);
  172. write_pin(sel0, FALSE);
  173. write_pin(mot0, FALSE);
  174. write_pin(dir, FALSE);
  175. write_pin(step, FALSE);
  176. write_pin(wgate, FALSE);
  177. write_pin(side, FALSE);
  178. }
  179. void floppy_init(void)
  180. {
  181. floppy_mcu_init();
  182. /* Output pins, unbuffered. */
  183. configure_pin(densel, GPO_bus);
  184. configure_pin(sel0, GPO_bus);
  185. configure_pin(mot0, GPO_bus);
  186. configure_pin(dir, GPO_bus);
  187. configure_pin(step, GPO_bus);
  188. configure_pin(wgate, GPO_bus);
  189. configure_pin(side, GPO_bus);
  190. configure_pin(wdata, GPO_bus);
  191. /* Input pins. */
  192. configure_pin(index, GPI_bus);
  193. configure_pin(trk0, GPI_bus);
  194. configure_pin(wrprot, GPI_bus);
  195. /* Configure INDEX-changed IRQs and timer. */
  196. timer_init(&index.delay_timer, index_delay_timer, NULL);
  197. IRQx_set_prio(irq_index_delay, TIMER_IRQ_PRI);
  198. IRQx_enable(irq_index_delay);
  199. exti->rtsr = 0;
  200. exti->imr = exti->ftsr = m(pin_index);
  201. IRQx_set_prio(irq_index, INDEX_IRQ_PRI);
  202. IRQx_enable(irq_index);
  203. }
  204. static struct gw_info gw_info = {
  205. .max_index = 15, .max_cmd = CMD_SELECT,
  206. .sample_freq = 72000000u
  207. };
  208. static void auto_off_arm(void)
  209. {
  210. auto_off.armed = TRUE;
  211. auto_off.deadline = time_now() + time_ms(delay_params.auto_off);
  212. }
  213. static void floppy_end_command(void *ack, unsigned int ack_len)
  214. {
  215. auto_off_arm();
  216. usb_write(EP_TX, ack, ack_len);
  217. u_cons = u_prod = 0;
  218. if (ack_len == USB_FS_MPS) {
  219. ASSERT(floppy_state == ST_command_wait);
  220. floppy_state = ST_zlp;
  221. }
  222. }
  223. /*
  224. * READ PATH
  225. */
  226. static struct {
  227. time_t start;
  228. uint8_t status;
  229. uint8_t idx, nr_idx;
  230. bool_t packet_ready;
  231. bool_t write_finished;
  232. bool_t terminate_at_index;
  233. bool_t no_flux_area;
  234. unsigned int packet_len;
  235. int ticks_since_index;
  236. uint32_t ticks_since_flux;
  237. uint32_t index_ticks[15];
  238. uint8_t packet[USB_FS_MPS];
  239. } rw;
  240. static void rdata_encode_flux(void)
  241. {
  242. const uint16_t buf_mask = ARRAY_SIZE(dma.buf) - 1;
  243. uint16_t cons = dma.cons, prod;
  244. timcnt_t prev = dma.prev_sample, curr, next;
  245. uint32_t ticks = rw.ticks_since_flux;
  246. int ticks_since_index = rw.ticks_since_index;
  247. ASSERT(rw.idx < rw.nr_idx);
  248. /* We don't want to race the Index IRQ handler. */
  249. IRQ_global_disable();
  250. /* Find out where the DMA engine's producer index has got to. */
  251. prod = ARRAY_SIZE(dma.buf) - dma_rdata.ndtr;
  252. if (rw.idx != index.count) {
  253. /* We have just passed the index mark: Record information about
  254. * the just-completed revolution. */
  255. int partial_flux = ticks + (timcnt_t)(index.rdata_cnt - prev);
  256. rw.index_ticks[rw.idx++] = ticks_since_index + partial_flux;
  257. ticks_since_index = -partial_flux;
  258. }
  259. IRQ_global_enable();
  260. /* Process the flux timings into the raw bitcell buffer. */
  261. for (; cons != prod; cons = (cons+1) & buf_mask) {
  262. next = dma.buf[cons];
  263. curr = next - prev;
  264. prev = next;
  265. ticks += curr;
  266. if (ticks == 0) {
  267. /* 0: Skip. */
  268. } else if (ticks < 250) {
  269. /* 1-249: One byte. */
  270. u_buf[U_MASK(u_prod++)] = ticks;
  271. } else {
  272. unsigned int high = ticks / 250;
  273. if (high <= 5) {
  274. /* 250-1499: Two bytes. */
  275. u_buf[U_MASK(u_prod++)] = 249 + high;
  276. u_buf[U_MASK(u_prod++)] = 1 + (ticks % 250);
  277. } else {
  278. /* 1500-(2^28-1): Five bytes */
  279. u_buf[U_MASK(u_prod++)] = 0xff;
  280. u_buf[U_MASK(u_prod++)] = 1 | (ticks << 1);
  281. u_buf[U_MASK(u_prod++)] = 1 | (ticks >> 6);
  282. u_buf[U_MASK(u_prod++)] = 1 | (ticks >> 13);
  283. u_buf[U_MASK(u_prod++)] = 1 | (ticks >> 20);
  284. }
  285. }
  286. ticks_since_index += ticks;
  287. ticks = 0;
  288. }
  289. /* If it has been a long time since the last flux timing, transfer some of
  290. * the accumulated time from the 16-bit timestamp into the 32-bit
  291. * accumulator. This avoids 16-bit overflow and because, we take care to
  292. * keep the 16-bit timestamp at least 200us behind, we cannot race the next
  293. * flux timestamp. */
  294. if (sizeof(timcnt_t) == sizeof(uint16_t)) {
  295. curr = tim_rdata->cnt - prev;
  296. if (unlikely(curr > sysclk_us(400))) {
  297. prev += sysclk_us(200);
  298. ticks += sysclk_us(200);
  299. }
  300. }
  301. /* Save our progress for next time. */
  302. dma.cons = cons;
  303. dma.prev_sample = prev;
  304. rw.ticks_since_flux = ticks;
  305. rw.ticks_since_index = ticks_since_index;
  306. }
  307. static uint8_t floppy_read_prep(struct gw_read_flux *rf)
  308. {
  309. if ((rf->nr_idx == 0) || (rf->nr_idx > gw_info.max_index))
  310. return ACK_BAD_COMMAND;
  311. /* Prepare Timer & DMA. */
  312. dma_rdata.mar = (uint32_t)(unsigned long)dma.buf;
  313. dma_rdata.ndtr = ARRAY_SIZE(dma.buf);
  314. rdata_prep();
  315. tim_rdata->egr = TIM_EGR_UG; /* update CNT, PSC, ARR */
  316. tim_rdata->sr = 0; /* dummy write */
  317. /* DMA soft state. */
  318. dma.cons = 0;
  319. dma.prev_sample = tim_rdata->cnt;
  320. /* Start Timer. */
  321. tim_rdata->cr1 = TIM_CR1_CEN;
  322. index.count = 0;
  323. floppy_state = ST_read_flux;
  324. memset(&rw, 0, sizeof(rw));
  325. rw.nr_idx = rf->nr_idx;
  326. rw.start = time_now();
  327. rw.status = ACK_OKAY;
  328. return ACK_OKAY;
  329. }
  330. static void make_read_packet(unsigned int n)
  331. {
  332. unsigned int c = U_MASK(u_cons);
  333. unsigned int l = ARRAY_SIZE(u_buf) - c;
  334. if (l < n) {
  335. memcpy(rw.packet, &u_buf[c], l);
  336. memcpy(&rw.packet[l], u_buf, n-l);
  337. } else {
  338. memcpy(rw.packet, &u_buf[c], n);
  339. }
  340. u_cons += n;
  341. rw.packet_ready = TRUE;
  342. }
  343. static void floppy_read(void)
  344. {
  345. unsigned int avail = (uint32_t)(u_prod - u_cons);
  346. if (floppy_state == ST_read_flux) {
  347. rdata_encode_flux();
  348. avail = (uint32_t)(u_prod - u_cons);
  349. if (avail > sizeof(u_buf)) {
  350. /* Overflow */
  351. printk("OVERFLOW %u %u %u %u\n", u_cons, u_prod,
  352. rw.packet_ready, ep_tx_ready(EP_TX));
  353. floppy_flux_end();
  354. rw.status = ACK_FLUX_OVERFLOW;
  355. floppy_state = ST_read_flux_drain;
  356. u_cons = u_prod = avail = 0;
  357. } else if (rw.idx >= rw.nr_idx) {
  358. /* Read all requested revolutions. */
  359. floppy_flux_end();
  360. floppy_state = ST_read_flux_drain;
  361. } else if ((index.count == 0)
  362. && (time_since(rw.start) > time_ms(2000))) {
  363. /* Timeout */
  364. printk("NO INDEX\n");
  365. floppy_flux_end();
  366. rw.status = ACK_NO_INDEX;
  367. floppy_state = ST_read_flux_drain;
  368. u_cons = u_prod = avail = 0;
  369. }
  370. } else if ((avail < USB_FS_MPS)
  371. && !rw.packet_ready
  372. && ep_tx_ready(EP_TX)) {
  373. /* Final packet, including ACK byte (NUL). */
  374. memset(rw.packet, 0, USB_FS_MPS);
  375. make_read_packet(avail);
  376. floppy_state = ST_command_wait;
  377. floppy_end_command(rw.packet, avail+1);
  378. return; /* FINISHED */
  379. }
  380. if (!rw.packet_ready && (avail >= USB_FS_MPS))
  381. make_read_packet(USB_FS_MPS);
  382. if (rw.packet_ready && ep_tx_ready(EP_TX)) {
  383. usb_write(EP_TX, rw.packet, USB_FS_MPS);
  384. rw.packet_ready = FALSE;
  385. }
  386. }
  387. /*
  388. * WRITE PATH
  389. */
  390. static unsigned int _wdata_decode_flux(timcnt_t *tbuf, unsigned int nr)
  391. {
  392. unsigned int todo = nr;
  393. uint32_t x, ticks = rw.ticks_since_flux;
  394. if (todo == 0)
  395. return 0;
  396. if (rw.no_flux_area) {
  397. unsigned int nfa_pulse = sysclk_ns(1250);
  398. while (ticks >= nfa_pulse) {
  399. *tbuf++ = nfa_pulse - 1;
  400. ticks -= nfa_pulse;
  401. if (!--todo)
  402. goto out;
  403. }
  404. rw.no_flux_area = FALSE;
  405. }
  406. while (u_cons != u_prod) {
  407. x = u_buf[U_MASK(u_cons)];
  408. if (x == 0) {
  409. /* 0: Terminate */
  410. u_cons++;
  411. rw.write_finished = TRUE;
  412. goto out;
  413. } else if (x < 250) {
  414. /* 1-249: One byte */
  415. u_cons++;
  416. } else if (x < 255) {
  417. /* 250-254: Two bytes */
  418. if ((uint32_t)(u_prod - u_cons) < 2)
  419. goto out;
  420. u_cons++;
  421. x = (x - 249) * 250;
  422. x += u_buf[U_MASK(u_cons++)] - 1;
  423. } else {
  424. /* 255: Five bytes */
  425. if ((uint32_t)(u_prod - u_cons) < 5)
  426. goto out;
  427. u_cons++;
  428. x = (u_buf[U_MASK(u_cons++)] ) >> 1;
  429. x |= (u_buf[U_MASK(u_cons++)] & 0xfe) << 6;
  430. x |= (u_buf[U_MASK(u_cons++)] & 0xfe) << 13;
  431. x |= (u_buf[U_MASK(u_cons++)] & 0xfe) << 20;
  432. }
  433. ticks += x;
  434. if (ticks < sysclk_ns(800))
  435. continue;
  436. if (ticks > sysclk_us(150)) {
  437. rw.no_flux_area = TRUE;
  438. goto out;
  439. }
  440. *tbuf++ = ticks - 1;
  441. ticks = 0;
  442. if (!--todo)
  443. goto out;
  444. }
  445. out:
  446. rw.ticks_since_flux = ticks;
  447. return nr - todo;
  448. }
  449. static void wdata_decode_flux(void)
  450. {
  451. const uint16_t buf_mask = ARRAY_SIZE(dma.buf) - 1;
  452. uint16_t nr_to_wrap, nr_to_cons, nr, dmacons;
  453. /* Find out where the DMA engine's consumer index has got to. */
  454. dmacons = ARRAY_SIZE(dma.buf) - dma_wdata.ndtr;
  455. /* Find largest contiguous stretch of ring buffer we can fill. */
  456. nr_to_wrap = ARRAY_SIZE(dma.buf) - dma.prod;
  457. nr_to_cons = (dmacons - dma.prod - 1) & buf_mask;
  458. nr = min(nr_to_wrap, nr_to_cons);
  459. /* Now attempt to fill the contiguous stretch with flux data calculated
  460. * from buffered bitcell data. */
  461. dma.prod += _wdata_decode_flux(&dma.buf[dma.prod], nr);
  462. dma.prod &= buf_mask;
  463. }
  464. static void floppy_process_write_packet(void)
  465. {
  466. int len = ep_rx_ready(EP_RX);
  467. if ((len >= 0) && !rw.packet_ready) {
  468. usb_read(EP_RX, rw.packet, len);
  469. rw.packet_ready = TRUE;
  470. rw.packet_len = len;
  471. }
  472. if (rw.packet_ready) {
  473. unsigned int avail = ARRAY_SIZE(u_buf) - (uint32_t)(u_prod - u_cons);
  474. unsigned int n = rw.packet_len;
  475. if (avail >= n) {
  476. unsigned int p = U_MASK(u_prod);
  477. unsigned int l = ARRAY_SIZE(u_buf) - p;
  478. if (l < n) {
  479. memcpy(&u_buf[p], rw.packet, l);
  480. memcpy(u_buf, &rw.packet[l], n-l);
  481. } else {
  482. memcpy(&u_buf[p], rw.packet, n);
  483. }
  484. u_prod += n;
  485. rw.packet_ready = FALSE;
  486. }
  487. }
  488. }
  489. static uint8_t floppy_write_prep(struct gw_write_flux *wf)
  490. {
  491. if (get_wrprot() == LOW)
  492. return ACK_WRPROT;
  493. wdata_prep();
  494. /* WDATA DMA setup: From a circular buffer into the WDATA Timer's ARR. */
  495. dma_wdata.par = (uint32_t)(unsigned long)&tim_wdata->arr;
  496. dma_wdata.mar = (uint32_t)(unsigned long)dma.buf;
  497. /* Initialise DMA ring indexes (consumer index is implicit). */
  498. dma_wdata.ndtr = ARRAY_SIZE(dma.buf);
  499. dma.prod = 0;
  500. floppy_state = ST_write_flux_wait_data;
  501. memset(&rw, 0, sizeof(rw));
  502. rw.status = ACK_OKAY;
  503. index.delay = time_sysclk(wf->index_delay_ticks);
  504. rw.terminate_at_index = wf->terminate_at_index;
  505. return ACK_OKAY;
  506. }
  507. static void floppy_write_wait_data(void)
  508. {
  509. bool_t write_finished;
  510. floppy_process_write_packet();
  511. wdata_decode_flux();
  512. /* Wait for DMA and input buffers to fill, or write stream to end. We must
  513. * take care because, since we are not yet draining the DMA buffer, the
  514. * write stream may end without us noticing and setting rw.write_finished.
  515. * Hence we peek for a NUL byte in the input buffer if it's non-empty. */
  516. write_finished = ((u_prod == u_cons)
  517. ? rw.write_finished
  518. : (u_buf[U_MASK(u_prod-1)] == 0));
  519. if (((dma.prod != (ARRAY_SIZE(dma.buf)-1))
  520. || ((uint32_t)(u_prod - u_cons) < (ARRAY_SIZE(u_buf) - 512)))
  521. && !write_finished)
  522. return;
  523. floppy_state = ST_write_flux_wait_index;
  524. rw.start = time_now();
  525. /* Enable DMA only after flux values are generated. */
  526. dma_wdata_start();
  527. /* Preload timer with first flux value. */
  528. tim_wdata->egr = TIM_EGR_UG;
  529. tim_wdata->sr = 0; /* dummy write, gives h/w time to process EGR.UG=1 */
  530. barrier(); /* Trigger timer update /then/ wait for next index pulse */
  531. index.count = 0;
  532. }
  533. static void floppy_write_wait_index(void)
  534. {
  535. if (index.count == 0) {
  536. if (time_since(rw.start) > time_ms(2000)) {
  537. /* Timeout */
  538. floppy_flux_end();
  539. rw.status = ACK_NO_INDEX;
  540. floppy_state = ST_write_flux_drain;
  541. }
  542. return;
  543. }
  544. /* Start timer. */
  545. tim_wdata->cr1 = TIM_CR1_CEN;
  546. /* Enable output. */
  547. configure_pin(wdata, AFO_bus);
  548. write_pin(wgate, TRUE);
  549. index.count = 0;
  550. floppy_state = ST_write_flux;
  551. }
  552. static void floppy_write_check_underflow(void)
  553. {
  554. uint32_t avail = u_prod - u_cons;
  555. if (/* We've run the input buffer dry. */
  556. (avail == 0)
  557. /* The input buffer is nearly dry, and doesn't contain EOStream. */
  558. || ((avail < 16) && (u_buf[U_MASK(u_prod-1)] != 0))) {
  559. /* Underflow */
  560. printk("UNDERFLOW %u %u %u %u\n", u_cons, u_prod,
  561. rw.packet_ready, ep_rx_ready(EP_RX));
  562. floppy_flux_end();
  563. rw.status = ACK_FLUX_UNDERFLOW;
  564. floppy_state = ST_write_flux_drain;
  565. }
  566. }
  567. static void floppy_write(void)
  568. {
  569. uint16_t dmacons, todo, prev_todo;
  570. floppy_process_write_packet();
  571. wdata_decode_flux();
  572. /* Early termination on index pulse? */
  573. if (rw.terminate_at_index && (index.count != 0))
  574. goto terminate;
  575. if (!rw.write_finished) {
  576. floppy_write_check_underflow();
  577. return;
  578. }
  579. /* Wait for DMA ring to drain. */
  580. todo = ~0;
  581. do {
  582. /* Check for early termination on index pulse. */
  583. if (rw.terminate_at_index && (index.count != 0))
  584. goto terminate;
  585. /* Check progress of draining the DMA ring. */
  586. prev_todo = todo;
  587. dmacons = ARRAY_SIZE(dma.buf) - dma_wdata.ndtr;
  588. todo = (dma.prod - dmacons) & (ARRAY_SIZE(dma.buf) - 1);
  589. } while ((todo != 0) && (todo <= prev_todo));
  590. terminate:
  591. floppy_flux_end();
  592. floppy_state = ST_write_flux_drain;
  593. }
  594. static void floppy_write_drain(void)
  595. {
  596. /* Drain the write stream. */
  597. if (!rw.write_finished) {
  598. floppy_process_write_packet();
  599. (void)_wdata_decode_flux(dma.buf, ARRAY_SIZE(dma.buf));
  600. return;
  601. }
  602. /* Wait for space to write ACK packet. */
  603. if (!ep_tx_ready(EP_TX))
  604. return;
  605. /* ACK with Status byte. */
  606. u_buf[0] = rw.status;
  607. floppy_state = ST_command_wait;
  608. floppy_end_command(u_buf, 1);
  609. /* Reset INDEX handling. */
  610. IRQ_global_disable();
  611. index.delay = 0;
  612. IRQx_clear_pending(irq_index_delay);
  613. timer_cancel(&index.delay_timer);
  614. IRQ_global_enable();
  615. }
  616. static void process_command(void)
  617. {
  618. uint8_t cmd = u_buf[0];
  619. uint8_t len = u_buf[1];
  620. uint8_t resp_sz = 2;
  621. auto_off_arm();
  622. switch (cmd) {
  623. case CMD_GET_INFO: {
  624. uint8_t idx = u_buf[2];
  625. if ((len != 3) || (idx != 0))
  626. goto bad_command;
  627. memset(&u_buf[2], 0, 32);
  628. gw_info.fw_major = fw_major;
  629. gw_info.fw_minor = fw_minor;
  630. memcpy(&u_buf[2], &gw_info, sizeof(gw_info));
  631. resp_sz += 32;
  632. break;
  633. }
  634. case CMD_SEEK: {
  635. uint8_t cyl = u_buf[2];
  636. if ((len != 3) || (cyl > 85))
  637. goto bad_command;
  638. u_buf[1] = floppy_seek(cyl) ? ACK_OKAY : ACK_NO_TRK0;
  639. goto out;
  640. }
  641. case CMD_SIDE: {
  642. uint8_t side = u_buf[2];
  643. if ((len != 3) || (side > 1))
  644. goto bad_command;
  645. write_pin(side, side);
  646. break;
  647. }
  648. case CMD_SET_PARAMS: {
  649. uint8_t idx = u_buf[2];
  650. if ((len < 3) || (idx != PARAMS_DELAYS)
  651. || (len > (3 + sizeof(delay_params))))
  652. goto bad_command;
  653. memcpy(&delay_params, &u_buf[3], len-3);
  654. break;
  655. }
  656. case CMD_GET_PARAMS: {
  657. uint8_t idx = u_buf[2];
  658. uint8_t nr = u_buf[3];
  659. if ((len != 4) || (idx != PARAMS_DELAYS)
  660. || (nr > sizeof(delay_params)))
  661. goto bad_command;
  662. memcpy(&u_buf[2], &delay_params, nr);
  663. resp_sz += nr;
  664. break;
  665. }
  666. case CMD_MOTOR: {
  667. uint8_t mask = u_buf[2];
  668. if ((len != 3) || (mask & ~1))
  669. goto bad_command;
  670. drive_motor(mask & 1);
  671. break;
  672. }
  673. case CMD_READ_FLUX: {
  674. struct gw_read_flux rf = { .nr_idx = 2 };
  675. if ((len < 2) || (len > (2 + sizeof(rf))))
  676. goto bad_command;
  677. memcpy(&rf, &u_buf[2], len-2);
  678. u_buf[1] = floppy_read_prep(&rf);
  679. goto out;
  680. }
  681. case CMD_WRITE_FLUX: {
  682. struct gw_write_flux wf = { 0 };
  683. if ((len < 2) || (len > (2 + sizeof(wf))))
  684. goto bad_command;
  685. memcpy(&wf, &u_buf[2], len-2);
  686. u_buf[1] = floppy_write_prep(&wf);
  687. goto out;
  688. }
  689. case CMD_GET_FLUX_STATUS: {
  690. if (len != 2)
  691. goto bad_command;
  692. u_buf[1] = rw.status;
  693. goto out;
  694. }
  695. case CMD_GET_INDEX_TIMES: {
  696. uint8_t f = u_buf[2], n = u_buf[3];
  697. if ((len != 4) || (n > 15) || ((f+n) > gw_info.max_index))
  698. goto bad_command;
  699. memcpy(&u_buf[2], rw.index_ticks+f, n*4);
  700. resp_sz += n*4;
  701. break;
  702. }
  703. case CMD_SELECT: {
  704. uint8_t mask = u_buf[2];
  705. if ((len != 3) || (mask & ~1))
  706. goto bad_command;
  707. drive_select(mask & 1);
  708. break;
  709. }
  710. default:
  711. goto bad_command;
  712. }
  713. u_buf[1] = ACK_OKAY;
  714. out:
  715. floppy_end_command(u_buf, resp_sz);
  716. return;
  717. bad_command:
  718. u_buf[1] = ACK_BAD_COMMAND;
  719. goto out;
  720. }
  721. static void floppy_configure(void)
  722. {
  723. auto_off_arm();
  724. floppy_flux_end();
  725. floppy_state = ST_command_wait;
  726. u_cons = u_prod = 0;
  727. }
  728. void floppy_process(void)
  729. {
  730. int len;
  731. if (auto_off.armed && (time_since(auto_off.deadline) >= 0)) {
  732. floppy_flux_end();
  733. drive_motor(FALSE);
  734. drive_select(FALSE);
  735. auto_off.armed = FALSE;
  736. //gpio_write_pin(gpioa, 0, LOW);
  737. //delay_ms(100); /* force disconnect */
  738. //gpio_write_pin(gpioa, 0, HIGH);
  739. }
  740. switch (floppy_state) {
  741. case ST_command_wait:
  742. len = ep_rx_ready(EP_RX);
  743. if ((len >= 0) && (len < (sizeof(u_buf)-u_prod))) {
  744. usb_read(EP_RX, &u_buf[u_prod], len);
  745. u_prod += len;
  746. }
  747. if ((u_prod >= 2) && (u_prod >= u_buf[1]) && ep_tx_ready(EP_TX)) {
  748. process_command();
  749. }
  750. break;
  751. case ST_zlp:
  752. if (ep_tx_ready(EP_TX)) {
  753. usb_write(EP_TX, NULL, 0);
  754. floppy_state = ST_command_wait;
  755. }
  756. break;
  757. case ST_read_flux:
  758. case ST_read_flux_drain:
  759. floppy_read();
  760. break;
  761. case ST_write_flux_wait_data:
  762. floppy_write_wait_data();
  763. break;
  764. case ST_write_flux_wait_index:
  765. floppy_write_wait_index();
  766. break;
  767. case ST_write_flux:
  768. floppy_write();
  769. break;
  770. case ST_write_flux_drain:
  771. floppy_write_drain();
  772. break;
  773. default:
  774. break;
  775. }
  776. }
  777. const struct usb_class_ops usb_cdc_acm_ops = {
  778. .reset = floppy_reset,
  779. .configure = floppy_configure
  780. };
  781. /*
  782. * INTERRUPT HANDLERS
  783. */
  784. static void index_delay_timer(void *unused)
  785. {
  786. index.count++;
  787. }
  788. static void IRQ_INDEX_delay(void)
  789. {
  790. timer_set(&index.delay_timer, index.timestamp + index.delay);
  791. }
  792. static void IRQ_INDEX_changed(void)
  793. {
  794. /* Clear INDEX-changed flag. */
  795. exti->pr = m(pin_index);
  796. index.rdata_cnt = tim_rdata->cnt;
  797. index.timestamp = time_now();
  798. if (index.delay != 0) {
  799. IRQx_set_pending(irq_index_delay);
  800. } else {
  801. index.count++;
  802. }
  803. }
  804. /*
  805. * Local variables:
  806. * mode: C
  807. * c-file-style: "Linux"
  808. * c-basic-offset: 4
  809. * tab-width: 4
  810. * indent-tabs-mode: nil
  811. * End:
  812. */