📄 ul_c450.c
字号:
if(u450_inb(udrv->port,UART_MCR)&U450_MCR_OEQ(udrv)) { UL_FCALL2(u450_weot,u450_wait_1); } else UL_FNEXT(u450_wait_1); return UL_RC_PROC;};int u450_wait_1(ul_drv *udrv, int ret_code){ uchar lsr_val; if(ret_code<0) {UL_FRET;return ret_code;}; lsr_val=u450_inb(udrv->port,UART_LSR); u450_outb(udrv->port,UART_MCR,U450_MCR_IE(udrv)); u450_outb(udrv->port,UART_IER,UART_IER_THRI|UART_IER_RDI); if(lsr_val&UART_LSR_DR) { UL_FRET; return u450_recch_sub(udrv,lsr_val,u450_inb(udrv->port,UART_RX)); }; U450_FIX_RDI_GARBAGE(udrv,ret_code); if(!(lsr_val&UART_LSR_THRE)) return UL_RC_WIRQ; if(!udrv->wait_time) { UL_FRET; LOG_CHIO(" Timeout!"); return UL_RC_ETIMEOUT; }; UL_FNEXT(u450_wait_2); u450_outb(udrv->port,UART_TX,0); return UL_RC_WIRQ;};int u450_wait_2(ul_drv *udrv, int ret_code){ uchar lsr_val; lsr_val=u450_inb(udrv->port,UART_LSR); if(lsr_val&UART_LSR_DR) { UL_FRET; return u450_recch_sub(udrv,lsr_val,u450_inb(udrv->port,UART_RX)); }; U450_FIX_RDI_GARBAGE(udrv,ret_code); if(!(lsr_val&UART_LSR_THRE)) return UL_RC_WIRQ; if(!udrv->wait_time--) { UL_FRET; LOG_CHIO(" Timeout!"); return UL_RC_ETIMEOUT; }; u450_outb(udrv->port,UART_TX,0); return UL_RC_WIRQ;};/*** Connect to RS485 bus ***/ int u450_connect_1(ul_drv *udrv, int ret_code); int u450_connect_2(ul_drv *udrv, int ret_code);int u450_connect(ul_drv *udrv, int ret_code){ unsigned u; LOG_CHIO(" C_0 "); u=udrv->last_ctrl; udrv->wait_time=((udrv->my_adr-u-1)&0xF)+4; if(((u&0x180)!=0x180)|| (u==0x1FF)) udrv->wait_time+=0x10; udrv->last_ctrl=0; udrv->char_buff=0; udrv->chip_temp=(udrv->my_adr&0x3F)|0x40; u450_inb(udrv->port,UART_MSR); UL_FCALL2(*udrv->fnc_wait,u450_connect_1); return UL_RC_PROC;};int u450_connect_1(ul_drv *udrv, int ret_code){ LOG_CHIO(" C_1 "); if(ret_code!=UL_RC_ETIMEOUT) { UL_FRET; LOG_CHIO(" EARBIT1!"); return UL_RC_EARBIT; }; /* check for RxD low */ if(u450_inb(udrv->port,UART_MSR)&U450_MSR_RxD(udrv)) { UL_FRET; LOG_CHIO(" EARBIT2!"); return UL_RC_EARBIT; }; u450_outb(udrv->port,UART_LCR,U450_LCR_ULB); u450_inb(udrv->port,UART_LSR); udrv->chip_temp|=0x300; u450_outb(udrv->port,UART_IER, (UART_IER_RLSI|UART_IER_RDI)); u450_outb(udrv->port,UART_MCR,U450_MCR_OE(udrv)); UL_FNEXT(u450_connect_2); /* wait for break condition now */ return UL_RC_WIRQ;};int u450_connect_2(ul_drv *udrv, int ret_code){ uchar lsr_val; LOG_CHIO(" C_2 "); lsr_val=u450_inb(udrv->port,UART_LSR); if(lsr_val&UART_LSR_BI) udrv->chip_temp&=~0x100; if(lsr_val&UART_LSR_DR) { udrv->chip_temp&=~0x200; u450_inb(udrv->port,UART_RX); } if (udrv->chip_temp&0x300) { return UL_RC_WIRQ; } u450_outb(udrv->port,UART_LCR,U450_LCR_ULC); u450_outb(udrv->port,UART_MCR,U450_MCR_IE(udrv)); u450_inb(udrv->port,UART_LSR); u450_inb(udrv->port,UART_RX); if(udrv->chip_temp==1) {LOG_CHIO(" Connected"); UL_FRET; }else{ udrv->wait_time=(udrv->chip_temp&3)+1; udrv->chip_temp>>=2; UL_FCALL2(*udrv->fnc_wait,u450_connect_1); }; return UL_RC_PROC;};/* UL_FNEXT(u450_recch); UL_FCALL(u450_recch); UL_FCALL2(u450_recch,u450_recch); UL_FRET;*/#ifdef FOR_LINUX_KERNELstatic char *u450_port_name="ulan_u450";#endif/*** 16450 initialize ports ***/int u450_pinit(ul_drv *udrv){ unsigned u; int baud=udrv->baud_val; if (UL_REQ_IOS(udrv->port,8,u450_port_name)<0) { LOG_FATAL(KERN_CRIT "uLan u450_pinit : cannot reguest ports !\n"); return UL_RC_EPORT; }; if (!baud) baud=19200; u=(udrv->baud_base+baud/2)/baud; if (u>0xFFFF) u=0xFFFF; udrv->baud_div=u; udrv->chip_buff[0]=udrv->chip_buff[1]=0; u450_outb(udrv->port,UART_MCR,UART_MCR_OUT1|UART_MCR_DTR); u450_outb(udrv->port,UART_LCR,UART_LCR_DLAB); u450_outb(udrv->port,(uchar)UART_DLL,(uchar)udrv->baud_div); u450_outb(udrv->port,(uchar)UART_DLM,(uchar)(udrv->baud_div>>8)); u450_outb(udrv->port,UART_LCR,U450_LCR_UL); u450_outb(udrv->port,UART_IER,0); u450_outb(udrv->port,UART_FCR,0); /* disable FIFOs */ u450_inb(udrv->port,UART_LSR); /* reset errors */ u450_inb(udrv->port,UART_RX); /* and other irq */ u450_outb(udrv->port,UART_MCR,U450_MCR_IE(udrv)); /* connect irq */ return UL_RC_PROC;};/*** 16450 deinitialize ports ***/int u450_pdone(ul_drv *udrv){ u450_outb(udrv->port,UART_IER, 0); /* disable interrupts */ u450_outb(udrv->port,UART_MCR, U450_MCR_IE(udrv)&3); /* transmitter off */ u450_inb(udrv->port,UART_IIR); /* flush irq */ u450_inb(udrv->port,UART_LSR); /* flush irq */ UL_REL_IOS(udrv->port,8); return UL_RC_PROC;};/*** 16450 generate irq for irq_probe */int u450_genirq(ul_drv *udrv,int param){ if(param) { u450_outb(udrv->port,UART_MCR, U450_MCR_IE(udrv)); /* transmitter off */ u450_outb(udrv->port,UART_IER, UART_IER_MSI); /* enable interrupts */ u450_outb(udrv->port,UART_LCR, U450_LCR_ULB); /* trig break */ }else{ u450_outb(udrv->port,UART_IER, 0); /* disable interrupts */ u450_outb(udrv->port,UART_MCR, U450_MCR_IE(udrv)); /* transmitter off */ u450_inb(udrv->port,UART_MSR); /* flush irq */ }; return UL_RC_PROC;};/* support for hardware tests */int u450_hwtest(ul_drv *udrv,int param){ unsigned u; switch(param) { case 0x10: case 0x11: u450_outb(udrv->port,UART_IER, 0); /* disable interrupts */ u450_outb(udrv->port,UART_MCR, U450_MCR_OE(udrv)); /* transmitter on */ u450_outb(udrv->port,UART_LCR, param&1? U450_LCR_UL:U450_LCR_ULB); /* set TD lines */ case 0x12: u=u450_inb(udrv->port,UART_MSR); return u450_inb(udrv->port,UART_LSR)|(u<<8)| (u&(U450_MSR_TxD(udrv))?0:0x100000)| (u&(U450_MSR_RxD(udrv))?0:0x10000); case 0x13: u450_outb(udrv->port,UART_MCR, U450_MCR_IE(udrv)); /* transmitter off */ u=u450_inb(udrv->port,UART_MSR); return u450_inb(udrv->port,UART_LSR)|(u<<8)| (u&(U450_MSR_TxD(udrv))?0:0x100000)| (u&(U450_MSR_RxD(udrv))?0:0x10000); } return UL_RC_ENOFNC;};/*** Control functions of chip driver ***/int u450_cctrl(ul_drv *udrv, int ctrl_fnc, int param){ switch (ctrl_fnc) { case UL_CC_DIN: /* switch off line transmitter */ { u450_outb(udrv->port,UART_MCR, U450_MCR_IE(udrv)); u450_outb(udrv->port,UART_LCR, U450_LCR_UL); return UL_RC_PROC; }; case UL_CC_DOUT: /* switch on line transmitter */ { u450_outb(udrv->port,UART_MCR, U450_MCR_OE(udrv)); u450_outb(udrv->port,UART_LCR, U450_LCR_UL); return UL_RC_PROC; }; case UL_CC_PINIT: /* initialize ports (parameter baud)*/ { return u450_pinit(udrv); }; case UL_CC_PDONE: /* deinitialize ports */ { return u450_pdone(udrv); }; case UL_CC_GENIRQ: /* generate irq for irq_probe */ {return u450_genirq(udrv,param); }; case UL_CC_HWTEST: /* support for hardware testing */ {return u450_hwtest(udrv,param); }; }; return UL_RC_ENOFNC;};/*** 16450 chip driver initialize ***/int u450_init(ul_drv *udrv, int port, int irq, int baud, long baudbase, int options){ unsigned u; unsigned old_mcr; unsigned old_lcr; if (UL_REQ_IOS(port,8,u450_port_name)<0) { LOG_FATAL(KERN_CRIT "uLan u450_init : cannot reguest ports !\n"); return UL_RC_EPORT; }; #ifdef CONFIG_OC_UL_DRV_U450_VARPINS U450_SET_MCR_CODES(udrv,U450_MCR_IE_C,U450_MCR_OE_C,U450_MCR_OEQ_C); if(!(options&U450_CHOPT_MSRSWAP)) U450_SET_MSR_CODES(udrv,U450_MSR_RxD_C,U450_MSR_RxD_C,U450_MSR_DTxD_C); else U450_SET_MSR_CODES(udrv,UART_MSR_DSR,UART_MSR_CTS,UART_MSR_DCTS); #endif /*CONFIG_OC_UL_DRV_U450_VARPINS*/ LOG_PORTS("uLan u450_init : probe MCR\n"); old_mcr=u450_inb(port,UART_MCR); LOG_PORTS("uLan u450_init : MCR = 0x%02X\n",old_mcr); u450_outb(port,UART_MCR,UART_MCR_OUT1|UART_MCR_DTR); #ifdef FOR_LINUX_KERNEL set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(ULD_HZ/10); #elif defined(_WIN32) /* !!!!!!!!!!!!!! */ /* KeStallExecutionProcessor(20000); */ { LARGE_INTEGER delay; delay=RtlConvertLongToLargeInteger(-30*10000); KeDelayExecutionThread(KernelMode,FALSE,&delay); } #else sleep(1); #endif old_lcr=u450_inb(port,UART_LCR); u450_outb(port,UART_LCR,UART_LCR_SBC); #ifdef FOR_LINUX_KERNEL set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(ULD_HZ/10); #elif defined(_WIN32) /* !!!!!!!!!!!!!! */ /* KeStallExecutionProcessor(2000); */ { LARGE_INTEGER delay; delay=RtlConvertLongToLargeInteger(-10*10000); KeDelayExecutionThread(KernelMode,FALSE,&delay); } #else sleep(1); #endif if(u450_inb(port,UART_MSR)&U450_MSR_TxD(udrv)) { u450_outb(port,UART_LCR,U450_LCR_UL); LOG_PORTS("uLan u450_init : MCR test 1 OK\n"); #ifdef FOR_LINUX_KERNEL set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(ULD_HZ/10); #elif defined(_WIN32) /* !!!!!!!!!!!!!! */ /* KeStallExecutionProcessor(2000); */ { LARGE_INTEGER delay; delay=RtlConvertLongToLargeInteger(-10*10000); KeDelayExecutionThread(KernelMode,FALSE,&delay); } #else sleep(1); #endif if(!(u450_inb(port,UART_MSR)&U450_MSR_TxD(udrv))) { LOG_PORTS("uLan u450_init : MCR test 2 OK\n"); udrv->chip_options=options; udrv->baud_base=baudbase; /* check and setup baud base oscilator frequency */ if(!udrv->baud_base){ udrv->baud_base=U450_BAUD_BASE_DEFAULT; } if(!baud) baud=19200; udrv->baud_val=baud; u=(udrv->baud_base+baud/2)/baud; if (u>0xFFFF) u=0xFFFF; udrv->baud_div=u; udrv->port=port; udrv->irq=irq; udrv->fnc_recch=&u450_recch; udrv->fnc_sndch=&u450_sndch; udrv->fnc_wait=&u450_wait; udrv->fnc_pool=&u450_pool; udrv->fnc_connect=&u450_connect; udrv->fnc_cctrl=&u450_cctrl; UL_REL_IOS(port,8); return 0; }; LOG_PORTS("uLan u450_init : MCR test 2 Error\n"); }; u450_outb(port,UART_LCR,(uchar)old_lcr); u450_outb(port,UART_MCR,(uchar)old_mcr); LOG_PORTS("uLan u450_init : MCR test Error\n"); UL_REL_IOS(port,8); return UL_RC_EPORT;};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -