• Home • Files • Structures         • Download

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);
}





 

© MicroControl GmbH & Co. KG

CANpie - V2.00