Beispiel #1
0
static int
fd_intr(void *arg)
{
	struct fd_softc *sc = arg;

	sc->fd_intrcnt.ev_count++;
	fd_reset(sc);
	return 0;
}
Beispiel #2
0
void
fd_attach(device_t parent, device_t self, void *aux)
{
        struct fd_softc *sc = device_private(self);
	struct confargs *ca = aux;

	sc->fd_bst = ca->ca_bustag;
	if (bus_space_map(ca->ca_bustag, ca->ca_addr,
			  0x1000000,	
			  BUS_SPACE_MAP_LINEAR,
			  &sc->fd_bsh) != 0) {
		printf("%s: cannot map registers\n", device_xname(self));
		return;
	}
	evcnt_attach_dynamic(&sc->fd_intrcnt, EVCNT_TYPE_INTR, NULL,
			     device_xname(self), "intr");

	bus_intr_establish(sc->fd_bst, SYS_INTR_FDC, 0, 0, fd_intr, sc);

	fd_reset(sc);
	printf(": not fully implemented\n");
}
Beispiel #3
0
int main()
{
  char  buffer[80];
  char* data;
  uint16_t value;
  uint8_t cmd;

	// wait
	_delay_ms( 100 );
	USART_init();

  FD_DDR |= FD_DIR|FD_STEP;
  // STATUS_DDR |= STATUS_LED; 

  fd_reset();
  _delay_ms(100);

  // print welcome 
  USART_writeln( "100 Fl0ppy Music 0.1.1 (c) 2013 Matthias Hannig" );

  // checkout leds...
  hc4094_init();

  
  hc4094_write( 0xff );
  hc4094_write( 0b01111111 );
  hc4094_strobe();

  hc4094_output(1);

 
  // setup timer
  TCCR1A = 0;
  TCCR1B = (1<<WGM12)|(1<<CS12)|(1<<CS10); // Clear on match, Prescale: 1024
  // TCCR1B = (1<<CS12)|(1<<CS10); // Clear on 0xffff, Prescale: 1024
  // TCCR1B = (1<<CS12); // Clear on 0xffff, Prescale: 256

  sei();

  uint8_t leds = 0;
  uint16_t pos = 0;


	for(;;) {

    hc4094_write( ~(1<<leds) );
    hc4094_strobe();
    
    // play imperial march
    if( imperial_tones_seq[pos] == 255 ) {
      pos = 0;
      continue;
    }    
    
    if( imperial_tones_seq[pos] == 0 ) {
      fd_stop();
    }
    else {
      fd_play();
    }

    // Wedding mode. 
    // There was no time left for everything else. *sigh*
    fd_set_tone( imperial_tones_seq[pos] );
    wait_ms( imperial_delay_seq[pos] );

    pos++;
    leds++;

    if( leds > 8 ) {
      leds = 1;
    } 
    

    // Default serial interface
    /* 
    
		cli();
		data = USART_has_data();
		if( data != NULL ) {
			// parse and process data
      memset( buffer, 0, 80 );
     
			strncpy( buffer, data, 3 );
			cmd = atoi( buffer );

			strncpy( buffer, data+3, 80 );
			value = atoi( buffer );

			switch( cmd ) {
				case 100:
					USART_writeln( "100 Fl0ppy Music 0.1.1 (c) 2013 Matthias Hannig" );
					break;
			
        // set tone
				case 200:
          if( value > 0 ) {
            fd_play();
          }
          else {
            fd_stop();
          }

          fd_set_tone( value );
  
          leds++;

          if( leds > 8 ) {
            leds = 0;
          }

          hc4094_write( ~(1<<leds) );
          hc4094_strobe();
      
					break;
			}

		}
		sei();
    */
	}	
}
Beispiel #4
0
static int fd_transfer(uint8_t minor, bool is_read, uint8_t rawflag)
{
    uint16_t nb = 0;
    int tries;
    uint8_t err = 0;
    uint8_t *driveptr = &fd_tab[minor & 1];
    irqflags_t irq;

    if(rawflag == 1 && d_blkoff(BLKSHIFT))
        return -1;

    udata.u_nblock *= 2;

    if (rawflag == 2)
        goto bad2;

    irq = di();
    if (fd_selected != minor) {
        uint8_t err = fd_motor_on(minor|(minor > 1 ? 0: 0x10));
        if (err)
            goto bad;
        motorct = 150;	/* 3 seconds */
    }
    irqrestore(irq);


//    kprintf("Issue command: %c drive %d block %d for %d\n", "wr"[is_read], minor, udata.u_block, udata.u_nblock);
    fd_cmd[0] = rawflag;
    fd_cmd[1] = is_read ? FD_READ : FD_WRITE;

    /* There are 16 256 byte sectors for DSDD. These are organised so that we
       switch head then step.

       Sectors 0-15 (our block 0-7)	Track 0, side 0
       Sectors 16-31 (our block 8-15)	Track 0, side 1

       etc */
    fd_cmd[2] = udata.u_block / 16;		/* Get the track we need */
    fd_cmd[3] = ((udata.u_block & 15) << 1);    /* 0 - 1 base is corrected in asm */
    fd_cmd[4] = is_read ? OPDIR_READ: OPDIR_WRITE;

    fd_data = (uint16_t)udata.u_dptr;

    while (udata.u_nblock--) {
        for (tries = 0; tries < 4 ; tries++) {
//            kprintf("Sector: %d Head: %d Track %d\n", (fd_cmd[3]&15)+1, fd_cmd[3]>>4, fd_cmd[2]);
            err = fd_operation(driveptr);
            if (err == 0)
                break;
            if (tries > 1)
                fd_reset(driveptr);
        }
        /* FIXME: should we try the other half and then bale out ? */
        if (tries == 3)
            goto bad;
        fd_data += 256;
        fd_cmd[3]++;	/* Next sector for next block */
        if (fd_cmd[3] == 32) {	/* Next track */
            fd_cmd[3] = 0;
            fd_cmd[2]++;
        }
        nb++;
    }
    return nb << (BLKSHIFT - 1);
bad:
    kprintf("fd%d: error %x\n", minor, err);
bad2:
    udata.u_error = EIO;
    return -1;
}
Beispiel #5
0
static int fd_transfer(uint8_t minor, bool is_read, uint8_t rawflag)
{
    int8_t tries;
    uint8_t err = 0;
    uint8_t drive = minor & 3;
    uint8_t trackno, sector;
    uint8_t large = !(minor & 0x10);
    const uint8_t *skew = skewtab[large];		/* skew table */

    if(rawflag == 2)
        goto bad2;

    fd_map = rawflag;
    if (rawflag && d_blkoff(BLKSHIFT))
            return -1;


    /* Command to go to the controller after any seek is done */
    fd_cmd[0] = is_read ? FD_READ : FD_WRITE;
    /* Control byte: autowait, DD, motor, 5", drive bit */
    fd_cmd[1] = 0xE0 | selmap[drive];
    if (large)
        fd_cmd[1] = 0x10;	/* turn on 8" bit */
    /* Directon of xfer */
    fd_cmd[2] = is_read ? OPDIR_READ: OPDIR_WRITE;
    fd_cmd[5] = 0x10 | delay[drive];

    /*
     *	Restore the track register to match this drive
     */
    if (track[drive] != 0xFF)
        fd_track = track[drive];
    else
        fd_reset();

    /*
     *	Begin transfers
     */
    while (udata.u_done < udata.u_nblock) {
        /* Need to consider SS v DS here */
        if (large) {
            fd_aux = 0x4C | (udata.u_block & 16) ? 2 : 0;
            trackno = udata.u_block / 32;
            sector = udata.u_block % 16;
        } else {
            trackno = udata.u_block / 20;
            sector = udata.u_block % 20;
            if (sector > 9) {
                sector -= 10;
                fd_aux = 0x5E;	/* side 1 */
            } else
                fd_aux = 0x5C;
        }
        /* Buffer */
        fd_cmd[3] = ((uint16_t)udata.u_dptr) & 0xFF;
        fd_cmd[4] = ((uint16_t)udata.u_dptr) >> 8;

        for (tries = 0; tries < 4 ; tries++) {
            (void)fd_data;
            fd_sector = skew[sector];	/* Also makes 1 based */
            if (fd_track != trackno) {
                fd_data = trackno;
                if (fd_seek()) {
                    fd_reset();
                    continue;
                }
            }
            /* Do the read or write */
            err = fd_operation();
            if (err == 0)
                break;
            /* Try and recover */
            if (tries > 1)
                fd_reset();
        }
        if (tries == 4)
            goto bad;
        udata.u_block++;
        udata.u_done++;
    }
    /* Save the track */
    track[drive] = fd_track;
    return udata.u_done << 9;
bad:
    track[drive] = fd_track;
    kprintf("fd%d: error %x\n", minor, err);
bad2:
    udata.u_error = EIO;
    return -1;
}