📄 st16c554.c
字号:
} return byRet;}inline unsigned char st0cpopRX(void){//为空时返回最后接收到的一个数据,从未接收到数据时返回缓冲区第一个字节数据 unsigned char byRet; byRet = st0C.abyRecvData[st0C.sRecvHead]; if(!st0cIsEmpty_rx()){ st0C.sRecvHead++; st0C.sRecvHead %= ST_RECV_LEN; } return byRet;}inline unsigned char st0dpopRX(void){//为空时返回最后接收到的一个数据,从未接收到数据时返回缓冲区第一个字节数据 unsigned char byRet; byRet = st0D.abyRecvData[st0D.sRecvHead]; if(!st0dIsEmpty_rx()){ st0D.sRecvHead++; st0D.sRecvHead %= ST_RECV_LEN; } return byRet;}inline unsigned char st0epopRX(void){//为空时返回最后接收到的一个数据,从未接收到数据时返回缓冲区第一个字节数据 unsigned char byRet; byRet = st0E.abyRecvData[st0E.sRecvHead]; if(!st0eIsEmpty_rx()){ st0E.sRecvHead++; st0E.sRecvHead %= ST_RECV_LEN; } return byRet;}inline unsigned char st0fpopRX(void){//为空时返回最后接收到的一个数据,从未接收到数据时返回缓冲区第一个字节数据 unsigned char byRet; byRet = st0F.abyRecvData[st0F.sRecvHead]; if(!st0fIsEmpty_rx()){ st0F.sRecvHead++; st0F.sRecvHead %= ST_RECV_LEN; } return byRet;}inline unsigned char st0gpopRX(void){//为空时返回最后接收到的一个数据,从未接收到数据时返回缓冲区第一个字节数据 unsigned char byRet; byRet = st0G.abyRecvData[st0G.sRecvHead]; if(!st0gIsEmpty_rx()){ st0G.sRecvHead++; st0G.sRecvHead %= ST_RECV_LEN; } return byRet;}inline unsigned char st0hpopRX(void){//为空时返回最后接收到的一个数据,从未接收到数据时返回缓冲区第一个字节数据 unsigned char byRet; byRet = st0H.abyRecvData[st0H.sRecvHead]; if(!st0hIsEmpty_rx()){ st0H.sRecvHead++; st0H.sRecvHead %= ST_RECV_LEN; } return byRet;}static void InitCommont(ST_COM *pst,int nBaud, unsigned char byMode){ volatile unsigned char byRx; int i; if(0 != pst->sInited){ iounmap((void *) (pst->pbyBase0)); } pst->pbyBase0 = (unsigned char *)ioremap_nocache(pst->nAddress0, 8); pst->RBR = (int)(pst->pbyBase0); pst->THR = (int)(pst->pbyBase0); pst->DLL = (int)(pst->pbyBase0); pst->DLM = (int)(pst->pbyBase0+1); pst->IER = (int)(pst->pbyBase0+1); pst->FCR = (int)(pst->pbyBase0+2); pst->IIR = (int)(pst->pbyBase0+2); pst->LCR = (int)(pst->pbyBase0+3); pst->MCR = (int)(pst->pbyBase0+4); pst->LSR = (int)(pst->pbyBase0+5); pst->MSR = (int)(pst->pbyBase0+6); pst->SPR = (int)(pst->pbyBase0+7); pst->sRecvHead = 0; pst->sRecvTail = 0; pst->sSendHead = 0; pst->sSendTail = 0; //IER //接收保持和中断允许 *(volatile unsigned char *)(pst->IER) = 0x01;//0x05; //FIFO控制器 //set FCR.FIFO允许,RXD复位,TXD复位,DMAmode=1,触发为14 *(volatile unsigned char *)(pst->FCR) = 0xcf; for(i=0; i<100; i++); //set FCR.RXD复位,TXD复位 *(volatile unsigned char *)(pst->FCR) = 0xc9; //Modem状态 //set MCR.中断A-D开 //*(volatile unsigned char *)(pst->MCR) = 0x08; //change by zhujiang,our program not use this now if(byMode&0x80){ *(volatile unsigned char *)(pst->LCR) = 0x82|(byMode&0x7f);//7 bit } else{ //set LCR.8BIT,1STOP,ODDPARITY,选择特殊寄存器 *(volatile unsigned char *)(pst->LCR) = 0x83|byMode; }/*************************************************************************** ** SET st baudrate. BAUD RATE GENRATOR PROGRAMMING TABLE Output Baud Rate DLM DLL (7.3278MHz Clock) (HEX) (HEX) 200 09 00 1200 01 80 2400 00 C0 4800 00 60 9600 00 30 19.2K 00 18 38.4K 00 0C 76.8K 00 06 153.6K 00 03 230.4K 00 02 460.8K 00 01 ** ***************************************************************************/ // 特殊寄存器已打开,设置BPS// *(volatile unsigned char *)(pst->DLL) = BAUDBASE/nBaud;// 高位// *(volatile unsigned char *)(pst->DLM) = 0x00; switch(nBaud){ case 200: *(volatile unsigned char *)(pst->DLL) = 0x00; //高位 *(volatile unsigned char *)(pst->DLM) = 0x09; break; case 1200: *(volatile unsigned char *)(pst->DLL) = 0x80; //高位 *(volatile unsigned char *)(pst->DLM) = 0x01; break; case 2400: *(volatile unsigned char *)(pst->DLL) = 0xC0; //高位 *(volatile unsigned char *)(pst->DLM) = 0x00; break; case 4800: *(volatile unsigned char *)(pst->DLL) = 0x60; //高位 *(volatile unsigned char *)(pst->DLM) = 0x00; break; case 9600: *(volatile unsigned char *)(pst->DLL) = 0x30; //高位 *(volatile unsigned char *)(pst->DLM) = 0x00; break; case 19200: *(volatile unsigned char *)(pst->DLL) = 0x18; //高位 *(volatile unsigned char *)(pst->DLM) = 0x00; break; case 38400: *(volatile unsigned char *)(pst->DLL) = 0x0C; //高位 *(volatile unsigned char *)(pst->DLM) = 0x00; break; case 76800: *(volatile unsigned char *)(pst->DLL) = 0x06; //高位 *(volatile unsigned char *)(pst->DLM) = 0x00; break; case 153600: *(volatile unsigned char *)(pst->DLL) = 0x03; //高位 *(volatile unsigned char *)(pst->DLM) = 0x00; break; default: break; } if(byMode&0x80){ *(volatile unsigned char *)(pst->LCR) = 0x02|(byMode&0x7f);//7 bit } else{ //set LCR.8BIT,1STOP,ODDPARITY,选择特殊寄存器 *(volatile unsigned char *)(pst->LCR) = 0x03|byMode; } //空读一次 byRx = *(volatile unsigned char *)(pst->RBR); //读空 i=0; while(1){ //检查接收状态 byRx = *(volatile unsigned char *)(pst->LSR); if(byRx&0x01){ byRx = *(volatile unsigned char *)(pst->RBR); } else break; //防止死循环 i++; if(i > 4096)//每个UART最多只能缓存16个字节 break; } pst->sInited = 1;}//ST16C554初始化void Init_ST0A(int nBaud, unsigned char byMode){ InitCommont(&st0A,nBaud,byMode);}void Init_ST0B(int nBaud, unsigned char byMode){ InitCommont(&st0B,nBaud,byMode);}void Init_ST0C(int nBaud, unsigned char byMode){ InitCommont(&st0C,nBaud,byMode);}void Init_ST0D(int nBaud, unsigned char byMode){ InitCommont(&st0D,nBaud,byMode);}void Init_ST0E(int nBaud, unsigned char byMode){ InitCommont(&st0E,nBaud,byMode);}void Init_ST0F(int nBaud, unsigned char byMode){ InitCommont(&st0F,nBaud,byMode);}void Init_ST0G(int nBaud, unsigned char byMode){ InitCommont(&st0G,nBaud,byMode);}void Init_ST0H(int nBaud, unsigned char byMode){ InitCommont(&st0H,nBaud,byMode);}//ST16C554的接收unsigned char ST0A_Rxd(void){ volatile unsigned char byRx; volatile unsigned char bySt; int nRxCnt = 0; while(nRxCnt < 256){ bySt = *(volatile unsigned char *)(st0A.LSR);//检查接收状态 if(bySt&0x01){//数据就绪 byRx = *(volatile unsigned char *)(st0A.RBR); pushST0ARX(byRx); } else break; nRxCnt++; } return byRx;}unsigned char ST0B_Rxd(void){ volatile unsigned char byRx; volatile unsigned char bySt; int nRxCnt = 0; while(nRxCnt < 256){ bySt = *(volatile unsigned char *)(st0B.LSR);//检查接收状态 if(bySt&0x01){//数据就绪 byRx = *(volatile unsigned char *)(st0B.RBR); pushST0BRX(byRx); } else{ break; } nRxCnt++; } return byRx;}unsigned char ST0C_Rxd(void){ volatile unsigned char byRx; volatile unsigned char bySt; int nRxCnt = 0; while(nRxCnt < 256){ bySt = *(volatile unsigned char *)(st0C.LSR);//检查接收状态 if(bySt&0x01){//数据就绪 byRx = *(volatile unsigned char *)(st0C.RBR); pushST0CRX(byRx); } else break; nRxCnt++; } return byRx;}unsigned char ST0D_Rxd(void){ volatile unsigned char byRx; volatile unsigned char bySt; int nRxCnt = 0; while(nRxCnt < 256){ bySt = *(volatile unsigned char *)(st0D.LSR);//检查接收状态 if(bySt&0x01){//数据就绪 byRx = *(volatile unsigned char *)(st0D.RBR); pushST0DRX(byRx); } else break; nRxCnt++; } return byRx;}unsigned char ST0E_Rxd(void){ volatile unsigned char byRx; volatile unsigned char bySt; int nRxCnt = 0; while(nRxCnt < 256){ bySt = *(volatile unsigned char *)(st0E.LSR);//检查接收状态 if(bySt&0x01){//数据就绪 byRx = *(volatile unsigned char *)(st0E.RBR); pushST0ERX(byRx); } else break; nRxCnt++; } return byRx;}unsigned char ST0F_Rxd(void){ volatile unsigned char byRx; volatile unsigned char bySt; int nRxCnt = 0; while(nRxCnt < 256){ bySt = *(volatile unsigned char *)(st0F.LSR);//检查接收状态 if(bySt&0x01){//数据就绪 byRx = *(volatile unsigned char *)(st0F.RBR); pushST0FRX(byRx); } else{ break; } nRxCnt++; } return byRx;}unsigned char ST0G_Rxd(void){ volatile unsigned char byRx; volatile unsigned char bySt; int nRxCnt = 0; while(nRxCnt < 256){ bySt = *(volatile unsigned char *)(st0G.LSR);//检查接收状态 if(bySt&0x01){//数据就绪 byRx = *(volatile unsigned char *)(st0G.RBR); pushST0GRX(byRx); } else break; nRxCnt++; } return byRx;}unsigned char ST0H_Rxd(void){ volatile unsigned char byRx; volatile unsigned char bySt; int nRxCnt = 0; while(nRxCnt < 256){ bySt = *(volatile unsigned char *)(st0H.LSR);//检查接收状态 if(bySt&0x01){//数据就绪 byRx = *(volatile unsigned char *)(st0H.RBR); pushST0HRX(byRx); } else break; nRxCnt++; } return byRx;}//ST16C554的发送//返回:1,成功// 0,失败int ST_ComTxd(ST_COM *pst,unsigned char byTxd){ unsigned char byRx; int nTxCnt = 0; while(nTxCnt < 256){ byRx = *(volatile unsigned char *)(pst->LSR);//检查发送状态 if(byRx&0x20){//发送就绪 *(volatile unsigned char *)(pst->THR) = byTxd; return 1; } else{ nTxCnt++; } } return 0;}static void UART0_interrupt(int irq, void *dev_id, struct pt_regs *regs){ //save_flags_cli(flags); if (st0A.sInited) ST0A_Rxd();// printk(KERN_INFO "UART0_interrupt1\n" ); if (st0B.sInited) ST0B_Rxd();// printk(KERN_INFO "UART0_interrupt2\n" ); if (st0C.sInited); ST0C_Rxd(); // printk(KERN_INFO "UART0_interrupt3\n" ); if (st0D.sInited) ST0D_Rxd();// printk(KERN_INFO "UART0_interrupt4\n" ); //restore_flags(flags);}static void UART1_interrupt(int irq, void *dev_id, struct pt_regs *regs){ if (st0E.sInited) ST0E_Rxd();// printk(KERN_INFO "UART1_interrupt0\n" ); if (st0F.sInited) ST0F_Rxd();// printk(KERN_INFO "UART1_interrupt1\n" ); if (st0G.sInited) ST0G_Rxd();// printk(KERN_INFO "UART1_interrupt2\n" ); if (st0H.sInited) ST0H_Rxd();// printk(KERN_INFO "UART1_interrupt3\n" );}static int st16c554_open(struct inode *inode, struct file *filp){ int nRet = 0; MOD_INC_USE_COUNT; return nRet;}static int st16c554_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){ int nRet = 0; switch(cmd) { default: return -EINVAL; } return nRet;}static int st16c554_read(struct file *filp, char *buffer, size_t count, loff_t *ppos){ int nRet = 0; return nRet;}static int st16c554_release(struct inode *inode, struct file *filp){ int nRet = 0; MOD_DEC_USE_COUNT; return nRet;}static int st16c554_ComWrite(const char *buf, size_t nCount ,ST_COM *mPst){ int i,j,nRet; unsigned char abySend[ST_SEND_LEN]; int m,k; m=nCount/ST_SEND_LEN; k=nCount%ST_SEND_LEN; for(i=0; i<m; i++){ if (copy_from_user(abySend,buf+i*ST_SEND_LEN,ST_SEND_LEN)){ return -EFAULT; } for(nRet=0; nRet<ST_SEND_LEN; nRet++){ ST_ComTxd(mPst,abySend[nRet]); //ST0A_Txd(abySend[nRet]); for(j=0; j<delay_counter; j++);//300000// printk("A:%02X\n", abySend[nRet]); } } if (k>0){ if (copy_from_user(abySend,buf+m*ST_SEND_LEN,k)){ return -EFAULT; } for(nRet=0; nRet<k; nRet++){ ST_ComTxd(mPst,abySend[nRet]); //ST0A_Txd(abySend[nRet]); for(j=0; j<delay_counter; j++);//300000// printk("A:%02X\n", abySend[nRet]); } } return nRet; }static int ST0A_open(struct inode *inode, struct file *filp){ int nRet = 0; MOD_INC_USE_COUNT; return nRet;}static int ST0A_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){ int nRet = 0; switch(cmd) { case ST_INIT: copy_from_user(&st0A_init, (struct tagST_INIT *)arg, sizeof(struct tagST_INIT)); Init_ST0A(st0A_init.nBaud, st0A_init.byMode); break; default: return -EINVAL; } return nRet;}static int ST0A_read(struct file *filp, char *buf, size_t count, loff_t *ppos){ int i; int nLen; unsigned char abyRecv[ST_RECV_LEN]; nLen = get_ST0A_rxLen(); nLen = nLen>count ? count : nLen; for(i=0; i<nLen; i++){ abyRecv[i] = st0A.abyRecvData[st0A.sRecvHead]; if(st0A.sRecvHead != st0A.sRecvTail){ st0A.sRecvHead++; st0A.sRecvHead %= ST_RECV_LEN; } else break; } copy_to_user((void *)buf, &abyRecv, i); return i;}static int ST0A_write (struct file *file, const char *buf, size_t count, loff_t *ppos){ return st16c554_ComWrite(buf,count,&st0A); }static int ST0A_release(struct inode *inode, struct file *filp){ int nRet = 0; MOD_DEC_USE_COUNT; return nRet;}static int ST0B_open(struct inode *inode, struct file *filp){ int nRet = 0; MOD_INC_USE_COUNT; return nRet;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -