示例#1
0
文件: irq.c 项目: bietje/andromeda
int
native_setup_irq_handler(unsigned int irq)
{
  struct irq_data *data = get_irq_data(irq);
  if(data->handle == NULL)
  {
    return -E_NULL_PTR;
  }
  else
  {
    setup_irq_handler(irq);
  }

  /* now we check if we might have to reset some values.. */
  if(data->base_handle == NULL || data->base_handle == &do_irq)
  {
    data->base_handle = &do_irq;
    return -E_SUCCESS;
  }
  else
  {
    /*
     * A different base handler has to be used.
     */
    writel((void*)data->irq_base+DYNAMIC_IRQ_HANDLER_VALUE, (uint32_t)data->
                                                                   base_handle);
  }
  return 0;
}
示例#2
0
文件: irq.c 项目: bietje/andromeda
uint32_t
debug_dynamic_irq()
{
  struct irq_data *data = alloc_irq();
  setup_irq_handler(data->irq);
  debug("irq: %x - vector: %x\n", data->irq, data->irq_config->vector);
  install_irq_vector(data);
  return data->irq_config->vector;
}
示例#3
0
/* UDC ISR function */
void INT_UDC(void)
{
    uint32_t txstat, rxstat;

    /* read what caused UDC irq */
    uint32_t intsrc = INT2FLAG & 0x7fffff;

   if (intsrc & USBRST_INTR) /* usb reset */
    {
        EN_INT = EN_SUSP_INTR   |  /* Enable Suspend Irq */
                 EN_RESUME_INTR |  /* Enable Resume Irq */
                 EN_USBRST_INTR |  /* Enable USB Reset Irq */
                 EN_OUT0_INTR   |  /* Enable OUT Token receive Irq EP0 */
                 EN_IN0_INTR    |  /* Enable IN Token transmit Irq EP0 */
                 EN_SETUP_INTR;    /* Enable SETUP Packet Receive Irq */

        TX0CON = TXACKINTEN |      /* Set as one to enable the EP0 tx irq */
                 TXNAK;            /* Set as one to response NAK handshake */

        RX0CON = RXACKINTEN |
                 RXEPEN     |      /* Endpoint 0 Enable. When cleared the
                                    * endpoint does not respond to an SETUP
                                    * or OUT token */
                 RXNAK;            /* Set as one to response NAK handshake */

        usb_drv_rcv_done = true;
    }

    if (intsrc & SETUP_INTR)       /* setup interrupt */
    {
        setup_irq_handler();
    }

    if (intsrc & IN0_INTR)         /* ep0 in interrupt */
    {
        txstat = TX0STAT;          /* read clears flags */

        /* TODO handle errors */
        if (txstat & TXACK)        /* check TxACK flag */
        {
            /* Decrement by max packet size is intentional.
             * This way if we have final packet short one we will get negative len
             * after transfer, which in turn indicates we *don't* need to send
             * zero length packet. If the final packet is max sized packet we will
             * get zero len after transfer which indicates we need to send
             * zero length packet to signal host end of the transfer.
             */
            if (ctrlep[DIR_IN].cnt > 0)
            {
                /* we still have data to send */
                ep0_in_dma_setup();

            }
            else
            {
                if (ctrlep[DIR_IN].cnt == 0)
                {
                    ep0_in_dma_setup();
                }

                /* final ack received */
                usb_drv_send_done = true;
            }
        }
    }

    if (intsrc & OUT0_INTR)        /* ep0 out interrupt */
    {
        rxstat = RX0STAT;

        /* TODO handle errors */
        if (rxstat & RXACK)        /* RxACK */
        {
            int xfer_size = rxstat & 0x7ff;
            ctrlep[DIR_OUT].cnt -= xfer_size;

            if (ctrlep[DIR_OUT].cnt > 0 && xfer_size == 64)
            {
                /* advance the buffer */
                ctrlep[DIR_OUT].buf += xfer_size;
                ep0_out_dma_setup();
            }
            else
                usb_drv_rcv_done = true;
        }
    }

    if (intsrc & RESUME_INTR)      /* usb resume */
    {
        TX0CON |=  TXCLR;          /* TxClr */
        TX0CON &= ~TXCLR;

        RX0CON |=  RXCLR;          /* RxClr */
        RX0CON &= ~RXCLR;
    }
}