Пример #1
0
void v_hook_spiral(void) {
 h_pos = 0;
 pal_mutex = 1;
 do_dma(DMA_68K, DMA_DST_VRAM, (u32 *)hscroll_buf, 0xfc00, 0x380);
 if(sprite_ram_mutex == 1) {
  do_dma(DMA_68K, DMA_DST_VRAM, (u32 *)sprite_ram, SPRITE_BASE, 80);
 sprite_ram_mutex = 0;
 }  
 pal_mutex = 0;
}
Пример #2
0
/*
 * drain_dma_poll - Drain all outstanding DMA operations for a particular
 * DMA channel via polling.
 * @chan - DMA channel
 * Return 0 on success and -errno on error.
 */
int drain_dma_poll(struct dma_channel *chan)
{
	int cookie, err;
	unsigned long ts;

	if (chan) {
		if ((err = request_dma_channel(chan)))
			goto error;
		if ((cookie = do_dma(chan,
			DO_DMA_POLLING, 0, 0, 0, NULL)) < 0) {
			err = cookie;
			free_dma_channel(chan);
			goto error;
		}
		free_dma_channel(chan);
		ts = jiffies;
		while (1 != poll_dma_completion(cookie, chan)) {
			cpu_relax();
			if (time_after(jiffies,ts + DMA_TO)) {
				err = -EBUSY;
				break;
			}
		}
error:
		if (err)
			printk(KERN_ERR "%s %d err %d\n", __func__, __LINE__, err);
	} else {
		err = -EINVAL;
	}
	return err;
}
Пример #3
0
void snesc_vblank(void)
{
  /* stuff pending for DMA? */
  unsigned char do_flags = snesc_do_copy;
  if(do_flags) {
    snesc_do_copy = 0;
    do_dma(do_flags);
    do_flags &= 0x3f;	/* mask out palette and sprite flags (used by do_dma) */
    if (do_flags) {
      int x = 0;
      while (do_flags) {
        switch(snesc_dma_transfers[x].src.c.type) {	/* type of transfer */
        case 0:	/* VRAM */
          *((unsigned short*)0x4300) = 0x1801;	/* 2 regs write once, Bus B addr $2118 (VRAM data write) */
          *((unsigned short*)0x2116) = snesc_dma_transfers[x].dest;	/* VRAM address */
          break;
        case 1:	/* OAM */
          *((unsigned short*)0x4300) = 0x400;	/* DMA OAM write */
          *((unsigned short*)0x2102) = snesc_dma_transfers[x].dest;	/* OAM address */
          break;
        case 2:	/* CGRAM */
          *((unsigned short*)0x4300) = 0x2200;	/* CGRAM write */
          *((unsigned char*)0x2121) = snesc_dma_transfers[x].dest;	/* CGRAM address (trunc'd to 8 bits) */
          break;
        }
        *((unsigned short*)0x4302) = snesc_dma_transfers[x].src.c.addr;	/* DMA source address (16-bit) */
        *((unsigned short*)0x4305) = snesc_dma_transfers[x].size;	/* DMA size */
        *((unsigned char*)0x4304) = snesc_dma_transfers[x].src.c.bank;	/* DMA source address (bank) */
        *((unsigned char*)0x420b) = 1;	/* enable DMA 0 */
        x++;
        do_flags--;
      }
    }
  }

  while(*((unsigned char*)0x4212) & 1) {}
  
  /* update input buffers */
  unsigned int pad;
  for(pad = 0; pad < 4 ; pad++) {
    snesc_controllers[pad] |= ((unsigned short*)0x4218)[pad];
  }
  
  /* timer ticks */
  unsigned char timers_enabled = snesc_timer_enabled;
  unsigned int tc = 0;
  while(timers_enabled & 1) {
    snesc_timers[tc]++;
    tc++;
    timers_enabled >>= 1;
  }
}
Пример #4
0
void AiLenChanged(usf_state_t *state) {
	unsigned int duration = get_dma_duration(state);

	if (AI_STATUS_REG & AI_STATUS_BUSY) {
		state->fifo[1].address = AI_DRAM_ADDR_REG;
		state->fifo[1].length = AI_LEN_REG;
		state->fifo[1].duration = duration;

		if (state->enableFIFOfull)
			AI_STATUS_REG |= AI_STATUS_FULL;
		else
			do_dma(state, &state->fifo[1]);
	}
	else {
		state->fifo[0].address = AI_DRAM_ADDR_REG;
		state->fifo[0].length = AI_LEN_REG;
		state->fifo[0].duration = duration;
		AI_STATUS_REG |= AI_STATUS_BUSY;

		do_dma(state, &state->fifo[0]);
	}
}
Пример #5
0
void AiTimerDone(usf_state_t *state) {
	if (AI_STATUS_REG & AI_STATUS_FULL) {
		state->fifo[0].address  = state->fifo[1].address;
		state->fifo[0].length   = state->fifo[1].length;
		state->fifo[0].duration = state->fifo[1].duration;
		AI_STATUS_REG &= ~AI_STATUS_FULL;

		do_dma(state, &state->fifo[0]);
	}
	else {
		AI_STATUS_REG &= ~AI_STATUS_BUSY;
	}
}
Пример #6
0
void v_bottom_test2(void) {
 scanline = 0;
 if(sprite_ram_mutex == 1) {
  do_dma(DMA_68K, DMA_DST_VRAM, (u32 *)sprite_ram, SPRITE_BASE,  80*8);
  sprite_ram_mutex = 0; 
 } 
 theta++;
 if(theta == 0)
  theta = 1;
 if(theta==0xff)
  theta = 1;


 looper++;
}
static void fifo_pop(struct ai_controller* ai)
{
   if (ai->regs[AI_STATUS_REG] & AI_STATUS_FULL)
   {
      ai->fifo[0].address  = ai->fifo[1].address;
      ai->fifo[0].length   = ai->fifo[1].length;
      ai->fifo[0].duration = ai->fifo[1].duration;
      ai->regs[AI_STATUS_REG] &= ~AI_STATUS_FULL;

      do_dma(ai, &ai->fifo[0]);
   }
   else
   {
      ai->regs[AI_STATUS_REG] &= ~AI_STATUS_BUSY;
   }
}
Пример #8
0
static void fifo_push(struct ai_controller* ai)
{
    unsigned int duration = get_dma_duration(ai);

    if (ai->regs[AI_STATUS_REG] & AI_STATUS_BUSY)
    {
        ai->fifo[1].address = ai->regs[AI_DRAM_ADDR_REG];
        ai->fifo[1].length = ai->regs[AI_LEN_REG];
        ai->fifo[1].duration = duration;
        ai->regs[AI_STATUS_REG] |= AI_STATUS_FULL;
    }
    else
    {
        ai->fifo[0].address = ai->regs[AI_DRAM_ADDR_REG];
        ai->fifo[0].length = ai->regs[AI_LEN_REG];
        ai->fifo[0].duration = duration;
        ai->regs[AI_STATUS_REG] |= AI_STATUS_BUSY;

        do_dma(ai, &ai->fifo[0]);
    }
}
Пример #9
0
static int sscape_download_boot(struct sscape_info *devc, unsigned char *block, int size, int flag)
{
	unsigned long flags;
	unsigned char temp;
	volatile int done, timeout_val;
	static unsigned char codec_dma_bits = 0;

	if (flag & CPF_FIRST)
	{
		/*
		 * First block. Have to allocate DMA and to reset the board
		 * before continuing.
		 */

		save_flags(flags);
		cli();
		codec_dma_bits = sscape_read(devc, GA_CDCFG_REG);

		if (devc->dma_allocated == 0)
			devc->dma_allocated = 1;

		restore_flags(flags);

		sscape_write(devc, GA_HMCTL_REG, 
			(temp = sscape_read(devc, GA_HMCTL_REG)) & 0x3f);	/*Reset */

		for (timeout_val = 10000; timeout_val > 0; timeout_val--)
			sscape_read(devc, GA_HMCTL_REG);	/* Delay */

		/* Take board out of reset */
		sscape_write(devc, GA_HMCTL_REG,
			(temp = sscape_read(devc, GA_HMCTL_REG)) | 0x80);
	}
	/*
	 * Transfer one code block using DMA
	 */
	if (audio_devs[devc->codec_audiodev]->dmap_out->raw_buf == NULL)
	{
		printk(KERN_WARNING "soundscape: DMA buffer not available\n");
		return 0;
	}
	memcpy(audio_devs[devc->codec_audiodev]->dmap_out->raw_buf, block, size);

	save_flags(flags);
	cli();
	
	/******** INTERRUPTS DISABLED NOW ********/
	
	do_dma(devc, SSCAPE_DMA_A,
	       audio_devs[devc->codec_audiodev]->dmap_out->raw_buf_phys,
	       size, DMA_MODE_WRITE);

	/*
	 * Wait until transfer completes.
	 */
	
	done = 0;
	timeout_val = 30;
	while (!done && timeout_val-- > 0)
	{
		int resid;

		if (HZ / 50)
			sleep(HZ / 50);
		clear_dma_ff(devc->dma);
		if ((resid = get_dma_residue(devc->dma)) == 0)
			done = 1;
	}

	restore_flags(flags);
	if (!done)
		return 0;

	if (flag & CPF_LAST)
	{
		/*
		 * Take the board out of reset
		 */
		outb((0x00), PORT(HOST_CTRL));
		outb((0x00), PORT(MIDI_CTRL));

		temp = sscape_read(devc, GA_HMCTL_REG);
		temp |= 0x40;
		sscape_write(devc, GA_HMCTL_REG, temp);	/* Kickstart the board */

		/*
		 * Wait until the ODB wakes up
		 */

		save_flags(flags);
		cli();
		done = 0;
		timeout_val = 5 * HZ;
		while (!done && timeout_val-- > 0)
		{
			unsigned char x;
			
			sleep(1);
			x = inb(PORT(HOST_DATA));
			if (x == 0xff || x == 0xfe)		/* OBP startup acknowledge */
			{
				DDB(printk("Soundscape: Acknowledge = %x\n", x));
				done = 1;
			}
		}
		sscape_write(devc, GA_CDCFG_REG, codec_dma_bits);

		restore_flags(flags);
		if (!done)
		{
			printk(KERN_ERR "soundscape: The OBP didn't respond after code download\n");
			return 0;
		}
		save_flags(flags);
		cli();
		done = 0;
		timeout_val = 5 * HZ;
		while (!done && timeout_val-- > 0)
		{
			sleep(1);
			if (inb(PORT(HOST_DATA)) == 0xfe)	/* Host startup acknowledge */
				done = 1;
		}
		restore_flags(flags);
		if (!done)
		{
			printk(KERN_ERR "soundscape: OBP Initialization failed.\n");
			return 0;
		}
		printk(KERN_INFO "SoundScape board initialized OK\n");
		set_control(devc, CTL_MASTER_VOL, 100);
		set_control(devc, CTL_SYNTH_VOL, 100);

#ifdef SSCAPE_DEBUG3
		/*
		 * Temporary debugging aid. Print contents of the registers after
		 * downloading the code.
		 */
		{
			int i;

			for (i = 0; i < 13; i++)
				printk("I%d = %02x (new value)\n", i, sscape_read(devc, i));
		}
#endif

	}
	return 1;
}
Пример #10
0
void UPD71071::write_io8(uint32 addr, uint32 data)
{
	switch(addr & 0x0f) {
	case 0x00:
		if(data & 1) {
			// dma reset
			for(int i = 0; i < 4; i++) {
				dma[i].mode = 0;
			}
			selch = base = 0;
			cmd = tmp = 0;
			sreq = tc = 0;
			mask = 0x0f;
		}
		b16 = data & 2;
		break;
	case 0x01:
		selch = data & 3;
		base = data & 4;
		break;
	case 0x02:
		dma[selch].bcreg = (dma[selch].bcreg & 0xff00) | data;
//		if(!base) {
			dma[selch].creg = (dma[selch].creg & 0xff00) | data;
//		}
		break;
	case 0x03:
		dma[selch].bcreg = (dma[selch].bcreg & 0xff) | (data << 8);
//		if(!base) {
			dma[selch].creg = (dma[selch].creg & 0xff) | (data << 8);
//		}
		break;
	case 0x04:
		dma[selch].bareg = (dma[selch].bareg & 0xffff00) | data;
//		if(!base) {
			dma[selch].areg = (dma[selch].areg & 0xffff00) | data;
//		}
		break;
	case 0x05:
		dma[selch].bareg = (dma[selch].bareg & 0xff00ff) | (data << 8);
//		if(!base) {
			dma[selch].areg = (dma[selch].areg & 0xff00ff) | (data << 8);
//		}
		break;
	case 0x06:
		dma[selch].bareg = (dma[selch].bareg & 0xffff) | (data << 16);
//		if(!base) {
			dma[selch].areg = (dma[selch].areg & 0xffff) | (data << 16);
//		}
		break;
	case 0x08:
		cmd = (cmd & 0xff00) | data;
		break;
	case 0x09:
		cmd = (cmd & 0xff) | (data << 8);
		break;
	case 0x0a:
		dma[selch].mode = data;
		break;
	case 0x0e:
		if((sreq = data) != 0) {
#ifndef SINGLE_MODE_DMA
			do_dma();
#endif
		}
		break;
	case 0x0f:
		mask = data;
		break;
	}
}
Пример #11
0
void do_write(int argc, char *argv[], char *envp[])
{
	uint32_t vmeaddr;
	int am;
	int dps;
	int eln;
	void *buf = NULL;
	uint8_t *cp;
	uint16_t *sp;
	uint32_t *ip;
	uint64_t *lp;
	int i = 0;

	if (argc < 6) {
	usage:
		printf("Usage: w <VME Address> <Address Modifier>"
		       " <Data Port Size> [-- <elements to write>] [<filename>]\n");
		exit(EXIT_FAILURE);
	}

	while (strcmp(argv[i], "--")) {
		if (i == 5) {
			buf = get_data_from_file(argv[i]);
			break;
		}
		++i;
	}
	if (!(argc - (++i)) && !buf)
		goto usage;

	get_obligitary_params(argv, &vmeaddr, &am, &dps);

	if (!buf) {
		eln = argc - i;
		buf = get_data_from_cmd_line(argv, i, dps, eln);
	}

	printf("Will write %d element(s)@%x ", eln, vmeaddr);
	i = 0;
	switch (dps) {
	case 8:
		printf("one byte long:\n");
		cp = buf;
		while (i < eln)
			printf("[%d] --> %#x\n", i++, *cp++);
		break;
	case 16:
		printf("2 bytes long:\n");
		sp = buf;
		while (i < eln)
			printf("[%d] --> %#x\n", i++, *sp++);
		break;
	case 32:
		printf("4 bytes long:\n");
		ip = buf;
		while (i < eln)
			printf("[%d] --> %#x\n", i++, *ip++);
		break;
	case 64:
		printf("8 bytes long:\n");
		lp = buf;
		while (i < eln)
			printf("[%d] --> %#lx\n", i++, *lp++);
		break;
	}

	do_dma('w', vmeaddr, am, dps, buf, eln);
}
Пример #12
0
void do_read(int argc, char *argv[], char *envp[])
{
	uint32_t vmeaddr;
	int am;
	int dps;
	int eln;
	void *buf;
	uint8_t *cp;
	uint16_t *sp;
	uint32_t *ip;
	uint64_t *lp;
	int i;

	if (argc != 6) {
		printf("Usage: r <VME Address> <Address Modifier>"
		       " <Data Port Size> <number of elements>\n");
		exit(EXIT_FAILURE);
	}

	get_obligitary_params(argv, &vmeaddr, &am, &dps);
	sscanf(argv[5], "%d", &eln);

	if (!(buf = calloc(eln, dps/8))) {
		perror("calloc");
		exit(1);
	}

	do_dma('r', vmeaddr, am, dps, buf, eln);

	printf("Read %d elements ", eln);
	switch (dps) {
	case 8:
		printf("one byte long:\n");
		cp = buf;
		for (i = 0; i < eln; i++, cp++)
			printf("[%d] --> %#x\n", i, *cp);
		break;
	case 16:
		printf("2 bytes long:\n");
		sp = buf;
		for (i = 0; i < eln; i++, sp++)
			printf("[%d] --> %#x\n", i, *sp);
		break;
	case 32:
		printf("4 bytes long:\n");
		ip = buf;
		for (i = 0; i < eln; i++, ip++)
			printf("[%d] --> %#x\n", i, *ip);

		break;
	case 64:
		printf("8 bytes long:\n");
		lp = buf;
		for (i = 0; i < eln; i++, lp++)
			printf("[%d] --> %#lx\n", i, *lp);
		break;
	default:
		break;
	}

	free(buf);

}
Пример #13
0
static int
sscape_download_boot (struct sscape_info *devc, unsigned char *block, int size, int flag)
{
  unsigned long   flags;
  unsigned char   temp;
  int             done, timeout_val;
  static unsigned char codec_dma_bits = 0;

  if (flag & CPF_FIRST)
    {
      /*
         * First block. Have to allocate DMA and to reset the board
         * before continuing.
       */

      save_flags (flags);
      cli ();
      codec_dma_bits = sscape_read (devc, GA_CDCFG_REG);
#if 0
      sscape_write (devc, GA_CDCFG_REG,
		    codec_dma_bits & ~0x08);	/* Disable codec DMA */
#endif

      if (devc->dma_allocated == 0)
	{
	  devc->dma_allocated = 1;
	}
      restore_flags (flags);

      sscape_write (devc, GA_HMCTL_REG,
		    (temp = sscape_read (devc, GA_HMCTL_REG)) & 0x3f);	/*Reset */

      for (timeout_val = 10000; timeout_val > 0; timeout_val--)
	sscape_read (devc, GA_HMCTL_REG);	/* Delay */

      /* Take board out of reset */
      sscape_write (devc, GA_HMCTL_REG,
		    (temp = sscape_read (devc, GA_HMCTL_REG)) | 0x80);
    }

  /*
   * Transfer one code block using DMA
   */
  memcpy (audio_devs[devc->my_audiodev]->dmap_out->raw_buf, block, size);

  save_flags (flags);
  cli ();
/******** INTERRUPTS DISABLED NOW ********/
  do_dma (devc, SSCAPE_DMA_A,
	  audio_devs[devc->my_audiodev]->dmap_out->raw_buf_phys,
	  size, DMA_MODE_WRITE);

  /*
   * Wait until transfer completes.
   */
  sscape_sleep_flag.flags = WK_NONE;
  done = 0;
  timeout_val = 100;
  while (!done && timeout_val-- > 0)
    {
      int             resid;


      {
	unsigned long   tlimit;

	if (1)
	  current_set_timeout (tlimit = jiffies + (1));
	else
	  tlimit = (unsigned long) -1;
	sscape_sleep_flag.flags = WK_SLEEP;
	module_interruptible_sleep_on (&sscape_sleeper);
	if (!(sscape_sleep_flag.flags & WK_WAKEUP))
	  {
	    if (jiffies >= tlimit)
	      sscape_sleep_flag.flags |= WK_TIMEOUT;
	  }
	sscape_sleep_flag.flags &= ~WK_SLEEP;
      };
      clear_dma_ff (devc->dma);
      if ((resid = get_dma_residue (devc->dma)) == 0)
	{
	  done = 1;
	}
    }

  restore_flags (flags);
  if (!done)
    return 0;

  if (flag & CPF_LAST)
    {
      /*
         * Take the board out of reset
       */
      outb (0x00, PORT (HOST_CTRL));
      outb (0x00, PORT (MIDI_CTRL));

      temp = sscape_read (devc, GA_HMCTL_REG);
      temp |= 0x40;
      sscape_write (devc, GA_HMCTL_REG, temp);	/* Kickstart the board */

      /*
         * Wait until the ODB wakes up
       */

      save_flags (flags);
      cli ();
      done = 0;
      timeout_val = 5 * HZ;
      while (!done && timeout_val-- > 0)
	{

	  {
	    unsigned long   tlimit;

	    if (1)
	      current_set_timeout (tlimit = jiffies + (1));
	    else
	      tlimit = (unsigned long) -1;
	    sscape_sleep_flag.flags = WK_SLEEP;
	    module_interruptible_sleep_on (&sscape_sleeper);
	    if (!(sscape_sleep_flag.flags & WK_WAKEUP))
	      {
		if (jiffies >= tlimit)
		  sscape_sleep_flag.flags |= WK_TIMEOUT;
	      }
	    sscape_sleep_flag.flags &= ~WK_SLEEP;
	  };
	  if (inb (PORT (HOST_DATA)) == 0xff)	/* OBP startup acknowledge */
	    done = 1;
	}
      sscape_write (devc, GA_CDCFG_REG, codec_dma_bits);

      restore_flags (flags);
      if (!done)
	{
	  printk ("SoundScape: The OBP didn't respond after code download\n");
	  return 0;
	}

      save_flags (flags);
      cli ();
      done = 0;
      timeout_val = 5 * HZ;
      while (!done && timeout_val-- > 0)
	{

	  {
	    unsigned long   tlimit;

	    if (1)
	      current_set_timeout (tlimit = jiffies + (1));
	    else
	      tlimit = (unsigned long) -1;
	    sscape_sleep_flag.flags = WK_SLEEP;
	    module_interruptible_sleep_on (&sscape_sleeper);
	    if (!(sscape_sleep_flag.flags & WK_WAKEUP))
	      {
		if (jiffies >= tlimit)
		  sscape_sleep_flag.flags |= WK_TIMEOUT;
	      }
	    sscape_sleep_flag.flags &= ~WK_SLEEP;
	  };
	  if (inb (PORT (HOST_DATA)) == 0xfe)	/* Host startup acknowledge */
	    done = 1;
	}
      restore_flags (flags);
      if (!done)
	{
	  printk ("SoundScape: OBP Initialization failed.\n");
	  return 0;
	}

      printk ("SoundScape board of type %d initialized OK\n",
	      get_board_type (devc));

      set_control (devc, CTL_MASTER_VOL, 100);
      set_control (devc, CTL_SYNTH_VOL, 100);

#ifdef SSCAPE_DEBUG3
      /*
         * Temporary debugging aid. Print contents of the registers after
         * downloading the code.
       */
      {
	int             i;

	for (i = 0; i < 13; i++)
	  printk ("I%d = %02x (new value)\n", i, sscape_read (devc, i));
      }
#endif

    }

  return 1;
}
Пример #14
0
static int
sscape_download_boot(struct sscape_info * devc, u_char *block, int size, int flag)
{
    u_long   flags;
    u_char   temp;
    int             done, timeout_val;

    if (flag & CPF_FIRST) {
	/*
	 * First block. Have to allocate DMA and to reset the board
	 * before continuing.
	 */

	flags = splhigh();
	if (devc->dma_allocated == 0) {
	    devc->dma_allocated = 1;
	}
	splx(flags);

	sscape_write(devc, GA_HMCTL_REG,
	   (temp = sscape_read(devc, GA_HMCTL_REG)) & 0x3f);	/* Reset */

	for (timeout_val = 10000; timeout_val > 0; timeout_val--)
	    sscape_read(devc, GA_HMCTL_REG);	/* Delay */

	/* Take board out of reset */
	sscape_write(devc, GA_HMCTL_REG,
		   (temp = sscape_read(devc, GA_HMCTL_REG)) | 0x80);
    }
    /*
     * Transfer one code block using DMA
     */
    bcopy(block, audio_devs[devc->my_audiodev]->dmap_out->raw_buf, size);

    flags = splhigh();
    /******** INTERRUPTS DISABLED NOW ********/
    do_dma(devc, SSCAPE_DMA_A,
	       audio_devs[devc->my_audiodev]->dmap_out->raw_buf_phys,
	       size, 1);

    /*
     * Wait until transfer completes.
     */
    sscape_sleep_flag.aborting = 0;
    sscape_sleep_flag.mode = WK_NONE;
    done = 0;
    timeout_val = 100;
    while (!done && timeout_val-- > 0) {
	int   chn;
	sscape_sleeper = &chn;
	DO_SLEEP(chn, sscape_sleep_flag, 1);

	done = 1;
    }

    splx(flags);
    if (!done)
	return 0;

    if (flag & CPF_LAST) {
	/*
	 * Take the board out of reset
	 */
	outb(PORT(HOST_CTRL), 0x00);
	outb(PORT(MIDI_CTRL), 0x00);

	temp = sscape_read(devc, GA_HMCTL_REG);
	temp |= 0x40;
	sscape_write(devc, GA_HMCTL_REG, temp);	/* Kickstart the board */

	/*
	 * Wait until the ODB wakes up
	 */

	flags = splhigh();
	done = 0;
	timeout_val = 5 * hz;
	while (!done && timeout_val-- > 0) {
	  int   chn;

	  sscape_sleeper = &chn;
	  DO_SLEEP(chn, sscape_sleep_flag, 1);

	  if (inb(PORT(HOST_DATA)) == 0xff)	/* OBP startup acknowledge */
	    done = 1;
	}
	splx(flags);
	if (!done) {
	    printf("SoundScape: The OBP didn't respond after code download\n");
	    return 0;
	}
	flags = splhigh();
	done = 0;
	timeout_val = 5 * hz;
	while (!done && timeout_val-- > 0) {
	  int   chn;

	  sscape_sleeper = &chn;
	  DO_SLEEP(chn, sscape_sleep_flag, 1);

	  if (inb(PORT(HOST_DATA)) == 0xfe)	/* Host startup acknowledge */
	    done = 1;
	}
	splx(flags);
	if (!done) {
	    printf("SoundScape: OBP Initialization failed.\n");
	    return 0;
	}
	printf("SoundScape board of type %d initialized OK\n",
	       get_board_type(devc));

	set_control(devc, CTL_MASTER_VOL, 100);
	set_control(devc, CTL_SYNTH_VOL, 100);

#ifdef SSCAPE_DEBUG3
	/*
	 * Temporary debugging aid. Print contents of the registers
	 * after downloading the code.
	 */
	{
	    int             i;

	    for (i = 0; i < 13; i++)
		printf("I%d = %02x (new value)\n", i, sscape_read(devc, i));
	}
#endif

    }
    return 1;
}
Пример #15
0
/**
*******************************************************************************
@brief
    Main program code.

@param
    argument_count

    Number of command line arguments passed to executable.

@param
    arguments

    Address of array containing command line arguments.

@retval
    EXIT_SUCCESS

    Success.

@retval
    EXIT_FAILURE

    Failure.
 ******************************************************************************/
int main(int argument_count, char **arguments)
{
	DM7820_Error dm7820_status;
	uint16_t *temp_buf = NULL;
	uint16_t read_data;
	int status;
	uint32_t i;

	struct option options[] = {
		{"help", 0, 0, 1},
		{"minor", 1, 0, 2},
		{0, 0, 0, 0}
	};

	struct sigaction signal_action;

	uint8_t help_option = 0x00;
	uint8_t minor_option = 0x00;

	unsigned long int minor_number = 0;

	program_name = arguments[0];

	signal_action.sa_handler = sigint_handler;
	sigfillset(&(signal_action.sa_mask));
	signal_action.sa_flags = 0;

	if (sigaction(SIGINT, &signal_action, NULL) < 0) {
		error(EXIT_FAILURE, errno, "ERROR: sigaction() FAILED");
	}

	fprintf(stdout, "\n");
	fprintf(stdout, "\tDM7820 DMA Capture Example Program\n");
	fprintf(stdout, "\n");

	/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
	   Process command line options
	   %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */

	while (1) {

		/*
		 * Parse the next command line option and any arguments it may require
		 */

		status = getopt_long(argument_count,
				     arguments, "", options, NULL);

		/*
		 * If getopt_long() returned -1, then all options have been processed
		 */

		if (status == -1) {
			break;
		}

		/*
		 * Figure out what getopt_long() found
		 */

		switch (status) {

			/*#################################################################
			   User entered '--help'
			   ############################################################## */

		case 1:

			/*
			 * Refuse to accept duplicate '--help' options
			 */

			if (help_option) {
				error(0, 0, "ERROR: Duplicate option '--help'");
				usage();
			}

			/*
			 * '--help' option has been seen
			 */

			help_option = 0xFF;
			break;

			/*#################################################################
			   User entered '--minor'
			   ############################################################## */

		case 2:{
				char *invalid_char_p;

				/*
				 * Refuse to accept duplicate '--minor' options
				 */

				if (minor_option) {
					error(0, 0,
					      "ERROR: Duplicate option '--minor'");
					usage();
				}

				/*
				 * Convert option argument string to unsigned long integer
				 */

				errno = 0;

				minor_number =
				    strtoul(optarg, &invalid_char_p, 10);

				/*
				 * Catch unsigned long int overflow
				 */

				if ((minor_number == ULONG_MAX)
				    && (errno == ERANGE)) {
					error(0, 0,
					      "ERROR: Device minor number caused numeric overflow");
					usage();
				}

				/*
				 * Catch argument strings with valid decimal prefixes, for
				 * example "1q", and argument strings which cannot be converted,
				 * for example "abc1"
				 */

				if ((*invalid_char_p != '\0')
				    || (invalid_char_p == optarg)) {
					error(0, 0,
					      "ERROR: Non-decimal device minor number");
					usage();
				}

				/*
				 * '--minor' option has been seen
				 */

				minor_option = 0xFF;
				break;
			}

			/*#################################################################
			   User entered unsupported option
			   ############################################################## */

		case '?':
			usage();
			break;

			/*#################################################################
			   getopt_long() returned unexpected value
			   ############################################################## */

		default:
			error(EXIT_FAILURE,
			      0,
			      "ERROR: getopt_long() returned unexpected value %#x",
			      status);
			break;
		}
	}

	/*
	 * Recognize '--help' option before any others
	 */

	if (help_option) {
		usage();
	}

	/*
	 * '--minor' option must be given
	 */

	if (minor_option == 0x00) {
		error(0, 0, "ERROR: Option '--minor' is required");
		usage();
	}

	/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
	   Device initialization
	   %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */

	fprintf(stdout, "Opening device with minor number %lu ...\n",
		minor_number);

	dm7820_status = DM7820_General_Open_Board(minor_number, &board);
	DM7820_Return_Status(dm7820_status, "DM7820_General_Open_Board()");

	/*
	 * Reset device
	 */

	fprintf(stdout, "Resetting device ...\n");

	dm7820_status = DM7820_General_Reset(board);
	DM7820_Return_Status(dm7820_status, "DM7820_General_Reset()");

	/*
	 * Make sure FIFO 1 empty interrupt is disabled to prevent stray interrupts
	 */

	fprintf(stdout, "Disabling FIFO 1 empty interrupt ...\n");

	dm7820_status = DM7820_General_Enable_Interrupt(board,
							DM7820_INTERRUPT_FIFO_1_EMPTY,
							0x00);
	DM7820_Return_Status(dm7820_status,
			     "DM7820_General_Enable_Interrupt()");

	do_digital_io();
	do_incenc();
	do_8254();
	do_pwm();
	do_fifo();
	do_dma();

	/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
	   Main processing
	   %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */

	/*
	 * Create a large buffer to place data from DMA.  This should be done AFTER
	 * the driver has created its buffers as the kernel space DMA buffers must
	 * be contiguous and ours do not have to be.
	 */

	dm7820_status =
	    DM7820_FIFO_DMA_Create_Buffer(&temp_buf, DMA_BUF_SIZE * 8);
	DM7820_Return_Status(dm7820_status, "DM7820_FIFO_DMA_Create_Buffer()");

	fprintf(stdout, "Installing user ISR ...\n");
	dm7820_status = DM7820_General_InstallISR(board, ISR);
	DM7820_Return_Status(dm7820_status, "DM7820_General_InstallISR()");

	fprintf(stdout, "Setting ISR priority ...\n");
	dm7820_status = DM7820_General_SetISRPriority(board, 99);
	DM7820_Return_Status(dm7820_status, "DM7820_General_SetISRPriority()");

	/*
	 * Enable FIFO
	 */

	fprintf(stdout, "Enabling FIFO 1 ...\n");

	dm7820_status = DM7820_FIFO_Enable(board, DM7820_FIFO_QUEUE_1, 0xFF);
	DM7820_Return_Status(dm7820_status, "DM7820_FIFO_Enable()");

	/*
	 *  Enabling DMA channel 0
	 */

	fprintf(stdout, "Enabling and Starting DMA 1 ...\n");

	dm7820_status = DM7820_FIFO_DMA_Enable(board,
					       DM7820_FIFO_QUEUE_1, 0xFF, 0xFF);
	DM7820_Return_Status(dm7820_status, "DM7820_FIFO_DMA_Enable()");

	/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
	 * Gather the data from the device and place it in our user buffer
	 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/

	int temp_interrupts = dma_done_interrupts;

	/*
	 * Loop here waiting for 4 of the 8 buffers we allocated to fill with
	 * data from the FIFO/DMA.  This will be equivalent to a FIFO half-full
	 * DMA transfer.  The ISR in the driver will keep the DMA/FIFO going while
	 * we take some time to read the data from the DMA buffer in the device and
	 * place this data in our buffer.
	 */

	fprintf(stdout, "Waiting to receive all data from DMA ...\n\n");

	uint32_t offset = 0;

	do {

		/*
		 * Check to see if we received an interrupt this time
		 */

		if (dma_done_interrupts != temp_interrupts) {
			temp_interrupts = dma_done_interrupts;

			/*
			 * Check to see if 4 DMA transfers have successfully completed.
			 * This also denotes our FIFO was half full and has been transferred
			 * to DMA in 4 small transfers (based on our DMA configuration).
			 */

			if ((temp_interrupts % 4 == 0) && (temp_interrupts > 0)) {
				/*
				 * Read the 4 buffers that have completed transfer.
				 * Also the offset must be adjusted here so the DMA data is read
				 * into the next block of our buffer.
				 */

				dm7820_status =
				    DM7820_FIFO_DMA_Read(board,
							 DM7820_FIFO_QUEUE_1,
							 (temp_buf +
							  (BUF_SIZE * offset)),
							 4);
				DM7820_Return_Status(dm7820_status,
						     "DM7820_FIFO_DMA_Read()");

				fprintf(stdout, "Retrieved DMA data ... \n");

				/*
				 * Increase the offset of the user-space buffer to which our DMA
				 * data will be copied.
				 */

				offset += 2;
			}

		}

		/*
		 * Loop until we receive 8 megs or 4M samples.
		 */

	} while (temp_interrupts < 32 && !exit_program);

	/*
	 * Uninstall the user ISR
	 */

	fprintf(stdout, "\nInterrupts received removing user ISR ...\n");

	dm7820_status = DM7820_General_RemoveISR(board);
	DM7820_Return_Status(dm7820_status, "DM7820_General_RemoveISR()");

	/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
	 * Verify data has been successfully sent
	 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/

	fprintf(stdout, "Read Complete ... Testing Data ...\n");
	fprintf(stdout, "\n\t     INDEX\tVALUE\n");

	/*
	 * Loop Buffer Size*2 times to print out all the samples.
	 */

	for (i = 1; i < DMA_BUF_SIZE * 2; i++) {

		/*
		 * Read each sample from the buffer and print it.
		 */

		read_data = temp_buf[i] - temp_buf[i - 1];

		fprintf(stdout, "\t     %d\t%6.2f ns\n", i,
			(float)(read_data) * 1000. * ((float)UTC_RATE / 5));
	}

	fprintf(stdout, "\n%d samples received.\n", i);

	/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
	 * Clean up and exit.
	 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/

	/*
	 * Free our large buffer
	 */

	dm7820_status =
	    DM7820_FIFO_DMA_Free_Buffer(&temp_buf, DMA_BUF_SIZE * 8);
	DM7820_Return_Status(dm7820_status, "DM7820_FIFO_DMA_Free_Buffer()");

	clean_up();

	fprintf(stdout, "\n");
	fprintf(stdout, "Successful end of example program.\n");

	exit(EXIT_SUCCESS);
}