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

📄 irq.c

📁 HMS30C7202下的CAN驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
/* irq.c * * Written by Sebastian Stolzenberg email:stolzi@sebastian-stolzenberg.de * Version 1.0  04 Feb 2003 */#include <linux/time.h>#include <linux/timer.h>#include "../include/candrv.h"#include "../include/irq.h"#include "../include/c_can.h"/* prototypes of irq sub functions */inline void c_can_irq_read_handler( struct chip_t *pchip,                                    u32 msgid, struct timeval tv  );inline void c_can_irq_write_handler( struct chip_t *pchip );void c_can_irq_rtr_handler( struct chip_t *pchip,                            u32 msgid, struct timeval tv );/* bit masks for CAN controller */u16 readMaskCM = IFXCM_ARB | IFXCM_CNTRL | IFXCM_CLRINTPND  | IFXCM_TRND | IFXCM_DA | IFXCM_DB;u16 msgLstReadMaskCM = IFXCM_CNTRL;u16 msgLstWriteMaskCM =  IFXCM_CNTRL | IFXCM_WRRD;u8 idxobj = 0;/* prototypes of bus off and error passiv counter functions */void startTimer (struct chip_t *pchip, time_t seconds, long nanosec, void (*function)(unsigned long));void functBusOffTimer (unsigned long chip_ptr);void functTimeTrigTimer (unsigned long chip_ptr);/* helps to map data from word to byte format */union Data{        unsigned short wdata[4];        unsigned char bdata[8];};////////////////////////////////////////////////////////////////////////////////** * c_can_irq_write_handler * * Send a message from the output fifo ( if any ). */inline void c_can_irq_write_handler( struct chip_t *pchip){        /* Get ready to send next message */        spin_lock( &pchip->spwlock );        DEBUGMSG("(c%dm%d)calling c_can_irq_write_handler(...)",                 pchip->chip_nr, pchip->pmsgobj[idxobj]->object);        /* is buffer empty ? */        if ( pchip->pmsgobj[idxobj]->fifo->txrp == pchip->pmsgobj[idxobj]->fifo->txwp ) {                /* Nothing to write */                DEBUGMSG("(c%dm%d)Nothin to write",                         pchip->chip_nr, pchip->pmsgobj[idxobj]->object);                spin_unlock( &pchip->spwlock );                /* stop transmission and wake up any waiting writer */                pchip->pmsgobj[idxobj]->fifo->flags &= ~TX_IN_PROGRESS;                pchip->pmsgobj[idxobj]->rv = 0;                wake_up_interruptible( &pchip->pmsgobj[idxobj]->fifo->writeq );                return;        }        /* Send the message */        pchip->pmsgobj[idxobj]->fifo->flags |= TX_IN_PROGRESS;        if ( pchip->send_msg( pchip->pmsgobj[idxobj],                              (struct canmsg_t *)pchip->pmsgobj[idxobj]->fifo->txrp )) {                /* Failed... */                spin_unlock( &pchip->spwlock );                DEBUGMSG("(c%dm%d)c_can_irq_handler: Unable to send message",                         pchip->chip_nr, pchip->pmsgobj[idxobj]->object );                pchip->rv = -1;        } else {                /* Another message sent */                pchip->stat.cntTxPkt++;                pchip->stat.cntTxData +=                        ((struct canmsg_t *)pchip->pmsgobj[idxobj]->fifo->txrp)->length;                pchip->pmsgobj[idxobj]->fifo->txrp += sizeof( struct canmsg_t );                if ( pchip->pmsgobj[idxobj]->fifo->txrp >=                     ( pchip->pmsgobj[idxobj]->fifo->ptxbuf +                     pchip->pmsgobj[idxobj]->fifo->txsize )) {                        pchip->pmsgobj[idxobj]->fifo->txrp =                        pchip->pmsgobj[idxobj]->fifo->ptxbuf; /* wrapped */                }        }        /* Wake up any waiting writer */        spin_unlock( &pchip->spwlock );        wake_up_interruptible( &pchip->pmsgobj[idxobj]->fifo->writeq );        return;}////////////////////////////////////////////////////////////////////////////////** * c_can_irq_read_handler * * Message received from the line. Write it in the input fifo-> */inline void c_can_irq_read_handler( struct chip_t *pchip,                                    u32 msgid, struct timeval tv ){        int i=0;        u16 bDataAvail=1 ;        u16 msgCntlReg = 0;        u16 spacefree = 0;        union Data readData;        DEBUGMSG("(c%dm%d)calling c_can_irq_read_handler(...)",                  pchip->chip_nr, pchip->pmsgobj[idxobj]->object);        /* run till no new data was received */        while ( bDataAvail ) {                spin_lock( &pchip->sprlock );                if ( pchip->pmsgobj[idxobj]->fifo->rxrp ==                     pchip->pmsgobj[idxobj]->fifo->rxwp ) {                        spacefree = pchip->pmsgobj[idxobj]->fifo->rxsize;                } else {                        spacefree = ( ( pchip->pmsgobj[idxobj]->fifo->rxrp +                                        pchip->pmsgobj[idxobj]->fifo->rxsize -                                        pchip->pmsgobj[idxobj]->fifo->rxwp ) %                                        pchip->pmsgobj[idxobj]->fifo->rxsize );                }                /* is enough buffer space available */                if ( spacefree <= sizeof( struct canmsg_t )) {                        CANMSG("(c%dm%d)Fifo full - Message lost!",                               pchip->chip_nr, pchip->pmsgobj[idxobj]->object);                        if ( ! (pchip->pmsgobj[idxobj]->fifo->flags & RD_BUFF_OVRWRT ) ) {                                wake_up_interruptible( &pchip->pmsgobj[idxobj]->fifo->readq );                                pchip->stat.cntRxFifoOvr++;                                pchip->pmsgobj[idxobj]->rv = -1;                        } else {                                /* move read pointer forward one message */                                pchip->pmsgobj[idxobj]->fifo->rxrp += sizeof( struct canmsg_t );                                if ( pchip->pmsgobj[idxobj]->fifo->rxrp >=                                    ( pchip->pmsgobj[idxobj]->fifo->prxbuf +                                      pchip->pmsgobj[idxobj]->fifo->rxsize )) {                                        pchip->pmsgobj[idxobj]->fifo->rxrp =                                        pchip->pmsgobj[idxobj]->fifo->prxbuf; /* wrapped */                                }                        }                }                if ( ( spacefree > sizeof( struct canmsg_t ) ) ||                     ( pchip->pmsgobj[idxobj]->fifo->flags & RD_BUFF_OVRWRT ) ) {                        /* Message length */                        msgCntlReg = pchip->read_register( pchip, CCIF1DMC );                        ((struct canmsg_t *)pchip->pmsgobj[idxobj]->fifo->rxwp)->length =                                msgCntlReg & 0x000F;                        /* Message id */                        ((struct canmsg_t *)pchip->pmsgobj[idxobj]->fifo->rxwp )->id = (u32)msgid;                        /* Timestamp */                        ((struct canmsg_t *)pchip->pmsgobj[idxobj]->fifo->rxwp )->timestamp_sec = tv.tv_sec;                        ((struct canmsg_t *)pchip->pmsgobj[idxobj]->fifo->rxwp )->timestamp_usec = tv.tv_usec;                        /* Fetch message bytes */                        if (((struct canmsg_t *)pchip->pmsgobj[idxobj]->fifo->rxwp)->length > 0)                                readData.wdata[0] = pchip->read_register(pchip, CCIF1DA1);                        if (((struct canmsg_t *)pchip->pmsgobj[idxobj]->fifo->rxwp)->length > 2)                                readData.wdata[1] = pchip->read_register(pchip, CCIF1DA2);                        if (((struct canmsg_t *)pchip->pmsgobj[idxobj]->fifo->rxwp)->length > 4)                                readData.wdata[2] = pchip->read_register(pchip, CCIF1DB1);                        if (((struct canmsg_t *)pchip->pmsgobj[idxobj]->fifo->rxwp)->length > 6)                                readData.wdata[3] = pchip->read_register(pchip, CCIF1DB2);                        /* write to fifo */                        for ( i=0;                              i < ((struct canmsg_t *)pchip->pmsgobj[idxobj]->fifo->rxwp)->length;                              i++ ) {                                ((struct canmsg_t *)pchip->pmsgobj[idxobj]->fifo->rxwp)->data[ i ] =                                        readData.bdata[i];                        }                        /* fill unused data bytes with 00 */                        for ( ; i < 8; i++ ) {                                ((struct canmsg_t *)pchip->pmsgobj[idxobj]->fifo->rxwp)->data[ i ] = 0;                        }                        DEBUGMSG("(c%dm%d)Received Message:",                                 pchip->chip_nr, pchip->pmsgobj[idxobj]->object);                        DEBUGMSG(" id = %d",                                 ((struct canmsg_t *)pchip->pmsgobj[idxobj]->fifo->rxwp)->id);                        DEBUGMSG(" length = %d",                                 ((struct canmsg_t *)pchip->pmsgobj[idxobj]->fifo->rxwp)->length);                        for ( i=0;                              i < ((struct canmsg_t *)pchip->pmsgobj[idxobj]->fifo->rxwp)->length;                              i++ )                                DEBUGMSG(" data[%d] = 0x%.2x", i,                                        ((struct canmsg_t *)pchip->pmsgobj[idxobj]->fifo->rxwp)->data[i] =                                                readData.bdata[i]);                        /* Another received packet */                        pchip->stat.cntRxPkt++;                        /* Add databytes read to statistics block */                        pchip->stat.cntRxData +=                                ((struct canmsg_t *)pchip->pmsgobj[idxobj]->fifo->rxwp)->length;                        /* One message has been read -> move fifo pointers */                        pchip->pmsgobj[idxobj]->fifo->rxwp += sizeof( struct canmsg_t );                        if ( pchip->pmsgobj[idxobj]->fifo->rxwp >=                            ( pchip->pmsgobj[idxobj]->fifo->prxbuf +                              pchip->pmsgobj[idxobj]->fifo->rxsize )) {                                pchip->pmsgobj[idxobj]->fifo->rxwp =                                pchip->pmsgobj[idxobj]->fifo->prxbuf; /* wrapped */                        }                }                spin_unlock( &pchip->sprlock );                /* Check if new data arrived */                c_can_if1_busycheck(pchip);                pchip->write_register(readMaskCM, pchip, CCIF1CM);                pchip->write_register(idxobj+1, pchip, CCIF1CR);                c_can_if1_busycheck(pchip);                if ( !( ( bDataAvail = pchip->read_register( pchip, CCIF1DMC ) ) &                      IFXMC_NEWDAT ))                        break;                if ( bDataAvail & IFXMC_MSGLST ) {                        CANMSG("(c%dm%d)c-can fifo full: Message lost!",                        pchip->chip_nr, pchip->pmsgobj[idxobj]->object);                }        } /* while */        /* Wake up any waiting reader */        wake_up_interruptible( &pchip->pmsgobj[idxobj]->fifo->readq );}////////////////////////////////////////////////////////////////////////////////* * c_can_irq_rtr_handler */void c_can_irq_rtr_handler( struct chip_t *pchip, u32 msgid, struct timeval tv ){        short int i=0;        struct rtr_id *prtr_search = pchip->prtr_queue;        union Data rtrData;        spin_lock( &pchip->rtr_lock );        prtr_search->rtr_message->id = msgid;        prtr_search->rtr_message->length =                ( pchip->read_register( pchip, CCIF1DMC ) & 0x000f);        /* Fetch message bytes */        if (prtr_search->rtr_message->length > 0)                rtrData.wdata[0] = pchip->read_register(pchip, CCIF1DA1);        if (prtr_search->rtr_message->length > 2)                rtrData.wdata[1] = pchip->read_register(pchip, CCIF1DA2);        if (prtr_search->rtr_message->length > 4)                rtrData.wdata[2] = pchip->read_register(pchip, CCIF1DB1);        if (prtr_search->rtr_message->length > 6)                rtrData.wdata[3] = pchip->read_register(pchip, CCIF1DB2);        for ( i=0; i<prtr_search->rtr_message->length; i++ ) {                prtr_search->rtr_message->data[ i ] = rtrData.bdata[i];        }        /* Timestamp */        prtr_search->rtr_message->timestamp_sec= tv.tv_sec;        prtr_search->rtr_message->timestamp_usec = tv.tv_usec;        spin_unlock( &pchip->rtr_lock );        wake_up_interruptible( &prtr_search->rtr_wq );        return;}////////////////////////////////////////////////////////////////////////////////* * c_can_irq_handler * * IRQ-handler called by linux kernel */void c_can_irq_handler( int irq, void *dev_id, struct pt_regs *regs ){        struct chip_t *pchip = (struct chip_t *)dev_id;        struct rtr_id *rtr_search = pchip->prtr_queue;        int id0=0, id1=0;        u16 errcount = 0;        u16 irqreg = 0;        u32 msgid = 0;        u16 tempCntlReg = 0;        struct timeval tv;        u16 i;        if (pchip->ntype != CAN_CHIPTYPE_C_CAN) {                DEBUGMSG("\n(c%d)IRQ not for c_can_irq_handler(...)", pchip->chip_nr);                return;        }        /* read IRQ register which gives us the interrupt reason */        irqreg = pchip->read_register( pchip, CCINTR );        /* Run till no more interrupts are pending */        while ( irqreg ) {                DEBUGMSG( "(c%d)IRQ handler: addr=%.8lx irqreg=0x%.4x",                 pchip->chip_nr,                (long)( pchip->/*v*/base_addr/* + CCSR*/),                irqreg);

⌨️ 快捷键说明

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