include/hcs12/candriver.h
changeset 0 4472ee7c6c3e
child 7 126e37bcca0f
equal deleted inserted replaced
-1:000000000000 0:4472ee7c6c3e
       
     1 /*
       
     2 This file is part of CanFestival, a library implementing CanOpen Stack. 
       
     3 
       
     4 Copyright (C): Edouard TISSERANT and Francis DUPIN
       
     5 
       
     6 See COPYING file for copyrights details.
       
     7 
       
     8 This library is free software; you can redistribute it and/or
       
     9 modify it under the terms of the GNU Lesser General Public
       
    10 License as published by the Free Software Foundation; either
       
    11 version 2.1 of the License, or (at your option) any later version.
       
    12 
       
    13 This library is distributed in the hope that it will be useful,
       
    14 but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    16 Lesser General Public License for more details.
       
    17 
       
    18 You should have received a copy of the GNU Lesser General Public
       
    19 License along with this library; if not, write to the Free Software
       
    20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
       
    21 */
       
    22 
       
    23 #ifndef __CANDRIVER__
       
    24 #define __CANDRIVER__
       
    25 
       
    26 //#include DEBUG_CAN
       
    27 
       
    28 #include <can.h>
       
    29 #include <objdictdef.h>
       
    30 
       
    31 
       
    32 /*
       
    33 The CAN message received are stored in a fifo stack
       
    34 We consider one stack for all the 5 can devices. It is a choice !
       
    35 */
       
    36 
       
    37 /* Be free to change this value */
       
    38 #define MAX_STACK_MSG_RCV 5
       
    39 
       
    40 /* Number of incomings and outcomings CAN Line. The layer CanOpen must be
       
    41 used only for ONE line CAN. But you may used one or more CAN drivers, without
       
    42 a CanOpen layer.
       
    43 Only 2 lines are implemented. If more lines are needed, copy void __attribute__((interrupt)) can0HdlRcv (void) to void __attribute__((interrupt)) canXHdlRcv (void) and make 
       
    44 changes : [0] to [x], CAN0 to CANX, etc
       
    45 */
       
    46 #define NB_LINE_CAN 1
       
    47 
       
    48 /* Whose hardware HCS12 CAN block is used for CanOpen ? Chose between CAN0, ..., CAN4
       
    49 If you use CANOPEN_LINE_NUMBER_USED = CANI, the value of NB_LINE_CAN must be
       
    50 more or equal to I + 1
       
    51 Value other than CAN0 not tested, but should work fine.
       
    52  */
       
    53 #define CANOPEN_LINE_NUMBER_USED CAN0
       
    54 
       
    55 /* Stack of received messages 
       
    56 MSG received on CAN0 module is stored in stackMsgRcv[0], etc
       
    57 */
       
    58 extern volatile Message stackMsgRcv[NB_LINE_CAN][MAX_STACK_MSG_RCV];
       
    59 
       
    60 
       
    61 /* Copy from the stack of the message to treat */
       
    62 extern Message msgRcv;
       
    63 
       
    64 
       
    65 /* To move on the stack of messages 
       
    66  */
       
    67 typedef struct {
       
    68   UNS8 w ; /* received */
       
    69   UNS8 r ; /* To transmit */
       
    70 } t_pointerStack;
       
    71 
       
    72 
       
    73 /* Pointer for write or read a message in/from the reception stack */
       
    74 extern volatile t_pointerStack ptrMsgRcv[NB_LINE_CAN];
       
    75 
       
    76 /* 
       
    77 Parameters to define the  clock system for the CAN bus
       
    78 example : 
       
    79 CAN_BUS_TIME clk = {
       
    80       1,  // clksrc: Use the bus clock : 16 MHz, the freq. of the quartz's board        
       
    81       0,  // brp :  chose btw 0 and 63 (6 bits).  freq time quantum = 16MHz / (brp + 1) 
       
    82       1,  // sjw : chose btw 0 and 3 (2 bits). Sync on (sjw + 1 ) time quantum          
       
    83       1,  // samp : chose btw 0 and 3 (2 bits) (samp + 1 ) samples per bit              
       
    84       4,  // tseg2 : chose btw 0 and 7 (3 bits) Segment 2 width = (tseg2 + 1)  tq       
       
    85       9,  // tseg1 : chose btw 0 and 15 (4 bits) Segment 1 width = (tseg1 + 1)  tq      
       
    86 
       
    87       
       
    88       With these values, 
       
    89       - The width of the bit time is 16 time quantum :
       
    90           - 1 tq for the SYNC segment (could not be modified)
       
    91           - 10 tq for the TIME 1 segment (tseg1 = 9)
       
    92           - 5 tq for the TIME 2 segment (tseg2 = 4)
       
    93       - Because the bus clock of the MSCAN is 16 MHZ, and the 
       
    94         freq of the time quantum is 16 MHZ (brp = 0), and  there are 16 tq in the bit time,
       
    95         so the freq of the bit time is 1 MHz.
       
    96       
       
    97   };
       
    98 */
       
    99 typedef struct {
       
   100   UNS8  clksrc;     /* use of internal clock  or clock bus        */
       
   101   UNS8  brp;        /* define the bus speed                       */
       
   102   UNS8  sjw;        /* Number of time quantum for synchro - 1     */
       
   103   UNS8  samp;       /* Number of sample per bit (1 or 3)          */
       
   104   UNS8  tseg2;      /* Width of the time segment 2 (in tq) - 1    */
       
   105   UNS8  tseg1;      /* Width of the time segment 1 (in tq) - 1    */
       
   106 } canBusTime;
       
   107 
       
   108 /* 
       
   109 Parameters to init the filters for received messages
       
   110 */
       
   111 typedef struct {
       
   112   UNS8  idam;        /* Put 0x01 for 16 bits acceptance filter    */
       
   113   UNS8  canidar0;
       
   114   UNS8  canidmr0;
       
   115   UNS8  canidar1;
       
   116   UNS8  canidmr1; 
       
   117   UNS8  canidar2;
       
   118   UNS8  canidmr2;
       
   119   UNS8  canidar3;
       
   120   UNS8  canidmr3;
       
   121   UNS8  canidar4;
       
   122   UNS8  canidmr4;
       
   123   UNS8  canidar5;
       
   124   UNS8  canidmr5; 
       
   125   UNS8  canidar6;
       
   126   UNS8  canidmr6;
       
   127   UNS8  canidar7;
       
   128   UNS8  canidmr7;  
       
   129 } canBusFilterInit;
       
   130 
       
   131 /*
       
   132 Parameters to init MSCAN
       
   133 Example
       
   134 CAN_BUS_INIT bi = {
       
   135     0,     no low power                  
       
   136     0,     no time stamp                
       
   137     1,     enable MSCAN                 
       
   138     0,     clock source : oscillator    
       
   139     0,     no loop back                 
       
   140     0,     no listen only               
       
   141     0,     no low pass filter for wk up 
       
   142     {
       
   143       1,       Use the oscillator clock                         
       
   144       0,       Quartz oscillator : freq time quantum =  freq oscillator clock / (0 + 1)
       
   145       1,       Sync on (1 + 1) time quantum                            
       
   146       1,       1 sample per bit                                  
       
   147       4,       time segment 2 width : (4 + 1) tq                     
       
   148       9,       time segment 1 width : (9 + 1) tq                     
       
   149     }
       
   150   };   
       
   151 */
       
   152 
       
   153 typedef struct {
       
   154   UNS8  cswai;      /* Low power/normal in wait mode   (1/0)      */
       
   155   UNS8  time;       /* Timer for time-stamp enable/disable (1/0)  */
       
   156   UNS8  cane;       /* Enable MSCAN (yes=1) Do it !               */
       
   157   UNS8  clksrc;     /* clock source bus/oscillator (1/0)          */
       
   158   UNS8  loopb;      /* loop back mode for test (yes=1/no=0)       */
       
   159   UNS8  listen;     /* MSCAN is listen only (yes=1/no=0 ie normal)*/
       
   160   UNS8  wupm;       /* low pas filter for wake up (yes=1/no=0)    */
       
   161   canBusTime 
       
   162         clk;        /* Values for clock system init               */
       
   163   canBusFilterInit
       
   164   fi;               /* Values for filter acceptance msg init      */
       
   165   
       
   166 } canBusInit;
       
   167 
       
   168 extern canBusInit bi;
       
   169 
       
   170 
       
   171 /*
       
   172 For the received messsage, add a Identificator to
       
   173 the list of ID to accept.
       
   174 You can use several times this function to accept several messages.
       
   175 It configures registers on 16 bits.
       
   176 Automatically, it configure the filter to
       
   177 - not accepting the msg on 29 bits (ide=1 refused)
       
   178 - not filtering on rtr state (rtr = 1 and rtr = 0 are accepted)
       
   179 Algo :
       
   180 if CANIDARx = 0 then  CANIDARx = id . else do nothing
       
   181 CANIDMRx = CANIDMRx OR (CANIDARx XOR id )
       
   182 nFilter : 0 to 3
       
   183 Must be in init mode before.
       
   184 */
       
   185 char canAddIdToFilter (
       
   186 		       UNS16 adrCAN,
       
   187 		       UNS8 nFilter,
       
   188 		       UNS16 id /* 11 bits, the 5 msb not used */
       
   189 		       );
       
   190 
       
   191 /*
       
   192 Enable one of the 5 MSCAN.
       
   193 Must be done only one time after a reset of the CPU.
       
   194 To do before any CAN initialisation
       
   195 */
       
   196 char canEnable (
       
   197 		UNS16 adrCAN /* First address of MSCANx registers */
       
   198 		);
       
   199 
       
   200 
       
   201 /* 
       
   202 Initialize one of the 5 mscan
       
   203 can be done multiple times in your code
       
   204 Return 0 : OK
       
   205 When it return from the function,
       
   206 mscan is on sleep mode with wake up disabled.
       
   207       is not on init mode
       
   208 */
       
   209 char canInit (
       
   210 	      UNS16 adrCAN,   /* First address of MSCANx registers  */
       
   211 	      canBusInit 
       
   212 	      bi       /* All the parameters to init the bus */
       
   213 	      );
       
   214 /*
       
   215 Initialize the parameters of the system clock for the MSCAN
       
   216 You must put the MSCAN in sleep mode before with canSleepMode()
       
   217 Return 0 : OK
       
   218        1 : Not in sleep mode. Unable to init MSCAN 
       
   219 */
       
   220 char canInitClock (
       
   221 		   UNS16 adrCAN, /* First address of MSCANx registers */
       
   222 		   canBusTime clk);
       
   223 
       
   224 /* 
       
   225 Initialize one filter for acceptance of received msg.
       
   226 Filters MUST be configured on 16 bits 
       
   227 (See doc Motorola mscan bloc guide fig 4.3)
       
   228 Must be in init mode before.
       
   229 adrCAN  : adress of the first register of the mscan module
       
   230 nFilter : the filter : 0 to 3.
       
   231 ar : Value to write in acceptance register
       
   232      Beware ! hight byte and low byte inverted.
       
   233      for example if nFilter = 0, hight byte of ar -> CANIDAR0
       
   234                                  low   byte of ar -> CANIDAR1
       
   235 mr : Value to write in mask register
       
   236      Beware ! hight byte and low byte inverted.
       
   237      for example if nFilter = 2, hight byte of ar -> CANIDMR4
       
   238                                  low   byte of ar -> CANIDMR5
       
   239 */
       
   240 char canInit1Filter (
       
   241 		     UNS16 adrCAN, 
       
   242 		     UNS8 nFilter,
       
   243 		     UNS16 ar,
       
   244 		     UNS16 mr
       
   245 		     );
       
   246 
       
   247 /*
       
   248 Initialise the parameters for filtering the messages received.
       
   249 You must put the MSCAN in init mode before with canInitMode()
       
   250 Return 0 : OK
       
   251        1 : Not in init mode. Unable to init MSCAN 
       
   252 */
       
   253 
       
   254 char canInitFilter (
       
   255 		    UNS16 adrCAN, /* First address of MSCANx registers */
       
   256 		    canBusFilterInit fi);
       
   257 /*
       
   258 Put one of the 5 mscan in Init mode
       
   259 Loop until init mode is reached.
       
   260 */
       
   261 
       
   262 char canInitMode (
       
   263 		  UNS16 adrCAN /* First address of MSCANx registers */
       
   264 		  );	
       
   265 
       
   266 /*
       
   267 Leave the Init mode
       
   268 loop until init mode leaved.
       
   269 */
       
   270 
       
   271 char canInitModeQ (
       
   272 		   UNS16 adrCAN /* First address of MSCANx registers */
       
   273 		   );
       
   274 
       
   275 
       
   276 
       
   277 /*
       
   278 Transmit a msg on CAN "adrCan"
       
   279 Return : 0      No error
       
   280          other  error : no buffer available to make the transmission
       
   281 */	
       
   282 
       
   283 char canMsgTransmit (
       
   284 		     UNS16 adrCAN,  /* First address of MSCANx registers */
       
   285 		     Message msg  /* Message to transmit                */
       
   286 		     );
       
   287 
       
   288 /*
       
   289 Put one of the 5 mscan in sleep mode
       
   290 Beware! If some messages are to be sent,
       
   291 or if it is receiving, going into sleep mode
       
   292 may take time.
       
   293 Wake up is disabled : stay in sleep mode even if
       
   294 bus traffic detected.
       
   295 return 0 if 0K, other if error : mscan is on init mode.
       
   296 Stay in this function until the sleep mode
       
   297 is reached.
       
   298 */
       
   299 char canSleepMode (
       
   300 		   UNS16 adrCAN /* First address of MSCANx registers */
       
   301 		   );	
       
   302 
       
   303 /*
       
   304 Leave the sleep mode
       
   305 loop until sleep mode leaved.
       
   306 return 0 : OK
       
   307 return 1 : error : in init mode
       
   308 */
       
   309 char canSleepModeQ (
       
   310 		    UNS16 adrCAN /* First address of MSCANx registers */
       
   311 		    );	
       
   312 
       
   313 /*
       
   314 Put one of the 5 mscan in sleep mode
       
   315 MSCAN must not be in init mode.
       
   316 wake up is enabled : wake up if traffic on CAN is detected
       
   317 Beware! If some messages are to be sent,
       
   318 or if it is receiving, going into sleep mode
       
   319 may take time.
       
   320 Loop until sleep mode reached.
       
   321 return 0 if 0K, other if error
       
   322 */
       
   323 char canSleepWupMode (
       
   324 		      UNS16 adrCAN /* First address of MSCANx registers */
       
   325 		      );	
       
   326 
       
   327 /*
       
   328 Test if one of the 5 mscan is in init mode.
       
   329 Return 
       
   330        0     -> Not in init mode
       
   331        other -> In init mode
       
   332 */
       
   333 char canTestInitMode (
       
   334 		      UNS16 adrCAN /* First address of MSCANx registers */
       
   335 		      );   
       
   336 
       
   337 /*
       
   338 Test if one of the 5 mscan is in sleep mode.
       
   339 Return 
       
   340        0     -> Not in sleep mode
       
   341        other -> In sleep mode
       
   342 */
       
   343 char canTestSleepMode (
       
   344 		       UNS16 adrCAN /* First address of MSCANx registers */
       
   345 		       );   
       
   346 
       
   347 
       
   348 
       
   349 #endif /*__CANDRIVER__*/
       
   350