//
// Fill in the details of a PCMCIA slot and initialize the device
//
void
cf_hwr_init(struct cf_slot *slot)
{
    static int int_init = 0;
    unsigned long new_state = *SA11X0_GPIO_PIN_LEVEL;
    if (!int_init) {
        int_init = 1;
#ifdef CYGPKG_KERNEL
        // Set up interrupts
        cyg_drv_interrupt_create(SA1110_CF_DETECT,
                                 99,                     // Priority - what goes here?
                                 (cyg_addrword_t) slot,  //  Data item passed to interrupt handler
                                 (cyg_ISR_t *)cf_detect_isr,
                                 (cyg_DSR_t *)cf_detect_dsr,
                                 &cf_detect_interrupt_handle,
                                 &cf_detect_interrupt);
        cyg_drv_interrupt_attach(cf_detect_interrupt_handle);
        cyg_drv_interrupt_configure(SA1110_CF_DETECT, true, true);  // Detect either edge
        cyg_drv_interrupt_acknowledge(SA1110_CF_DETECT);
        cyg_drv_interrupt_unmask(SA1110_CF_DETECT);
        cyg_drv_interrupt_create(SA1110_CF_IRQ,
                                 99,                     // Priority - what goes here?
                                 (cyg_addrword_t) slot,  //  Data item passed to interrupt handler
                                 (cyg_ISR_t *)cf_irq_isr,
                                 (cyg_DSR_t *)cf_irq_dsr,
                                 &cf_irq_interrupt_handle,
                                 &cf_irq_interrupt);
        cyg_drv_interrupt_attach(cf_irq_interrupt_handle);
        cyg_drv_interrupt_unmask(SA1110_CF_IRQ);
#endif
        cyg_drv_interrupt_configure(SA1110_CF_IRQ, false, false);  // Falling edge
        cyg_drv_interrupt_acknowledge(SA1110_CF_IRQ);
    }
    slot->attr = (unsigned char *)0x38000000;
    slot->attr_length = 0x200;
    slot->io = (unsigned char *)0x30000000;
    slot->io_length = 0x04000000;
    slot->mem = (unsigned char *)0x3C000000;
    slot->mem_length = 0x04000000;
    slot->int_num = SA1110_CF_IRQ;
#ifdef CYG_HAL_STARTUP_ROM
    // Disable CF bus & power (idle/off)
    assabet_BCR(SA1110_BCR_CF_POWER |
                SA1110_BCR_CF_RESET |
                SA1110_BCR_CF_BUS,
                SA1110_BCR_CF_POWER_OFF |
                SA1110_BCR_CF_RESET_DISABLE |
                SA1110_BCR_CF_BUS_OFF);
#endif
    if ((new_state & SA1110_GPIO_CF_DETECT) == SA1110_GPIO_CF_PRESENT) {
        if ((_assabet_BCR & SA1110_BCR_CF_POWER) == SA1110_BCR_CF_POWER_ON) {
            // Assume that the ROM environment has turned the bus on
            slot->state = CF_SLOT_STATE_Ready;
        } else {
            slot->state = CF_SLOT_STATE_Inserted;
        }
    } else {
        slot->state = CF_SLOT_STATE_Empty;
    }
}
Example #2
0
static void InstallAvsHandler (void)
{

	if (bInitialized) return;
	
	cyg_drv_interrupt_create(CYGNUM_HAL_INTERRUPT_AVS0,
                             99,
                             (cyg_addrword_t)0,
                             avsGeneric_ISR,
                             avsGeneric_DSR,
                             &avs0_interrupt_handle,
                             &avs0_interrupt);
    cyg_drv_interrupt_attach(avs0_interrupt_handle);

	cyg_drv_interrupt_create(CYGNUM_HAL_INTERRUPT_AVS1,
                             99,
                             (cyg_addrword_t)0,
                             avsGeneric_ISR,
                             avsGeneric_DSR,
                             &avs1_interrupt_handle,
                             &avs1_interrupt);
    cyg_drv_interrupt_attach(avs1_interrupt_handle);
    
   	cyg_drv_interrupt_create(CYGNUM_HAL_INTERRUPT_AVS2,
                             99,
                             (cyg_addrword_t)0,
                             avsGeneric_ISR,
                             avsGeneric_DSR,
                             &avs2_interrupt_handle,
                             &avs2_interrupt);
    cyg_drv_interrupt_attach(avs2_interrupt_handle);
    
    bInitialized = true;
}    
Example #3
0
// Function to initialize the device.  Called at bootstrap time.
static bool 
edb7xxx_serial_init(struct cyg_devtab_entry *tab)
{
    serial_channel *chan = (serial_channel *)tab->priv;
    edb7xxx_serial_info *edb7xxx_chan = (edb7xxx_serial_info *)chan->dev_priv;
#ifdef CYGDBG_IO_INIT
    diag_printf("EDB7XXX SERIAL init - dev: %x.%d\n", edb7xxx_chan->control, edb7xxx_chan->tx_int_num);
#endif
    (chan->callbacks->serial_init)(chan);  // Really only required for interrupt driven devices
    if (chan->out_cbuf.len != 0) {
        cyg_drv_interrupt_create(edb7xxx_chan->tx_int_num,
                                 99,                     // Priority - unused
                                 (cyg_addrword_t)chan,   //  Data item passed to interrupt handler
                                 edb7xxx_serial_tx_ISR,
                                 edb7xxx_serial_tx_DSR,
                                 &edb7xxx_chan->serial_tx_interrupt_handle,
                                 &edb7xxx_chan->serial_tx_interrupt);
        cyg_drv_interrupt_attach(edb7xxx_chan->serial_tx_interrupt_handle);
        cyg_drv_interrupt_mask(edb7xxx_chan->tx_int_num);
        edb7xxx_chan->tx_enabled = false;
    }
    if (chan->in_cbuf.len != 0) {
        cyg_drv_interrupt_create(edb7xxx_chan->rx_int_num,
                                 99,                     // Priority - unused
                                 (cyg_addrword_t)chan,   //  Data item passed to interrupt handler
                                 edb7xxx_serial_rx_ISR,
                                 edb7xxx_serial_rx_DSR,
                                 &edb7xxx_chan->serial_rx_interrupt_handle,
                                 &edb7xxx_chan->serial_rx_interrupt);
        cyg_drv_interrupt_attach(edb7xxx_chan->serial_rx_interrupt_handle);
        cyg_drv_interrupt_unmask(edb7xxx_chan->rx_int_num);
    }
    edb7xxx_serial_config_port(chan, &chan->config, true);
    return true;
}
Example #4
0
void hal_clock_initialize(cyg_uint32 period)
{
    cyg_uint32 tmod;

    // Disable timer 0
    HAL_READ_UINT32(E7T_TMOD, tmod);
    tmod &= ~(E7T_TMOD_TE0);
    HAL_WRITE_UINT32(E7T_TMOD, 0);

    tmod &= ~(E7T_TMOD_TMD0 | E7T_TMOD_TCLR0);
    tmod |= E7T_TMOD_TE0;

    // Set counter
    HAL_WRITE_UINT32(E7T_TDATA0, period);

    // And enable timer
    HAL_WRITE_UINT32(E7T_TMOD, tmod);

    _period = period;

#ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
    cyg_drv_interrupt_create(CYGNUM_HAL_INTERRUPT_EXT0,
                             99,           // Priority
                             0,            // Data item passed to interrupt handler
                             e7t_abort_isr,
                             0,
                             &abort_interrupt_handle,
                             &abort_interrupt);
    cyg_drv_interrupt_attach(abort_interrupt_handle);
    cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_EXT0);
#endif
}
Example #5
0
void
hasp_mpc5xxx_i2c_init()
{
    initReset();										// initialise the reset pin
    resetHigh();

    cyg_drv_mutex_init(&i2c_lock);
    cyg_drv_cond_init(&i2c_wait, &i2c_lock);
    cyg_drv_interrupt_create(i2c_intr_vector,
                             0,
                             (cyg_addrword_t) 0,
                             &mpc5xxx_i2c_isr,
                             &mpc5xxx_i2c_dsr,
                             &(i2c_interrupt_handle),
                             &(i2c_interrupt_data));
    cyg_drv_interrupt_attach(i2c_interrupt_handle);

    HAL_WRITE_UINT32(I2C_0_FDR_REG, 0x89000000);		// Set clock to 100MHz / 352

    HAL_WRITE_UINT32(I2C_0_ADDRESS_REG, 0x00000000);	// Set MPC5xxx slave address, not useful to us

    HAL_WRITE_UINT32(I2C_0_CONTROL_REG, I2C_ENABLE);	// Enable the I2C device but do not start any transfers and leave interrupts disabled.

    HAL_WRITE_UINT32(I2C_0_STATUS_REG, 0x00000000);		// Clear any pending conditions including interrupts.

    HAL_INTERRUPT_UNMASK(i2c_intr_vector);				// Interrupts can now be safely unmasked

    i2c_flag = 0;

    resetLow();

}
Example #6
0
// Function to initialize the device.  Called at bootstrap time.
static bool 
vrc437x_serial_init(struct cyg_devtab_entry *tab)
{
    serial_channel *chan = (serial_channel *)tab->priv;
    vrc437x_serial_info *vrc437x_chan = (vrc437x_serial_info *)chan->dev_priv;
    static bool init = false;
#ifdef CYGDBG_IO_INIT
    diag_printf("VRC437X SERIAL init '%s' - dev: %x\n", tab->name, vrc437x_chan->base);
#endif
    (chan->callbacks->serial_init)(chan);  // Really only required for interrupt driven devices
    if (!init && chan->out_cbuf.len != 0) {
        init = true;
// Note that the hardware is rather broken.  The interrupt status needs to
// be read using only channel A
        cyg_drv_interrupt_create(VRC437X_SCC_INT,
                                 99,                     
                                 (cyg_addrword_t)VRC437X_SCC_BASE+SCC_CHANNEL_A,
                                 vrc437x_serial_ISR,
                                 vrc437x_serial_DSR,
                                 &vrc437x_serial_interrupt_handle,
                                 &vrc437x_serial_interrupt);
        cyg_drv_interrupt_attach(vrc437x_serial_interrupt_handle);
        cyg_drv_interrupt_unmask(VRC437X_SCC_INT);
    }
    vrc437x_serial_config_port(chan, &chan->config, true);
    return true;
}
bool altera_avalon_uart_init(struct cyg_devtab_entry *tab)
{
  serial_channel *chan = (serial_channel *)tab->priv;
  altera_avalon_uart_dev *uart_chan = (altera_avalon_uart_dev *)chan->dev_priv;

	(chan->callbacks->serial_init)(chan);

	/* enable interrupts at the device */

	if (chan->out_cbuf.len != 0)
	{
	  cyg_drv_interrupt_create(uart_chan->irq,
							   99,                     /* Priority - unused */
							   (cyg_addrword_t)chan,   /* Data item passed to interrupt handler */
							   altera_avalon_uart_ISR,
							   altera_avalon_uart_DSR,
							   &uart_chan->serial_interrupt_handle,
							   &uart_chan->serial_interrupt);

	  cyg_drv_interrupt_attach(uart_chan->serial_interrupt_handle);

	  IOWR_ALTERA_AVALON_UART_CONTROL(uart_chan->base,
					  ALTERA_AVALON_UART_CONTROL_RTS_MSK  |
					  ALTERA_AVALON_UART_CONTROL_RRDY_MSK |
					  ALTERA_AVALON_UART_CONTROL_DCTS_MSK);

	  cyg_drv_interrupt_unmask(uart_chan->irq);
	}
	return true;
}
Example #8
0
// Function to initialize the device.  Called at bootstrap time.
static bool 
smdk2410_serial_init(struct cyg_devtab_entry *tab)
{
    serial_channel *chan = (serial_channel *)tab->priv;
    smdk2410_serial_info *smdk2410_chan = (smdk2410_serial_info *)chan->dev_priv;
    cyg_uint32 _intsubm;
#ifdef CYGDBG_IO_INIT
    diag_printf("SMDK2410 SERIAL init - dev: 0x%08x.%d\n", 
                smdk2410_chan->base, smdk2410_chan->int_num);
#endif
    (chan->callbacks->serial_init)(chan);  // Really only required for interrupt driven devices
    if (chan->out_cbuf.len != 0) {
        cyg_drv_interrupt_create(smdk2410_chan->int_num,
                                 1,                    // Priority - unused
                                 (cyg_addrword_t)chan, //  Data item passed to interrupt handler
                                 smdk2410_serial_ISR,
                                 smdk2410_serial_DSR,
                                 &smdk2410_chan->serial_interrupt_handle,
                                 &smdk2410_chan->serial_interrupt);
        cyg_drv_interrupt_attach(smdk2410_chan->serial_interrupt_handle);
        cyg_drv_interrupt_unmask(smdk2410_chan->int_num);

        HAL_READ_UINT32(INTSUBMSK, _intsubm);
        _intsubm &= ~(smdk2410_chan->bit_sub_rxd<<0);         // BIT_SUB_RXD
        HAL_WRITE_UINT32(INTSUBMSK, _intsubm);
    }
    smdk2410_serial_config_port(chan, &chan->config, true);
    return true;
}
Example #9
0
static void
aeb_setup_timer1(cyg_uint32 period)
{
    cyg_uint32 iocr;

    // Set counter GATE input low (0) to halt counter while it's being setup
    HAL_READ_UINT32(CYG_DEVICE_IOCR, iocr);
    iocr = (iocr & ~IOCR_CT1G) | IOCR_CT1G_LOW;
    HAL_WRITE_UINT32(CYG_DEVICE_IOCR, iocr);

    // Scale timer0 clock
    HAL_WRITE_UINT32(CYG_DEVICE_CPM_CT1CCR, CT_X16);

    // Initialize counter, mode 2 = rate generator
    HAL_WRITE_UINT8(CYG_DEVICE_TIMER_CTL, 
                    TIMER_CTL_TYPE_BIN|
                    TIMER_CTL_MODE_RG|
                    TIMER_CTL_RW_BOTH|
                    TIMER_CTL_SC_CTR1);
    HAL_WRITE_UINT8(CYG_DEVICE_TIMER1, (period & 0xFF));        // LSB
    HAL_WRITE_UINT8(CYG_DEVICE_TIMER1, ((period >> 8) & 0xFF)); // MSB
    // Enable timer
    iocr = (iocr & ~IOCR_CT1G) | IOCR_CT1G_HIGH;
    HAL_WRITE_UINT32(CYG_DEVICE_IOCR, iocr);
    cyg_drv_interrupt_create(CYGNUM_HAL_INTERRUPT_TIMER1,
                             99,             // Priority
                             0,              // Data item passed to interrupt handler
                             aeb_timer1_isr,
                             0,
                             &timer1_interrupt_handle,
                             &timer1_interrupt);
    cyg_drv_interrupt_attach(timer1_interrupt_handle);
    cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_TIMER1);
}
Example #10
0
//==========================================================================
// Initialize driver & hardware state
//==========================================================================
void cyg_lpc2xxx_i2c_init(struct cyg_i2c_bus *bus)
{
    cyg_lpc2xxx_i2c_extra* extra = (cyg_lpc2xxx_i2c_extra*)bus->i2c_extra;
    cyg_uint16             duty_cycle;
  
    cyg_drv_mutex_init(&extra->i2c_lock);
    cyg_drv_cond_init(&extra->i2c_wait, &extra->i2c_lock);
    cyg_drv_interrupt_create(I2C_ISRVEC(extra),
                             I2C_ISRPRI(extra),
                             (cyg_addrword_t) extra,
                             &lpc2xxx_i2c_isr,
                             &lpc2xxx_i2c_dsr,
                             &(extra->i2c_interrupt_handle),
                             &(extra->i2c_interrupt_data));
    cyg_drv_interrupt_attach(extra->i2c_interrupt_handle);
  
   
    CLR_CON(extra, CON_EN | CON_STA | CON_SI | CON_AA);
    HAL_WRITE_UINT8(I2C_ADR(extra), 0);
    
    //
    // Setup I2C bus frequency
    //
    duty_cycle = (I2C_CLK(extra) / I2C_BUS_FREQ(extra)) / 2;
    HAL_WRITE_UINT16(I2C_SCLL(extra), duty_cycle);
    HAL_WRITE_UINT16(I2C_SCLH(extra), duty_cycle);
    
    SET_CON(extra, CON_EN);
}
Example #11
0
void
kbd_init(void)
{
    // Initialize environment, setup interrupt handler
    cyg_drv_interrupt_create(CYGNUM_HAL_INTERRUPT_KBDINT,
                             99,                     // Priority - what goes here?
                             0,                      //  Data item passed to interrupt handler
                             (cyg_ISR_t *)keyboard_isr,
                             (cyg_DSR_t *)keyboard_dsr,
                             &kbd_interrupt_handle,
                             &kbd_interrupt);
    cyg_drv_interrupt_attach(kbd_interrupt_handle);
    cyg_drv_interrupt_acknowledge(CYGNUM_HAL_INTERRUPT_KBDINT);
    cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_KBDINT);
    // Set up the mbox for keyboard data
    cyg_mbox_create(&kbd_events_mbox_handle, &kbd_events_mbox);
    // This semaphore is set when there is a keypress
    cyg_semaphore_init(&kbd_sem, 0);  
    // Create a thread whose job it is to de-bounce the keyboard and
    // actually process the input, turning it into a series of events
    cyg_thread_create(10,                           // Priority - just a number
                      kbd_server,                   // entry
                      0,                            // initial parameter
                      "KBD_server",                 // Name
                      &kbd_server_stack[0],         // Stack
                      STACK_SIZE,                   // Size
                      &kbd_server_thread_handle,    // Handle
                      &kbd_server_thread_data       // Thread data structure
            );
    cyg_thread_resume(kbd_server_thread_handle);  // Start it
}
Example #12
0
// Initialize the interface - performed at system startup
// This function must set up the interface, including arranging to
// handle interrupts, etc, so that it may be "started" cheaply later.
static bool emaclite_init(struct cyg_netdevtab_entry *dtp)
{
	struct eth_drv_sc *sc = (struct eth_drv_sc *)dtp->device_instance;
	struct emaclite_info *qi = (struct emaclite_info *)sc->driver_private;

	unsigned char _enaddr[6];
	bool esa_ok;

	/* Try to read the ethernet address of the transciever ... */
#if defined(CYGPKG_REDBOOT) && defined(CYGSEM_REDBOOT_FLASH_CONFIG)
	esa_ok = flash_get_config(qi->esa_key, _enaddr, CONFIG_ESA);
#else
	esa_ok = CYGACC_CALL_IF_FLASH_CFG_OP(CYGNUM_CALL_IF_FLASH_CFG_GET, 
					qi->esa_key, _enaddr, CONFIG_ESA);
#endif
	if (esa_ok) {
		memcpy(qi->enaddr, _enaddr, sizeof(qi->enaddr));
	} else {
		/* No 'flash config' data available - use default */
		diag_printf("Emaclite_ETH - Warning! Using default ESA for '%s'\n", dtp->name);
	}

	/* Initialize Xilinx driver  - device id 0*/
	if (XEmacLite_Initialize(&qi->dev, 0) != XST_SUCCESS) {
		diag_printf("Emaclite_ETH - can't initialize\n");
		return false;
	}
	if (XEmacLite_SelfTest(&qi->dev) != XST_SUCCESS) {
		diag_printf("Emaclite_ETH - self test failed\n");
		return false;
	}

	XEmacLite_SetMacAddress(&qi->dev, qi->enaddr);
	XEmacLite_SetSendHandler(&qi->dev, sc, emaclite_TxEvent);
	XEmacLite_SetRecvHandler(&qi->dev, sc, emaclite_RxEvent);


#ifdef CYGPKG_NET
	/* Set up to handle interrupts */
	cyg_drv_interrupt_create(qi->int_vector,
				0,  // Highest //CYGARC_SIU_PRIORITY_HIGH,
				(cyg_addrword_t)sc, //  Data passed to ISR
				(cyg_ISR_t *)emaclite_isr,
				(cyg_DSR_t *)eth_drv_dsr,
				&qi->emaclite_interrupt_handle,
				&qi->emaclite_interrupt);
	cyg_drv_interrupt_attach(qi->emaclite_interrupt_handle);
	cyg_drv_interrupt_acknowledge(qi->int_vector);
	cyg_drv_interrupt_unmask(qi->int_vector);
#endif

	/* Operating mode */
	_s3esk_dev = &qi->dev;

	/* Initialize upper level driver for ecos */
	(sc->funs->eth_drv->init)(sc, (unsigned char *)&qi->enaddr);

	return true;
}
Example #13
0
bool netxeth_init(struct cyg_netdevtab_entry *tab)
{
  struct eth_drv_sc*  sc         = tab->device_instance;
  PNETX_ETH_PORT_INFO ptPortInfo = (PNETX_ETH_PORT_INFO)sc->driver_private;
  bool fRet = false;

  if(!xc_open(ptPortInfo->ulPort))
    return false;
 
  //TODO: Check HAL_PHYS_TO_VIRT_ADDRESS usage
  if(NULL == s_ptFifoArea)
    s_ptFifoArea                = (PFIFO_AREA_T)hal_phys_to_virt_address(Addr_pointer_fifo, false);

  if(NULL == s_ptMiiMu)
    s_ptMiiMu                   = (MIIMU_REG_T*)hal_phys_to_virt_address(Adr_miimu_reg, false);
    
  if(NULL == s_pulxPECInterruptRegisters)
    s_pulxPECInterruptRegisters = (cyg_uint32*)hal_phys_to_virt_address(Addr_xpec_irq_registers, false);
  
  if(NULL == ptPortInfo->pulxPECBase)
    ptPortInfo->pulxPECBase     = (cyg_uint32*)hal_phys_to_virt_address(ptPortInfo->ulxPECBasePhys, false);
  
  if(NULL == ptPortInfo->pulxMACBase)
    ptPortInfo->pulxMACBase     = (cyg_uint32*)hal_phys_to_virt_address(ptPortInfo->ulxMACBasePhys, false);

  if(NULL == ptPortInfo->pulSRAMBase)
    ptPortInfo->pulSRAMBase     = (cyg_uint32*)hal_phys_to_virt_address(ptPortInfo->ulSRAMBasePhys, false);

  cyg_drv_interrupt_create(ptPortInfo->ulInterrupt, 
                           0, 
                           (unsigned)sc, 
                           netxeth_ISR, 
                           eth_drv_dsr, 
                           &ptPortInfo->hInterrupt,
                           &ptPortInfo->tInterruptObject);
  cyg_drv_interrupt_attach(ptPortInfo->hInterrupt);

  //TODO: insert xpec firmware pointer
  if(s_ptMiiMu &&
     s_pulxPECInterruptRegisters &&
     ptPortInfo->pulxPECBase &&
     ptPortInfo->pulxMACBase &&
     (ptPortInfo->pulSRAMBase || (ptPortInfo->ulPort == 0)) ) //port 0 may return a null pointer, as internal ram segment starts at 0
  {   
    if(!s_fPhyInitialized)
    {
      s_fPhyInitialized = InitInternalPHY();
    }

    ((sc)->funs->eth_drv->init)(sc, ptPortInfo->abMAC);
    netxeth_control(sc, ETH_DRV_SET_MAC_ADDRESS, ptPortInfo->abMAC, sizeof(ptPortInfo->abMAC));
    
    fRet = true;
  }
  
  return fRet;
}
Example #14
0
static bool mpc555_serial_init(struct cyg_devtab_entry * tab)
{
   serial_channel * chan = (serial_channel *)tab->priv;
   mpc555_serial_info * mpc555_chan = (mpc555_serial_info *)chan->dev_priv;

   if(!mpc555_serial_config_port(chan, &chan->config, true))
     return false;

   (chan->callbacks->serial_init)(chan);  // Really only required for interrupt driven devices
   if(chan->out_cbuf.len != 0)
   { 
     arbiter.priority = CYGNUM_HAL_ISR_SOURCE_PRIORITY_QSCI;
     arbiter.data     = 0;
     arbiter.arbiter  = hal_arbitration_isr_qsci;
     
     // Install the arbitration isr, Make sure that is is not installed twice
     hal_mpc5xx_remove_arbitration_isr(&arbiter);
     hal_mpc5xx_install_arbitration_isr(&arbiter); 

     // Create the Tx interrupt, do not enable it yet
     cyg_drv_interrupt_create(mpc555_chan->tx_interrupt_num,
                              mpc555_chan->tx_interrupt_priority,
                              (cyg_addrword_t)chan,   //  Data item passed to interrupt handler
                              mpc555_serial_tx_ISR,
                              mpc555_serial_tx_DSR,
                              &mpc555_chan->tx_interrupt_handle,
                              &mpc555_chan->tx_interrupt);
     cyg_drv_interrupt_attach(mpc555_chan->tx_interrupt_handle);

     // Create the Rx interrupt, this can be safely unmasked now
     cyg_drv_interrupt_create(mpc555_chan->rx_interrupt_num,
                              mpc555_chan->rx_interrupt_priority,
                              (cyg_addrword_t)chan,
                              mpc555_serial_rx_ISR,
                              mpc555_serial_rx_DSR,
                              &mpc555_chan->rx_interrupt_handle,
                              &mpc555_chan->rx_interrupt);
     cyg_drv_interrupt_attach(mpc555_chan->rx_interrupt_handle);
     cyg_drv_interrupt_unmask(mpc555_chan->rx_interrupt_num);
    }

    return true;
}
Example #15
0
void hal_stm32_dma_init( hal_stm32_dma_stream *stream, int pri )
{
    stream->ctlr = hal_stm32_dma_controller[CYGHWR_HAL_STM32_DMA_CONTROLLER(stream->desc)].base;
    stream->stream = CYGHWR_HAL_STM32_DMA_STREAM(stream->desc);

    dma_diag("ctlr %08x stream %d chan %d pri %d\n", stream->ctlr, stream->stream,
             CYGHWR_HAL_STM32_DMA_CHANNEL(stream->desc), pri );
             
    cyg_drv_interrupt_create( CYGHWR_HAL_STM32_DMA_INTERRUPT(stream->desc),
                              pri,
                              (CYG_ADDRWORD)stream,
                              hal_stm32_dma_isr,
                              hal_stm32_dma_dsr,
                              &stream->handle,
                              &stream->interrupt );
    cyg_drv_interrupt_attach( stream->handle );
    cyg_drv_interrupt_unmask( CYGHWR_HAL_STM32_DMA_INTERRUPT(stream->desc) );

    // Enable DMA controller clock
    CYGHWR_HAL_STM32_CLOCK_ENABLE( hal_stm32_dma_controller[CYGHWR_HAL_STM32_DMA_CONTROLLER(stream->desc)].clock );


    // Clear CCR, disable channel and put into known state
    HAL_WRITE_UINT32(stream->ctlr+CYGHWR_HAL_STM32_DMA_CCR(stream->stream), 0 );

    
    // Initialize a private copy of the CCR, we don't write this to
    // the hardware until we are ready to start the transfer.

    stream->ccr = CYGHWR_HAL_STM32_DMA_CCR_EN;

#if defined (CYGHWR_HAL_CORTEXM_STM32_FAMILY_HIPERFORMANCE)
    // Select channel number in F2/F4 variants. The F1 variants simply
    // have the various device DMA request lines wire-ORed together.
    stream->ccr |= CYGHWR_HAL_STM32_DMA_CCR_CHSEL(CYGHWR_HAL_STM32_DMA_CHANNEL(stream->desc));
#endif
    
    // Set stream direction
    if( CYGHWR_HAL_STM32_DMA_MODE(stream->desc) == CYGHWR_HAL_STM32_DMA_MODE_M2P )
        stream->ccr |= CYGHWR_HAL_STM32_DMA_CCR_MEM2P;

    // Set memory increment mode
    stream->ccr |= CYGHWR_HAL_STM32_DMA_CCR_MINC;
           
    // Transfer end interrupt enable
    stream->ccr |= CYGHWR_HAL_STM32_DMA_CCR_TCIE;

    // Use top 2 bits of priority to define DMA stream priority
    stream->ccr |= CYGHWR_HAL_STM32_DMA_CCR_PL((pri>>6)&3);
    
    dma_diag("ccr %08x\n", stream->ccr);
}
Example #16
0
void createPHYInterrupt(struct eth_drv_sc *sc)
{
	cyg_drv_interrupt_create(CYGNUM_HAL_INTERRUPT_IRQ2,
						0,
						(cyg_addrword_t) sc, //  Data item passed to interrupt handler
						(cyg_ISR_t *) phy_isr,
						(cyg_DSR_t *) phy_dsr,
						&phy_interrupt_handle,
						&phy_interrupt);
	cyg_drv_interrupt_attach(phy_interrupt_handle);
	cyg_drv_interrupt_acknowledge(CYGNUM_HAL_INTERRUPT_IRQ2);
	cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_IRQ2);

}
Example #17
0
// Function to initialize the device.  Called at bootstrap time.
static bool 
ebsa285_serial_init(struct cyg_devtab_entry *tab)
{
    serial_channel *chan = (serial_channel *)tab->priv;
    ebsa285_serial_info *ebsa285_chan = (ebsa285_serial_info *)chan->dev_priv;
#ifdef CYGDBG_IO_INIT
    diag_printf("EBSA285 SERIAL init - dev: %x\n", ebsa285_chan);
#endif
    (chan->callbacks->serial_init)(chan);  // Really only required for interrupt driven devices
    if (chan->out_cbuf.len != 0) {

        // first for rx
        cyg_drv_interrupt_create(ebsa285_chan->rx.int_num,
                                 99,                   // Priority - unused
                                 (cyg_addrword_t)chan, //  Data item passed to interrupt handler
                                 ebsa285_serial_rx_ISR,
                                 ebsa285_serial_rx_DSR,
                                 &ebsa285_chan->rx.serial_interrupt_handle,
                                 &ebsa285_chan->rx.serial_interrupt);
        cyg_drv_interrupt_attach(ebsa285_chan->rx.serial_interrupt_handle);
        cyg_drv_interrupt_unmask(ebsa285_chan->rx.int_num);

        // then for tx
        cyg_drv_interrupt_create(ebsa285_chan->tx.int_num,
                                 99,                   // Priority - unused
                                 (cyg_addrword_t)chan, //  Data item passed to interrupt handler
                                 ebsa285_serial_tx_ISR,
                                 ebsa285_serial_tx_DSR,
                                 &ebsa285_chan->tx.serial_interrupt_handle,
                                 &ebsa285_chan->tx.serial_interrupt);
        cyg_drv_interrupt_attach(ebsa285_chan->tx.serial_interrupt_handle);
        // DO NOT cyg_drv_interrupt_unmask(ebsa285_chan->tx.int_num);
        ebsa285_chan->tx_active = 0;
    }
    (void)ebsa285_serial_config_port(chan, &chan->config, true);
    return true;
}
Example #18
0
bool mn10300_serial_init(struct cyg_devtab_entry *tab)
{
    serial_channel *chan = (serial_channel *)tab->priv;
    mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv;

    (chan->callbacks->serial_init)(chan);  // Really only required for interrupt driven devices

#ifndef CYGPKG_IO_SERIAL_MN10300_POLLED_MODE    
    if (chan->out_cbuf.len != 0) {
        // Install and enable the receive interrupt
        cyg_drv_interrupt_create(mn10300_chan->rx_int,
                                 4,                      // Priority - what goes here?
                                 (cyg_addrword_t)chan,   //  Data item passed to interrupt handler
                                 mn10300_serial_rx_ISR,
                                 mn10300_serial_rx_DSR,
                                 &mn10300_chan->rx_interrupt_handle,
                                 &mn10300_chan->rx_interrupt);
        cyg_drv_interrupt_attach(mn10300_chan->rx_interrupt_handle);
        cyg_drv_interrupt_unmask(mn10300_chan->rx_int);

        // Install and enable the transmit interrupt
        cyg_drv_interrupt_create(mn10300_chan->tx_int,
                                 4,                      // Priority - what goes here?
                                 (cyg_addrword_t)chan,   //  Data item passed to interrupt handler
                                 mn10300_serial_tx_ISR,
                                 mn10300_serial_tx_DSR,
                                 &mn10300_chan->tx_interrupt_handle,
                                 &mn10300_chan->tx_interrupt);
        cyg_drv_interrupt_attach(mn10300_chan->tx_interrupt_handle);
        cyg_drv_interrupt_mask(mn10300_chan->tx_int);
    }
#endif
    
    mn10300_serial_config_port(chan, &chan->config, true);
    
    return true;
}
Example #19
0
void
cyg_spi_at91_bus_init(void)
{
    // Create and attach SPI interrupt object
    cyg_drv_interrupt_create(CYGNUM_HAL_INTERRUPT_SPI,
                             4,                   
                             (cyg_addrword_t)&cyg_spi_at91_bus,   
                             spi_at91_ISR,
                             spi_at91_DSR,
                             &cyg_spi_at91_bus.spi_interrupt_handle,
                             &cyg_spi_at91_bus.spi_interrupt);

    cyg_drv_interrupt_attach(cyg_spi_at91_bus.spi_interrupt_handle);

    // Init transfer mutex and condition
    cyg_drv_mutex_init(&cyg_spi_at91_bus.transfer_mx);
    cyg_drv_cond_init(&cyg_spi_at91_bus.transfer_cond, 
                      &cyg_spi_at91_bus.transfer_mx);
   
    // Init flags
    cyg_spi_at91_bus.transfer_end = true;
    cyg_spi_at91_bus.cs_up        = false;
    
    // Soft reset the SPI controller
    HAL_WRITE_UINT32(AT91_SPI+AT91_SPI_CR, AT91_SPI_CR_SWRST);

    // Configure SPI pins
      
    // NOTE: here we let the SPI controller control 
    //       the data in, out and clock signals, but 
    //       we need to handle the chip selects manually 
    //       in order to achieve better chip select control 
    //       inbetween transactions.
    
    // Put SPI MISO, MOIS and SPCK pins into peripheral mode
    HAL_WRITE_UINT32(AT91_SPI_PIO+AT91_PIO_PDR, AT91_PIO_PSR_SPCK |
                                                AT91_PIO_PSR_MISO |
                                                AT91_PIO_PSR_MOIS); 
 
    // Put SPI chip select pins in IO output mode
    HAL_WRITE_UINT32(AT91_SPI_PIO+AT91_PIO_SODR, AT91_SPI_PIO_NPCS(0x0F));
    HAL_WRITE_UINT32(AT91_SPI_PIO+AT91_PIO_PER,  AT91_SPI_PIO_NPCS(0x0F));
    HAL_WRITE_UINT32(AT91_SPI_PIO+AT91_PIO_OER,  AT91_SPI_PIO_NPCS(0x0F));

    // Call upper layer bus init
    CYG_SPI_BUS_COMMON_INIT(&cyg_spi_at91_bus.spi_bus);
}
Example #20
0
void
hal_platform_init(void)
{
    // Init superIO before calling if_init (which will use UARTs)
    cyg_hal_init_superIO();

    hal_if_init();

#if defined(CYGPKG_REDBOOT) && defined(CYGPKG_IO_PCI)
    cyg_hal_plf_pci_init();
#endif

    // Set up interrupt arbiter
    cyg_drv_interrupt_create(CYGNUM_HAL_INTERRUPT_PCI, 1,
                             0, cyg_hal_plf_pci_arbiter, NULL,
                             &intr_handle, &intr);
    cyg_drv_interrupt_attach(intr_handle);
    cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_PCI);
}
Example #21
0
static void spi_at91_init_bus(cyg_spi_at91_bus_t * spi_bus)
{
    cyg_uint32 ctr;
    // Create and attach SPI interrupt object
    cyg_drv_interrupt_create(spi_bus->interrupt_number,
                             4,                   
                             (cyg_addrword_t)spi_bus,   
                             spi_at91_ISR,
                             spi_at91_DSR,
                             &spi_bus->spi_interrupt_handle,
                             &spi_bus->spi_interrupt);

    cyg_drv_interrupt_attach(spi_bus->spi_interrupt_handle);

    // Init transfer mutex and condition
    cyg_drv_mutex_init(&spi_bus->transfer_mx);
    cyg_drv_cond_init(&spi_bus->transfer_cond, 
                      &spi_bus->transfer_mx);
   
    // Init flags
    spi_bus->transfer_end = true;
    spi_bus->cs_up        = false;
    
    // Soft reset the SPI controller
    HAL_WRITE_UINT32(spi_bus->base+AT91_SPI_CR, AT91_SPI_CR_SWRST);

    // Configure SPI pins
      

    // Put SPI chip select pins in IO output mode
    for(ctr = 0;ctr<4;ctr++)
    {
       if(spi_bus->cs_en[ctr])
       {
          HAL_ARM_AT91_GPIO_CFG_DIRECTION(spi_bus->cs_gpio[ctr],AT91_PIN_OUT);
          HAL_ARM_AT91_GPIO_SET(spi_bus->cs_gpio[ctr]);
       }
    }
    // Call upper layer bus init
    CYG_SPI_BUS_COMMON_INIT(&spi_bus->spi_bus);
}
static void sys_timer_init(void)
{
#ifdef CYGSEM_REDBOOT_BSP_SYSCALLS_GPROF
    HAL_CLOCK_INITIALIZE(set_period);
#else
    HAL_CLOCK_INITIALIZE(CYGNUM_HAL_RTC_PERIOD);
#endif // CYGSEM_REDBOOT_BSP_SYSCALLS_GPROF

    cyg_drv_interrupt_create(
        CYGNUM_HAL_INTERRUPT_RTC,
        0,                      // Priority - unused
        (CYG_ADDRWORD)0,        // Data item passed to ISR & DSR
        sys_timer_isr,          // ISR
        sys_timer_dsr,          // DSR
        &sys_timer_handle,      // handle to intr obj
        &sys_timer_interrupt ); // space for int obj

    cyg_drv_interrupt_attach(sys_timer_handle);

    cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_RTC);
}
Example #23
0
File: intr.c Project: 0xCA5A/dd-wrt
void intr_main( void )
{
    CYG_INTERRUPT_STATE oldints;

    cyg_drv_interrupt_create(CYGNUM_HAL_INTERRUPT_RTC, 1,
                             ISR_DATA, isr, NULL, &intr_handle, &intr);
    cyg_drv_interrupt_attach(intr_handle);
    HAL_CLOCK_INITIALIZE( CYGNUM_HAL_RTC_PERIOD );
    cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_RTC);

    HAL_ENABLE_INTERRUPTS();

    while( ticks < 10 )
    {
        
    }

    HAL_DISABLE_INTERRUPTS(oldints);

    CYG_TEST_PASS_FINISH("HAL interrupt test");
}
Example #24
0
void hal_clock_initialize(cyg_uint32 period)
{
    cyg_uint32 iocr;

    // Set counter GATE input low (0) to halt counter while it's being setup
    HAL_READ_UINT32(CYG_DEVICE_IOCR, iocr);
    iocr = (iocr & ~IOCR_CT0G) | IOCR_CT0G_LOW;
    HAL_WRITE_UINT32(CYG_DEVICE_IOCR, iocr);

    // Scale timer0 clock
    HAL_WRITE_UINT32(CYG_DEVICE_CPM_CT0CCR, CT_X16);

    // Initialize counter, mode 2 = rate generator
    HAL_WRITE_UINT8(CYG_DEVICE_TIMER_CTL, 
                    TIMER_CTL_TYPE_BIN|
                    TIMER_CTL_MODE_RG|
                    TIMER_CTL_RW_BOTH|
                    TIMER_CTL_SC_CTR0);
    HAL_WRITE_UINT8(CYG_DEVICE_TIMER0, (period & 0xFF));        // LSB
    HAL_WRITE_UINT8(CYG_DEVICE_TIMER0, ((period >> 8) & 0xFF)); // MSB
    // Enable timer
    iocr = (iocr & ~IOCR_CT0G) | IOCR_CT0G_HIGH;
    HAL_WRITE_UINT32(CYG_DEVICE_IOCR, iocr);
    _period = period;
#ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
    cyg_drv_interrupt_create(CYGNUM_HAL_INTERRUPT_EXT0,
                             99,           // Priority
                             0,            // Data item passed to interrupt handler
                             aeb_abort_isr,
                             0,
                             &abort_interrupt_handle,
                             &abort_interrupt);
    cyg_drv_interrupt_attach(abort_interrupt_handle);
    cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_EXT0);
#endif
#ifdef _TIMERS_TESTING
    aeb_setup_timer1(period/10);
#endif
}
Example #25
0
static void
lcd_panel_init(void)
{
    // Enable touch panel
    *(volatile cyg_uint8 *)PEDR   |= 0x04;  

    // Idle state (so interrupt works)
    *(volatile cyg_uint8 *)TOUCH_CTL = 0x70;  

    // Enable ADC machinery
    *(volatile cyg_uint32 *)SYSCON1 |= SYSCON1_ADC_CLOCK_128kHZ;

    cyg_drv_interrupt_create(CYGNUM_HAL_INTERRUPT_EINT2,
                             99,                     // Priority - what goes here?
                             0,                      //  Data item passed to interrupt handler
                             lcd_panel_isr,
                             lcd_panel_dsr,
                             &lcd_panel_interrupt_handle,
                             &lcd_panel_interrupt);
    cyg_drv_interrupt_attach(lcd_panel_interrupt_handle);
    cyg_drv_interrupt_acknowledge(CYGNUM_HAL_INTERRUPT_EINT2);
    cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_EINT2);
    // Set up the mbox for panel data
    cyg_mbox_create(&lcd_panel_events_mbox_handle, &lcd_panel_events_mbox);
    // This semaphore is set when there is a touch
    cyg_semaphore_init(&lcd_panel_sem, 0);  
    // Create a thread whose job it is to de-bounce the keyboard and
    // actually process the input, turning it into a series of events
    cyg_thread_create(10,                           // Priority - just a number
                      lcd_panel_server,             // entry
                      0,                            // initial parameter
                      "LCD_PANEL_server",           // Name
                      &lcd_panel_server_stack[0],   // Stack
                      STACK_SIZE,                   // Size
                      &lcd_panel_server_thread_handle,    // Handle
                      &lcd_panel_server_thread_data       // Thread data structure
            );
    cyg_thread_resume(lcd_panel_server_thread_handle);  // Start it
}
Example #26
0
bool netxeth_init(struct cyg_netdevtab_entry *tab)
{
  struct eth_drv_sc*  sc         = tab->device_instance;
  PNETX_ETH_PORT_INFO ptPortInfo = (PNETX_ETH_PORT_INFO)sc->driver_private;
  bool fRet = false;

  if(!xc_open(ptPortInfo->ulPort))
    return false;

  cyg_drv_interrupt_create(ptPortInfo->ulInterrupt, 
                           0, 
                           (unsigned)sc, 
                           netxeth_ISR, 
                           eth_drv_dsr, 
                           &ptPortInfo->hInterrupt,
                           &ptPortInfo->tInterruptObject);
  cyg_drv_interrupt_attach(ptPortInfo->hInterrupt);

  //TODO: insert xpec firmware pointer
  if(s_ptMiiMu &&
     s_pulxPECInterruptRegisters &&
     ptPortInfo->pulxPECBase &&
     ptPortInfo->pulxMACBase &&
     (ptPortInfo->pulSRAMBase || (ptPortInfo->ulPort == 0)) ) //port 0 may return a null pointer, as internal ram segment starts at 0
  {   
    if(!s_fPhyInitialized)
    {
      s_fPhyInitialized = InitInternalPHY();
    }

    ((sc)->funs->eth_drv->init)(sc, ptPortInfo->abMAC);
    netxeth_control(sc, ETH_DRV_SET_MAC_ADDRESS, ptPortInfo->abMAC, sizeof(ptPortInfo->abMAC));
    
    fRet = true;
  }
  
  return fRet;
}
// Function to initialize the device.  Called at bootstrap time.
static bool
quicc2pro_serial_init(struct cyg_devtab_entry *tab)
{
    serial_channel *chan = (serial_channel *)tab->priv;
    quicc2pro_serial_info *quicc2pro_chan = (quicc2pro_serial_info *)chan->dev_priv;
#ifdef CYGDBG_IO_INIT
    diag_printf("QUICC2PRO SERIAL init - dev: %x.%d\n", quicc2pro_chan->base, quicc2pro_chan->int_num);
#endif
    (chan->callbacks->serial_init)(chan);  // Really only required for interrupt driven devices
    if (chan->out_cbuf.len != 0) {
        cyg_drv_interrupt_create(quicc2pro_chan->int_num,
                                 0,         // can change IRQ0 priority
                                 (cyg_addrword_t)chan,   //  Data item passed to interrupt handler
                                 quicc2pro_serial_ISR,
                                 quicc2pro_serial_DSR,
                                 &quicc2pro_chan->serial_interrupt_handle,
                                 &quicc2pro_chan->serial_interrupt);
        cyg_drv_interrupt_attach(quicc2pro_chan->serial_interrupt_handle);
        cyg_drv_interrupt_unmask(quicc2pro_chan->int_num);
    }
    quicc2pro_serial_config_port(chan, &chan->config, true);
    return true;
}
Example #28
0
void intr_main( void )
{
    CYG_INTERRUPT_STATE oldints;

    cyg_drv_interrupt_create(CYGNUM_HAL_INTERRUPT_RTC, 1,
                             ISR_DATA, isr, dsr, &intr_handle, &intr);
    cyg_drv_interrupt_attach(intr_handle);
    HAL_CLOCK_INITIALIZE( CYGNUM_HAL_RTC_PERIOD );
    cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_RTC);

    HAL_ENABLE_INTERRUPTS();

    while( ticks < 10 )
    {
        
    }


    CYG_TEST_CHECK( dsr_ticks == 10, "DSR not called sufficient times");
    
    HAL_DISABLE_INTERRUPTS(oldints);

    CYG_TEST_PASS_FINISH("HAL interrupt test");
}
// Function to initialize the device.  Called at bootstrap time.
static bool
aaed2000_serial_init(struct cyg_devtab_entry *tab)
{
    serial_channel *chan = (serial_channel *)tab->priv;
    aaed2000_serial_info *aaed2000_chan = (aaed2000_serial_info *)chan->dev_priv;
#ifdef CYGDBG_IO_INIT
    diag_printf("AAED2000 SERIAL init - dev: 0x%08x.%d\n",
                aaed2000_chan->base, aaed2000_chan->int_num);
#endif
    (chan->callbacks->serial_init)(chan);  // Really only required for interrupt driven devices
    if (chan->out_cbuf.len != 0) {
        cyg_drv_interrupt_create(aaed2000_chan->int_num,
                                 1,                    // Priority - unused
                                 (cyg_addrword_t)chan, //  Data item passed to interrupt handler
                                 aaed2000_serial_ISR,
                                 aaed2000_serial_DSR,
                                 &aaed2000_chan->serial_interrupt_handle,
                                 &aaed2000_chan->serial_interrupt);
        cyg_drv_interrupt_attach(aaed2000_chan->serial_interrupt_handle);
        cyg_drv_interrupt_unmask(aaed2000_chan->int_num);
    }
    aaed2000_serial_config_port(chan, &chan->config, true);
    return true;
}
Example #30
0
/****************************************************************************
 Function: TskFunc_dacMode

 Description: This routine is the dual DAC mode example function.

 Inputs:      none
 Returns:     none
****************************************************************************/
void TskFunc_dacMode (void)
{
    unsigned int          p6228RegBaseAddr[4]; /* for all 4 VIM sites */
    P6228_REG_ADDR        p6228Regs[4];        /* for all 4 VIM sites */
    P6228_BOARD_PARAMS    p6228BoardParams[4]; /* for all 4 VIM sites */
    P6228_DAC_PARAMS      p6228DACParams[4];   /* for all 4 VIM sites */
    unsigned int          moduleId;
    int                   referenceClock;
    int                   cntr;
    volatile unsigned int flagDmaComplete[2];
    volatile unsigned int loopCount = LOOP_COUNT;
    volatile unsigned int valid;


    puts ("[dacMode] Entry\n");

    /* Turn all led's off */
    P4205_LED_OFF(P4205_BOARD_CNTL_STATUS, P4205_FP_LED_ALL);

    /* turn on "running" indicator */
    P4205_LED_ON(P4205_BOARD_CNTL_STATUS, P4205_FP_LED1);

    /* Initialize the address resources for all the VIM sites:
     *     Access Type = Power Pc
     *     Base address = 0, for Power PC
     */
    P4205VimInit(P4205_PPC_ACCESS, 0, p4205VimResource);

    puts ("[dacMode] Initialization\n");

    /* Reset and Release All VIM sites */
    P4205_RESET_VIM_ALL(P4205_BOARD_CNTL_STATUS);
    BaseboardDelayuS(10);
    P4205_RELEASE_VIM_ALL(P4205_BOARD_CNTL_STATUS);

    /* Detect if a VIM module is installed */
    if( (P4205_MODULE_PRESENT_VIM(P4205_BOARD_CNTL_STATUS, TOP_VIM_ID))     \
         == P4205_FALSE )
    {
        /* Vim module is either not installed OR not seated properly */
        P4205_LED_ON(P4205_BOARD_CNTL_STATUS, P4205_FP_LED0);
        P4205_LED_OFF(P4205_BOARD_CNTL_STATUS, P4205_FP_LED1);
        puts("[dacMode] failed to locate a Vim module.\n");
        TASK_EXIT();
    }

    /* Initialize the DMA complete flags to zero */
    flagDmaComplete[0] = 0;
    flagDmaComplete[1] = 0;


    /* get VIM base address, check module, allocate data table ----------- */

    /* assign the 6228 register base addresses for VIM sites */
    p6228RegBaseAddr[TOP_VIM_ID] =                                          \
                          ((p4205VimResource[TOP_VIM_ID]).VimAccessBase) +  \
                          P6228_CONTROL_ACCESS_SPACE;
    p6228RegBaseAddr[BOT_VIM_ID] =                                          \
                          ((p4205VimResource[BOT_VIM_ID]).VimAccessBase) +  \
                          P6228_CONTROL_ACCESS_SPACE;

    /* get module id; if module is not a 6228, indicate error */
    moduleId = VIMGetModuleId((unsigned int *) p6228RegBaseAddr[TOP_VIM_ID]);
    if( moduleId != P6228_MODULE_ID )
    {
        P4205_LED_ON(P4205_BOARD_CNTL_STATUS, P4205_FP_LED0);
        P4205_LED_OFF(P4205_BOARD_CNTL_STATUS, P4205_FP_LED1);
        puts ("[dacMode] failed to locate the 6228.\n");
        TASK_EXIT();
    }

    /* Allocate system memory for top_dataTable buffer */
    if( (top_dataTable = (int *)malloc((TABLE_SIZE*sizeof(int)) +    \
                                       HAL_DCACHE_LINE_SIZE))        \
         == NULL )
    {
        /* Failure in allocating memory from heap - check heap size */
        P4205_LED_ON(P4205_BOARD_CNTL_STATUS, P4205_FP_LED0);
        P4205_LED_OFF(P4205_BOARD_CNTL_STATUS, P4205_FP_LED1);
        puts("Unable to allocate memory for top_dataTable.\n");
        TASK_EXIT();
    }

    /* Align top_dataTable buffer for proper cache operations */
    top_dataTable = (int *)(((int)top_dataTable + (HAL_DCACHE_LINE_SIZE-1)) & \
                            (~(HAL_DCACHE_LINE_SIZE-1)));


    /* Allocate system memory for bot_dataTable buffer */
    if( (bot_dataTable = (int *)malloc((TABLE_SIZE*sizeof(int)) +    \
                                       HAL_DCACHE_LINE_SIZE))        \
         == NULL )
    {
        /* Failure in allocating memory from heap - check heap size */
        P4205_LED_ON(P4205_BOARD_CNTL_STATUS, P4205_FP_LED0);
        P4205_LED_OFF(P4205_BOARD_CNTL_STATUS, P4205_FP_LED1);
        puts("Unable to allocate memory for bot_dataTable.\n");
        TASK_EXIT();
    }

    /* Align bot_dataTable buffer for proper cache operations */
    bot_dataTable = (int *)(((int)bot_dataTable + (HAL_DCACHE_LINE_SIZE-1)) & \
                            (~(HAL_DCACHE_LINE_SIZE-1)));


    /* Initialize the 6228 using library routines ----------------------- */

    /* Initialize 6228 register address table  */
    P6228InitRegAddr (p6228RegBaseAddr[TOP_VIM_ID], &p6228Regs[TOP_VIM_ID]);
    P6228InitRegAddr (p6228RegBaseAddr[BOT_VIM_ID], &p6228Regs[BOT_VIM_ID]);

    /* Reset board registers to default values */
    P6228ResetRegs (&p6228Regs[TOP_VIM_ID]);
    P6228ResetRegs (&p6228Regs[BOT_VIM_ID]);

    /* Set 6228 board parameter table to default values */
    P6228SetBoardDefaults (&p6228BoardParams[TOP_VIM_ID]);
    P6228SetBoardDefaults (&p6228BoardParams[BOT_VIM_ID]);

    /* Set 6228 DAC parameter table to default values */
    P6228SetDACDefaults (&p6228DACParams[TOP_VIM_ID]);
    P6228SetDACDefaults (&p6228DACParams[BOT_VIM_ID]);


    /* Modifications to default board parameters. -------------------------
     *
     * Note: when board parameters are for registers addressable by VIM nodes
     * A or C (depending on installed location of the 6228), only TOP_VIM_ID
     * parameters are set.
     */

    /* make the 6228 a sync master and terminate the sync bus */
    p6228BoardParams[TOP_VIM_ID].syncControl     = P6228_SYNC_BUS_MASTER;
    p6228BoardParams[TOP_VIM_ID].syncTermination = P6228_TERMINATED;

    /* set clock parameters based on use of internal or external clock */
    if (CLOCK_SOURCE == INTERNAL)
    {
        p6228BoardParams[TOP_VIM_ID].clockSelect       = P6228_ONBOARD_CLOCK; /* default */
        p6228BoardParams[TOP_VIM_ID].onboardOscDisable = P6228_OSC_ENABLE;    /* default */
        referenceClock                                 = INT_REF_CLOCK;
    }
    else           /* using an external clock */
    {
        p6228BoardParams[TOP_VIM_ID].clockSelect       = P6228_EXT_CLOCK;
        p6228BoardParams[TOP_VIM_ID].onboardOscDisable = P6228_OSC_DISABLE;
        referenceClock                                 = EXT_REF_CLOCK;
    }

    /* select FIFO clock source by selecting either P6228_DAC_CLK_SELECT or
     * P6228_DAC_CLK_BYPASS.
     *
     * When P6228_DAC_CLK_SELECT is chosen, the FIFO clock is from the
     * PLLLOCK pin on the DAC5686.  A clock is present only when the
     * DAC5686's PLL is disabled and is not in dual clock mode.
     *
     * When P6228_DAC_CLK_BYPASS is selected, the FIFO clock is the VIM clock
     * supplied to the two DAC5686's on the 6228.
     */
    p6228BoardParams[TOP_VIM_ID].DACClkSel  = P6228_DAC_CLK_SELECT;
    p6228BoardParams[TOP_VIM_ID].DACPllVdd  = P6228_PLL_VDD_DISABLE;

    p6228BoardParams[BOT_VIM_ID].DACClkSel  = P6228_DAC_CLK_SELECT;
    p6228BoardParams[BOT_VIM_ID].DACPllVdd  = P6228_PLL_VDD_DISABLE;

    /* packing mode - the program default packing mode is the ReadyFlow
     * default, P6228_PACK_MODE_CHANNEL_PACK.  This can be changed using the
     * PACK_MODE define at the top of the program.  The 6228 Packing Modes
     * do not specify if this data is real or complex.  This information is
     * needed to generate the data table and the DATA_TYPE define is provided
     * with the PACK_MODE define above.
     */
    p6228BoardParams[TOP_VIM_ID].packMode = PACK_MODE;
    p6228BoardParams[BOT_VIM_ID].packMode = PACK_MODE;


    /* Modifications to default DAC parameters. ------------------------ */

    /* DAC full bypass mode - to use the DAC5686 in full bypass mode, the
     * DAC5686 must also be set to dual clock mode (P6228_DAC_DUAL_CLOCK).
     * The internal PLL must be disabled and the DAC Clock from the PLLLOCK
     * pin cannot be used.  These are both board parameters.  Parameters for
     * the DAC6586 at both VIM sites are set identically.
     */

    p6228DACParams[TOP_VIM_ID].bypassMode = P6228_DAC_FULL_BYPASS_DISABLE;
    if (p6228DACParams[TOP_VIM_ID].bypassMode == P6228_DAC_FULL_BYPASS_ENABLE)
    {
        /* set for dual clock mode */
        p6228DACParams[TOP_VIM_ID].dualClockMode = P6228_DAC_DUAL_CLOCK;

        /* set board parameters */
        p6228BoardParams[TOP_VIM_ID].DACClkSel = P6228_DAC_CLK_BYPASS;
        p6228BoardParams[TOP_VIM_ID].DACPllVdd = P6228_PLL_VDD_DISABLE;
    }

    p6228DACParams[BOT_VIM_ID].bypassMode = P6228_DAC_FULL_BYPASS_DISABLE;
    if (p6228DACParams[BOT_VIM_ID].bypassMode == P6228_DAC_FULL_BYPASS_ENABLE)
    {
        /* set for dual clock mode */
        p6228DACParams[BOT_VIM_ID].dualClockMode = P6228_DAC_DUAL_CLOCK;

        /* set board parameters */
        p6228BoardParams[BOT_VIM_ID].DACClkSel = P6228_DAC_CLK_BYPASS;
        p6228BoardParams[BOT_VIM_ID].DACPllVdd = P6228_PLL_VDD_DISABLE;
    }


    /* if not in full bypass mode, we can choose between the PLL clock or
     * an internal divided clock for the DAC5686.  The choice will determine
     * what clock we can use for the FIFO.
     */
    else
    {
        if (p6228BoardParams[TOP_VIM_ID].DACPllVdd == P6228_PLL_VDD_ENABLE)
        {
            /* just to make sure we've bypassed the DAC clock when the PLL
             * is enabled.
             */
            p6228BoardParams[TOP_VIM_ID].DACClkSel  = P6228_DAC_CLK_BYPASS;

            /* select PLL divider ratio to X 1, X 2, X 4 or X 8 */
            p6228DACParams[TOP_VIM_ID].pllDividerRatio = P6228_DAC_PLL_DIVIDER_RATIO_X_1;
        }

        if (p6228BoardParams[BOT_VIM_ID].DACPllVdd == P6228_PLL_VDD_ENABLE)
        {
            /* just to make sure we've bypassed the DAC clock when the PLL
             * is enabled.
             */
            p6228BoardParams[BOT_VIM_ID].DACClkSel  = P6228_DAC_CLK_BYPASS;

            /* select PLL divider ratio to X 1, X 2, X 4 or X 8 */
            p6228DACParams[BOT_VIM_ID].pllDividerRatio = P6228_DAC_PLL_DIVIDER_RATIO_X_1;
        }


        /* if the PLL is disabled, we can select the VIM clock or the clock on
         * the DAC6586 PLLLOCK pin.  By selecting FIR filter, the FIFO clock
         * will be the VIM clock divided by 2, 4, 8 or 16.
         */

         p6228DACParams[TOP_VIM_ID].filterSelect = P6228_DAC_INTERP_FIR_FILTER_X_2;
         p6228DACParams[BOT_VIM_ID].filterSelect = P6228_DAC_INTERP_FIR_FILTER_X_2;
    }

    /* allow NCO sync */
    p6228DACParams[TOP_VIM_ID].phstrSync = P6228_DAC_PHSTR_SYNC_ENABLED;
    p6228DACParams[BOT_VIM_ID].phstrSync = P6228_DAC_PHSTR_SYNC_ENABLED;

    /* nominally set gain */
    p6228DACParams[TOP_VIM_ID].dacAGain  = 0xFFF;
    p6228DACParams[TOP_VIM_ID].dacBGain  = 0xFFF;
    p6228DACParams[BOT_VIM_ID].dacAGain  = 0xFFF;
    p6228DACParams[BOT_VIM_ID].dacBGain  = 0xFFF;

    /* our data table will always be two's compliment in this program */
    p6228DACParams[TOP_VIM_ID].inputMode = P6228_DAC_DATA_IN_TWOS_COMPLIMENT;
    p6228DACParams[BOT_VIM_ID].inputMode = P6228_DAC_DATA_IN_TWOS_COMPLIMENT;


    /* Set up 6228 for program operation ------------------------------- */

    /* Initialize Board Registers */
    P6228InitBoardRegs(&p6228BoardParams[TOP_VIM_ID], &p6228Regs[TOP_VIM_ID]);
    P6228InitBoardRegs(&p6228BoardParams[BOT_VIM_ID], &p6228Regs[BOT_VIM_ID]);

    /* Initialize DAC Registers */
    P6228InitDACRegs(referenceClock, &p6228DACParams[TOP_VIM_ID], &p6228BoardParams[TOP_VIM_ID], &p6228Regs[TOP_VIM_ID]);
    displayDACRegs(&p6228Regs[TOP_VIM_ID]);
    P6228InitDACRegs(referenceClock, &p6228DACParams[BOT_VIM_ID], &p6228BoardParams[BOT_VIM_ID], &p6228Regs[BOT_VIM_ID]);
    displayDACRegs(&p6228Regs[BOT_VIM_ID]);

    /* generate data table */
    if (DAC_DATA_TYPE == DC_DAC_DATA)
    {
        /* set both halfs of every table word with a DC value */
        for (cntr = 0; cntr < TABLE_SIZE; cntr++)
            top_dataTable [cntr] = 0x80008000;
    }
    else                               /* DAC_DATA_TYPE == AC_DAC_DATA */
    {
        /* Calculate data tables - TABLE_SIZE, DATA_TYPE, DATA_SIZE and
         * PACK_MODE are defines at the top of the program.
         */
        if (tableGen (top_dataTable, TABLE_SIZE, DATA_TYPE, DATA_SIZE, PACK_MODE) == 1)
        {
            P4205_LED_ON(P4205_BOARD_CNTL_STATUS, P4205_FP_LED0);
            P4205_LED_OFF(P4205_BOARD_CNTL_STATUS, P4205_FP_LED1);
            puts ("[dacMode] invalid data table parameters specified.\n");
            TASK_EXIT();
        }
    }
    memcpy (bot_dataTable, top_dataTable, TABLE_SIZE*sizeof(int));


    /* Set up BiFIFO --------------------------------------------------- */

    /* check that the clock set up is valid */
    if (P6228CalcBifoClock (&p6228BoardParams[TOP_VIM_ID],
                            &p6228DACParams[TOP_VIM_ID],
                            referenceClock) == -1)
    {
        P4205_LED_ON(P4205_BOARD_CNTL_STATUS, P4205_FP_LED0);
        P4205_LED_OFF(P4205_BOARD_CNTL_STATUS, P4205_FP_LED1);
        puts ("[dacMode] Invalid clock set up.\n");
        TASK_EXIT();
    }
    if (P6228CalcBifoClock (&p6228BoardParams[BOT_VIM_ID],
                            &p6228DACParams[BOT_VIM_ID],
                            referenceClock) == -1)
    {
        P4205_LED_ON(P4205_BOARD_CNTL_STATUS, P4205_FP_LED0);
        P4205_LED_OFF(P4205_BOARD_CNTL_STATUS, P4205_FP_LED1);
        puts ("[dacMode] Invalid clock set up.\n");
        TASK_EXIT();
    }

    /* Verify clock is valid for both VIM sites before flushing the BiFIFOs. */
    do
    {
        valid = P6228_VALID_CLOCK_CHECK_REG(p6228Regs[TOP_VIM_ID].interruptStatus);
        BaseboardDelayuS(1);
    } while (!valid);
    do
    {
        valid = P6228_VALID_CLOCK_CHECK_REG(p6228Regs[BOT_VIM_ID].interruptStatus);
        BaseboardDelayuS(1);
    } while (!valid);

    /* Flush the Bifo, and program BIFO thresholds. */
    P4205FlushVimBifo(p4205VimResource,    /* Vim Resource base */
                      TOP_VIM_ID,          /* Vim interface Id */
                      BIFOSIZE,            /* BIFO Size */
                      BIFOSIZE-10,         /* Output almost-full level */
                      512,                 /* Output almost-empty level */
                      BIFOSIZE-10,         /* Input almost-full level */
                      512);                /* Input almost-empty level */

    P4205FlushVimBifo(p4205VimResource,    /* Vim Resource base */
                      BOT_VIM_ID,          /* Vim interface Id */
                      BIFOSIZE,            /* BIFO Size */
                      BIFOSIZE-10,         /* Output almost-full level */
                      512,                 /* Output almost-empty level */
                      BIFOSIZE-10,         /* Input almost-full level */
                      512);                /* Input almost-empty level */

    /* Flush data to memory buffer and send first buffer of data */
    /* Flush the cache before data transmit */
    HAL_DCACHE_FLUSH(top_dataTable, (TABLE_SIZE*sizeof(int)));
    HAL_DCACHE_FLUSH(bot_dataTable, (TABLE_SIZE*sizeof(int)));


    /* if the DAC5686 is in PLL mode, check for PLL lock */
    if (p6228BoardParams[TOP_VIM_ID].DACClkSel == P6228_DAC_CLK_BYPASS)
    {
        if (P6228_GET_DAC_CTRL_PLL_LOCK(p6228Regs[TOP_VIM_ID].dacControlStatus) ==
            P6228_PLL_UNLOCKED)
        {
            P4205_LED_ON(P4205_BOARD_CNTL_STATUS, P4205_FP_LED0);
            P4205_LED_OFF(P4205_BOARD_CNTL_STATUS, P4205_FP_LED1);
            puts ("[dacMode] DAC6586 PLL not locked.\n");
            TASK_EXIT();
        }
    }
    if (p6228BoardParams[BOT_VIM_ID].DACClkSel == P6228_DAC_CLK_BYPASS)
    {
        if (P6228_GET_DAC_CTRL_PLL_LOCK(p6228Regs[BOT_VIM_ID].dacControlStatus) ==
            P6228_PLL_UNLOCKED)
        {
            P4205_LED_ON(P4205_BOARD_CNTL_STATUS, P4205_FP_LED0);
            P4205_LED_OFF(P4205_BOARD_CNTL_STATUS, P4205_FP_LED1);
            puts ("[dacMode] DAC6586 PLL not locked.\n");
            TASK_EXIT();
        }
    }

    /* generate a sync signal to sync the DAC5686 */
    if (!P6228SyncGenerate (&p6228Regs[TOP_VIM_ID]))
    {
        P4205_LED_ON(P4205_BOARD_CNTL_STATUS, P4205_FP_LED0);
        P4205_LED_OFF(P4205_BOARD_CNTL_STATUS, P4205_FP_LED1);
        puts ("[dacMode] sync line held reset by another process.\n");
        TASK_EXIT();
    }


    /* Disable interrupts */
    PLX9656DmaToPciIntDisable((p4205VimResource[TOP_VIM_ID]).Plx9656Base,
                              PLX9656_DMA_CH(TOP_VIM_ID%2));
    PLX9656DmaToPciIntDisable((p4205VimResource[BOT_VIM_ID]).Plx9656Base,
                              PLX9656_DMA_CH(BOT_VIM_ID%2));

    PLX9656DmaDoneIntDisable((p4205VimResource[TOP_VIM_ID]).Plx9656Base,
                             PLX9656_DMA_CH(TOP_VIM_ID%2));
    PLX9656DmaDoneIntDisable((p4205VimResource[BOT_VIM_ID]).Plx9656Base,
                             PLX9656_DMA_CH(BOT_VIM_ID%2));


    /* Pre-initialize DMA configuration parameters for data acquistion */

    /* Abort any existing transfers */
    PLX9656DmaAbort((p4205VimResource[TOP_VIM_ID]).Plx9656Base,
                    PLX9656_DMA_CH(TOP_VIM_ID%2));
    PLX9656DmaAbort((p4205VimResource[BOT_VIM_ID]).Plx9656Base,
                    PLX9656_DMA_CH(BOT_VIM_ID%2));

    /* Write DMA register values for Top Vim site */
    PLX9656DmaSetup((p4205VimResource[TOP_VIM_ID]).Plx9656Base,
                    PLX9656_DMA_CH(TOP_VIM_ID%2),
                    (PLX9656_DMAMODE_LCL_BUS_WIDTH_32_BIT | /* Mode */
                     PLX9656_DMAMODE_TA_READY_ENABLE      |
                     PLX9656_DMAMODE_LCL_BURST_ENABLE     |
                     PLX9656_DMAMODE_DONE_INT_DISABLE     |
                     PLX9656_DMAMODE_LCL_ADDR_CONSTANT    |
                     PLX9656_DMAMODE_DEMAND_MODE_DISABLE),
                    (unsigned int) top_dataTable,           /* PCI address */
                    (p4205VimResource[TOP_VIM_ID]).bifo,    /* Local address */
                    (TABLE_SIZE*sizeof(int)),               /* Transfer size */
                    (PLX9656_DMADPR_DESCRIPT_LOC_LCL      | /* Descriptor */
                     PLX9656_DMADPR_END_OF_CHAIN_DISABLE  |
                     PLX9656_DMADPR_TERM_COUNT_INT_ENABLE |
                     PLX9656_DMADPR_XFER_DIR_PCI2LCL));
    PLX9656DmaSetup((p4205VimResource[BOT_VIM_ID]).Plx9656Base,
                    PLX9656_DMA_CH(BOT_VIM_ID%2),
                    (PLX9656_DMAMODE_LCL_BUS_WIDTH_32_BIT | /* Mode */
                     PLX9656_DMAMODE_TA_READY_ENABLE      |
                     PLX9656_DMAMODE_LCL_BURST_ENABLE     |
                     PLX9656_DMAMODE_DONE_INT_DISABLE     |
                     PLX9656_DMAMODE_LCL_ADDR_CONSTANT    |
                     PLX9656_DMAMODE_DEMAND_MODE_DISABLE),
                    (unsigned int) bot_dataTable,           /* PCI address */
                    (p4205VimResource[BOT_VIM_ID]).bifo,    /* Local address */
                    (TABLE_SIZE*sizeof(int)),               /* Transfer size */
                    (PLX9656_DMADPR_DESCRIPT_LOC_LCL      | /* Descriptor */
                     PLX9656_DMADPR_END_OF_CHAIN_DISABLE  |
                     PLX9656_DMADPR_TERM_COUNT_INT_ENABLE |
                     PLX9656_DMADPR_XFER_DIR_PCI2LCL));

    /* Start Top and Bottom VIM DMAs */
    PLX9656_DMA_START((p4205VimResource[TOP_VIM_ID]).Plx9656Base,        \
                       PLX9656_DMA_CH(TOP_VIM_ID%2));
    PLX9656_DMA_START((p4205VimResource[BOT_VIM_ID]).Plx9656Base,        \
                       PLX9656_DMA_CH(BOT_VIM_ID%2));


    /* Wait until done */
    while( !PLX9656_DMA_DONE((p4205VimResource[TOP_VIM_ID]).Plx9656Base, \
                             PLX9656_DMA_CH(TOP_VIM_ID%2)) )
        ;
    while( !PLX9656_DMA_DONE((p4205VimResource[BOT_VIM_ID]).Plx9656Base, \
                             PLX9656_DMA_CH(BOT_VIM_ID%2)) )
        ;


    /* Change to DMA Demand mode, and Enable DMA Done Interrupt */
    PLX9656_DMA_SET_MODE((p4205VimResource[TOP_VIM_ID]).Plx9656Base,
                         PLX9656_DMA_CH(TOP_VIM_ID%2),
                         (PLX9656_DMAMODE_LCL_BUS_WIDTH_32_BIT | /* Mode */
                          PLX9656_DMAMODE_TA_READY_ENABLE      |
                          PLX9656_DMAMODE_LCL_BURST_ENABLE     |
                          PLX9656_DMAMODE_DONE_INT_ENABLE      |
                          PLX9656_DMAMODE_LCL_ADDR_CONSTANT    |
                          PLX9656_DMAMODE_DEMAND_MODE_ENABLE));
    PLX9656_DMA_SET_MODE((p4205VimResource[BOT_VIM_ID]).Plx9656Base,
                         PLX9656_DMA_CH(BOT_VIM_ID%2),
                         (PLX9656_DMAMODE_LCL_BUS_WIDTH_32_BIT | /* Mode */
                          PLX9656_DMAMODE_TA_READY_ENABLE      |
                          PLX9656_DMAMODE_LCL_BURST_ENABLE     |
                          PLX9656_DMAMODE_DONE_INT_ENABLE      |
                          PLX9656_DMAMODE_LCL_ADDR_CONSTANT    |
                          PLX9656_DMAMODE_DEMAND_MODE_ENABLE));


    /* Initialize interrupts ----------------------------------------- */
    /* Note that the top and bottom VIM channels SHARE the SAME interrupt */

    /* Clear any pending interrupt conditions */
    PLX9656DmaIntClear((p4205VimResource[TOP_VIM_ID]).Plx9656Base,
                       PLX9656_DMA_CH(TOP_VIM_ID%2));
    PLX9656DmaIntClear((p4205VimResource[BOT_VIM_ID]).Plx9656Base,
                       PLX9656_DMA_CH(BOT_VIM_ID%2));

    /* Map PLX DMA complete interrupt handler into the dispatcher.  The
     * PLXDmaDone_isr() interrupt handler will handle BOTH channels.
     */
    cyg_drv_interrupt_create(P4205_GTMPP_INTVEC(                         \
                              (p4205VimResource[TOP_VIM_ID]).            \
                              GT64260MPP.gppNum_Plx9656Int),   // Interrupt vector
                             1,                                // priority - not used
                             (cyg_addrword_t)flagDmaComplete,  // User Data
                             (cyg_ISR_t *)PLXDmaDone_isr,      // Isr
                             NULL,                             // No DSR
                             &plxDma_hIntr,                    // Interrupt Handle
                             &plxDma_oIntr);                   // Interrupt Object

    /* Attach the interrupt */
    cyg_drv_interrupt_attach(plxDma_hIntr);


    /* Enable DMA Complete interrupt */
    PLX9656DmaToPciIntEnable((p4205VimResource[TOP_VIM_ID]).Plx9656Base,
                             PLX9656_DMA_CH(TOP_VIM_ID%2));
    PLX9656DmaDoneIntEnable((p4205VimResource[TOP_VIM_ID]).Plx9656Base,
                            PLX9656_DMA_CH(TOP_VIM_ID%2));

    PLX9656DmaToPciIntEnable((p4205VimResource[BOT_VIM_ID]).Plx9656Base,
                             PLX9656_DMA_CH(BOT_VIM_ID%2));
    PLX9656DmaDoneIntEnable((p4205VimResource[BOT_VIM_ID]).Plx9656Base,
                            PLX9656_DMA_CH(BOT_VIM_ID%2));


    /* Enable PLX9656 interrupt.  Top and bottom VIMs are connected to the
     * same GPP pin.
     */
    cyg_drv_interrupt_unmask(P4205_GTMPP_INTVEC(                         \
                              (p4205VimResource[TOP_VIM_ID]).            \
                              GT64260MPP.gppNum_Plx9656Int));

    /* Enable Direct BIFO Write Access for Demand mode */
    P4205_VIM_DMA_RQST_BIFO_WRITE(p4205VimResource, TOP_VIM_ID);
    P4205_VIM_DMA_RQST_BIFO_WRITE(p4205VimResource, BOT_VIM_ID);


    /* main loop --------------------------------------------------- */

    /* Turn third green LED to indicate main loop entry */
    P4205_LED_ON(P4205_BOARD_CNTL_STATUS, P4205_FP_LED3);

    /* enable FIFO reads */
    P6228_ENABLE_FIFO_READ(p6228Regs[TOP_VIM_ID].syncGateGenerator);
    P6228_REG_READ(p6228Regs[TOP_VIM_ID].syncGateGenerator);  /* dummy read */
    P6228_ENABLE_FIFO_READ(p6228Regs[BOT_VIM_ID].syncGateGenerator);
    P6228_REG_READ(p6228Regs[BOT_VIM_ID].syncGateGenerator);  /* dummy read */

    puts ("[dacMode] Running\n");

    while (loopCount--)
    {
        /* Indicate activity */
        P4205_LED_TOGGLE(P4205_BOARD_CNTL_STATUS, P4205_FP_LED3);

        /* Start Top VIM DMA */
        PLX9656_DMA_START((p4205VimResource[TOP_VIM_ID]).Plx9656Base,       \
                           PLX9656_DMA_CH(TOP_VIM_ID%2));

        /* Start Bottom VIM DMA */
        PLX9656_DMA_START((p4205VimResource[BOT_VIM_ID]).Plx9656Base,       \
                           PLX9656_DMA_CH(BOT_VIM_ID%2));

        /* Wait for DMAs to complete (flags set in ISR) */
        while( !(flagDmaComplete[0]) && !(flagDmaComplete[1]) )
            ;

        /* clear DMA complete flags */
        flagDmaComplete[0] = 0;
        flagDmaComplete[1] = 0;
    }                                  /* end if main loop */

    /* turn off "running" and "activity" indicators */
    P4205_LED_OFF(P4205_BOARD_CNTL_STATUS, P4205_FP_LED1);
    P4205_LED_OFF(P4205_BOARD_CNTL_STATUS, P4205_FP_LED3);

    free(top_dataTable);
    free(bot_dataTable);

    puts ("[dacMode] program done.");

    TASK_EXIT();
}