mc_pcmcia.c
来自「canpie 一个can bus的协议栈 - CAN interface fo」· C语言 代码 · 共 942 行 · 第 1/2 页
C
942 行
/*****************************************************************************\* CANpie ** ** File : mc_pcmcia.c ** Description : Kernel driver for the MicroControl mCAN.pc.PCMCIA ** Author : Uwe Koppe ** e-mail : koppe@microcontrol.net ** ** - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ** ** *\*****************************************************************************/#include <asm/atomic.h> // atomic data types and operations#include <asm/delay.h> // delay()#include <asm/io.h> // inb() and outb()#include <linux/timer.h> // add_timer()#include <linux/sched.h> // schedule()#include <net/can/canpie.h>#include <net/can/canpie_hal.h>#include <net/can/cpcanmsg.h>#include "mc_pcmcia_cs.h"/*------------------------------------------------------------------------** Global variables used for the core functions***//*------------------------------------------------------------------------** Global variables used for access to the CAN card***/#define PCMCIA_BUFFER_SIZE 16#define PCMCIA_CHANNEL_MAX 2#define PCMCIA_COM_SIZE 16 // size of communication buffer static _U08 aubDataReadBufG[PCMCIA_COM_SIZE]; // buffer for read operationstatic _U08 aubDataWriteBufG[PCMCIA_COM_SIZE]; // buffer for write operationstatic _TsMcPcmciaInfo * ptsInfoS = NULL;static struct timer_list tsTimerS;static int aslCanLogIf[PCMCIA_CHANNEL_MAX]; // assignment of logical CAN-I/Fstatic atomic_t ulTimerStopS;//extern _U16 uwCpPcmciaInterruptG;extern _TsCpCanMsg tsCanRcvMsgG;_TsCpCanMsg tsCanTrmMsgG;//-----------------------------------------------------------------------------// the CpVar_InitFlag is used to keep track if a channel// is already initialized,// Bit 0 = channel 0// Bit 1 = channel 1// ....// Bit 15 = channel 15// a bit value of 0 means not initialized// a bit value of 1 means initialized_U16 CpVar_InitFlag = 0;/*------------------------------------------------------------------------** CpStruct_BitTimingTable** The bit timing structure has to be fitted to the used CAN controller.** If more than one CAN channel is used the structure has to be extended.*/const _TsCpBitrate atsBitTimingTable[] = { { 0x00, 0x31, 0x1C, 0x00 }, /* 10 KBit/sec */ { 0x01, 0x18, 0x1C, 0x01 }, /* 20 KBit/sec */ { 0x02, 0x09, 0x1C, 0x02 }, /* 50 KBit/sec */ { 0x03, 0x04, 0x1C, 0x03 }, /* 100 KBit/sec */ { 0x04, 0x03, 0x1C, 0x04 }, /* 125 KBit/sec */ { 0x05, 0x01, 0x1C, 0x05 }, /* 250 KBit/sec */ { 0x06, 0x00, 0x1C, 0x06 }, /* 500 KBit/sec */ { 0x07, 0x00, 0x16, 0x07 }, /* 800 KBit/sec */ { 0x08, 0x00, 0x14, 0x08 }, /* 1 MBit/sec */};/*------------------------------------------------------------------------** constants when reading the status of the CAN interface***/const _U08 FIFO_MASK_RCV_EMPTY = 0x01;const _U08 FIFO_MASK_TRM_FULL = 0x04;enum FifoStatus_e { eFIFO_STATUS_EMPTY = 0, // no data in FIFO eFIFO_STATUS_DATA, // data in FIFO available eFIFO_STATUS_FULL};static _U08 mc_pcmcia_data_read(void);static _U08 mc_pcmcia_data_write(void);static _U08 mc_pcmcia_status(_U08 ubFifoTypeV);static void mc_pcmcia_task(unsigned long ulParamV);/*------------------------------------------------------------------------** CpCoreAllocBuffer()***/#if CP_FULL_CAN == 1_U08 Cp_PREFIX CpCoreAllocBuffer (_U08 channel, CpStruct_CAN * msg, _U08 direction){#if CP_SMALL_CODE == 0 //--- test the channel number ------------------------------------ if( (channel + 1) > CP_CHANNEL_MAX) return (CpErr_CHANNEL);#endif return (CpErr_OK);}#endif//----------------------------------------------------------------------------//// CpPcmciaBitrate() //// setup baudrate ////----------------------------------------------------------------------------//_TvCpStatus CpPcmciaBitrate(_TsCpPort * ptsPortV, _TsCpBitrate * ptsBitrateV){ _U16 uwCountT; _U08 ubCanBtr0T; // value written in btr0 register _U08 ubCanBtr1T; // value written in btr1 register _U08 ubCanNumT; // CAN number for PCMCIA interface //---------------------------------------------------------------- // test the physical channel number // if( ptsPortV->slPhyIf >= PCMCIA_CHANNEL_MAX) return (CpErr_CHANNEL); //---------------------------------------------------------------- // setup the values for btr0 and btr1 // if(ptsBitrateV->ubBaudSel == CP_BAUD_BTR) { ubCanBtr0T = ptsBitrateV->ubBtr0; ubCanBtr1T = ptsBitrateV->ubBtr1; } else { //--- take values from table ----------------------------- ubCanBtr0T = atsBitTimingTable[ptsBitrateV->ubBaudSel].ubBtr0; ubCanBtr1T = atsBitTimingTable[ptsBitrateV->ubBaudSel].ubBtr1; } PK_DBG("btr0=%X btr1=%X\n", ubCanBtr0T, ubCanBtr1T); //---------------------------------------------------------------- // init the CAN port and setup baudrate // ubCanNumT = (_U08) (ptsPortV->slPhyIf) + 1; //--- setup the data in the write buffer --------------- aubDataWriteBufG[0] = 0x30; aubDataWriteBufG[1] = ubCanNumT; aubDataWriteBufG[2] = 0x00; aubDataWriteBufG[3] = 0x00; aubDataWriteBufG[4] = 0x00; aubDataWriteBufG[5] = 0x00; aubDataWriteBufG[6] = ubCanBtr0T; aubDataWriteBufG[7] = ubCanBtr1T; aubDataWriteBufG[8] = 0x00; aubDataWriteBufG[9] = 0x00; aubDataWriteBufG[10] = 0x00; aubDataWriteBufG[11] = 0x00; aubDataWriteBufG[12] = 0xFF; aubDataWriteBufG[13] = 0xE0; aubDataWriteBufG[14] = 0x00; aubDataWriteBufG[15] = 0x00; //--- send the data to the CAN card ------------------------------ mc_pcmcia_data_write(); //--- wait for 500 ms -------------------------------------------- for(uwCountT = 0; uwCountT < 500; uwCountT++) { udelay(1000); } //--- read data from card ---------------------------------------- mc_pcmcia_data_read(); if( (aubDataReadBufG[0] == 0x00) && (aubDataReadBufG[1] == 0x01) ) { PK_DBG("Baudrate setting OK\n"); return (CpErr_OK); } PK_DBG("Baudrate setting failed\n"); return (CpErr_BAUDRATE);}/*------------------------------------------------------------------------** CpCoreBufferTransmit()***/#if CP_FULL_CAN == 1_U08 Cp_PREFIX CpCoreBufferTransmit(_U08 channel, CpStruct_CAN * msg){#if CP_SMALL_CODE == 0 //--- test the channel number ------------------------------------ if( (channel + 1) > CP_CHANNEL_MAX) return (CpErr_CHANNEL);#endif return (CpErr_OK);}#endif//----------------------------------------------------------------------------//// CpPcmciaCanMode() //// Set mode of CAN controller ////----------------------------------------------------------------------------//_TvCpStatus CpPcmciaCanMode(_TsCpPort * ptsPortV, _U08 ubModeV){ _U08 ubReturnT = CpErr_OK; //---------------------------------------------------------------- // test the channel number // return(ubReturnT);}//----------------------------------------------------------------------------//// CpPcmciaCanStatus() //// Retrive status of CAN controller ////----------------------------------------------------------------------------//_TvCpStatus CpPcmciaCanStatus(_TsCpPort * ptsPortV, _U08 * pubStatusV){ _U08 ubStatusT = 0; _U08 ubReturnT = CpErr_OK; //---------------------------------------------------------------- // test the channel number // *pubStatusV = ubStatusT; return(ubReturnT);}//----------------------------------------------------------------------------//// CpPcmciaDriverInit() //// initialize the CAN card ////----------------------------------------------------------------------------//_TvCpStatus CpPcmciaDriverInit(_U08 ubPhysPortV, _TsCpPort * ptvPortV){ //---------------------------------------------------------------- return (CpErr_OK);}//----------------------------------------------------------------------------//// CpPcmciaDriverRelease() //// release the CAN driver ////----------------------------------------------------------------------------//_TvCpStatus CpPcmciaDriverRelease(_TsCpPort * ptvPortV){ _U08 ubReturnT = CpErr_OK; return(ubReturnT);}/*------------------------------------------------------------------------** CpCoreIntHandler()***/void CpCoreIntHandler(void){}//----------------------------------------------------------------------------//// CpCoreHDI() //// ////----------------------------------------------------------------------------//_U08 CpCoreHDI(_U08 ubChannelV, CpStruct_HDI * hdi){ //---------------------------------------------------------------- // test the channel number // #if CP_SMALL_CODE == 0 if( (ubChannelV + 1) > CP_CHANNEL_MAX) return (CpErr_CHANNEL); #endif //---------------------------------------------------------------- // set the support flags according to the configuration // options // return (CpErr_OK);}/*------------------------------------------------------------------------** CpCoreFilterAll()***/_U08 Cp_PREFIX CpCoreFilterAll(_U08 channel, _BIT enable){#if CP_SMALL_CODE == 0 //--- test the channel number ------------------------------------ if( (channel + 1) > CP_CHANNEL_MAX) return (CpErr_CHANNEL);#endif return (CpErr_OK);}/*------------------------------------------------------------------------** CpCoreFilterMsg()***/_U08 Cp_PREFIX CpCoreFilterMsg(_U08 channel, _U16 id, _BIT enable){#if CP_SMALL_CODE == 0 //--- test the channel number ------------------------------------ if( (channel + 1) > CP_CHANNEL_MAX) return (CpErr_CHANNEL);#endif return (CpErr_OK);}//----------------------------------------------------------------------------//// CpPcmciaMsgRead() //// Read CAN message from controller ////----------------------------------------------------------------------------//_TvCpStatus CpPcmciaMsgRead( _TsCpPort * ptsPortV, _TsCpCanMsg * ptsCanMsgV, _U16 * puwMsgCntV){ _U08 ubReturnT = CpErr_OK; _U16 uwMsgCntT = 0; //---------------------------------------------------------------- // read data from the receive queue // uwMsgCntT = can_queue_rcv_pop(ptsPortV, ptsCanMsgV, *puwMsgCntV); *puwMsgCntV = uwMsgCntT; return(ubReturnT); }//----------------------------------------------------------------------------//// CpPcmciaMsgWrite() //// send CAN message ////----------------------------------------------------------------------------//_TvCpStatus CpPcmciaMsgWrite( _TsCpPort * ptsPortV, _TsCpCanMsg * ptsCanMsgV, _U16 * puwMsgCntV){ _U08 ubTrmFifoStatusT; _U08 ubDataCntT; _U32 ulIdentifierT; _TsCpCanMsg tsCanMsgT; //---------------------------------------------------------------- // get status from PCMCIA transmit FIFO // ubTrmFifoStatusT = mc_pcmcia_status(CP_FIFO_TRM); //---------------------------------------------------------------- // read as long from the transmit FIFO (memory) until the FIFO // on the PCMCIA card is full // while(ubTrmFifoStatusT != eFIFO_STATUS_FULL) { //--------------------------------------------------- // copy data from the transmit queue // if( can_queue_trm_pop(ptsPortV, &tsCanMsgT, 1) != 1) { //--- no more messages to read -------------- break; } //--------------------------------------------------- // setup the data in the write buffer // if( CpMsgIsExtended(&tsCanMsgT) ) { aubDataWriteBufG[0x00] = 0x45; // command: extended message ulIdentifierT = CpMsgGetExtId(&tsCanMsgT); } else { aubDataWriteBufG[0x00] = 0x44; // command: standard message ulIdentifierT = CpMsgGetStdId(&tsCanMsgT); } aubDataWriteBufG[0x01] = ptsPortV->slPhyIf + 1; // channel aubDataWriteBufG[0x02] = CpMsgGetDlc(&tsCanMsgT); if(CpMsgIsRemote(&tsCanMsgT)) { aubDataWriteBufG[0x02] |= 0x10; } //--- identifier -------------------------- aubDataWriteBufG[0x03] = (_U08) ulIdentifierT; ulIdentifierT = ulIdentifierT >> 8; aubDataWriteBufG[0x04] = (_U08) ulIdentifierT; ulIdentifierT = ulIdentifierT >> 8; aubDataWriteBufG[0x05] = (_U08) ulIdentifierT; ulIdentifierT = ulIdentifierT >> 8; aubDataWriteBufG[0x07] = (_U08) ulIdentifierT; //--- data -------------------------------- for(ubDataCntT = 7; ubDataCntT < 15; ubDataCntT++) { aubDataWriteBufG[ubDataCntT] = CpMsgGetData(&tsCanMsgT, ubDataCntT - 7); } //--- send the data to the CAN card ------------------------------ mc_pcmcia_data_write(); } return (CpErr_OK);}/*----------------------------------------------------------------------------*\** module init and exit code **** function implementation **\*----------------------------------------------------------------------------*/
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?