nico@215: nico@215: nico@215: CanFestival: include/hcs12/candriver.h Source File nico@215: nico@215: nico@215: nico@215: nico@215:
nico@215:
nico@215:
nico@215:
nico@215: nico@215:

candriver.h

Go to the documentation of this file.
00001 /*
nico@215: 00002 This file is part of CanFestival, a library implementing CanOpen Stack. 
nico@215: 00003 
nico@215: 00004 Copyright (C): Edouard TISSERANT and Francis DUPIN
nico@215: 00005 
nico@215: 00006 See COPYING file for copyrights details.
nico@215: 00007 
nico@215: 00008 This library is free software; you can redistribute it and/or
nico@215: 00009 modify it under the terms of the GNU Lesser General Public
nico@215: 00010 License as published by the Free Software Foundation; either
nico@215: 00011 version 2.1 of the License, or (at your option) any later version.
nico@215: 00012 
nico@215: 00013 This library is distributed in the hope that it will be useful,
nico@215: 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of
nico@215: 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
nico@215: 00016 Lesser General Public License for more details.
nico@215: 00017 
nico@215: 00018 You should have received a copy of the GNU Lesser General Public
nico@215: 00019 License along with this library; if not, write to the Free Software
nico@215: 00020 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
nico@215: 00021 */
nico@215: 00022 
nico@215: 00023 #ifndef __CANDRIVER__
nico@215: 00024 #define __CANDRIVER__
nico@215: 00025 
nico@215: 00026 //#include DEBUG_CAN
nico@215: 00027 
nico@215: 00028 #include <can.h>
nico@215: 00029 #include <objdictdef.h>
nico@215: 00030 
nico@215: 00031 
nico@215: 00032 /*
nico@215: 00033 The CAN message received are stored in a fifo stack
nico@215: 00034 We consider one stack for all the 5 can devices. It is a choice !
nico@215: 00035 */
nico@215: 00036 
nico@215: 00037 /* Be free to change this value */
nico@215: 00038 #define MAX_STACK_MSG_RCV 5
nico@215: 00039 
nico@215: 00040 /* Number of incomings and outcomings CAN Line. The layer CanOpen must be
nico@215: 00041 used only for ONE line CAN. But you may used one or more CAN drivers, without
nico@215: 00042 a CanOpen layer.
nico@215: 00043 Only 2 lines are implemented. If more lines are needed, copy void __attribute__((interrupt)) can0HdlRcv (void) to void __attribute__((interrupt)) canXHdlRcv (void) and make 
nico@215: 00044 changes : [0] to [x], CAN0 to CANX, etc
nico@215: 00045 */
nico@215: 00046 #define NB_LINE_CAN 1
nico@215: 00047 
nico@215: 00048 /* Whose hardware HCS12 CAN block is used for CanOpen ? Chose between CAN0, ..., CAN4
nico@215: 00049 If you use CANOPEN_LINE_NUMBER_USED = CANI, the value of NB_LINE_CAN must be
nico@215: 00050 more or equal to I + 1
nico@215: 00051 Value other than CAN0 not tested, but should work fine.
nico@215: 00052  */
nico@215: 00053 #define CANOPEN_LINE_NUMBER_USED CAN0
nico@215: 00054 
nico@215: 00055 /* Stack of received messages 
nico@215: 00056 MSG received on CAN0 module is stored in stackMsgRcv[0], etc
nico@215: 00057 */
nico@215: 00058 extern volatile Message stackMsgRcv[NB_LINE_CAN][MAX_STACK_MSG_RCV];
nico@215: 00059 
nico@215: 00060 
nico@215: 00061 /* Copy from the stack of the message to treat */
nico@215: 00062 extern Message msgRcv;
nico@215: 00063 
nico@215: 00064 
nico@215: 00065 /* To move on the stack of messages 
nico@215: 00066  */
nico@215: 00067 typedef struct {
nico@215: 00068   UNS8 w ; /* received */
nico@215: 00069   UNS8 r ; /* To transmit */
nico@215: 00070 } t_pointerStack;
nico@215: 00071 
nico@215: 00072 
nico@215: 00073 /* Pointer for write or read a message in/from the reception stack */
nico@215: 00074 extern volatile t_pointerStack ptrMsgRcv[NB_LINE_CAN];
nico@215: 00075 
nico@215: 00076 /* 
nico@215: 00077 Parameters to define the  clock system for the CAN bus
nico@215: 00078 example : 
nico@215: 00079 CAN_BUS_TIME clk = {
nico@215: 00080       1,  // clksrc: Use the bus clock : 16 MHz, the freq. of the quartz's board        
nico@215: 00081       0,  // brp :  chose btw 0 and 63 (6 bits).  freq time quantum = 16MHz / (brp + 1) 
nico@215: 00082       1,  // sjw : chose btw 0 and 3 (2 bits). Sync on (sjw + 1 ) time quantum          
nico@215: 00083       1,  // samp : chose btw 0 and 3 (2 bits) (samp + 1 ) samples per bit              
nico@215: 00084       4,  // tseg2 : chose btw 0 and 7 (3 bits) Segment 2 width = (tseg2 + 1)  tq       
nico@215: 00085       9,  // tseg1 : chose btw 0 and 15 (4 bits) Segment 1 width = (tseg1 + 1)  tq      
nico@215: 00086 
nico@215: 00087       
nico@215: 00088       With these values, 
nico@215: 00089       - The width of the bit time is 16 time quantum :
nico@215: 00090           - 1 tq for the SYNC segment (could not be modified)
nico@215: 00091           - 10 tq for the TIME 1 segment (tseg1 = 9)
nico@215: 00092           - 5 tq for the TIME 2 segment (tseg2 = 4)
nico@215: 00093       - Because the bus clock of the MSCAN is 16 MHZ, and the 
nico@215: 00094         freq of the time quantum is 16 MHZ (brp = 0), and  there are 16 tq in the bit time,
nico@215: 00095         so the freq of the bit time is 1 MHz.
nico@215: 00096       
nico@215: 00097   };
nico@215: 00098 */
nico@215: 00099 typedef struct {
nico@215: 00100   UNS8  clksrc;     /* use of internal clock  or clock bus        */
nico@215: 00101   UNS8  brp;        /* define the bus speed                       */
nico@215: 00102   UNS8  sjw;        /* Number of time quantum for synchro - 1     */
nico@215: 00103   UNS8  samp;       /* Number of sample per bit (1 or 3)          */
nico@215: 00104   UNS8  tseg2;      /* Width of the time segment 2 (in tq) - 1    */
nico@215: 00105   UNS8  tseg1;      /* Width of the time segment 1 (in tq) - 1    */
nico@215: 00106 } canBusTime;
nico@215: 00107 
nico@215: 00108 /* 
nico@215: 00109 Parameters to init the filters for received messages
nico@215: 00110 */
nico@215: 00111 typedef struct {
nico@215: 00112   UNS8  idam;        /* Put 0x01 for 16 bits acceptance filter    */
nico@215: 00113   UNS8  canidar0;
nico@215: 00114   UNS8  canidmr0;
nico@215: 00115   UNS8  canidar1;
nico@215: 00116   UNS8  canidmr1; 
nico@215: 00117   UNS8  canidar2;
nico@215: 00118   UNS8  canidmr2;
nico@215: 00119   UNS8  canidar3;
nico@215: 00120   UNS8  canidmr3;
nico@215: 00121   UNS8  canidar4;
nico@215: 00122   UNS8  canidmr4;
nico@215: 00123   UNS8  canidar5;
nico@215: 00124   UNS8  canidmr5; 
nico@215: 00125   UNS8  canidar6;
nico@215: 00126   UNS8  canidmr6;
nico@215: 00127   UNS8  canidar7;
nico@215: 00128   UNS8  canidmr7;  
nico@215: 00129 } canBusFilterInit;
nico@215: 00130 
nico@215: 00131 /*
nico@215: 00132 Parameters to init MSCAN
nico@215: 00133 Example
nico@215: 00134 CAN_BUS_INIT bi = {
nico@215: 00135     0,     no low power                  
nico@215: 00136     0,     no time stamp                
nico@215: 00137     1,     enable MSCAN                 
nico@215: 00138     0,     clock source : oscillator    
nico@215: 00139     0,     no loop back                 
nico@215: 00140     0,     no listen only               
nico@215: 00141     0,     no low pass filter for wk up 
nico@215: 00142     {
nico@215: 00143       1,       Use the oscillator clock                         
nico@215: 00144       0,       Quartz oscillator : freq time quantum =  freq oscillator clock / (0 + 1)
nico@215: 00145       1,       Sync on (1 + 1) time quantum                            
nico@215: 00146       1,       1 sample per bit                                  
nico@215: 00147       4,       time segment 2 width : (4 + 1) tq                     
nico@215: 00148       9,       time segment 1 width : (9 + 1) tq                     
nico@215: 00149     }
nico@215: 00150   };   
nico@215: 00151 */
nico@215: 00152 
nico@215: 00153 typedef struct {
nico@215: 00154   UNS8  cswai;      /* Low power/normal in wait mode   (1/0)      */
nico@215: 00155   UNS8  time;       /* Timer for time-stamp enable/disable (1/0)  */
nico@215: 00156   UNS8  cane;       /* Enable MSCAN (yes=1) Do it !               */
nico@215: 00157   UNS8  clksrc;     /* clock source bus/oscillator (1/0)          */
nico@215: 00158   UNS8  loopb;      /* loop back mode for test (yes=1/no=0)       */
nico@215: 00159   UNS8  listen;     /* MSCAN is listen only (yes=1/no=0 ie normal)*/
nico@215: 00160   UNS8  wupm;       /* low pas filter for wake up (yes=1/no=0)    */
nico@215: 00161   canBusTime 
nico@215: 00162         clk;        /* Values for clock system init               */
nico@215: 00163   canBusFilterInit
nico@215: 00164   fi;               /* Values for filter acceptance msg init      */
nico@215: 00165   
nico@215: 00166 } canBusInit;
nico@215: 00167 
nico@215: 00168 extern canBusInit bi;
nico@215: 00169 
nico@215: 00170 
nico@215: 00171 
nico@215: 00172 /*
nico@215: 00173 For the received messsage, add a Identificator to
nico@215: 00174 the list of ID to accept.
nico@215: 00175 You can use several times this function to accept several messages.
nico@215: 00176 It configures registers on 16 bits.
nico@215: 00177 Automatically, it configure the filter to
nico@215: 00178 - not accepting the msg on 29 bits (ide=1 refused)
nico@215: 00179 - not filtering on rtr state (rtr = 1 and rtr = 0 are accepted)
nico@215: 00180 Algo :
nico@215: 00181 if CANIDARx = 0 then  CANIDARx = id . else do nothing
nico@215: 00182 CANIDMRx = CANIDMRx OR (CANIDARx XOR id )
nico@215: 00183 nFilter : 0 to 3
nico@215: 00184 Must be in init mode before.
nico@215: 00185 */
nico@215: 00186 char canAddIdToFilter (
nico@215: 00187                        UNS16 adrCAN,
nico@215: 00188                        UNS8 nFilter,
nico@215: 00189                        UNS16 id /* 11 bits, the 5 msb not used */
nico@215: 00190                        );
nico@215: 00191 
nico@215: 00192 /*
nico@215: 00193  Use this function to change the CAN message acceptance filters and masks.
nico@215: 00194  */
nico@215: 00195 char canChangeFilter (UNS16 adrCAN, canBusFilterInit fi);
nico@215: 00196 
nico@215: 00197 
nico@215: 00198 /*
nico@215: 00199 Enable one of the 5 MSCAN.
nico@215: 00200 Must be done only one time after a reset of the CPU.
nico@215: 00201 To do before any CAN initialisation
nico@215: 00202 */
nico@215: 00203 char canEnable (
nico@215: 00204                 UNS16 adrCAN /* First address of MSCANx registers */
nico@215: 00205                 );
nico@215: 00206 
nico@215: 00207 
nico@215: 00208 /* 
nico@215: 00209 Initialize one of the 5 mscan
nico@215: 00210 can be done multiple times in your code
nico@215: 00211 Return 0 : OK
nico@215: 00212 When it return from the function,
nico@215: 00213 mscan is on sleep mode with wake up disabled.
nico@215: 00214       is not on init mode
nico@215: 00215 */
nico@215: 00216 char canInit (
nico@215: 00217               UNS16 adrCAN,   /* First address of MSCANx registers  */
nico@215: 00218               canBusInit 
nico@215: 00219               bi       /* All the parameters to init the bus */
nico@215: 00220               );
nico@215: 00221 /*
nico@215: 00222 Initialize the parameters of the system clock for the MSCAN
nico@215: 00223 You must put the MSCAN in sleep mode before with canSleepMode()
nico@215: 00224 Return 0 : OK
nico@215: 00225        1 : Not in sleep mode. Unable to init MSCAN 
nico@215: 00226 */
nico@215: 00227 char canInitClock (
nico@215: 00228                    UNS16 adrCAN, /* First address of MSCANx registers */
nico@215: 00229                    canBusTime clk);
nico@215: 00230 
nico@215: 00231 /* 
nico@215: 00232 Initialize one filter for acceptance of received msg.
nico@215: 00233 Filters MUST be configured on 16 bits 
nico@215: 00234 (See doc Motorola mscan bloc guide fig 4.3)
nico@215: 00235 Must be in init mode before.
nico@215: 00236 adrCAN  : adress of the first register of the mscan module
nico@215: 00237 nFilter : the filter : 0 to 3.
nico@215: 00238 ar : Value to write in acceptance register
nico@215: 00239      Beware ! hight byte and low byte inverted.
nico@215: 00240      for example if nFilter = 0, hight byte of ar -> CANIDAR0
nico@215: 00241                                  low   byte of ar -> CANIDAR1
nico@215: 00242 mr : Value to write in mask register
nico@215: 00243      Beware ! hight byte and low byte inverted.
nico@215: 00244      for example if nFilter = 2, hight byte of ar -> CANIDMR4
nico@215: 00245                                  low   byte of ar -> CANIDMR5
nico@215: 00246 */
nico@215: 00247 char canInit1Filter (
nico@215: 00248                      UNS16 adrCAN, 
nico@215: 00249                      UNS8 nFilter,
nico@215: 00250                      UNS16 ar,
nico@215: 00251                      UNS16 mr
nico@215: 00252                      );
nico@215: 00253 
nico@215: 00254 /*
nico@215: 00255 Initialise the parameters for filtering the messages received.
nico@215: 00256 You must put the MSCAN in init mode before with canInitMode()
nico@215: 00257 Return 0 : OK
nico@215: 00258        1 : Not in init mode. Unable to init MSCAN 
nico@215: 00259 */
nico@215: 00260 
nico@215: 00261 char canInitFilter (
nico@215: 00262                     UNS16 adrCAN, /* First address of MSCANx registers */
nico@215: 00263                     canBusFilterInit fi);
nico@215: 00264 /*
nico@215: 00265 Put one of the 5 mscan in Init mode
nico@215: 00266 Loop until init mode is reached.
nico@215: 00267 */
nico@215: 00268 
nico@215: 00269 char canInitMode (
nico@215: 00270                   UNS16 adrCAN /* First address of MSCANx registers */
nico@215: 00271                   );    
nico@215: 00272 
nico@215: 00273 /*
nico@215: 00274 Leave the Init mode
nico@215: 00275 loop until init mode leaved.
nico@215: 00276 */
nico@215: 00277 
nico@215: 00278 char canInitModeQ (
nico@215: 00279                    UNS16 adrCAN /* First address of MSCANx registers */
nico@215: 00280                    );
nico@215: 00281 
nico@215: 00282 
nico@215: 00283 
nico@215: 00284 /*
nico@215: 00285 Transmit a msg on CAN "adrCan"
nico@215: 00286 Return : 0      No error
nico@215: 00287          other  error : no buffer available to make the transmission
nico@215: 00288 */      
nico@215: 00289 
nico@215: 00290 char canMsgTransmit (
nico@215: 00291                      UNS16 adrCAN,  /* First address of MSCANx registers */
nico@215: 00292                      Message msg  /* Message to transmit                */
nico@215: 00293                      );
nico@215: 00294 
nico@215: 00295 /*
nico@215: 00296  Set the interruptions. Must be call just after having left the init mode.
nico@215: 00297  */          
nico@215: 00298 char canSetInterrupt (UNS16 adrCAN);                 
nico@215: 00299 
nico@215: 00300 /*
nico@215: 00301 Put one of the 5 mscan in sleep mode
nico@215: 00302 Beware! If some messages are to be sent,
nico@215: 00303 or if it is receiving, going into sleep mode
nico@215: 00304 may take time.
nico@215: 00305 Wake up is disabled : stay in sleep mode even if
nico@215: 00306 bus traffic detected.
nico@215: 00307 return 0 if 0K, other if error : mscan is on init mode.
nico@215: 00308 Stay in this function until the sleep mode
nico@215: 00309 is reached.
nico@215: 00310 */
nico@215: 00311 char canSleepMode (
nico@215: 00312                    UNS16 adrCAN /* First address of MSCANx registers */
nico@215: 00313                    );   
nico@215: 00314 
nico@215: 00315 /*
nico@215: 00316 Leave the sleep mode
nico@215: 00317 loop until sleep mode leaved.
nico@215: 00318 return 0 : OK
nico@215: 00319 return 1 : error : in init mode
nico@215: 00320 */
nico@215: 00321 char canSleepModeQ (
nico@215: 00322                     UNS16 adrCAN /* First address of MSCANx registers */
nico@215: 00323                     );  
nico@215: 00324 
nico@215: 00325 /*
nico@215: 00326 Put one of the 5 mscan in sleep mode
nico@215: 00327 MSCAN must not be in init mode.
nico@215: 00328 wake up is enabled : wake up if traffic on CAN is detected
nico@215: 00329 Beware! If some messages are to be sent,
nico@215: 00330 or if it is receiving, going into sleep mode
nico@215: 00331 may take time.
nico@215: 00332 Loop until sleep mode reached.
nico@215: 00333 return 0 if 0K, other if error
nico@215: 00334 */
nico@215: 00335 char canSleepWupMode (
nico@215: 00336                       UNS16 adrCAN /* First address of MSCANx registers */
nico@215: 00337                       );        
nico@215: 00338 
nico@215: 00339 /*
nico@215: 00340 Test if one of the 5 mscan is in init mode.
nico@215: 00341 Return 
nico@215: 00342        0     -> Not in init mode
nico@215: 00343        other -> In init mode
nico@215: 00344 */
nico@215: 00345 char canTestInitMode (
nico@215: 00346                       UNS16 adrCAN /* First address of MSCANx registers */
nico@215: 00347                       );   
nico@215: 00348 
nico@215: 00349 /*
nico@215: 00350 Test if one of the 5 mscan is in sleep mode.
nico@215: 00351 Return 
nico@215: 00352        0     -> Not in sleep mode
nico@215: 00353        other -> In sleep mode
nico@215: 00354 */
nico@215: 00355 char canTestSleepMode (
nico@215: 00356                        UNS16 adrCAN /* First address of MSCANx registers */
nico@215: 00357                        );   
nico@215: 00358 
nico@215: 00359 
nico@215: 00360 
nico@215: 00361 #endif /*__CANDRIVER__*/
nico@215: 00362 
nico@215: 

Generated on Fri Jun 8 08:51:39 2007 for CanFestival by  nico@215: nico@215: doxygen 1.5.1
nico@215: nico@215: