floppy.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979
  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_MAX,
  206. .sample_freq = 72000000u,
  207. .hw_type = STM32F
  208. };
  209. static void auto_off_arm(void)
  210. {
  211. auto_off.armed = TRUE;
  212. auto_off.deadline = time_now() + time_ms(delay_params.auto_off);
  213. }
  214. static void floppy_end_command(void *ack, unsigned int ack_len)
  215. {
  216. auto_off_arm();
  217. usb_write(EP_TX, ack, ack_len);
  218. u_cons = u_prod = 0;
  219. if (ack_len == USB_FS_MPS) {
  220. ASSERT(floppy_state == ST_command_wait);
  221. floppy_state = ST_zlp;
  222. }
  223. }
  224. /*
  225. * READ PATH
  226. */
  227. static struct {
  228. time_t start;
  229. uint8_t status;
  230. uint8_t idx, nr_idx;
  231. bool_t packet_ready;
  232. bool_t write_finished;
  233. bool_t terminate_at_index;
  234. bool_t no_flux_area;
  235. unsigned int packet_len;
  236. int ticks_since_index;
  237. uint32_t ticks_since_flux;
  238. uint32_t index_ticks[15];
  239. uint8_t packet[USB_FS_MPS];
  240. } rw;
  241. static void rdata_encode_flux(void)
  242. {
  243. const uint16_t buf_mask = ARRAY_SIZE(dma.buf) - 1;
  244. uint16_t cons = dma.cons, prod;
  245. timcnt_t prev = dma.prev_sample, curr, next;
  246. uint32_t ticks = rw.ticks_since_flux;
  247. int ticks_since_index = rw.ticks_since_index;
  248. ASSERT(rw.idx < rw.nr_idx);
  249. /* We don't want to race the Index IRQ handler. */
  250. IRQ_global_disable();
  251. /* Find out where the DMA engine's producer index has got to. */
  252. prod = ARRAY_SIZE(dma.buf) - dma_rdata.ndtr;
  253. if (rw.idx != index.count) {
  254. /* We have just passed the index mark: Record information about
  255. * the just-completed revolution. */
  256. int partial_flux = ticks + (timcnt_t)(index.rdata_cnt - prev);
  257. rw.index_ticks[rw.idx++] = ticks_since_index + partial_flux;
  258. ticks_since_index = -partial_flux;
  259. }
  260. IRQ_global_enable();
  261. /* Process the flux timings into the raw bitcell buffer. */
  262. for (; cons != prod; cons = (cons+1) & buf_mask) {
  263. next = dma.buf[cons];
  264. curr = next - prev;
  265. prev = next;
  266. ticks += curr;
  267. if (ticks == 0) {
  268. /* 0: Skip. */
  269. } else if (ticks < 250) {
  270. /* 1-249: One byte. */
  271. u_buf[U_MASK(u_prod++)] = ticks;
  272. } else {
  273. unsigned int high = ticks / 250;
  274. if (high <= 5) {
  275. /* 250-1499: Two bytes. */
  276. u_buf[U_MASK(u_prod++)] = 249 + high;
  277. u_buf[U_MASK(u_prod++)] = 1 + (ticks % 250);
  278. } else {
  279. /* 1500-(2^28-1): Five bytes */
  280. u_buf[U_MASK(u_prod++)] = 0xff;
  281. u_buf[U_MASK(u_prod++)] = 1 | (ticks << 1);
  282. u_buf[U_MASK(u_prod++)] = 1 | (ticks >> 6);
  283. u_buf[U_MASK(u_prod++)] = 1 | (ticks >> 13);
  284. u_buf[U_MASK(u_prod++)] = 1 | (ticks >> 20);
  285. }
  286. }
  287. ticks_since_index += ticks;
  288. ticks = 0;
  289. }
  290. /* If it has been a long time since the last flux timing, transfer some of
  291. * the accumulated time from the 16-bit timestamp into the 32-bit
  292. * accumulator. This avoids 16-bit overflow and because, we take care to
  293. * keep the 16-bit timestamp at least 200us behind, we cannot race the next
  294. * flux timestamp. */
  295. if (sizeof(timcnt_t) == sizeof(uint16_t)) {
  296. curr = tim_rdata->cnt - prev;
  297. if (unlikely(curr > sysclk_us(400))) {
  298. prev += sysclk_us(200);
  299. ticks += sysclk_us(200);
  300. }
  301. }
  302. /* Save our progress for next time. */
  303. dma.cons = cons;
  304. dma.prev_sample = prev;
  305. rw.ticks_since_flux = ticks;
  306. rw.ticks_since_index = ticks_since_index;
  307. }
  308. static uint8_t floppy_read_prep(struct gw_read_flux *rf)
  309. {
  310. if ((rf->nr_idx == 0) || (rf->nr_idx > gw_info.max_index))
  311. return ACK_BAD_COMMAND;
  312. /* Prepare Timer & DMA. */
  313. dma_rdata.mar = (uint32_t)(unsigned long)dma.buf;
  314. dma_rdata.ndtr = ARRAY_SIZE(dma.buf);
  315. rdata_prep();
  316. tim_rdata->egr = TIM_EGR_UG; /* update CNT, PSC, ARR */
  317. tim_rdata->sr = 0; /* dummy write */
  318. /* DMA soft state. */
  319. dma.cons = 0;
  320. dma.prev_sample = tim_rdata->cnt;
  321. /* Start Timer. */
  322. tim_rdata->cr1 = TIM_CR1_CEN;
  323. index.count = 0;
  324. floppy_state = ST_read_flux;
  325. memset(&rw, 0, sizeof(rw));
  326. rw.nr_idx = rf->nr_idx;
  327. rw.start = time_now();
  328. rw.status = ACK_OKAY;
  329. return ACK_OKAY;
  330. }
  331. static void make_read_packet(unsigned int n)
  332. {
  333. unsigned int c = U_MASK(u_cons);
  334. unsigned int l = ARRAY_SIZE(u_buf) - c;
  335. if (l < n) {
  336. memcpy(rw.packet, &u_buf[c], l);
  337. memcpy(&rw.packet[l], u_buf, n-l);
  338. } else {
  339. memcpy(rw.packet, &u_buf[c], n);
  340. }
  341. u_cons += n;
  342. rw.packet_ready = TRUE;
  343. }
  344. static void floppy_read(void)
  345. {
  346. unsigned int avail = (uint32_t)(u_prod - u_cons);
  347. if (floppy_state == ST_read_flux) {
  348. rdata_encode_flux();
  349. avail = (uint32_t)(u_prod - u_cons);
  350. if (avail > sizeof(u_buf)) {
  351. /* Overflow */
  352. printk("OVERFLOW %u %u %u %u\n", u_cons, u_prod,
  353. rw.packet_ready, ep_tx_ready(EP_TX));
  354. floppy_flux_end();
  355. rw.status = ACK_FLUX_OVERFLOW;
  356. floppy_state = ST_read_flux_drain;
  357. u_cons = u_prod = avail = 0;
  358. } else if (rw.idx >= rw.nr_idx) {
  359. /* Read all requested revolutions. */
  360. floppy_flux_end();
  361. floppy_state = ST_read_flux_drain;
  362. } else if ((index.count == 0)
  363. && (time_since(rw.start) > time_ms(2000))) {
  364. /* Timeout */
  365. printk("NO INDEX\n");
  366. floppy_flux_end();
  367. rw.status = ACK_NO_INDEX;
  368. floppy_state = ST_read_flux_drain;
  369. u_cons = u_prod = avail = 0;
  370. }
  371. } else if ((avail < USB_FS_MPS)
  372. && !rw.packet_ready
  373. && ep_tx_ready(EP_TX)) {
  374. /* Final packet, including ACK byte (NUL). */
  375. memset(rw.packet, 0, USB_FS_MPS);
  376. make_read_packet(avail);
  377. floppy_state = ST_command_wait;
  378. floppy_end_command(rw.packet, avail+1);
  379. return; /* FINISHED */
  380. }
  381. if (!rw.packet_ready && (avail >= USB_FS_MPS))
  382. make_read_packet(USB_FS_MPS);
  383. if (rw.packet_ready && ep_tx_ready(EP_TX)) {
  384. usb_write(EP_TX, rw.packet, USB_FS_MPS);
  385. rw.packet_ready = FALSE;
  386. }
  387. }
  388. /*
  389. * WRITE PATH
  390. */
  391. static unsigned int _wdata_decode_flux(timcnt_t *tbuf, unsigned int nr)
  392. {
  393. unsigned int todo = nr;
  394. uint32_t x, ticks = rw.ticks_since_flux;
  395. if (todo == 0)
  396. return 0;
  397. if (rw.no_flux_area) {
  398. unsigned int nfa_pulse = sysclk_ns(1250);
  399. while (ticks >= nfa_pulse) {
  400. *tbuf++ = nfa_pulse - 1;
  401. ticks -= nfa_pulse;
  402. if (!--todo)
  403. goto out;
  404. }
  405. rw.no_flux_area = FALSE;
  406. }
  407. while (u_cons != u_prod) {
  408. x = u_buf[U_MASK(u_cons)];
  409. if (x == 0) {
  410. /* 0: Terminate */
  411. u_cons++;
  412. rw.write_finished = TRUE;
  413. goto out;
  414. } else if (x < 250) {
  415. /* 1-249: One byte */
  416. u_cons++;
  417. } else if (x < 255) {
  418. /* 250-254: Two bytes */
  419. if ((uint32_t)(u_prod - u_cons) < 2)
  420. goto out;
  421. u_cons++;
  422. x = (x - 249) * 250;
  423. x += u_buf[U_MASK(u_cons++)] - 1;
  424. } else {
  425. /* 255: Five bytes */
  426. if ((uint32_t)(u_prod - u_cons) < 5)
  427. goto out;
  428. u_cons++;
  429. x = (u_buf[U_MASK(u_cons++)] ) >> 1;
  430. x |= (u_buf[U_MASK(u_cons++)] & 0xfe) << 6;
  431. x |= (u_buf[U_MASK(u_cons++)] & 0xfe) << 13;
  432. x |= (u_buf[U_MASK(u_cons++)] & 0xfe) << 20;
  433. }
  434. ticks += x;
  435. if (ticks < sysclk_ns(800))
  436. continue;
  437. if (ticks > sysclk_us(150)) {
  438. rw.no_flux_area = TRUE;
  439. goto out;
  440. }
  441. *tbuf++ = ticks - 1;
  442. ticks = 0;
  443. if (!--todo)
  444. goto out;
  445. }
  446. out:
  447. rw.ticks_since_flux = ticks;
  448. return nr - todo;
  449. }
  450. static void wdata_decode_flux(void)
  451. {
  452. const uint16_t buf_mask = ARRAY_SIZE(dma.buf) - 1;
  453. uint16_t nr_to_wrap, nr_to_cons, nr, dmacons;
  454. /* Find out where the DMA engine's consumer index has got to. */
  455. dmacons = ARRAY_SIZE(dma.buf) - dma_wdata.ndtr;
  456. /* Find largest contiguous stretch of ring buffer we can fill. */
  457. nr_to_wrap = ARRAY_SIZE(dma.buf) - dma.prod;
  458. nr_to_cons = (dmacons - dma.prod - 1) & buf_mask;
  459. nr = min(nr_to_wrap, nr_to_cons);
  460. /* Now attempt to fill the contiguous stretch with flux data calculated
  461. * from buffered bitcell data. */
  462. dma.prod += _wdata_decode_flux(&dma.buf[dma.prod], nr);
  463. dma.prod &= buf_mask;
  464. }
  465. static void floppy_process_write_packet(void)
  466. {
  467. int len = ep_rx_ready(EP_RX);
  468. if ((len >= 0) && !rw.packet_ready) {
  469. usb_read(EP_RX, rw.packet, len);
  470. rw.packet_ready = TRUE;
  471. rw.packet_len = len;
  472. }
  473. if (rw.packet_ready) {
  474. unsigned int avail = ARRAY_SIZE(u_buf) - (uint32_t)(u_prod - u_cons);
  475. unsigned int n = rw.packet_len;
  476. if (avail >= n) {
  477. unsigned int p = U_MASK(u_prod);
  478. unsigned int l = ARRAY_SIZE(u_buf) - p;
  479. if (l < n) {
  480. memcpy(&u_buf[p], rw.packet, l);
  481. memcpy(u_buf, &rw.packet[l], n-l);
  482. } else {
  483. memcpy(&u_buf[p], rw.packet, n);
  484. }
  485. u_prod += n;
  486. rw.packet_ready = FALSE;
  487. }
  488. }
  489. }
  490. static uint8_t floppy_write_prep(struct gw_write_flux *wf)
  491. {
  492. if (get_wrprot() == LOW)
  493. return ACK_WRPROT;
  494. wdata_prep();
  495. /* WDATA DMA setup: From a circular buffer into the WDATA Timer's ARR. */
  496. dma_wdata.par = (uint32_t)(unsigned long)&tim_wdata->arr;
  497. dma_wdata.mar = (uint32_t)(unsigned long)dma.buf;
  498. /* Initialise DMA ring indexes (consumer index is implicit). */
  499. dma_wdata.ndtr = ARRAY_SIZE(dma.buf);
  500. dma.prod = 0;
  501. floppy_state = ST_write_flux_wait_data;
  502. memset(&rw, 0, sizeof(rw));
  503. rw.status = ACK_OKAY;
  504. index.delay = time_sysclk(wf->index_delay_ticks);
  505. rw.terminate_at_index = wf->terminate_at_index;
  506. return ACK_OKAY;
  507. }
  508. static void floppy_write_wait_data(void)
  509. {
  510. bool_t write_finished;
  511. floppy_process_write_packet();
  512. wdata_decode_flux();
  513. /* Wait for DMA and input buffers to fill, or write stream to end. We must
  514. * take care because, since we are not yet draining the DMA buffer, the
  515. * write stream may end without us noticing and setting rw.write_finished.
  516. * Hence we peek for a NUL byte in the input buffer if it's non-empty. */
  517. write_finished = ((u_prod == u_cons)
  518. ? rw.write_finished
  519. : (u_buf[U_MASK(u_prod-1)] == 0));
  520. if (((dma.prod != (ARRAY_SIZE(dma.buf)-1))
  521. || ((uint32_t)(u_prod - u_cons) < (ARRAY_SIZE(u_buf) - 512)))
  522. && !write_finished)
  523. return;
  524. floppy_state = ST_write_flux_wait_index;
  525. rw.start = time_now();
  526. /* Enable DMA only after flux values are generated. */
  527. dma_wdata_start();
  528. /* Preload timer with first flux value. */
  529. tim_wdata->egr = TIM_EGR_UG;
  530. tim_wdata->sr = 0; /* dummy write, gives h/w time to process EGR.UG=1 */
  531. barrier(); /* Trigger timer update /then/ wait for next index pulse */
  532. index.count = 0;
  533. }
  534. static void floppy_write_wait_index(void)
  535. {
  536. if (index.count == 0) {
  537. if (time_since(rw.start) > time_ms(2000)) {
  538. /* Timeout */
  539. floppy_flux_end();
  540. rw.status = ACK_NO_INDEX;
  541. floppy_state = ST_write_flux_drain;
  542. }
  543. return;
  544. }
  545. /* Start timer. */
  546. tim_wdata->cr1 = TIM_CR1_CEN;
  547. /* Enable output. */
  548. configure_pin(wdata, AFO_bus);
  549. write_pin(wgate, TRUE);
  550. index.count = 0;
  551. floppy_state = ST_write_flux;
  552. }
  553. static void floppy_write_check_underflow(void)
  554. {
  555. uint32_t avail = u_prod - u_cons;
  556. if (/* We've run the input buffer dry. */
  557. (avail == 0)
  558. /* The input buffer is nearly dry, and doesn't contain EOStream. */
  559. || ((avail < 16) && (u_buf[U_MASK(u_prod-1)] != 0))) {
  560. /* Underflow */
  561. printk("UNDERFLOW %u %u %u %u\n", u_cons, u_prod,
  562. rw.packet_ready, ep_rx_ready(EP_RX));
  563. floppy_flux_end();
  564. rw.status = ACK_FLUX_UNDERFLOW;
  565. floppy_state = ST_write_flux_drain;
  566. }
  567. }
  568. static void floppy_write(void)
  569. {
  570. uint16_t dmacons, todo, prev_todo;
  571. floppy_process_write_packet();
  572. wdata_decode_flux();
  573. /* Early termination on index pulse? */
  574. if (rw.terminate_at_index && (index.count != 0))
  575. goto terminate;
  576. if (!rw.write_finished) {
  577. floppy_write_check_underflow();
  578. return;
  579. }
  580. /* Wait for DMA ring to drain. */
  581. todo = ~0;
  582. do {
  583. /* Check for early termination on index pulse. */
  584. if (rw.terminate_at_index && (index.count != 0))
  585. goto terminate;
  586. /* Check progress of draining the DMA ring. */
  587. prev_todo = todo;
  588. dmacons = ARRAY_SIZE(dma.buf) - dma_wdata.ndtr;
  589. todo = (dma.prod - dmacons) & (ARRAY_SIZE(dma.buf) - 1);
  590. } while ((todo != 0) && (todo <= prev_todo));
  591. terminate:
  592. floppy_flux_end();
  593. floppy_state = ST_write_flux_drain;
  594. }
  595. static void floppy_write_drain(void)
  596. {
  597. /* Drain the write stream. */
  598. if (!rw.write_finished) {
  599. floppy_process_write_packet();
  600. (void)_wdata_decode_flux(dma.buf, ARRAY_SIZE(dma.buf));
  601. return;
  602. }
  603. /* Wait for space to write ACK packet. */
  604. if (!ep_tx_ready(EP_TX))
  605. return;
  606. /* ACK with Status byte. */
  607. u_buf[0] = rw.status;
  608. floppy_state = ST_command_wait;
  609. floppy_end_command(u_buf, 1);
  610. /* Reset INDEX handling. */
  611. IRQ_global_disable();
  612. index.delay = 0;
  613. IRQx_clear_pending(irq_index_delay);
  614. timer_cancel(&index.delay_timer);
  615. IRQ_global_enable();
  616. }
  617. static void process_command(void)
  618. {
  619. uint8_t cmd = u_buf[0];
  620. uint8_t len = u_buf[1];
  621. uint8_t resp_sz = 2;
  622. auto_off_arm();
  623. switch (cmd) {
  624. case CMD_GET_INFO: {
  625. uint8_t idx = u_buf[2];
  626. if ((len != 3) || (idx != 0))
  627. goto bad_command;
  628. memset(&u_buf[2], 0, 32);
  629. gw_info.fw_major = fw_major;
  630. gw_info.fw_minor = fw_minor;
  631. memcpy(&u_buf[2], &gw_info, sizeof(gw_info));
  632. resp_sz += 32;
  633. break;
  634. }
  635. case CMD_SEEK: {
  636. uint8_t cyl = u_buf[2];
  637. if ((len != 3) || (cyl > 85))
  638. goto bad_command;
  639. u_buf[1] = floppy_seek(cyl) ? ACK_OKAY : ACK_NO_TRK0;
  640. goto out;
  641. }
  642. case CMD_SIDE: {
  643. uint8_t side = u_buf[2];
  644. if ((len != 3) || (side > 1))
  645. goto bad_command;
  646. write_pin(side, side);
  647. break;
  648. }
  649. case CMD_SET_PARAMS: {
  650. uint8_t idx = u_buf[2];
  651. if ((len < 3) || (idx != PARAMS_DELAYS)
  652. || (len > (3 + sizeof(delay_params))))
  653. goto bad_command;
  654. memcpy(&delay_params, &u_buf[3], len-3);
  655. break;
  656. }
  657. case CMD_GET_PARAMS: {
  658. uint8_t idx = u_buf[2];
  659. uint8_t nr = u_buf[3];
  660. if ((len != 4) || (idx != PARAMS_DELAYS)
  661. || (nr > sizeof(delay_params)))
  662. goto bad_command;
  663. memcpy(&u_buf[2], &delay_params, nr);
  664. resp_sz += nr;
  665. break;
  666. }
  667. case CMD_MOTOR: {
  668. uint8_t mask = u_buf[2];
  669. if ((len != 3) || (mask & ~1))
  670. goto bad_command;
  671. drive_motor(mask & 1);
  672. break;
  673. }
  674. case CMD_READ_FLUX: {
  675. struct gw_read_flux rf = { .nr_idx = 2 };
  676. if ((len < 2) || (len > (2 + sizeof(rf))))
  677. goto bad_command;
  678. memcpy(&rf, &u_buf[2], len-2);
  679. u_buf[1] = floppy_read_prep(&rf);
  680. goto out;
  681. }
  682. case CMD_WRITE_FLUX: {
  683. struct gw_write_flux wf = { 0 };
  684. if ((len < 2) || (len > (2 + sizeof(wf))))
  685. goto bad_command;
  686. memcpy(&wf, &u_buf[2], len-2);
  687. u_buf[1] = floppy_write_prep(&wf);
  688. goto out;
  689. }
  690. case CMD_GET_FLUX_STATUS: {
  691. if (len != 2)
  692. goto bad_command;
  693. u_buf[1] = rw.status;
  694. goto out;
  695. }
  696. case CMD_GET_INDEX_TIMES: {
  697. uint8_t f = u_buf[2], n = u_buf[3];
  698. if ((len != 4) || (n > 15) || ((f+n) > gw_info.max_index))
  699. goto bad_command;
  700. memcpy(&u_buf[2], rw.index_ticks+f, n*4);
  701. resp_sz += n*4;
  702. break;
  703. }
  704. case CMD_SELECT: {
  705. uint8_t mask = u_buf[2];
  706. if ((len != 3) || (mask & ~1))
  707. goto bad_command;
  708. drive_select(mask & 1);
  709. break;
  710. }
  711. case CMD_SWITCH_FW_MODE: {
  712. uint8_t mode = u_buf[2];
  713. if ((len != 3) || (mode & ~1))
  714. goto bad_command;
  715. if (mode == FW_MODE_BOOTLOADER) {
  716. usb_deinit();
  717. delay_ms(500);
  718. /* Poke a flag in SRAM1, picked up by the bootloader. */
  719. *(volatile uint32_t *)0x20010000 = 0xdeadbeef;
  720. system_reset();
  721. }
  722. break;
  723. }
  724. default:
  725. goto bad_command;
  726. }
  727. u_buf[1] = ACK_OKAY;
  728. out:
  729. floppy_end_command(u_buf, resp_sz);
  730. return;
  731. bad_command:
  732. u_buf[1] = ACK_BAD_COMMAND;
  733. goto out;
  734. }
  735. static void floppy_configure(void)
  736. {
  737. auto_off_arm();
  738. floppy_flux_end();
  739. floppy_state = ST_command_wait;
  740. u_cons = u_prod = 0;
  741. }
  742. void floppy_process(void)
  743. {
  744. int len;
  745. if (auto_off.armed && (time_since(auto_off.deadline) >= 0)) {
  746. floppy_flux_end();
  747. drive_motor(FALSE);
  748. drive_select(FALSE);
  749. auto_off.armed = FALSE;
  750. }
  751. switch (floppy_state) {
  752. case ST_command_wait:
  753. len = ep_rx_ready(EP_RX);
  754. if ((len >= 0) && (len < (sizeof(u_buf)-u_prod))) {
  755. usb_read(EP_RX, &u_buf[u_prod], len);
  756. u_prod += len;
  757. }
  758. if ((u_prod >= 2) && (u_prod >= u_buf[1]) && ep_tx_ready(EP_TX)) {
  759. process_command();
  760. }
  761. break;
  762. case ST_zlp:
  763. if (ep_tx_ready(EP_TX)) {
  764. usb_write(EP_TX, NULL, 0);
  765. floppy_state = ST_command_wait;
  766. }
  767. break;
  768. case ST_read_flux:
  769. case ST_read_flux_drain:
  770. floppy_read();
  771. break;
  772. case ST_write_flux_wait_data:
  773. floppy_write_wait_data();
  774. break;
  775. case ST_write_flux_wait_index:
  776. floppy_write_wait_index();
  777. break;
  778. case ST_write_flux:
  779. floppy_write();
  780. break;
  781. case ST_write_flux_drain:
  782. floppy_write_drain();
  783. break;
  784. default:
  785. break;
  786. }
  787. }
  788. const struct usb_class_ops usb_cdc_acm_ops = {
  789. .reset = floppy_reset,
  790. .configure = floppy_configure
  791. };
  792. /*
  793. * INTERRUPT HANDLERS
  794. */
  795. static void index_delay_timer(void *unused)
  796. {
  797. index.count++;
  798. }
  799. static void IRQ_INDEX_delay(void)
  800. {
  801. timer_set(&index.delay_timer, index.timestamp + index.delay);
  802. }
  803. static void IRQ_INDEX_changed(void)
  804. {
  805. /* Clear INDEX-changed flag. */
  806. exti->pr = m(pin_index);
  807. index.rdata_cnt = tim_rdata->cnt;
  808. index.timestamp = time_now();
  809. if (index.delay != 0) {
  810. IRQx_set_pending(irq_index_delay);
  811. } else {
  812. index.count++;
  813. }
  814. }
  815. /*
  816. * Local variables:
  817. * mode: C
  818. * c-file-style: "Linux"
  819. * c-basic-offset: 4
  820. * tab-width: 4
  821. * indent-tabs-mode: nil
  822. * End:
  823. */