cp_core.c//****************************************************************************// // File: cp_core.c // // Description: CANpie example core implementation // // Author: Uwe Koppe // // e-mail: koppe@microcontrol.net // // // // Copyright (C) MicroControl GmbH & Co. KG // // 53842 Troisdorf - Germany // // www.microcontrol.net // // // //----------------------------------------------------------------------------// // Redistribution and use in source and binary forms, with or without // // modification, are permitted provided that the following conditions // // are met: // // 1. Redistributions of source code must retain the above copyright // // notice, this list of conditions, the following disclaimer and // // the referenced file 'COPYING'. // // 2. Redistributions in binary form must reproduce the above copyright // // notice, this list of conditions and the following disclaimer in the // // documentation and/or other materials provided with the distribution. // // 3. Neither the name of MicroControl nor the names of its contributors // // may be used to endorse or promote products derived from this software // // without specific prior written permission. // // // // Provided that this notice is retained in full, this software may be // // distributed under the terms of the GNU Lesser General Public License // // ("LGPL") version 3 as distributed in the 'COPYING' file. // // // //----------------------------------------------------------------------------// // // // Date History // // ---------- -------------------------------------------------------------- // // 12.03.2008 Initial version // // // //****************************************************************************// //----------------------------------------------------------------------------- // SVN $Date: 2007-09-12 21:26:07 +0200 (Mit, 12 Sep 2007) $ // SVN $Rev: 89 $ --- $Author: microcontrol $ //----------------------------------------------------------------------------- /*----------------------------------------------------------------------------*\ ** Include files ** ** ** \*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*\ ** Include files ** ** ** \*----------------------------------------------------------------------------*/ #include <string.h> // for memcpy() function #include "compiler.h" #include "cp_core.h" #include "cp_msg.h" //------------------------------------------------------------------- // test the configuration // #ifndef CP_CAN_MSG_USER #error Driver must be compiled with CP_CAN_MSG_USER=1 #endif #if CP_CAN_MSG_USER!=1 #error Driver must be compiled with CP_CAN_MSG_USER=1 #endif /*----------------------------------------------------------------------------*\ ** Definitions ** ** ** \*----------------------------------------------------------------------------*/ //------------------------------------------------------------------- // buffer status information, it is stored in the 'ulMsgUser' // element of the _TsCpCanMsg structure // #define CP_BUFFER_VAL 0x0001 // buffer is valid #define CP_BUFFER_TRM 0x0002 // buffer is for transmit #define CP_BUFFER_RCV 0x0004 // buffer is for receive #define CP_BUFFER_PND 0x0020 // transmit buffer pending #define CP_BUFFER_UPD 0x0040 // receive buffer update //------------------------------------------------------------------- // Debugging // set CP_DBG_CAN_IRQ to 1 for measuring the CAN IRQ time // #define CP_DBG_CAN_IRQ 0 /*----------------------------------------------------------------------------*\ ** Variables of module ** ** ** \*----------------------------------------------------------------------------*/ //------------------------------------------------------------------- // these pointers store the callback handlers // _U08 (* pfnRcvIntHandler) (_TsCpCanMsg *, _U08); _U08 (* pfnTrmIntHandler) (_TsCpCanMsg *, _U08); _U08 (* pfnErrIntHandler) (_U08); //------------------------------------------------------------------- // mailboxes for up to CP_BUFFER_MAX CAN messages. These messages // can be either transmit or receive // _TsCpCanMsg atsCan1MsgS[CP_BUFFER_MAX]; //------------------------------------------------------------------------ // Bit Timing Table // Example bittiming table // const _U32 aulBitTimingTableS[] = { 0x002F812B, // 10 KBit/sec, 20 Tq, BRP = 300 0x002F8095, // 20 KBit/sec, 20 Tq, BRP = 150 0x002F803B, // 50 KBit/sec, 20 Tq, BRP = 60 0x002F801D, // 100 KBit/sec, 20 Tq, BRP = 30 0x002F8017, // 125 KBit/sec, 20 Tq, BRP = 24 0x002F800B, // 250 KBit/sec, 20 Tq, BRP = 12 0x002F8005, // 500 KBit/sec, 20 Tq, BRP = 6 0x001B8004, // 800 KBit/sec, 15 Tq, BRP = 5 0x002F8002 // 1 MBit/sec, 20 Tq, BRP = 3 }; /*----------------------------------------------------------------------------*\ ** Functions ** ** ** \*----------------------------------------------------------------------------*/ //----------------------------------------------------------------------------// // CpCoreAutobaud() // // run automatic baudrate detection // //----------------------------------------------------------------------------// _TvCpStatus CpCoreAutobaud(_TsCpPort * ptsPortV, _U08 * pubBaudSelV, _U16 * puwWaitV) { return(0); } //----------------------------------------------------------------------------// // CpCoreBaudrate() // // Setup baudrate of CAN controller // //----------------------------------------------------------------------------// _TvCpStatus CpCoreBaudrate(_TsCpPort * ptsPortV, _U08 ubBaudSelV) { _U32 ulCAN_Register_BittimingT; //---------------------------------------------------------------- //setup bit timing register for CANx // ulCAN_Register_BittimingT = aulBitTimingTableS[ubBaudSelV]; return (CpErr_OK); } //----------------------------------------------------------------------------// // CpCoreBufferGetData() // // // //----------------------------------------------------------------------------// _TvCpStatus CpCoreBufferGetData( _TsCpPort * ptsPortV, _U08 ubBufferIdxV, _U08 * pubDataV) { _U08 ubDataCntT; //---------------------------------------------------------------- // check for valid buffer number // if(ubBufferIdxV < CP_BUFFER_1 ) return(CpErr_BUFFER); if(ubBufferIdxV > CP_BUFFER_MAX) return(CpErr_BUFFER); //---------------------------------------------------------------- // align buffer number to index 0 for atsCanMsgS[] // ubBufferIdxV--; //---------------------------------------------------------------- // copy data from buffer // for(ubDataCntT = 0; ubDataCntT < 8; ubDataCntT++) { *pubDataV = atsCan1MsgS[ubBufferIdxV].tuMsgData.aubByte[ubDataCntT]; pubDataV++; } return (CpErr_OK); } //----------------------------------------------------------------------------// // CpCoreBufferGetDlc() // // // //----------------------------------------------------------------------------// _TvCpStatus CpCoreBufferGetDlc( _TsCpPort * ptsPortV, _U08 ubBufferIdxV, _U08 * pubDlcV) { //---------------------------------------------------------------- // check for valid buffer number // if(ubBufferIdxV < CP_BUFFER_1 ) return(CpErr_BUFFER); if(ubBufferIdxV > CP_BUFFER_MAX) return(CpErr_BUFFER); //---------------------------------------------------------------- // align buffer number to index 0 for atsCanMsgS[] // ubBufferIdxV--; *pubDlcV = atsCan1MsgS[ubBufferIdxV].ubMsgDLC; return (CpErr_OK); } //----------------------------------------------------------------------------// // CpCoreBufferInit() // // initialize CAN message buffer // //----------------------------------------------------------------------------// _TvCpStatus CpCoreBufferInit( _TsCpPort * ptsPortV, _TsCpCanMsg * ptsCanMsgV, _U08 ubBufferIdxV, _U08 ubDirectionV) { //---------------------------------------------------------------- // check for valid buffer number // if(ubBufferIdxV < CP_BUFFER_1 ) return(CpErr_BUFFER); if(ubBufferIdxV > CP_BUFFER_MAX) return(CpErr_BUFFER); //---------------------------------------------------------------- // align buffer number to index 0 for atsCanMsgS[] // ubBufferIdxV--; //---------------------------------------------------------------- // copy the data from the pCanMsgV pointer to the main buffer // memcpy(&atsCan1MsgS[ubBufferIdxV], ptsCanMsgV, sizeof(_TsCpCanMsg)); //---------------------------------------------------------------- // setup the buffer for Transmit / Receive operation // if(ubDirectionV == CP_BUFFER_DIR_TX) { //--------------------------------------------------- // direction is transmit // atsCan1MsgS[ubBufferIdxV].ulMsgUser = CP_BUFFER_VAL | CP_BUFFER_TRM; } else { //--------------------------------------------------- // direction is receive // atsCan1MsgS[ubBufferIdxV].ulMsgUser = CP_BUFFER_VAL | CP_BUFFER_RCV; } return (CpErr_OK); } //----------------------------------------------------------------------------// // CpCoreBufferRelease() // // // //----------------------------------------------------------------------------// _TvCpStatus CpCoreBufferRelease( _TsCpPort * ptsPortV, _U08 ubBufferIdxV) { //---------------------------------------------------------------- // check for valid buffer number // if(ubBufferIdxV < CP_BUFFER_1 ) return(CpErr_BUFFER); if(ubBufferIdxV > CP_BUFFER_MAX) return(CpErr_BUFFER); //---------------------------------------------------------------- // align buffer number to index 0 for atsCanMsgS[] // ubBufferIdxV--; //---------------------------------------------------------------- // clear the message buffer structure // clearing bit 0 of ulMsgUser disables the buffer // memset(&atsCan1MsgS[ubBufferIdxV], 0x00, sizeof(_TsCpCanMsg)); return (CpErr_OK); } //----------------------------------------------------------------------------// // CpCoreBufferSend() // // send message out of the CAN controller // //----------------------------------------------------------------------------// _TvCpStatus CpCoreBufferSend(_TsCpPort * ptsPortV, _U08 ubBufferIdxV) { _TsCpCanMsg * ptsCanMsgT; //---------------------------------------------------------------- // check for valid buffer number // if(ubBufferIdxV < CP_BUFFER_1 ) return(CpErr_BUFFER); if(ubBufferIdxV > CP_BUFFER_MAX) return(CpErr_BUFFER); //---------------------------------------------------------------- // internal buffer count starts at 0, the supplied buffer // number starts at 1: we adjust it here // ubBufferIdxV = ubBufferIdxV - 1; ptsCanMsgT = &atsCan1MsgS[ubBufferIdxV]; // write transmission request (send the message) return (CpErr_OK); } //----------------------------------------------------------------------------// // CpCoreBufferSetData() // // // //----------------------------------------------------------------------------// _TvCpStatus CpCoreBufferSetData( _TsCpPort * ptsPortV, _U08 ubBufferIdxV, _U08 * pubDataV) { _U08 ubDataCntT; //---------------------------------------------------------------- // check for valid buffer number // if(ubBufferIdxV < CP_BUFFER_1 ) return(CpErr_BUFFER); if(ubBufferIdxV > CP_BUFFER_MAX) return(CpErr_BUFFER); //---------------------------------------------------------------- // align buffer number to index 0 for atsCanMsgS[] // ubBufferIdxV--; //---------------------------------------------------------------- // copy data to buffer // for(ubDataCntT = 0; ubDataCntT < 8; ubDataCntT++) { atsCan1MsgS[ubBufferIdxV].tuMsgData.aubByte[ubDataCntT] = *pubDataV; pubDataV++; } return (CpErr_OK); } //----------------------------------------------------------------------------// // CpCoreBufferSetDlc() // // // //----------------------------------------------------------------------------// _TvCpStatus CpCoreBufferSetDlc( _TsCpPort * ptsPortV, _U08 ubBufferIdxV, _U08 ubDlcV) { //---------------------------------------------------------------- // check for valid buffer number // if(ubBufferIdxV < CP_BUFFER_1 ) return(CpErr_BUFFER); if(ubBufferIdxV > CP_BUFFER_MAX) return(CpErr_BUFFER); //---------------------------------------------------------------- // align buffer number to index 0 for atsCanMsgS[] // ubBufferIdxV--; //---------------------------------------------------------------- // copy DLC to buffer // atsCan1MsgS[ubBufferIdxV].ubMsgDLC = ubDlcV; return (CpErr_OK); } //----------------------------------------------------------------------------// // CpCoreCanMode() // // // //----------------------------------------------------------------------------// _TvCpStatus CpCoreCanMode(_TsCpPort * ptsPortV, _U08 ubModeV) { _U08 ubStatusT = 0; switch(ubModeV) { case CP_MODE_STOP: //------------------------------------------------ // Mode register ubStatusT = CpErr_OK; break; case CP_MODE_START: //------------------------------------------------ // Mode register: ubStatusT = CpErr_OK; break; default: ubStatusT = CpErr_NOT_SUPPORTED; break; } return(ubStatusT); } //----------------------------------------------------------------------------// // CpCoreCanState() // // // //----------------------------------------------------------------------------// _TvCpStatus CpCoreCanState(_TsCpPort * ptsPortV, _TsCpState * ptsStateV) { //---------------------------------------------------------------- // read global status register, e.g.: // // _U32 ulStatusT = 0; // ulStatusT = Register_of_CAN_controller // // set the bits of ptsStateV according to this status // here you see an example: // ptsStateV->ubCanErrState = CP_STATE_BUS_ACTIVE; ptsStateV->ubCanErrType = CP_ERR_TYPE_STUFF; //---------------------------------------------------------------- // if the CAN controller grants access to its internal // error counters, copy it here: // ptsStateV->ubCanRcvErrCnt = 8; ptsStateV->ubCanTrmErrCnt = 0; return(CpErr_OK); } //----------------------------------------------------------------------------// // CpCoreDriverInit() // // init CAN controller // //----------------------------------------------------------------------------// _TvCpStatus CpCoreDriverInit(_U08 ubPhyIfV, _TsCpPort * ptsPortV) { //---------------------------------------------------------------- // initialize the CAN controller here // return (CpErr_OK); } //----------------------------------------------------------------------------// // CpCoreDriverRelease() // // // //----------------------------------------------------------------------------// _TvCpStatus CpCoreDriverRelease(_TsCpPort * ptsPortV) { CpCoreCanMode(ptsPortV, CP_MODE_STOP); return (CpErr_OK); } //----------------------------------------------------------------------------// // CpCoreHDI() // // // //----------------------------------------------------------------------------// _TvCpStatus CpCoreHDI(_TsCpPort * ptsPortV, _TsCpHdi * ptsHdiV) { ptsHdiV->ulBitrate = 0; ptsHdiV->ulCanClock = 32; ptsHdiV->ulTimeStampRes = 1; ptsHdiV->uwBufferMax = CP_BUFFER_MAX; ptsHdiV->uwControllerType = CP_TARGET; ptsHdiV->uwIRQNumber = 0; ptsHdiV->uwSupportFlags = 0; ptsHdiV->uwVersionNumber = 1; return (CpErr_OK); } //----------------------------------------------------------------------------// // CpCoreIntFunctions() // // // //----------------------------------------------------------------------------// _TvCpStatus CpCoreIntFunctions( _TsCpPort * ptsPortV, _U08 (* pfnRcvHandler) (_TsCpCanMsg *, _U08), _U08 (* pfnTrmHandler) (_TsCpCanMsg *, _U08), _U08 (* pfnErrHandler) (_U08) ) { //---------------------------------------------------------------- // store the new callbacks // pfnRcvIntHandler = pfnRcvHandler; pfnTrmIntHandler = pfnTrmHandler; pfnErrIntHandler = pfnErrHandler; return (CpErr_OK); } //----------------------------------------------------------------------------// // CpCoreMsgRead() // // // //----------------------------------------------------------------------------// _TvCpStatus CpCoreMsgRead( _TsCpPort * ptsPortV, _TsCpCanMsg * ptsBufferV, _U32 * pulBufferSizeV) { return (CpErr_OK); } //----------------------------------------------------------------------------// // CpCoreMsgWrite() // // // //----------------------------------------------------------------------------// _TvCpStatus CpCoreMsgWrite(_TsCpPort * ptsPortV, _TsCpCanMsg * ptsBufferV, _U32 * pulBufferSizeV) { return (CpErr_OK); } //----------------------------------------------------------------------------// // CpCoreStatistic() // // // //----------------------------------------------------------------------------// _TvCpStatus CpCoreStatistic(_TsCpPort * ptsPortV, _TsCpStatistic * ptsStatsV) { return (CpErr_OK); }
|