⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 irq.c

📁 HMS30C7202下的CAN驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
#ifdef REGDUMP                c_can_registerdump(pchip);#endif                /* Handle change in status register */                if ( irqreg == INT_STAT ) {                        pchip->last_chip_status = pchip->chip_status;                        pchip->chip_status = pchip->read_register( pchip, CCSR );                        DEBUGMSG( "(c%d)Status register: 0x%x",                                  pchip->chip_nr, pchip->chip_status );                        if ( pchip->chip_status & SR_EWARN ) {                                /* There is an abnormal number of errors */                                pchip->stat.cntWarnings++;                                errcount = pchip->read_register( pchip, CCEC);                                DEBUGMSG( "(c%d)stat: Abnormal number of Error Warnings (txErr=%d, rxErr=%d)",                                          pchip->chip_nr, (errcount&0x00ff), ((errcount&0x7f00)>>8));                        }                        if ( pchip->chip_status & SR_EPASS ) {                                /* Chip entered errorpassive state */                                if ( !( pchip->last_chip_status & SR_EPASS ) ) {                                        /* it's a new errorpassive state */                                        pchip->stat.cntErrPassive++;                                        CANMSG( "(c%d)stat: Chip entered Error Passive state",                                                pchip->chip_nr);                                        if ( ! pchip->time_triggered ) {                                                CANMSG( "           Switching to time triggered mode to avoid blocking by");                                                CANMSG( "           ACK ERR interrupts.");                                                pchip->intreg_backup = pchip->read_register( pchip, CCCR & 0xe );                                                /* stop interrupt generation */                                                pchip->config_irqs( pchip, CR_SIE | CR_EIE );                                                /* start timer */                                                start_time_trig( pchip );                                                return;                                        }                                }                        } else if ( pchip->last_chip_status & SR_EPASS ) {                                CANMSG( "(c%d)stat: Chip left Error Passive state",                                        pchip->chip_nr);                                if ( ! pchip->time_triggered ) {                                        CANMSG( "           Switching back to interrupt mode.");                                        stop_time_trig( pchip );                                        c_can_config_irqs(pchip, pchip->intreg_backup);                                }                        }                        if ( pchip->chip_status & SR_BOFF ) {                                /* Chip is in busoff state */                                if ( !( pchip->last_chip_status & SR_BOFF ) ) {                                        /* it's a new busoff */                                        pchip->stat.cntBusOff ++;                                        /* reset TX_IN_PROGRESS bit of all message objects so that devices can be closed */                                        for ( i=0; i<pchip->obj_cnt; i++ ) {                                                if ( pchip->pmsgobj[i]->flags & CHANNEL_OPENED ) {                                                        pchip->pmsgobj[i]->fifo->flags &= ~TX_IN_PROGRESS;                                                        /* In- and output buffer initialization */                                                        //pchip->pmsgobj[i]->fifo->txrp = pchip->pmsgobj[i]->fifo->ptxbuf;                                                        //pchip->pmsgobj[i]->fifo->txwp = pchip->pmsgobj[i]->fifo->ptxbuf;                                                }                                        }                                        CANMSG( "(c%d)stat: Chip in Bus Off state",                                                pchip->chip_nr );                                        CANMSG( "(c%d)      try to restart chip and check state in 1s",                                                pchip->chip_nr );                                        /* return from normal and Error Passive time trigger mode */                                        stop_time_trig( pchip );                                        if ( ! pchip->time_triggered ) {                                                c_can_config_irqs(pchip, pchip->intreg_backup);                                                /* backup interrupt register */                                                pchip->intreg_backup = pchip->read_register(pchip, CCCR & 0xe);                                                /* stop interrupt generation */                                                pchip->config_irqs( pchip, CR_SIE | CR_EIE );                                        }                                        /* restart chip */                                        pchip->disable_configuration( pchip );                                        /* start timer */                                        startTimer( pchip, 1, 0, functBusOffTimer );                                        /* return from interrupt handler */                                        return;                                }                        } else if ( pchip->last_chip_status & SR_BOFF ) {                                CANMSG( "(c%d)stat: Chip left Bus Off state",                                        pchip->chip_nr);                        }                        if (pchip->chip_status & SR_TXOK) {                                DEBUGMSG("(c%d)stat: Transmitted a Message successfully",                                         pchip->chip_nr);                                pchip->write_register(pchip->chip_status & ~SR_TXOK, pchip, CCSR);                        }                        if (pchip->chip_status & SR_RXOK) {                                DEBUGMSG("(c%d)stat: Received a Message successfully",                                         pchip->chip_nr);                                pchip->write_register(pchip->chip_status & ~SR_RXOK, pchip, CCSR);                        }                        /* Errors to statistics */                        switch( pchip->chip_status & 0x07 ) {                                case SRLEC_NE: /* No error */                                        break;                                case SRLEC_SE: /* Stuff error */                                        pchip->stat.cntStuffErr++;                                        DEBUGMSG( "(c%d)stat: stuff error",                                                  pchip->chip_nr);                                        break;                                case SRLEC_FE: /* Form error */                                        pchip->stat.cntFormErr++;                                        DEBUGMSG( "(c%d)stat: form error",                                                  pchip->chip_nr);                                        break;                                case SRLEC_AE: /* Ack error */                                        pchip->stat.cntAckErr++;                                        DEBUGMSG( "(c%d)stat: acknowledge error",                                                  pchip->chip_nr);                                        break;                                case SRLEC_B1: /* Bit 1 error */                                        pchip->stat.cntBit1Err++;                                        DEBUGMSG( "(c%d)stat: bit 1 error",                                                  pchip->chip_nr);                                        break;                                case SRLEC_B0: /* Bit 0 error */                                        pchip->stat.cntBit0Err++;                                        DEBUGMSG( "(c%d)stat: bit 0 error",                                                  pchip->chip_nr);                                        break;                                case SRLEC_CR: /* CRC error */                                        pchip->stat.cntCrcErr++;                                        DEBUGMSG( "(c%d)stat: crc error",                                                  pchip->chip_nr);                                        break;                                case 7: /* unused */                                        break;                        }                } else {                        if ( irqreg >0 && irqreg <33 ) {                                /* get kernel time */                                do_gettimeofday(&tv);                                /*get number of interrupt causing message object */                                idxobj = irqreg-1;                                /*DEBUGMSG( "Interrupt handler: addr=%lx devid=%lx irqreq=%x status=0x%x\n",*/                                //            (unsigned long)pchip->vbase_addr + iIRQ,                                //      (unsigned long)dev_id,                                //      irqreg,                                //      statreg );                                //                                spin_lock( &pchip->if1lock );                                /* Message Lost Check */                                c_can_if1_busycheck( pchip );                                pchip->write_register( msgLstReadMaskCM, pchip, CCIF1CM );                                pchip->write_register( idxobj+1, pchip, CCIF1CR );                                c_can_if1_busycheck( pchip );                                tempCntlReg = pchip->read_register( pchip, CCIF1DMC );                                if (tempCntlReg & IFXMC_MSGLST) {                                        CANMSG( "(c%dm%d)Chip lost a message",                                                pchip->chip_nr, pchip->pmsgobj[idxobj]->object );                                        pchip->stat.cntMsgLst++;                                        /* Reset Message Lost Bit */                                        tempCntlReg = tempCntlReg & (~IFXMC_MSGLST);                                        pchip->write_register( tempCntlReg,                                                               pchip, CCIF1DMC );                                        pchip->write_register( msgLstWriteMaskCM, pchip, CCIF1CM );                                        pchip->write_register( idxobj+1, pchip, CCIF1CR );                                }                                /* Transfer Message Object to IF1 Buffer */                                c_can_if1_busycheck( pchip );                                pchip->write_register( readMaskCM, pchip, CCIF1CM );                                pchip->write_register( idxobj+1, pchip, CCIF1CR );                                /* Call irq sub functions depending on direction of message (send/receive) */                                c_can_if1_busycheck( pchip );                                if ( pchip->read_register( pchip, CCIF1A2 ) & IFXARB2_DIR ) {                                        spin_unlock( &pchip->if1lock );                                        c_can_irq_write_handler( pchip );                                } else {                                        if (pchip->pmsgobj[idxobj]->msg_mode & 1) {                                                id0 = pchip->read_register( pchip, CCIF1A1 );                                                id1 = ( pchip->read_register( pchip, CCIF1A2 ) & 0x1FFF ) << 16;                                                msgid = id0 | id1;                                        } else                                                msgid =( ( pchip->read_register( pchip, CCIF1A2 ) & 0x1FFC ) >> 2 ) & 0x7FF;                                        /* check if message is a rtr */                                        spin_unlock( &pchip->if1lock );                                        spin_lock( &pchip->rtr_lock );                                        while ( rtr_search != NULL ) {                                                if ( rtr_search->id == msgid )                                                        break;                                                rtr_search = rtr_search->next;                                        }                                        spin_unlock( &pchip->rtr_lock );                                        spin_lock( &pchip->if1lock );                                        /* transfer Message Object to IF1 Buffer */                                        c_can_if1_busycheck( pchip );                                        pchip->write_register( readMaskCM, pchip, CCIF1CM );                                        pchip->write_register( idxobj+1, pchip, CCIF1CR );                                        /* call read or rtr handler */                                        c_can_if1_busycheck(pchip);                                        if ( ( rtr_search != NULL ) && ( rtr_search->id == msgid ))                                                c_can_irq_rtr_handler( pchip, msgid, tv );                                        else                                                c_can_irq_read_handler( pchip, msgid, tv );                                        spin_unlock( &pchip->if1lock );                                } /* else */                        } /* if */                }                /* Get irq status again */                irqreg = pchip->read_register( pchip, CCINTR );        }        return;}/* * Starts a timer with given settings */void startTimer (struct chip_t *pchip, time_t seconds, long nanosecs, void (*function)(unsigned long)){        struct timespec value = { seconds, nanosecs };        /* init the timer structure */        init_timer( &pchip->interrupt_timer );        /* pointer to function that will be executed after timer expired */        pchip->interrupt_timer.function = function;        /* store pointer to chip structure in timer structure */        pchip->interrupt_timer.data = (unsigned long)pchip;        /* set timer to ms */        pchip->interrupt_timer.expires = jiffies + timespec_to_jiffies( &value );        add_timer( &pchip->interrupt_timer );}void functBusOffTimer (unsigned long chip_ptr){        static u8 busoff_counter = 1;        struct chip_t *pchip = (struct chip_t *)chip_ptr;        pchip->chip_status = pchip->read_register( pchip, CCSR );        DEBUGMSG( "(c%d)Status register: 0x%x",                pchip->chip_nr, pchip->chip_status );        if ( !(pchip->chip_status & SR_BOFF) ) {                CANMSG("(c%d) restart successfull, chip left busoff state",                         pchip->chip_nr);                /* chip left busoff state */                busoff_counter = 0;                if ( ! pchip->time_triggered ) {                        /* reallow interrupt generation */                        c_can_config_irqs(pchip, pchip->intreg_backup);                } else {                        /* restart time triggered mode */                        start_time_trig ( pchip );                }                return;        }        busoff_counter++;        CANMSG("(c%d) restart not successfull, try again",                 pchip->chip_nr);        if (busoff_counter == 15 )                CANMSG("(c%d) busoff since 15 seconds, switching to 5s delay",                         pchip->chip_nr);        /* reset init bit of C_CAN controller */        pchip->disable_configuration(pchip);        /* restart timer */        startTimer (pchip, (busoff_counter>14 ? 5 : 1), 0, functBusOffTimer);}void functTimeTrigTimer (unsigned long chip_ptr){        struct chip_t *pchip = (struct chip_t *)chip_ptr;        static spinlock_t timtriglock = SPIN_LOCK_UNLOCKED;        unsigned long intflags;        /* restart timer */        startTimer (pchip, 0, pchip->time_trig_nanosec, functTimeTrigTimer);        /* call interrupt function with spinlock so that int function won't be interrupted */        spin_lock_irqsave( &timtriglock, intflags );        c_can_irq_handler( pchip->irq, pchip, 0 );        spin_unlock_irqrestore( &timtriglock, intflags );}void start_time_trig ( struct chip_t *pchip ){        startTimer( pchip, 0, pchip->time_trig_nanosec, functTimeTrigTimer );}void stop_time_trig ( struct chip_t *pchip ){        del_timer( &pchip->interrupt_timer );}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -