📄 p3544sio.c
字号:
} else if (interruptID == UART_IIR_MSI) /* modem status register */ { char msr = PCI_IN_BYTE (pChan->msr); /* (|=) ... DON'T CLOBBER BITS ALREADY SET IN THE IER */ ier |= (UART_IER_RDI | UART_IER_MSI); /* if CTS is asserted by modem, enable tx interrupt */ if ((msr & UART_MSR_CTS) && (msr & UART_MSR_DCTS)) { PCI_OUT_BYTE(pChan->ier, (UART_IER_THRI | ier)); } else /* turn off TBE interrupt until CTS from modem */ { PCI_OUT_BYTE(pChan->ier, (ier & (~UART_IER_THRI))); } } } /* FOREVER */ pChan ++; } }/********************************************************************************* p3544Startup () - transmitter startup routine** Call interrupt level character output routine and enable interrupt if it is* in interrupt mode with no hardware flow control.* If the option for hardware flow control is enabled and CTS is set TRUE,* then the Tx interrupt is enabled.** RETURNS: OK*/LOCAL int p3544Startup ( p3544_CHAN * pChan /* tty device to start up */ ) { char ier = UART_IER_RDI; char mask; if (pChan->channelMode == SIO_MODE_INT) { if (pChan->options & CLOCAL) { /* No modem control */ ier |= UART_IER_THRI; } else { mask = PCI_IN_BYTE (pChan->msr) & UART_MSR_CTS; /* if the CTS is asserted enable Tx interrupt */ if (mask & UART_MSR_CTS) ier |= (UART_IER_THRI | UART_IER_MSI); else ier |= (UART_IER_MSI); } PCI_OUT_BYTE (pChan->ier, ier); } return (OK); }/******************************************************************************** p3544PRxChar () - poll the device for input.** RETURNS: OK if a character arrived, EIO on device error, EAGAIN* if the input buffer if empty.*/LOCAL int p3544PRxChar ( p3544_CHAN * pChan, /* pointer to channel */ char * pChar /* pointer to char */ ) { char pollStatus; pollStatus = PCI_IN_BYTE (pChan->lsr); if ((pollStatus & UART_LSR_DR) == 0x00) return (EAGAIN); /* got a character */ *pChar = PCI_IN_BYTE(pChan->data); return (OK); }/******************************************************************************** p3544PTxChar () - output a character in polled mode.* * Checks if the transmitter is empty. If empty, a character is written to* the data register. ** If the hardware flow control is enabled the handshake signal CTS has to be* asserted in order to send a character.** RETURNS: OK if a character arrived, EIO on device error, EAGAIN* if the output buffer if full.*/LOCAL int p3544PTxChar ( p3544_CHAN * pChan, /* pointer to channel */ char outChar /* char to send */ ) { char pollStatus; char msr; pollStatus = PCI_IN_BYTE (pChan->lsr); msr = PCI_IN_BYTE (pChan->msr); /* is the transmitter ready to accept a character? */ if ((pollStatus & UART_LSR_TEMT) == 0x00) return (EAGAIN); if (!(pChan->options & CLOCAL)) /* modem flow control ? */ { if (msr & UART_MSR_CTS) PCI_OUT_BYTE (pChan->data, outChar); else return (EAGAIN); } else PCI_OUT_BYTE (pChan->data, outChar); return (OK); }/****************************************************************************** * p3544_autoconfig () - initialize a specific serial port. * It determines what type of UART chip this serial port is * using: 8250, 16450, 16550, 16550A. The important question is * whether or not this UART is a 16550A, since this will determine * whether or not we can use its FIFO features. */void p3544_autoconfig( p3544_CHAN * pChan /* pointer to device */){ unsigned char status1, status2, scratch, scratch2; int intLevel; pChan->port_type = PORT_UNKNOWN; pChan->async_flags = ASTD_COM_FLAGS;//sucongna intLevel = intLock (); /* * Do a simple existence test first; if we fail this, there's * no point trying anything else. * * 0x80 is used as a nonsense port to prevent against false * positives due to ISA bus float. The assumption is that * 0x80 is a non-existent port; which should be safe since * include/asm/io.h also makes this assumption. */ scratch = PCI_IN_BYTE(pChan->ier); PCI_OUT_BYTE(pChan->ier, 0); PCI_OUT_BYTE( 0x080,0xff); scratch2 = PCI_IN_BYTE(pChan->ier); PCI_OUT_BYTE(pChan->ier, scratch); if (scratch2) { intUnlock (intLevel); return; /* We failed; there's nothing here */ } /* * Check to see if a UART is really there. Certain broken * internal modems based on the Rockwell chipset fail this * test, because they apparently don't implement the loopback * test mode. So this test is skipped on the COM 1 through * COM 4 ports. This *should* be safe, since no board * manufacturer would be stupid enough to design a board * that conflicts with COM 1-4 --- we hope! */ if (!(pChan->async_flags & ASYNC_SKIP_TEST)) { scratch = PCI_IN_BYTE(pChan->mcr); PCI_OUT_BYTE(pChan->mcr, UART_MCR_LOOP | scratch); PCI_OUT_BYTE(pChan->mcr, UART_MCR_LOOP | 0x0A); status1 = PCI_IN_BYTE(pChan->msr) & 0xF0; PCI_OUT_BYTE(pChan->mcr, scratch); if (status1 != 0x90) { intUnlock (intLevel); return; } } scratch2 = PCI_IN_BYTE(pChan->lcr); PCI_OUT_BYTE(pChan->lcr, 0xBF); /* set up for StarTech test */ PCI_OUT_BYTE(pChan->efr, 0); /* EFR is the same as FCR */ PCI_OUT_BYTE(pChan->lcr, 0); PCI_OUT_BYTE(pChan->fcr, UART_FCR_ENABLE_FIFO); scratch = PCI_IN_BYTE(pChan->iir) >> 6; switch (scratch) { case 0: pChan->port_type = PORT_16450; break; case 1: pChan->port_type = PORT_UNKNOWN; break; case 2: pChan->port_type = PORT_16550; break; case 3: pChan->port_type = PORT_16550A; break; } if (pChan->port_type == PORT_16550A) { /* Check for Startech UART's */ PCI_OUT_BYTE(pChan->lcr, scratch2 | UART_LCR_DLAB); if (PCI_IN_BYTE(pChan->efr) == 0) { pChan->port_type = PORT_16650; } else { PCI_OUT_BYTE(pChan->lcr, 0xBF); if (PCI_IN_BYTE(pChan->efr) == 0) pChan->port_type = PORT_16650V2; } } if (pChan->port_type == PORT_16550A) { /* Check for TI 16750 */ PCI_OUT_BYTE(pChan->lcr, scratch2 | UART_LCR_DLAB); PCI_OUT_BYTE(pChan->fcr, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE); scratch = PCI_IN_BYTE(pChan->iir) >> 5; if (scratch == 7) { PCI_OUT_BYTE(pChan->lcr, 0); scratch = PCI_IN_BYTE(pChan->iir) >> 5; if (scratch == 6) pChan->port_type = PORT_16750; } PCI_OUT_BYTE(pChan->fcr, UART_FCR_ENABLE_FIFO); } PCI_OUT_BYTE(pChan->lcr, scratch2); if (pChan->port_type == PORT_16450) { scratch = PCI_IN_BYTE(pChan->scr); PCI_OUT_BYTE(pChan->scr, 0xa5); status1 = PCI_IN_BYTE(pChan->scr); PCI_OUT_BYTE(pChan->scr, 0x5a); status2 = PCI_IN_BYTE(pChan->scr); PCI_OUT_BYTE(pChan->scr, scratch); if ((status1 != 0xa5) || (status2 != 0x5a)) pChan->port_type = PORT_8250; } if (pChan->port_type == PORT_UNKNOWN) { intUnlock (intLevel); return; }/* request_region(pChan->port,8,"serial(auto)");*/ /* * Reset the UART. */ PCI_OUT_BYTE(pChan->mcr, 0x00); PCI_OUT_BYTE(pChan->fcr, (UART_FCR_CLEAR_RCVR |UART_FCR_CLEAR_XMIT)); (void)PCI_IN_BYTE(pChan->data); PCI_OUT_BYTE(pChan->ier, 0); intUnlock (intLevel);} BOOL Hwa_COM_Install(UINT8 Com_Index, int BPS,BOOL Stop_Bit,UCHAR Odd_Enable,UCHAR Com_Size ) { UINT Tmpi; UINT8 Tmp_Option; char tyName [20];char Tmp_Task_Name[10]; if(Com_Index >= HWA_CPCI_3544_PORT_NUM) return FALSE; if(BPS>=HWA_CPCI_3544_BPS_MAX) return FALSE; if(Com_Size >=HWA_CPCI_3544_SIZEOF) return FALSE; if(Hwa_Cpci_3544_Inst ==FALSE) { CreateP3544(); Hwa_Cpci_3544_Inst=TRUE; } memset(tyName,0,20*sizeof(char)); sprintf (tyName, "%s%d", "/tyCo/", Com_Index+3); Hwa_Com_fd[Com_Index] = open(tyName, O_WRONLY,0 ); if (Hwa_Com_fd[Com_Index] == ERROR) { printf("tyco3 open is error \n"); return ERROR; } Tmp_Option=0; if(Odd_Enable >0) { Tmp_Option |=PARODD; } else { Tmp_Option &= ~PARODD; } switch (Com_Size) { case UART_LCR_WLEN5: Tmp_Option |= CS5; break; case UART_LCR_WLEN6: Tmp_Option |= CS6; break; case UART_LCR_WLEN7: Tmp_Option |= CS7; break; default: Tmp_Option |= CS8; break; } if (Stop_Bit) Tmp_Option |= UART_LCR_STOP; else Tmp_Option &=~ UART_LCR_STOP; printf("Tmp_Option=%x \n",Tmp_Option);// p3544OptsSet(Hwa_Com_fd[Com_Index],Tmp_Option ); Tmpi=p3544baudTable [BPS+5].rate;// p3544BaudSet(Hwa_Com_fd[Com_Index],Tmpi);memset(Tmp_Task_Name,0,10);sprintf(Tmp_Task_Name,"Sio%d",Com_Index); Hwa_Cpci_3544_Task_Id[Com_Index]=taskSpawn("Tmp_Task_Name",31,VX_FP_TASK ,0x10000,(FUNCPTR)Hwa_CPCI_3544_Rec_Task_Func,(int)(Com_Index),0,0,0,0,0,0,0,0,0); return TRUE; } BOOL Hwa_CPCI_3544_Transmit(UCHAR Com_Index,char *ptr, ULONG len) { if(Com_Index >= HWA_CPCI_3544_PORT_NUM) return FALSE; if(ptr ==NULL) return FALSE; if(Hwa_Com_fd[Com_Index] <1) { printf("PLEASE Open Com-%d \n",Com_Index); return FALSE; } write( Hwa_Com_fd[Com_Index], ptr, len ); } long Hwa_CPCI_3544_Receive(UCHAR Com_Index, UCHAR *ptr, ULONG len) { if(Com_Index >= HWA_CPCI_3544_PORT_NUM) return FALSE; if(ptr ==NULL) return FALSE; if(Hwa_Com_fd[Com_Index] <1) { printf("PLEASE Open Com-%d \n",Com_Index); return FALSE; }memcpy(ptr,(void *)(Hwa_PCI3544_Rec_Data_Buffer_char+Com_Index*8),len); /* read( Hwa_Com_fd[Com_Index], ptr, len );*/ }LOCAL void Hwa_CPCI_3544_Rec_Task_Func(UINT8 Inser_Para_Fd ){ UINT8 Tmp_Rec_Buffer[8]; UINT8 Tmp_Cur_Pt=0; UINT8 Last_Cur; UINT8 Cur_Ptr_Data=0; if(Inser_Para_Fd >4) { printf("Create Cur Task Error Inser_Para_Fd=%d \n",Inser_Para_Fd); return ; } memset(Tmp_Rec_Buffer,0,8); FOREVER { Last_Cur = read(Hwa_Com_fd[Inser_Para_Fd],Tmp_Rec_Buffer+Tmp_Cur_Pt, 8-Tmp_Cur_Pt); Tmp_Cur_Pt +=Last_Cur; if(8==Tmp_Cur_Pt) { memset((void *)(Hwa_PCI3544_Rec_Data_Buffer_char+Inser_Para_Fd*8),0,8); memcpy((void *)(Hwa_PCI3544_Rec_Data_Buffer_char+Inser_Para_Fd*8),Tmp_Rec_Buffer,8); memset(Tmp_Rec_Buffer,0,8); Tmp_Cur_Pt=0; Cur_Ptr_Data++; } } } BOOL HWA_Close_Task(UCHAR Com_Index) { if(Com_Index >= HWA_CPCI_3544_PORT_NUM) return FALSE;/* if(ptr ==NULL) return FALSE;*/ if(Hwa_Com_fd[Com_Index] <1) { printf("PLEASE Open Com-%d \n",Com_Index); return FALSE; } taskDelete(Hwa_Cpci_3544_Task_Id[Com_Index]); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -