uint8_t UARTDevice::Read8(uint32_t offset) {
  uint8_t ret;

  if (LCR & UART_LCR_DLAB) {
    switch (offset) {
    case UART_DLL:
      return DLL;
      break;
    case UART_DLH:
      return DLH;
      break;
    }
  }
  switch (offset) {
  case 0:
    ret = input;
    input = 0;
    ClearInterrupt(UART_IIR_RDI);
    ClearInterrupt(UART_IIR_CTI);
    {
      std::lock_guard<std::mutex> lock(fifoMutex);

      if (fifo.size() >= 1) {
        input = fifo.front();
        fifo.pop();
        LSR |= UART_LSR_DATA_READY;
      } else {
        LSR &= ~UART_LSR_DATA_READY;
      }
    }
    return ret;
  case UART_IER:
    return IER & 0x0F;
  case UART_MSR:
    return MSR;
  case UART_IIR:
    {
      ret = (IIR & 0x0f) | 0xC0; // the two top bits are always set
      if (IIR == UART_IIR_THRI) {
        ClearInterrupt(UART_IIR_THRI);
      }
      return ret;
    }
  case UART_LCR:
    return LCR;
  case UART_LSR:
    return LSR;

  default:
    cpu->DebugMessage("INFO (UART): 8-bit read of unsupported offset 0x%08x", offset);
    return 0;
  }
}
Esempio n. 2
0
static irqreturn_t isicom_interrupt(int irq, void *dev_id)
{
	struct isi_board *card = dev_id;
	struct isi_port *port;
	struct tty_struct *tty;
	unsigned long base;
	u16 header, word_count, count, channel;
	short byte_count;
	unsigned char *rp;

	if (!card || !(card->status & FIRMWARE_LOADED))
		return IRQ_NONE;

	base = card->base;

	/* did the card interrupt us? */
	if (!(inw(base + 0x0e) & 0x02))
		return IRQ_NONE;

	spin_lock(&card->card_lock);

	/*
	 * disable any interrupts from the PCI card and lower the
	 * interrupt line
	 */
	outw(0x8000, base+0x04);
	ClearInterrupt(base);

	inw(base);		/* get the dummy word out */
	header = inw(base);
	channel = (header & 0x7800) >> card->shift_count;
	byte_count = header & 0xff;

	if (channel + 1 > card->port_count) {
		printk(KERN_WARNING "ISICOM: isicom_interrupt(0x%lx): "
			"%d(channel) > port_count.\n", base, channel+1);
		outw(0x0000, base+0x04); /* enable interrupts */
		spin_unlock(&card->card_lock);
		return IRQ_HANDLED;
	}
	port = card->ports + channel;
	if (!(port->flags & ASYNC_INITIALIZED)) {
		outw(0x0000, base+0x04); /* enable interrupts */
		spin_unlock(&card->card_lock);
		return IRQ_HANDLED;
	}

	tty = port->tty;
	if (tty == NULL) {
		word_count = byte_count >> 1;
		while(byte_count > 1) {
			inw(base);
			byte_count -= 2;
		}
		if (byte_count & 0x01)
			inw(base);
		outw(0x0000, base+0x04); /* enable interrupts */
		spin_unlock(&card->card_lock);
		return IRQ_HANDLED;
	}
Esempio n. 3
0
void CPdd6410Uart::PostInit()
{
    DWORD dwCount=0;
    m_HardwareLock.Lock();
    m_pReg6410Uart->Write_UCON(0); // Set to Default;
    DisableInterrupt(S6410UART_INT_RXD | S6410UART_INT_TXD | S6410UART_INT_ERR | S6410UART_INT_MODEM);
    // Mask all interrupt.
    while ((GetInterruptStatus() & (S6410UART_INT_RXD | S6410UART_INT_TXD | S6410UART_INT_ERR | S6410UART_INT_MODEM))!=0 && dwCount <MAX_RETRY)
    {
        InitReceive(TRUE);
        InitLine(TRUE);
        ClearInterrupt(S6410UART_INT_RXD | S6410UART_INT_TXD | S6410UART_INT_ERR | S6410UART_INT_MODEM);
        dwCount++;
    } 
    ASSERT((GetInterruptStatus() & (S6410UART_INT_RXD | S6410UART_INT_TXD | S6410UART_INT_ERR | S6410UART_INT_MODEM))==0);
    m_HardwareLock.Unlock();
    CSerialPDD::PostInit();
    CeSetPriority(m_dwPriority256);
#ifdef DEBUG
    if ( ZONE_INIT )
    {
        m_pReg6410Uart->DumpRegister();
    }
#endif
    ThreadStart();  // Start IST.
}
void Timer_ConfigureInterrupt(void)
{
  SetInterruptHandler();
  ConfigureInterruptSourceModeRegister();
  ClearInterrupt();
  EnableCompareInterruptForRegisterC();
}
Esempio n. 5
0
int IntrHandler(void *arg) {
	unsigned int source;

	source = ClearInterrupt();
	printk(KERN_DEBUG PFX "Received PPS IRQ source=%08x\n", source);

	return 0;
}
static irqreturn_t isicom_interrupt(int irq, void *dev_id)
{
	struct isi_board *card = dev_id;
	struct isi_port *port;
	struct tty_struct *tty;
	unsigned long base;
	u16 header, word_count, count, channel;
	short byte_count;
	unsigned char *rp;

	if (!card || !(card->status & FIRMWARE_LOADED))
		return IRQ_NONE;

	base = card->base;

	
	if (!(inw(base + 0x0e) & 0x02))
		return IRQ_NONE;

	spin_lock(&card->card_lock);

	outw(0x8000, base+0x04);
	ClearInterrupt(base);

	inw(base);		
	header = inw(base);
	channel = (header & 0x7800) >> card->shift_count;
	byte_count = header & 0xff;

	if (channel + 1 > card->port_count) {
		pr_warning("%s(0x%lx): %d(channel) > port_count.\n",
			   __func__, base, channel+1);
		outw(0x0000, base+0x04); 
		spin_unlock(&card->card_lock);
		return IRQ_HANDLED;
	}
	port = card->ports + channel;
	if (!(port->port.flags & ASYNC_INITIALIZED)) {
		outw(0x0000, base+0x04); 
		spin_unlock(&card->card_lock);
		return IRQ_HANDLED;
	}

	tty = tty_port_tty_get(&port->port);
	if (tty == NULL) {
		word_count = byte_count >> 1;
		while (byte_count > 1) {
			inw(base);
			byte_count -= 2;
		}
		if (byte_count & 0x01)
			inw(base);
		outw(0x0000, base+0x04); 
		spin_unlock(&card->card_lock);
		return IRQ_HANDLED;
	}
void UARTDevice::ReceiveChar(uint8_t x) {
  std::lock_guard<std::mutex> lock(fifoMutex);

  fifo.push(x);
  if (fifo.size() >= 1) {
    input = fifo.front();
    fifo.pop();
    ClearInterrupt(UART_IIR_CTI);
    LSR |= UART_LSR_DATA_READY;
    ThrowCTI();
  }
};
Esempio n. 8
0
DWORD CPdd6410Uart::ThreadRun()
{
    DWORD dwData;
    DWORD interrupts;
    
    while ( m_hISTEvent!=NULL && !IsTerminated() )
    {
        if ( WaitForSingleObject( m_hISTEvent, m_dwISTTimeout) == WAIT_OBJECT_0)
        {
            m_HardwareLock.Lock();    
        
            while ( !IsTerminated() )
            {
                dwData = ( GetInterruptStatus() & (S6410UART_INT_RXD | S6410UART_INT_TXD | S6410UART_INT_ERR | S6410UART_INT_MODEM) );
                if (dwData)
                {
                    DEBUGMSG(ZONE_THREAD, (TEXT(" CPdd6410Uart::ThreadRun Active INT=%x\r\n"), dwData));

                    // Clear the interrupt value to notify to MDD
                    interrupts=NULL;
                    DEBUGCHK(interrupts==NULL);

                    if ((dwData & S6410UART_INT_RXD)!=0)
                    {
                        interrupts |= INTR_RX;
                    }
                    if ((dwData & S6410UART_INT_TXD)!=0)
                    {
                        interrupts |= INTR_TX;
                    }
                    if ((dwData & S6410UART_INT_ERR)!=0)
                    {
                        interrupts |= INTR_LINE | INTR_RX;
                    }
                    if ((dwData & S6410UART_INT_MODEM)!=0)
                    {
                        interrupts |=INTR_MODEM;
                    }
                    
                    NotifyPDDInterrupt( (INTERRUPT_TYPE)interrupts );
                    
                    ClearInterrupt(dwData);
                }
                else
                {
                    break;
                }
            }

            m_HardwareLock.Unlock();   

            InterruptDone(m_dwSysIntr);
        }
        else
        {
            DEBUGMSG(ZONE_THREAD,(TEXT(" CPdd6410Uart::ThreadRun timeout INT=%x,MASK=%d\r\n"),m_pReg6410Uart->Read_UINTP()/*m_pReg6410Uart->Read_UINTSP()*/, m_pReg6410Uart->Read_UINTM()) );
            ASSERT(FALSE);
        }
    }

    return 1;
}