drivers/hcs12/canOpenDriver.c
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 #define DEBUG_WAR_CONSOLE_ON
       
    24 #define DEBUG_ERR_CONSOLE_ON
       
    25 
       
    26 #include <stddef.h> /* for NULL */
       
    27 
       
    28 #include "../include/hcs12/asm-m68hc12/portsaccess.h"
       
    29 #include "../include/hcs12/asm-m68hc12/ports_def.h"
       
    30 #include "../include/hcs12/asm-m68hc12/ports.h"
       
    31 #include "../include/hcs12/applicfg.h"
       
    32 #include "../include/hcs12/candriver.h"
       
    33 #include "../include/hcs12/interrupt.h"
       
    34 #include "../include/hcs12/canOpenDriver.h"
       
    35 
       
    36 #include "../include/can.h"
       
    37 #include "../include/objdictdef.h"
       
    38 #include "../include/timer.h"
       
    39 
       
    40 
       
    41 
       
    42 
       
    43 
       
    44 
       
    45 volatile static Message stackMsgRcv[NB_LINE_CAN][MAX_STACK_MSG_RCV]; 
       
    46 volatile static t_pointerStack ptrMsgRcv[NB_LINE_CAN];
       
    47  
       
    48 volatile static TIMEVAL last_time_set = TIMEVAL_MAX;
       
    49 static UNS8 timer_is_set = 0;
       
    50 
       
    51 /* Prototypes */
       
    52 UNS8 f_can_receive(UNS8 notused, Message *m);
       
    53 UNS8 canSend(UNS8 notused, Message *m);
       
    54 void __attribute__((interrupt)) timer4Hdl (void);
       
    55 
       
    56 #define max(a,b) a>b?a:b
       
    57 
       
    58 /******************************************************************************/
       
    59 void setTimer(TIMEVAL value)
       
    60 {
       
    61   IO_PORTS_16(TC4H) += value;
       
    62   timer_is_set = 1; 
       
    63 }
       
    64 
       
    65 /******************************************************************************/
       
    66 TIMEVAL getElapsedTime()
       
    67 {
       
    68   return (IO_PORTS_16(TC4H) > last_time_set ? IO_PORTS_16(TC4H) - last_time_set : last_time_set - IO_PORTS_16(TC4H));
       
    69 }
       
    70 
       
    71 
       
    72 /******************************************************************************/
       
    73 void resetTimer(void)
       
    74 {
       
    75 
       
    76 }
       
    77 
       
    78 /******************************************************************************/
       
    79 void initTimer(void)
       
    80 {
       
    81   lock();   // Inhibition of interruptions
       
    82  
       
    83   // Configure the timer channel 4
       
    84   IO_PORTS_8(TIOS) |= 0x10; // Canal 4 in output
       
    85   IO_PORTS_8(TCTL1) &= ~(0x01 + 0x02); // Canal 4 unconnected to pin output
       
    86   IO_PORTS_8(TIE) |= 0x10; // allow interruption channel 4
       
    87   IO_PORTS_8(TSCR2) |= 0X05; // Pre-scaler = 32 
       
    88                              // If this value is changed, change must be done also
       
    89                              // in void __attribute__((interrupt)) timer4Hdl (void)
       
    90 
       
    91   IO_PORTS_8(TSCR1) |= 0x80; // Start timer
       
    92   unlock(); // Allow interruptions
       
    93 }
       
    94 
       
    95 /******************************************************************************/
       
    96 void __attribute__((interrupt)) timer4Hdl (void)
       
    97 {
       
    98   lock();
       
    99   last_time_set = IO_PORTS_16(TC4H);
       
   100   IO_PORTS_8(TFLG1) = 0x10; // RAZ flag interruption timer channel 4
       
   101   // Compute the next event : When the timer reach the value of TC4, an interrupt is
       
   102   // started 
       
   103   //IO_PORTS_16(TC4H) += 250; // To have an interruption every 1 ms
       
   104   //timerInterrupt(0);
       
   105   //MSG_WAR(0xFFFF, "timer4 IT", 0);
       
   106   {
       
   107     //MSG_WAR(0xFFFF, "t4 ", IO_PORTS_16(TCNTH) - IO_PORTS_16(TC4H));
       
   108   }
       
   109   TimeDispatch();
       
   110   unlock();
       
   111 }
       
   112 
       
   113 
       
   114 /******************************************************************************/
       
   115 void initSCI_0(void)
       
   116 {
       
   117   IO_PORTS_16(SCI0 + SCIBDH) = 
       
   118     ((1000000 / SERIAL_SCI0_BAUD_RATE) * BUS_CLOCK) >> 4 ;  
       
   119   IO_PORTS_8(SCI0  + SCICR1) = 0;    // format 8N1
       
   120   IO_PORTS_8(SCI0  + SCICR2) = 0x08; // Transmit enable only
       
   121 }
       
   122 
       
   123 /******************************************************************************/
       
   124 void initSCI_1(void)
       
   125 {
       
   126   IO_PORTS_16(SCI1 + SCIBDH) = 
       
   127     ((1000000 / SERIAL_SCI1_BAUD_RATE) * BUS_CLOCK) >> 4 ;  
       
   128   IO_PORTS_8(SCI1  + SCICR1) = 0;    // format 8N1
       
   129   IO_PORTS_8(SCI1  + SCICR2) = 0x08; // Transmit enable only
       
   130 }
       
   131 
       
   132 
       
   133 /******************************************************************************/
       
   134 char *
       
   135 hex_convert (char *buf, unsigned long value, char lastCar)
       
   136 {
       
   137   //Thanks to Stéphane Carrez for this function
       
   138   char num[32];
       
   139   int pos;
       
   140 
       
   141   *buf++ = '0';
       
   142   *buf++ = 'x';
       
   143 
       
   144   pos = 0;
       
   145   while (value != 0) {
       
   146     char c = value & 0x0F;
       
   147     num[pos++] = "0123456789ABCDEF"[(unsigned) c];
       
   148     value = (value >> 4) & (0x0fffffffL);
       
   149     }
       
   150   if (pos == 0)
       
   151     num[pos++] = '0';
       
   152 
       
   153   while (--pos >= 0)
       
   154     *buf++ = num[pos];
       
   155 
       
   156   *buf++ = lastCar;
       
   157   *buf = 0;
       
   158   return buf;
       
   159 }
       
   160 
       
   161 /******************************************************************************/
       
   162 void printSCI_str(char sci, const char * str) 
       
   163 {
       
   164   char i = 0;
       
   165   
       
   166   while ((*(str + i) != 0) && (i < 0xFF)) {
       
   167     if (*(str + i) == '\n')
       
   168       {
       
   169 	while ((IO_PORTS_8(sci + SCISR1) & 0X80) == 0); // wait if buffer not empty	
       
   170 	IO_PORTS_8(sci + SCIDRL) = 13; // return to start of line
       
   171       }
       
   172     while ((IO_PORTS_8(sci + SCISR1) & 0X80) == 0); // wait if buffer not empty
       
   173     IO_PORTS_8(sci + SCIDRL) = *(str + i++);
       
   174   }
       
   175 
       
   176 }
       
   177 
       
   178 /******************************************************************************/
       
   179 void printSCI_nbr(char sci, unsigned long nbr, char lastCar) 
       
   180 {
       
   181   char strNbr[12];
       
   182   hex_convert(strNbr, nbr, lastCar);
       
   183   printSCI_str(sci, strNbr);
       
   184 }
       
   185 
       
   186 /******************************************************************************/
       
   187 // PLL 24 MHZ if quartz on board is 16 MHZ
       
   188 void initPLL(void)
       
   189 {
       
   190   IO_PORTS_8(CLKSEL) &= ~0x80; // unselect the PLL
       
   191   IO_PORTS_8(PLLCTL) |= 0X60;  // PLL ON and bandwidth auto
       
   192   IO_PORTS_8(SYNR) = 0x02;
       
   193   IO_PORTS_8(REFDV) = 0x01;
       
   194   while ((IO_PORTS_8(CRGFLG) & 0x08) == 0);
       
   195   IO_PORTS_8(CLKSEL) |= 0x80;
       
   196 }
       
   197 
       
   198 /******************************************************************************/
       
   199 void initHCS12(void)
       
   200 {
       
   201 
       
   202 # ifdef USE_PLL
       
   203   MSG_WAR(0x3620, "Use the PLL ", 0);
       
   204   initPLL();
       
   205 # endif
       
   206 
       
   207 }
       
   208 
       
   209 /***************************************************************************/
       
   210 char canAddIdToFilter(UNS16 adrCAN, UNS8 nFilter, UNS16 id)
       
   211 {
       
   212   UNS8 fiMsb;
       
   213   UNS8 fiLsb;
       
   214   UNS8 idMsb = (UNS8) (id >> 3);
       
   215   UNS8 idLsb = (UNS8) (id << 5);
       
   216 
       
   217   if (! canTestInitMode(adrCAN)) {
       
   218     /* Error because not init mode */
       
   219     MSG_WAR(0X2600, "Not in init mode ", 0);
       
   220     return 1;   
       
   221   }
       
   222   switch (nFilter) {
       
   223     case 0:
       
   224       nFilter = CANIDAR0; /* First  bank */
       
   225       break;
       
   226     case 1:
       
   227       nFilter = CANIDAR2; /* First  bank */
       
   228       break;
       
   229     case 2:
       
   230       nFilter = CANIDAR4; /* Second bank */
       
   231       break;
       
   232     case 3:
       
   233       nFilter = CANIDAR6; /* Second bank */   
       
   234   }
       
   235   if (! IO_PORTS_16(adrCAN + nFilter)) {
       
   236     /* if CANIDARx = 0 */
       
   237     IO_PORTS_8(adrCAN + nFilter) = idMsb;
       
   238     IO_PORTS_8(adrCAN + nFilter + 1) = idLsb;
       
   239   }
       
   240   fiMsb = IO_PORTS_8(adrCAN + nFilter) ^ idMsb;
       
   241   fiLsb = IO_PORTS_8(adrCAN + nFilter + 1) ^ idLsb;
       
   242   /* address of CANIDMRx */
       
   243   IO_PORTS_8(adrCAN + nFilter + 4) = IO_PORTS_8(adrCAN + nFilter + 4) | fiMsb;
       
   244   IO_PORTS_8(adrCAN + nFilter + 5) = IO_PORTS_8(adrCAN + nFilter + 5) | fiLsb;
       
   245   IO_PORTS_8(adrCAN + nFilter + 5) |= 0x10; /* Not filtering on rtr value */
       
   246   return 0;
       
   247 }
       
   248 
       
   249 /***************************************************************************/
       
   250 char canEnable(UNS16 adrCAN)
       
   251 {
       
   252   /* Register CANCTL1
       
   253   bit 7 : 1 MSCAN enabled
       
   254   Other bits : default reset values
       
   255   */
       
   256   IO_PORTS_8(adrCAN + CANCTL1) = 0X80;
       
   257   return 0;
       
   258 }
       
   259 
       
   260 /***************************************************************************/
       
   261 char canInit(UNS16 adrCAN, canBusInit bi)
       
   262 {
       
   263   /* If not in init mode, go to sleep before going in init mode*/
       
   264   if (! canTestInitMode(adrCAN)) {
       
   265     canSleepMode(adrCAN);
       
   266     canInitMode(adrCAN); 
       
   267   }
       
   268   
       
   269   canEnable(adrCAN);                  /* Does nothing if already enable */
       
   270      /* The most secure way to go in init mode : put before MSCAN in sleep mode */
       
   271       //canSleepMode(adrCAN);
       
   272      /* Put MSCAN in Init mode */ 
       
   273      //canInitMode(adrCAN);
       
   274   canInitClock(adrCAN, bi.clk); 
       
   275   /* Init CANCTL1 register. Must be in init mode */
       
   276   IO_PORTS_8(adrCAN + CANCTL1) &=0xC4;// 0xCB; /* Clr the bits that may be modified */
       
   277   IO_PORTS_8(adrCAN + CANCTL1) = (bi.cane << 7) | (bi.loopb << 5 ) | 
       
   278     (bi.listen << 4) | (bi.wupm << 2);
       
   279   /* Initialize the filters for received msgs */
       
   280   /* We should decide to accept all the msgs  */
       
   281   canInitFilter(adrCAN, bi.fi);
       
   282   /* Before to modify CANCTL0, we must leave the init mode */
       
   283   canInitModeQ(adrCAN);
       
   284   /* Init CANCTL0 register. MSCAN must not be in init mode */
       
   285   /* Do not change the value of wupe (should be 0) and slprq (should be 1) */
       
   286   /* Do not change the value of initrq (should be 0) */	
       
   287   /* rxfrm is cleared, mupe also (should be before)*/
       
   288     IO_PORTS_8(adrCAN + CANCTL0) &= 0x53; /* Clr the bits that may be modified */
       
   289     IO_PORTS_8(adrCAN + CANCTL0) = (bi.cswai << 5) | (bi.time << 3);
       
   290     IO_PORTS_8(adrCAN + CANRIER) = 0X01; /* Allow interruptions on receive */
       
   291     IO_PORTS_8(adrCAN + CANTIER) = 0X00; /* disallow  interruptions on transmit */
       
   292     canInitModeQ(adrCAN); /* Leave the init mode */
       
   293     canSleepModeQ(adrCAN); /* Leave the sleep mode */    
       
   294   return 0;
       
   295 }
       
   296 
       
   297 /***************************************************************************/
       
   298 char canInitClock(UNS16 adrCAN, canBusTime clk)
       
   299 {
       
   300   if (! canTestInitMode(adrCAN)) {
       
   301     /* Not in Init mode */
       
   302     MSG_WAR(0X2601, "not in init mode ", 0);
       
   303     return 1;   
       
   304   }
       
   305   /* Set or reset CLKSRC (register CANCTL1). Does not change the other bits*/
       
   306   clk.clksrc = clk.clksrc << 6;
       
   307   IO_PORTS_8(adrCAN + CANCTL1) &= 0xBF;
       
   308   IO_PORTS_8(adrCAN + CANCTL1) |= clk.clksrc;
       
   309   /* Build the CANBTR0 register */
       
   310   IO_PORTS_8(adrCAN + CANBTR0) = 0x00;        /* Clear before changes */
       
   311   IO_PORTS_8(adrCAN + CANBTR0) = (clk.sjw << 6) | (clk.brp);
       
   312   /* Build the CANBTR1 register */
       
   313   IO_PORTS_8(adrCAN + CANBTR1) = 0x00;        /* Clear before changes */
       
   314   IO_PORTS_8(adrCAN + CANBTR1) = (clk.samp << 7) | (clk.tseg2 << 4) | 
       
   315     (clk.tseg1);  
       
   316   return 0;
       
   317 }
       
   318 
       
   319 /***************************************************************************/
       
   320 char canInit1Filter(UNS16 adrCAN, UNS8 nFilter, UNS16 ar, UNS16 mr)
       
   321 {
       
   322   if (! canTestInitMode(adrCAN)) {
       
   323     /* Error because not init mode */
       
   324     MSG_WAR(0X2602, "not in init mode ", 0);
       
   325     return 1;   
       
   326   }
       
   327   switch (nFilter) {
       
   328     case 0:
       
   329       nFilter = CANIDAR0; /* First  bank */
       
   330       break; 
       
   331     case 1:
       
   332       nFilter = CANIDAR2; /* First  bank */
       
   333       break;
       
   334     case 2:
       
   335       nFilter = CANIDAR4; /* Second bank */
       
   336       break;
       
   337     case 3:
       
   338       nFilter = CANIDAR6; /* Second bank */   
       
   339   }
       
   340   /* address of CANIDARx */
       
   341   IO_PORTS_8(adrCAN + nFilter)     = (UNS8) (ar >> 8);
       
   342   IO_PORTS_8(adrCAN + nFilter + 1) = (UNS8) (ar);
       
   343   IO_PORTS_8(adrCAN + nFilter + 4) = (UNS8) (mr >> 8);
       
   344   IO_PORTS_8(adrCAN + nFilter + 5) = (UNS8) (mr);
       
   345   return 0;
       
   346 }
       
   347 
       
   348 /***************************************************************************/
       
   349 char canInitFilter(UNS16 adrCAN, canBusFilterInit fi)
       
   350 {
       
   351 if (! canTestInitMode(adrCAN)) {
       
   352     /* Error because not init mode */
       
   353     MSG_WAR(0X2603, "not in init mode ", 0);
       
   354     return 1;   
       
   355   }
       
   356   IO_PORTS_8(adrCAN + CANIDAC)  = fi.idam << 4;
       
   357   IO_PORTS_8(adrCAN + CANIDAR0) = fi.canidar0;
       
   358   IO_PORTS_8(adrCAN + CANIDMR0) = fi.canidmr0;
       
   359   IO_PORTS_8(adrCAN + CANIDAR1) = fi.canidar1;
       
   360   IO_PORTS_8(adrCAN + CANIDMR1) = fi.canidmr1;
       
   361   IO_PORTS_8(adrCAN + CANIDAR2) = fi.canidar2;
       
   362   IO_PORTS_8(adrCAN + CANIDMR2) = fi.canidmr2;
       
   363   IO_PORTS_8(adrCAN + CANIDAR3) = fi.canidar3;
       
   364   IO_PORTS_8(adrCAN + CANIDMR3) = fi.canidmr3;
       
   365   IO_PORTS_8(adrCAN + CANIDAR4) = fi.canidar4;
       
   366   IO_PORTS_8(adrCAN + CANIDMR4) = fi.canidmr4;
       
   367   IO_PORTS_8(adrCAN + CANIDAR5) = fi.canidar5;
       
   368   IO_PORTS_8(adrCAN + CANIDMR5) = fi.canidmr5;
       
   369   IO_PORTS_8(adrCAN + CANIDAR6) = fi.canidar6;
       
   370   IO_PORTS_8(adrCAN + CANIDMR6) = fi.canidmr6;
       
   371   IO_PORTS_8(adrCAN + CANIDAR7) = fi.canidar7;
       
   372   IO_PORTS_8(adrCAN + CANIDMR7) = fi.canidmr7;
       
   373   return 0;
       
   374 }
       
   375 
       
   376 /***************************************************************************/
       
   377 char canInitMode(UNS16 adrCAN)
       
   378 {
       
   379   IO_PORTS_8(adrCAN + CANCTL0) |= 0x01; /* Set the bit INITRQ */ 
       
   380   while (! canTestInitMode(adrCAN)) {
       
   381   }
       
   382   return 0;
       
   383 }
       
   384 
       
   385 /***************************************************************************/
       
   386 char canInitModeQ(UNS16 adrCAN)
       
   387 {
       
   388   IO_PORTS_8(adrCAN + CANCTL0) &= 0xFE; /* Clear the bit INITRQ */ 
       
   389   while (canTestInitMode(adrCAN)) {
       
   390   }
       
   391   return 0;
       
   392 }
       
   393 
       
   394 /***************************************************************************/
       
   395 char canMsgTransmit(UNS16 adrCAN, Message msg)
       
   396 {
       
   397   /* Remind : only CAN A msg implemented. ie id on 11 bits, not 29 */
       
   398   UNS8 cantflg;
       
   399   UNS8 i;
       
   400   /* Looking for a free buffer */
       
   401   cantflg = IO_PORTS_8(adrCAN + CANTFLG);
       
   402   if ( cantflg == 0) { /* all the TXEx are set */
       
   403     MSG_WAR(0X2604, "No buffer free. Msg to transmit is losted ", 0);
       
   404     return 1; /* No buffer free */
       
   405   }
       
   406   else{
       
   407     /* Selecting a buffer */
       
   408     IO_PORTS_8(adrCAN + CANTBSEL) = cantflg;
       
   409     /* We put ide = 0 because id is on 11 bits only */
       
   410      IO_PORTS_8(adrCAN + CANTRSID) = (UNS8)(msg.cob_id.w >> 3);
       
   411     IO_PORTS_8(adrCAN + CANTRSID + 1) = (UNS8)((msg.cob_id.w << 5)|
       
   412     (msg.rtr << 4));
       
   413    
       
   414     IO_PORTS_8(adrCAN + CANTRSLEN) = msg.len & 0X0F;
       
   415     /* For the priority, we put the highter bits of the cob_id */
       
   416     IO_PORTS_8(adrCAN + CANTRSPRI) = IO_PORTS_8(adrCAN + CANTRSID);
       
   417     for (i = 0 ; i < msg.len ; i++) {
       
   418       IO_PORTS_8(adrCAN + CANTRSDTA + i) = msg.data[i];
       
   419     } 
       
   420     /* Transmitting the message */ 
       
   421     cantflg = IO_PORTS_8(adrCAN + CANTBSEL);/* to know which buf is selected */
       
   422     IO_PORTS_8(adrCAN + CANTBSEL) = 0x00;  
       
   423     IO_PORTS_8(adrCAN + CANTFLG) = cantflg;  /* Ready to transmit ! */  
       
   424   
       
   425  }
       
   426   return 0;
       
   427 }
       
   428 
       
   429 /***************************************************************************/
       
   430 char canSleepMode(UNS16 adrCAN)
       
   431 {
       
   432   IO_PORTS_8(adrCAN + CANCTL0) &= 0xFB;   /* clr the bit WUPE  to avoid a wake-up*/ 
       
   433   IO_PORTS_8(adrCAN + CANCTL0) |= 0x02;   /* Set the bit SLPRQ. go to Sleep !*/ 
       
   434 
       
   435    // IO_PORTS_8(adrCAN + CANCTL1) |= 0x04;
       
   436    // IO_PORTS_8(adrCAN + CANCTL0) |= 0x02;   /* Set the bit SLPRQ */ 
       
   437    while ( ! canTestSleepMode(adrCAN)) {
       
   438      }
       
   439 
       
   440   return 0;
       
   441 }
       
   442 
       
   443 /***************************************************************************/
       
   444 char canSleepModeQ(UNS16 adrCAN)
       
   445 {
       
   446   if (canTestInitMode(adrCAN)) {
       
   447     /* Error because in init mode */
       
   448     MSG_WAR(0X2606, "not in init mode ", 0);
       
   449     return 1;   
       
   450   }
       
   451   IO_PORTS_8(adrCAN + CANCTL0) &= 0xFD;   /* clr the bit SLPRQ */ 
       
   452     while ( canTestSleepMode(adrCAN)) {
       
   453     }
       
   454   return 0;
       
   455 }
       
   456  
       
   457 /***************************************************************************/
       
   458 char canSleepWupMode(UNS16 adrCAN)
       
   459 {
       
   460   if (canTestInitMode(adrCAN)) {
       
   461     MSG_WAR(0X2607, "not in init mode ", 0);
       
   462     return 1;   
       
   463   }
       
   464   IO_PORTS_8(adrCAN + CANCTL0) |= 0x06;   /* Set the bits WUPE & SLPRQ */ 
       
   465   while ( ! canTestSleepMode(adrCAN)) {
       
   466   }
       
   467   return 0;
       
   468 }
       
   469 
       
   470 /***************************************************************************/
       
   471 char canTestInitMode(UNS16 adrCAN)
       
   472 {
       
   473   return IO_PORTS_8(adrCAN + CANCTL1) & 0x01; /* Test the bit INITAK */
       
   474 }
       
   475 
       
   476 /***************************************************************************/
       
   477 char canTestSleepMode(UNS16 adrCAN)
       
   478 {
       
   479   return IO_PORTS_8(adrCAN + CANCTL1) & 0x02; /* Test the bit SLPAK */
       
   480 }
       
   481 
       
   482 /***************************************************************************/
       
   483 UNS8 canSend(UNS8 notused, Message *m)
       
   484 {
       
   485   canMsgTransmit(CANOPEN_LINE_NUMBER_USED, *m);
       
   486   return 0;
       
   487 }
       
   488 
       
   489 
       
   490 /**************************************************************************/
       
   491 UNS8 f_can_receive(UNS8 notused, Message *msgRcv)
       
   492 { 
       
   493   UNS8 i, j;
       
   494 
       
   495   switch (CANOPEN_LINE_NUMBER_USED) {
       
   496   case CAN0 : j = 0; break;
       
   497   case CAN1 : j = 1; break;
       
   498   case CAN2 : j = 2; break;
       
   499   case CAN3 : j = 3; break;
       
   500   case CAN4 : j = 4; break;
       
   501   }
       
   502 
       
   503   /* See if a message is pending in the stack */
       
   504   if (ptrMsgRcv[j].r == ptrMsgRcv[j].w)
       
   505     return 0x0; // No new message
       
   506 
       
   507   /* Increment the reading pointer of the stack */
       
   508   if (ptrMsgRcv[j].r == (MAX_STACK_MSG_RCV - 1)) 
       
   509      ptrMsgRcv[j].r = 0;
       
   510   else
       
   511     ptrMsgRcv[j].r ++;
       
   512 
       
   513   /* Store the message from the stack*/
       
   514   msgRcv->cob_id.w = stackMsgRcv[j][ptrMsgRcv[j].r].cob_id.w;
       
   515   msgRcv->len = stackMsgRcv[j][ptrMsgRcv[j].r].len;
       
   516   msgRcv->rtr = stackMsgRcv[j][ptrMsgRcv[j].r].rtr;
       
   517   for (i = 0 ; i < stackMsgRcv[j][ptrMsgRcv[j].r].len ; i++)
       
   518     msgRcv->data[i] = stackMsgRcv[j][ptrMsgRcv[j].r].data[i];
       
   519   return 0xFF;
       
   520 }
       
   521 
       
   522 
       
   523 /******************************************************************************
       
   524  ******************************* CAN INTERRUPT  *******************************/
       
   525 
       
   526 void __attribute__((interrupt)) can0HdlTra (void)
       
   527 {
       
   528  
       
   529 }
       
   530 
       
   531 void __attribute__((interrupt)) can0HdlRcv (void)
       
   532 { 
       
   533   UNS8 i;
       
   534   lock();
       
   535   IO_PORTS_8(PORTB) &= ~ 0x40; // led 6 port B : ON
       
   536   UNS8 NewPtrW; 
       
   537   /* We are obliged to save the message while the interruption is pending */
       
   538   /* Increment the writing stack pointer before writing the msg */
       
   539   if (ptrMsgRcv[0].w == (MAX_STACK_MSG_RCV - 1)) 
       
   540     NewPtrW = 0;
       
   541   else
       
   542     NewPtrW = ptrMsgRcv[0].w + 1;
       
   543   
       
   544   if (NewPtrW == ptrMsgRcv[0].r) {
       
   545     /* The stack is full. The last msg received before this one is lost */
       
   546     MSG_WAR(0X1620, "Stack for received msg is full", 0);
       
   547     //IO_PORTS_8(PORTB) &= ~0x40; // led  6         : ON (for debogue)
       
   548   }
       
   549   else
       
   550     ptrMsgRcv[0].w = NewPtrW;
       
   551   
       
   552   /* Store the message */
       
   553   stackMsgRcv[0][ptrMsgRcv[0].w].cob_id.w = IO_PORTS_16(CAN0 + CANRCVID) >> 5;
       
   554   stackMsgRcv[0][ptrMsgRcv[0].w].len = IO_PORTS_8(CAN0 + CANRCVLEN) & 0x0F;
       
   555   stackMsgRcv[0][ptrMsgRcv[0].w].rtr = (IO_PORTS_8(CAN0 + CANRCVID + 1) >> 4) & 0x01;
       
   556   for (i = 0 ; i < stackMsgRcv[0][ptrMsgRcv[0].w].len ; i++)
       
   557     stackMsgRcv[0][ptrMsgRcv[0].w].data[i] = IO_PORTS_8(CAN0 + CANRCVDTA + i);
       
   558   
       
   559   // The message is stored , so
       
   560   // we can now release the receive foreground buffer
       
   561   // and acknowledge the interruption
       
   562   IO_PORTS_8(CAN0 + CANRFLG) |= 0x01;
       
   563   // Not very usefull
       
   564   IO_PORTS_8(CAN0 + CANCTL0) |= 0x80;
       
   565   IO_PORTS_8(PORTB) |= 0x40; // led 6 port B : ON
       
   566   unlock();
       
   567 }
       
   568 
       
   569 void __attribute__((interrupt)) can0HdlWup (void)
       
   570 {
       
   571 
       
   572 }
       
   573 
       
   574 void __attribute__((interrupt)) can0HdlErr (void)
       
   575 {
       
   576 
       
   577 }
       
   578 
       
   579 void __attribute__((interrupt)) can1HdlTra (void)
       
   580 {
       
   581  
       
   582 }
       
   583 
       
   584 void __attribute__((interrupt)) can1HdlRcv (void)
       
   585 {
       
   586   UNS8 i;
       
   587   lock();
       
   588   UNS8 NewPtrW; 
       
   589   /* We are obliged to save the message while the interruption is pending */
       
   590   /* Increment the writing stack pointer before writing the msg */
       
   591   if (ptrMsgRcv[1].w == (MAX_STACK_MSG_RCV - 1)) 
       
   592     NewPtrW = 0;
       
   593   else
       
   594     NewPtrW = ptrMsgRcv[1].w + 1;
       
   595   
       
   596   if (NewPtrW == ptrMsgRcv[1].r) {
       
   597     /* The stack is full. The last msg received before this one is lost */
       
   598     MSG_WAR(0X2620, "Stack for received msg is full", 0);
       
   599   }
       
   600   else
       
   601     ptrMsgRcv[1].w = NewPtrW;
       
   602   
       
   603   /* Store the message */
       
   604   stackMsgRcv[1][ptrMsgRcv[1].w].cob_id.w = IO_PORTS_16(CAN1 + CANRCVID) >> 5;
       
   605   stackMsgRcv[1][ptrMsgRcv[1].w].len = IO_PORTS_8(CAN1 + CANRCVLEN) & 0x0F;
       
   606   stackMsgRcv[0][ptrMsgRcv[0].w].rtr = (IO_PORTS_8(CAN1 + CANRCVID + 1) >> 4) & 0x01;
       
   607   for (i = 0 ; i < stackMsgRcv[1][ptrMsgRcv[1].w].len ; i++)
       
   608     stackMsgRcv[1][ptrMsgRcv[1].w].data[i] = IO_PORTS_8(CAN1 + CANRCVDTA + i);
       
   609   
       
   610   // The message is stored , so
       
   611   // we can now release the receive foreground buffer
       
   612   // and acknowledge the interruption
       
   613   IO_PORTS_8(CAN1 + CANRFLG) |= 0x01;
       
   614   // Not very usefull
       
   615   IO_PORTS_8(CAN1 + CANCTL0) |= 0x80;
       
   616   unlock();
       
   617 }
       
   618 
       
   619 void __attribute__((interrupt)) can1HdlWup (void)
       
   620 {
       
   621 
       
   622 }
       
   623 
       
   624 void __attribute__((interrupt)) can1HdlErr (void)
       
   625 {
       
   626 
       
   627 }
       
   628 
       
   629 void __attribute__((interrupt)) can2HdlTra (void)
       
   630 {
       
   631 
       
   632 }
       
   633 
       
   634 void __attribute__((interrupt)) can2HdlRcv (void)
       
   635 {
       
   636 
       
   637 }
       
   638 
       
   639 void __attribute__((interrupt)) can2HdlWup (void)
       
   640 {
       
   641 
       
   642 }
       
   643 
       
   644 void __attribute__((interrupt)) can2HdlErr (void)
       
   645 {
       
   646 
       
   647 }
       
   648 
       
   649 void __attribute__((interrupt)) can3HdlTra (void)
       
   650 {
       
   651 
       
   652 }
       
   653 
       
   654 void __attribute__((interrupt)) can3HdlRcv (void)
       
   655 {
       
   656 
       
   657 }
       
   658 
       
   659 void __attribute__((interrupt)) can3HdlWup (void)
       
   660 {
       
   661 
       
   662 }
       
   663 
       
   664 void __attribute__((interrupt)) can3HdlErr (void)
       
   665 {
       
   666 
       
   667 }
       
   668 
       
   669 void __attribute__((interrupt)) can4HdlTra (void)
       
   670 {
       
   671 
       
   672 }
       
   673 
       
   674 void __attribute__((interrupt)) can4HdlRcv (void)
       
   675 {
       
   676 
       
   677 }
       
   678 
       
   679 void __attribute__((interrupt)) can4HdlWup (void)
       
   680 {
       
   681 
       
   682 }
       
   683 
       
   684 void __attribute__((interrupt)) can4HdlErr (void)
       
   685 {
       
   686 
       
   687 }
       
   688 
       
   689 
       
   690