Per Mårtensson 4 months ago
parent
commit
2da7406a00
8 changed files with 28 additions and 34 deletions
  1. 7 0
      RELEASE_NOTES
  2. 2 2
      inc/cdc_acm_protocol.h
  3. 2 0
      inc/intrinsics.h
  4. 1 0
      inc/util.h
  5. 1 2
      src/board.c
  6. 10 24
      src/floppy.c
  7. 3 4
      src/usb/hw_dwc_otg.c
  8. 2 2
      src/usb/hw_f7.c

+ 7 - 0
RELEASE_NOTES

@@ -3,6 +3,13 @@
 ** Keir Fraser <keir.xen@gmail.com>
 ************************************
 
+** v1.6 - 28 September 2024
+ - Flux write: Whole-track writes to hard-sectored disks
+ - Pre- and post-write delays: Specified by many drive datasheets
+   - Required for correct interaction with offset tunnel-erase heads
+ - Configurable "Index Mask", for debouncing noisy INDEX signals
+ - Seek (HDD): Remove arbitrary 100-cylinder limit
+
 ** v1.5 - 19 December 2023
  - AT32F403(A): Extend SRAM from 96kB to 224kB
  - Report USB buffer size in 'gw info'

+ 2 - 2
inc/cdc_acm_protocol.h

@@ -145,7 +145,7 @@
  *  Generate regular flux transitions at specified astable period. 
  *  Duration is specified by immediately preceding FLUXOP_SPACE opcode(s). */
 #define FLUXOP_ASTABLE    3
-#define FLUXOP_HARD_INDEX      4
+
 
 /*
  * COMMAND PACKETS
@@ -205,7 +205,7 @@ struct packed gw_write_flux {
     uint8_t cue_at_index;
     /* If non-zero, terminate the write at the next index pulse. */
     uint8_t terminate_at_index;
-        /** OPTIONAL FIELDS: **/
+    /** OPTIONAL FIELDS: **/
     /* Hard sector time, in ticks. Used to find first sector and to trigger
      * cue_at_index and terminate_at_index, if they are enabled. */
     uint32_t hard_sector_ticks; /* default: 0 (disabled) */

+ 2 - 0
inc/intrinsics.h

@@ -27,6 +27,8 @@ struct exception_frame {
 #define likely(x)     __builtin_expect(!!(x),1)
 #define unlikely(x)   __builtin_expect(!!(x),0)
 
+#define unreachable() do { ASSERT(0); __builtin_unreachable(); } while (0)
+
 #define illegal() asm volatile (".short 0xde00");
 
 #define barrier() asm volatile ("" ::: "memory")

+ 1 - 0
inc/util.h

@@ -80,6 +80,7 @@ uint32_t udiv64(uint64_t dividend, uint32_t divisor);
 void board_init(void);
 void act_led(bool_t on);
 void act_led2(bool_t on);
+
 #ifndef NDEBUG
 
 /* Serial console control */

+ 1 - 2
src/board.c

@@ -26,8 +26,7 @@ GPIO gpio_from_id(uint8_t id)
     case _I: return gpioi;
 #endif
     }
-    ASSERT(0);
-    return NULL;
+    unreachable();
 }
 
 uint8_t write_mapped_pin(

+ 10 - 24
src/floppy.c

@@ -42,7 +42,6 @@ static struct {
 
 static int bus_type = -1;
 static int unit_nr = -1;
-
 static struct unit {
     int cyl;
     bool_t initialised;
@@ -84,8 +83,6 @@ static struct index {
     time_t trigger_time;
     /* Timer structure for index_timer() calls. */
     struct timer timer;
-    volatile time_t prev;
-    volatile unsigned int hard_count;
 } index;
 
 /* Timer to clean up stale index.trigger_time. */
@@ -396,6 +393,7 @@ static void step_dir_set(bool_t assert)
 }
 #define step_dir_out() step_dir_set(FALSE)
 #define step_dir_in() step_dir_set(TRUE)
+
 #if MCU == STM32F8
 static void get_tg43_info(void){
 }
@@ -450,9 +448,8 @@ static uint8_t floppy_seek_initialise(struct unit *u)
     /* Synchronise to cylinder 0. */
     step_dir_out();
     for (nr = 0; nr < 256; nr++) {
-        if (get_trk0() == LOW){
+        if (get_trk0() == LOW)
             goto found_cyl0;
-        }
         step_once();
     }
 
@@ -504,9 +501,9 @@ static uint8_t floppy_seek(int cyl)
         return ACK_NO_UNIT;
     u = &unit[unit_nr];
 
-     op_delay_wait(DELAY_seek);
-     
-     if (!u->initialised) {
+    op_delay_wait(DELAY_seek);
+
+    if (!u->initialised) {
         uint8_t rc = floppy_seek_initialise(u);
         if (rc != ACK_OKAY)
             return rc;
@@ -539,6 +536,7 @@ static uint8_t floppy_seek(int cyl)
     op_delay_async(DELAY_read | DELAY_write | DELAY_seek,
                    delay_params.seek_settle * 1000u);
     u->cyl = cyl;
+
 #if MCU == STM32F7
     get_tg43_info();
 #endif
@@ -584,7 +582,6 @@ static void index_set_hard_sector_detection(uint32_t hard_sector_ticks)
 static void floppy_flux_end(void)
 {
     /* Turn off write pins. */
-  
     if (read_pin(wgate)) {
         write_pin(wgate, FALSE);
         configure_pin(wdata, GPO_bus);
@@ -761,7 +758,6 @@ static struct {
     unsigned int max_index;
     uint32_t max_index_linger;
     time_t deadline;
-     unsigned int hard_nr_index;
 } read;
 
 static void _write_28bit(uint32_t x)
@@ -789,7 +785,6 @@ static void rdata_encode_flux(void)
         /* We have just passed the index mark: Record information about 
          * the just-completed revolution. */
         read.nr_index = index.count;
-        read.hard_nr_index=0;
         ticks = (timcnt_t)(index.rdata_cnt - prev);
         IRQ_global_enable(); /* we're done reading ISR variables */
         u_buf[U_MASK(u_prod++)] = 0xff;
@@ -799,16 +794,7 @@ static void rdata_encode_flux(void)
          * pulses).  */
         watchdog_kick();
     }
-    //Fake index 2407
-    /*
-    if (read.hard_nr_index != index.hard_count) {
-        read.hard_nr_index = index.hard_count;
-        if (read.hard_nr_index!=0){
-            u_buf[U_MASK(u_prod++)] = 0xff;
-            u_buf[U_MASK(u_prod++)] = FLUXOP_HARD_INDEX;
-        }
-    }
-    */
+
     IRQ_global_enable();
 
     /* Process the flux timings into the raw bitcell buffer. */
@@ -861,6 +847,7 @@ static void rdata_encode_flux(void)
 static uint8_t floppy_read_prep(const struct gw_read_flux *rf)
 {
     op_delay_wait(DELAY_read);
+
     /* Prepare Timer & DMA. */
     dma_rdata.mar = (uint32_t)(unsigned long)dma.buf;
     dma_rdata.ndtr = ARRAY_SIZE(dma.buf);    
@@ -874,7 +861,6 @@ static uint8_t floppy_read_prep(const struct gw_read_flux *rf)
     tim_rdata->cr1 = TIM_CR1_CEN;
 
     index.count = 0;
-    index.hard_count = 0; //Per 2407
     usb_packet.ready = FALSE;
 
     floppy_state = ST_read_flux;
@@ -1238,6 +1224,7 @@ static void floppy_write_wait_data(void)
          || ((uint32_t)(u_prod - u_cons) < u_buf_threshold))
         && !write_finished)
         return;
+
     op_delay_wait(DELAY_write);
 
     floppy_state = ST_write_flux_wait_index;
@@ -1641,7 +1628,6 @@ static void process_command(void)
         uint8_t head = u_buf[2];
         if ((len != 3) || (head > 1))
             goto bad_command;
-
         if (read_pin(head) != head) {
             op_delay_wait(DELAY_head);
             write_pin(head, head);
@@ -1947,7 +1933,7 @@ static void index_timer(void *unused)
     /* index.trigger_time mustn't get so old that the time_diff() test in
      * IRQ_INDEX_changed() overflows. To prevent this, we ensure that,
      * at all times,
-     *   time_diff(index.isr_time, time_now()) < 2*INDEX_TIMER_PERIOD + delta,
+     *   time_diff(index.trigger_time, now) < 2*INDEX_TIMER_PERIOD + delta,
      * where delta is small. */
     if (time_diff(index.trigger_time, now) > INDEX_TIMER_PERIOD)
         index.trigger_time = now - INDEX_TIMER_PERIOD;

+ 3 - 4
src/usb/hw_dwc_otg.c

@@ -287,7 +287,7 @@ static void dwc_otg_configure_ep(uint8_t epnr, uint8_t type, uint32_t size)
              * Check we aren't trying to map it to multiple endpoints. */
             ep->rx = NULL;
             for (i = 0; i < conf_nr_ep; i++)
-                ASSERT(ep->rx != rx_bufn);
+                ASSERT(eps[i].rx != rx_bufn);
             ep->rx = rx_bufn;
             ep->rx_nr = ARRAY_SIZE(rx_bufn);
         }
@@ -410,9 +410,8 @@ static void handle_iepint(uint8_t epnr)
             handle_tx_ep0();
     }
 
-    if (iepint & OTG_DIEPINT_TXFE) {
-        ASSERT(0);
-    }
+    /* We don't set DIEPEMPMSK bits so TXFE notification is impossible. */
+    ASSERT(!(iepint & OTG_DIEPINT_TXFE));
 }
 
 static void dwc_otg_process(void)

+ 2 - 2
src/usb/hw_f7.c

@@ -65,7 +65,7 @@ void hw_usb_init(void)
         }
         break;
     default:
-        ASSERT(0);
+        unreachable();
     }
 
     peripheral_clock_delay();
@@ -109,7 +109,7 @@ void hw_usb_deinit(void)
         rcc->ahb1enr &= ~RCC_AHB1ENR_OTGHSEN;
         break;
     default:
-        ASSERT(0);
+        unreachable();
     }
 }