include/hcs12/candriver.h
changeset 0 4472ee7c6c3e
child 7 126e37bcca0f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/hcs12/candriver.h	Wed May 10 16:59:40 2006 +0200
@@ -0,0 +1,350 @@
+/*
+This file is part of CanFestival, a library implementing CanOpen Stack. 
+
+Copyright (C): Edouard TISSERANT and Francis DUPIN
+
+See COPYING file for copyrights details.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef __CANDRIVER__
+#define __CANDRIVER__
+
+//#include DEBUG_CAN
+
+#include <can.h>
+#include <objdictdef.h>
+
+
+/*
+The CAN message received are stored in a fifo stack
+We consider one stack for all the 5 can devices. It is a choice !
+*/
+
+/* Be free to change this value */
+#define MAX_STACK_MSG_RCV 5
+
+/* Number of incomings and outcomings CAN Line. The layer CanOpen must be
+used only for ONE line CAN. But you may used one or more CAN drivers, without
+a CanOpen layer.
+Only 2 lines are implemented. If more lines are needed, copy void __attribute__((interrupt)) can0HdlRcv (void) to void __attribute__((interrupt)) canXHdlRcv (void) and make 
+changes : [0] to [x], CAN0 to CANX, etc
+*/
+#define NB_LINE_CAN 1
+
+/* Whose hardware HCS12 CAN block is used for CanOpen ? Chose between CAN0, ..., CAN4
+If you use CANOPEN_LINE_NUMBER_USED = CANI, the value of NB_LINE_CAN must be
+more or equal to I + 1
+Value other than CAN0 not tested, but should work fine.
+ */
+#define CANOPEN_LINE_NUMBER_USED CAN0
+
+/* Stack of received messages 
+MSG received on CAN0 module is stored in stackMsgRcv[0], etc
+*/
+extern volatile Message stackMsgRcv[NB_LINE_CAN][MAX_STACK_MSG_RCV];
+
+
+/* Copy from the stack of the message to treat */
+extern Message msgRcv;
+
+
+/* To move on the stack of messages 
+ */
+typedef struct {
+  UNS8 w ; /* received */
+  UNS8 r ; /* To transmit */
+} t_pointerStack;
+
+
+/* Pointer for write or read a message in/from the reception stack */
+extern volatile t_pointerStack ptrMsgRcv[NB_LINE_CAN];
+
+/* 
+Parameters to define the  clock system for the CAN bus
+example : 
+CAN_BUS_TIME clk = {
+      1,  // clksrc: Use the bus clock : 16 MHz, the freq. of the quartz's board        
+      0,  // brp :  chose btw 0 and 63 (6 bits).  freq time quantum = 16MHz / (brp + 1) 
+      1,  // sjw : chose btw 0 and 3 (2 bits). Sync on (sjw + 1 ) time quantum          
+      1,  // samp : chose btw 0 and 3 (2 bits) (samp + 1 ) samples per bit              
+      4,  // tseg2 : chose btw 0 and 7 (3 bits) Segment 2 width = (tseg2 + 1)  tq       
+      9,  // tseg1 : chose btw 0 and 15 (4 bits) Segment 1 width = (tseg1 + 1)  tq      
+
+      
+      With these values, 
+      - The width of the bit time is 16 time quantum :
+          - 1 tq for the SYNC segment (could not be modified)
+          - 10 tq for the TIME 1 segment (tseg1 = 9)
+          - 5 tq for the TIME 2 segment (tseg2 = 4)
+      - Because the bus clock of the MSCAN is 16 MHZ, and the 
+        freq of the time quantum is 16 MHZ (brp = 0), and  there are 16 tq in the bit time,
+        so the freq of the bit time is 1 MHz.
+      
+  };
+*/
+typedef struct {
+  UNS8  clksrc;     /* use of internal clock  or clock bus        */
+  UNS8  brp;        /* define the bus speed                       */
+  UNS8  sjw;        /* Number of time quantum for synchro - 1     */
+  UNS8  samp;       /* Number of sample per bit (1 or 3)          */
+  UNS8  tseg2;      /* Width of the time segment 2 (in tq) - 1    */
+  UNS8  tseg1;      /* Width of the time segment 1 (in tq) - 1    */
+} canBusTime;
+
+/* 
+Parameters to init the filters for received messages
+*/
+typedef struct {
+  UNS8  idam;        /* Put 0x01 for 16 bits acceptance filter    */
+  UNS8  canidar0;
+  UNS8  canidmr0;
+  UNS8  canidar1;
+  UNS8  canidmr1; 
+  UNS8  canidar2;
+  UNS8  canidmr2;
+  UNS8  canidar3;
+  UNS8  canidmr3;
+  UNS8  canidar4;
+  UNS8  canidmr4;
+  UNS8  canidar5;
+  UNS8  canidmr5; 
+  UNS8  canidar6;
+  UNS8  canidmr6;
+  UNS8  canidar7;
+  UNS8  canidmr7;  
+} canBusFilterInit;
+
+/*
+Parameters to init MSCAN
+Example
+CAN_BUS_INIT bi = {
+    0,     no low power                  
+    0,     no time stamp                
+    1,     enable MSCAN                 
+    0,     clock source : oscillator    
+    0,     no loop back                 
+    0,     no listen only               
+    0,     no low pass filter for wk up 
+    {
+      1,       Use the oscillator clock                         
+      0,       Quartz oscillator : freq time quantum =  freq oscillator clock / (0 + 1)
+      1,       Sync on (1 + 1) time quantum                            
+      1,       1 sample per bit                                  
+      4,       time segment 2 width : (4 + 1) tq                     
+      9,       time segment 1 width : (9 + 1) tq                     
+    }
+  };   
+*/
+
+typedef struct {
+  UNS8  cswai;      /* Low power/normal in wait mode   (1/0)      */
+  UNS8  time;       /* Timer for time-stamp enable/disable (1/0)  */
+  UNS8  cane;       /* Enable MSCAN (yes=1) Do it !               */
+  UNS8  clksrc;     /* clock source bus/oscillator (1/0)          */
+  UNS8  loopb;      /* loop back mode for test (yes=1/no=0)       */
+  UNS8  listen;     /* MSCAN is listen only (yes=1/no=0 ie normal)*/
+  UNS8  wupm;       /* low pas filter for wake up (yes=1/no=0)    */
+  canBusTime 
+        clk;        /* Values for clock system init               */
+  canBusFilterInit
+  fi;               /* Values for filter acceptance msg init      */
+  
+} canBusInit;
+
+extern canBusInit bi;
+
+
+/*
+For the received messsage, add a Identificator to
+the list of ID to accept.
+You can use several times this function to accept several messages.
+It configures registers on 16 bits.
+Automatically, it configure the filter to
+- not accepting the msg on 29 bits (ide=1 refused)
+- not filtering on rtr state (rtr = 1 and rtr = 0 are accepted)
+Algo :
+if CANIDARx = 0 then  CANIDARx = id . else do nothing
+CANIDMRx = CANIDMRx OR (CANIDARx XOR id )
+nFilter : 0 to 3
+Must be in init mode before.
+*/
+char canAddIdToFilter (
+		       UNS16 adrCAN,
+		       UNS8 nFilter,
+		       UNS16 id /* 11 bits, the 5 msb not used */
+		       );
+
+/*
+Enable one of the 5 MSCAN.
+Must be done only one time after a reset of the CPU.
+To do before any CAN initialisation
+*/
+char canEnable (
+		UNS16 adrCAN /* First address of MSCANx registers */
+		);
+
+
+/* 
+Initialize one of the 5 mscan
+can be done multiple times in your code
+Return 0 : OK
+When it return from the function,
+mscan is on sleep mode with wake up disabled.
+      is not on init mode
+*/
+char canInit (
+	      UNS16 adrCAN,   /* First address of MSCANx registers  */
+	      canBusInit 
+	      bi       /* All the parameters to init the bus */
+	      );
+/*
+Initialize the parameters of the system clock for the MSCAN
+You must put the MSCAN in sleep mode before with canSleepMode()
+Return 0 : OK
+       1 : Not in sleep mode. Unable to init MSCAN 
+*/
+char canInitClock (
+		   UNS16 adrCAN, /* First address of MSCANx registers */
+		   canBusTime clk);
+
+/* 
+Initialize one filter for acceptance of received msg.
+Filters MUST be configured on 16 bits 
+(See doc Motorola mscan bloc guide fig 4.3)
+Must be in init mode before.
+adrCAN  : adress of the first register of the mscan module
+nFilter : the filter : 0 to 3.
+ar : Value to write in acceptance register
+     Beware ! hight byte and low byte inverted.
+     for example if nFilter = 0, hight byte of ar -> CANIDAR0
+                                 low   byte of ar -> CANIDAR1
+mr : Value to write in mask register
+     Beware ! hight byte and low byte inverted.
+     for example if nFilter = 2, hight byte of ar -> CANIDMR4
+                                 low   byte of ar -> CANIDMR5
+*/
+char canInit1Filter (
+		     UNS16 adrCAN, 
+		     UNS8 nFilter,
+		     UNS16 ar,
+		     UNS16 mr
+		     );
+
+/*
+Initialise the parameters for filtering the messages received.
+You must put the MSCAN in init mode before with canInitMode()
+Return 0 : OK
+       1 : Not in init mode. Unable to init MSCAN 
+*/
+
+char canInitFilter (
+		    UNS16 adrCAN, /* First address of MSCANx registers */
+		    canBusFilterInit fi);
+/*
+Put one of the 5 mscan in Init mode
+Loop until init mode is reached.
+*/
+
+char canInitMode (
+		  UNS16 adrCAN /* First address of MSCANx registers */
+		  );	
+
+/*
+Leave the Init mode
+loop until init mode leaved.
+*/
+
+char canInitModeQ (
+		   UNS16 adrCAN /* First address of MSCANx registers */
+		   );
+
+
+
+/*
+Transmit a msg on CAN "adrCan"
+Return : 0      No error
+         other  error : no buffer available to make the transmission
+*/	
+
+char canMsgTransmit (
+		     UNS16 adrCAN,  /* First address of MSCANx registers */
+		     Message msg  /* Message to transmit                */
+		     );
+
+/*
+Put one of the 5 mscan in sleep mode
+Beware! If some messages are to be sent,
+or if it is receiving, going into sleep mode
+may take time.
+Wake up is disabled : stay in sleep mode even if
+bus traffic detected.
+return 0 if 0K, other if error : mscan is on init mode.
+Stay in this function until the sleep mode
+is reached.
+*/
+char canSleepMode (
+		   UNS16 adrCAN /* First address of MSCANx registers */
+		   );	
+
+/*
+Leave the sleep mode
+loop until sleep mode leaved.
+return 0 : OK
+return 1 : error : in init mode
+*/
+char canSleepModeQ (
+		    UNS16 adrCAN /* First address of MSCANx registers */
+		    );	
+
+/*
+Put one of the 5 mscan in sleep mode
+MSCAN must not be in init mode.
+wake up is enabled : wake up if traffic on CAN is detected
+Beware! If some messages are to be sent,
+or if it is receiving, going into sleep mode
+may take time.
+Loop until sleep mode reached.
+return 0 if 0K, other if error
+*/
+char canSleepWupMode (
+		      UNS16 adrCAN /* First address of MSCANx registers */
+		      );	
+
+/*
+Test if one of the 5 mscan is in init mode.
+Return 
+       0     -> Not in init mode
+       other -> In init mode
+*/
+char canTestInitMode (
+		      UNS16 adrCAN /* First address of MSCANx registers */
+		      );   
+
+/*
+Test if one of the 5 mscan is in sleep mode.
+Return 
+       0     -> Not in sleep mode
+       other -> In sleep mode
+*/
+char canTestSleepMode (
+		       UNS16 adrCAN /* First address of MSCANx registers */
+		       );   
+
+
+
+#endif /*__CANDRIVER__*/
+