diff -r 003cc3c63855 -r f49e5a6b7804 doc/doxygen/html/canOpenDriver_8c-source.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/doxygen/html/canOpenDriver_8c-source.html Fri Jun 08 09:23:56 2007 +0200 @@ -0,0 +1,738 @@ + +
+00001 /* +00002 This file is part of CanFestival, a library implementing CanOpen Stack. +00003 +00004 Copyright (C): Edouard TISSERANT and Francis DUPIN +00005 +00006 See COPYING file for copyrights details. +00007 +00008 This library is free software; you can redistribute it and/or +00009 modify it under the terms of the GNU Lesser General Public +00010 License as published by the Free Software Foundation; either +00011 version 2.1 of the License, or (at your option) any later version. +00012 +00013 This library is distributed in the hope that it will be useful, +00014 but WITHOUT ANY WARRANTY; without even the implied warranty of +00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +00016 Lesser General Public License for more details. +00017 +00018 You should have received a copy of the GNU Lesser General Public +00019 License along with this library; if not, write to the Free Software +00020 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +00021 */ +00022 +00023 #define DEBUG_WAR_CONSOLE_ON +00024 #define DEBUG_ERR_CONSOLE_ON +00025 +00026 #include <stddef.h> /* for NULL */ +00027 +00028 #include "../include/hcs12/asm-m68hc12/portsaccess.h" +00029 #include "../include/hcs12/asm-m68hc12/ports_def.h" +00030 #include "../include/hcs12/asm-m68hc12/ports.h" +00031 #include "../include/data.h" +00032 #include "../include/hcs12/applicfg.h" +00033 #include "../include/hcs12/candriver.h" +00034 #include "../include/hcs12/interrupt.h" +00035 #include "../include/hcs12/canOpenDriver.h" +00036 #include "../include/can.h" +00037 #include "../include/objdictdef.h" +00038 #include "../include/timer.h" +00039 +00040 +00041 +00042 +00043 +00044 +00045 volatile static Message stackMsgRcv[NB_LINE_CAN][MAX_STACK_MSG_RCV]; +00046 volatile static t_pointerStack ptrMsgRcv[NB_LINE_CAN]; +00047 +00048 volatile static TIMEVAL last_time_set = TIMEVAL_MAX; +00049 static UNS8 timer_is_set = 0; +00050 +00051 /* Prototypes */ +00052 UNS8 f_can_receive(UNS8 notused, Message *m); +00053 UNS8 canSend(UNS8 notused, Message *m); +00054 void __attribute__((interrupt)) timer4Hdl (void); +00055 +00056 #define max(a,b) a>b?a:b +00057 +00058 /******************************************************************************/ +00059 void setTimer(TIMEVAL value) +00060 { +00061 IO_PORTS_16(TC4H) += value; +00062 timer_is_set = 1; +00063 } +00064 +00065 /******************************************************************************/ +00066 TIMEVAL getElapsedTime() +00067 { +00068 return (IO_PORTS_16(TC4H) > last_time_set ? IO_PORTS_16(TC4H) - last_time_set : last_time_set - IO_PORTS_16(TC4H)); +00069 } +00070 +00071 +00072 /******************************************************************************/ +00073 void resetTimer(void) +00074 { +00075 +00076 } +00077 +00078 /******************************************************************************/ +00079 void initTimer(void) +00080 { +00081 lock(); // Inhibition of interruptions +00082 +00083 // Configure the timer channel 4 +00084 IO_PORTS_8(TIOS) |= 0x10; // Canal 4 in output +00085 IO_PORTS_8(TCTL1) &= ~(0x01 + 0x02); // Canal 4 unconnected to pin output +00086 IO_PORTS_8(TIE) |= 0x10; // allow interruption channel 4 +00087 IO_PORTS_8(TSCR2) |= 0X05; // Pre-scaler = 32 +00088 // If this value is changed, change must be done also +00089 // in void __attribute__((interrupt)) timer4Hdl (void) +00090 +00091 IO_PORTS_8(TSCR1) |= 0x80; // Start timer +00092 unlock(); // Allow interruptions +00093 } +00094 +00095 /******************************************************************************/ +00096 void __attribute__((interrupt)) timer4Hdl (void) +00097 { +00098 lock(); +00099 last_time_set = IO_PORTS_16(TC4H); +00100 IO_PORTS_8(TFLG1) = 0x10; // RAZ flag interruption timer channel 4 +00101 // Compute the next event : When the timer reach the value of TC4, an interrupt is +00102 // started +00103 //IO_PORTS_16(TC4H) += 250; // To have an interruption every 1 ms +00104 //timerInterrupt(0); +00105 //MSG_WAR(0xFFFF, "timer4 IT", 0); +00106 { +00107 //MSG_WAR(0xFFFF, "t4 ", IO_PORTS_16(TCNTH) - IO_PORTS_16(TC4H)); +00108 } +00109 TimeDispatch(); +00110 unlock(); +00111 } +00112 +00113 +00114 /******************************************************************************/ +00115 void initSCI_0(void) +00116 { +00117 IO_PORTS_16(SCI0 + SCIBDH) = +00118 ((1000000 / SERIAL_SCI0_BAUD_RATE) * BUS_CLOCK) >> 4 ; +00119 IO_PORTS_8(SCI0 + SCICR1) = 0; // format 8N1 +00120 IO_PORTS_8(SCI0 + SCICR2) = 0x08; // Transmit enable only +00121 } +00122 +00123 /******************************************************************************/ +00124 void initSCI_1(void) +00125 { +00126 IO_PORTS_16(SCI1 + SCIBDH) = +00127 ((1000000 / SERIAL_SCI1_BAUD_RATE) * BUS_CLOCK) >> 4 ; +00128 IO_PORTS_8(SCI1 + SCICR1) = 0; // format 8N1 +00129 IO_PORTS_8(SCI1 + SCICR2) = 0x08; // Transmit enable only +00130 } +00131 +00132 +00133 /******************************************************************************/ +00134 char * +00135 hex_convert (char *buf, unsigned long value, char lastCar) +00136 { +00137 //Thanks to Stéphane Carrez for this function +00138 char num[32]; +00139 int pos; +00140 +00141 *buf++ = '0'; +00142 *buf++ = 'x'; +00143 +00144 pos = 0; +00145 while (value != 0) { +00146 char c = value & 0x0F; +00147 num[pos++] = "0123456789ABCDEF"[(unsigned) c]; +00148 value = (value >> 4) & (0x0fffffffL); +00149 } +00150 if (pos == 0) +00151 num[pos++] = '0'; +00152 +00153 while (--pos >= 0) +00154 *buf++ = num[pos]; +00155 +00156 *buf++ = lastCar; +00157 *buf = 0; +00158 return buf; +00159 } +00160 +00161 /******************************************************************************/ +00162 void printSCI_str(char sci, const char * str) +00163 { +00164 char i = 0; +00165 +00166 while ((*(str + i) != 0) && (i < 0xFF)) { +00167 if (*(str + i) == '\n') +00168 { +00169 while ((IO_PORTS_8(sci + SCISR1) & 0X80) == 0); // wait if buffer not empty +00170 IO_PORTS_8(sci + SCIDRL) = 13; // return to start of line +00171 } +00172 while ((IO_PORTS_8(sci + SCISR1) & 0X80) == 0); // wait if buffer not empty +00173 IO_PORTS_8(sci + SCIDRL) = *(str + i++); +00174 } +00175 +00176 } +00177 +00178 /******************************************************************************/ +00179 void printSCI_nbr(char sci, unsigned long nbr, char lastCar) +00180 { +00181 char strNbr[12]; +00182 hex_convert(strNbr, nbr, lastCar); +00183 printSCI_str(sci, strNbr); +00184 } +00185 +00186 /******************************************************************************/ +00187 // PLL 24 MHZ if quartz on board is 16 MHZ +00188 void initPLL(void) +00189 { +00190 IO_PORTS_8(CLKSEL) &= ~0x80; // unselect the PLL +00191 IO_PORTS_8(PLLCTL) |= 0X60; // PLL ON and bandwidth auto +00192 IO_PORTS_8(SYNR) = 0x02; +00193 IO_PORTS_8(REFDV) = 0x01; +00194 while ((IO_PORTS_8(CRGFLG) & 0x08) == 0); +00195 IO_PORTS_8(CLKSEL) |= 0x80; +00196 } +00197 +00198 /******************************************************************************/ +00199 void initHCS12(void) +00200 { +00201 +00202 # ifdef USE_PLL +00203 MSG_WAR(0x3620, "Use the PLL ", 0); +00204 initPLL(); +00205 # endif +00206 +00207 } +00208 +00209 /***************************************************************************/ +00210 char canAddIdToFilter(UNS16 adrCAN, UNS8 nFilter, UNS16 id) +00211 { +00212 UNS8 fiMsb; +00213 UNS8 fiLsb; +00214 UNS8 idMsb = (UNS8) (id >> 3); +00215 UNS8 idLsb = (UNS8) (id << 5); +00216 +00217 if (! canTestInitMode(adrCAN)) { +00218 /* Error because not init mode */ +00219 MSG_WAR(0X2600, "Not in init mode ", 0); +00220 return 1; +00221 } +00222 switch (nFilter) { +00223 case 0: +00224 nFilter = CANIDAR0; /* First bank */ +00225 break; +00226 case 1: +00227 nFilter = CANIDAR2; /* First bank */ +00228 break; +00229 case 2: +00230 nFilter = CANIDAR4; /* Second bank */ +00231 break; +00232 case 3: +00233 nFilter = CANIDAR6; /* Second bank */ +00234 } +00235 if (! IO_PORTS_16(adrCAN + nFilter)) { +00236 /* if CANIDARx = 0 */ +00237 IO_PORTS_8(adrCAN + nFilter) = idMsb; +00238 IO_PORTS_8(adrCAN + nFilter + 1) = idLsb; +00239 } +00240 fiMsb = IO_PORTS_8(adrCAN + nFilter) ^ idMsb; +00241 fiLsb = IO_PORTS_8(adrCAN + nFilter + 1) ^ idLsb; +00242 /* address of CANIDMRx */ +00243 IO_PORTS_8(adrCAN + nFilter + 4) = IO_PORTS_8(adrCAN + nFilter + 4) | fiMsb; +00244 IO_PORTS_8(adrCAN + nFilter + 5) = IO_PORTS_8(adrCAN + nFilter + 5) | fiLsb; +00245 IO_PORTS_8(adrCAN + nFilter + 5) |= 0x10; /* Not filtering on rtr value */ +00246 return 0; +00247 } +00248 +00249 /***************************************************************************/ +00250 char canChangeFilter(UNS16 adrCAN, canBusFilterInit fi) +00251 { +00252 /* If not in init mode, go to sleep before going in init mode*/ +00253 if (! canTestInitMode(adrCAN)) { +00254 canSleepMode(adrCAN); +00255 canInitMode(adrCAN); +00256 } +00257 //update the filters configuration +00258 canInitFilter(adrCAN, fi); +00259 canInitModeQ(adrCAN); +00260 canSleepModeQ(adrCAN); +00261 canSetInterrupt(adrCAN); +00262 return 0; +00263 } +00264 +00265 /***************************************************************************/ +00266 char canEnable(UNS16 adrCAN) +00267 { +00268 /* Register CANCTL1 +00269 bit 7 : 1 MSCAN enabled +00270 Other bits : default reset values +00271 */ +00272 IO_PORTS_8(adrCAN + CANCTL1) = 0X80; +00273 return 0; +00274 } +00275 +00276 /***************************************************************************/ +00277 char canInit(UNS16 adrCAN, canBusInit bi) +00278 { +00279 /* If not in init mode, go to sleep before going in init mode*/ +00280 if (! canTestInitMode(adrCAN)) { +00281 canSleepMode(adrCAN); +00282 canInitMode(adrCAN); +00283 } +00284 +00285 canEnable(adrCAN); /* Does nothing if already enable */ +00286 /* The most secure way to go in init mode : put before MSCAN in sleep mode */ +00287 //canSleepMode(adrCAN); +00288 /* Put MSCAN in Init mode */ +00289 //canInitMode(adrCAN); +00290 canInitClock(adrCAN, bi.clk); +00291 /* Init CANCTL1 register. Must be in init mode */ +00292 IO_PORTS_8(adrCAN + CANCTL1) &=0xC4;// 0xCB; /* Clr the bits that may be modified */ +00293 IO_PORTS_8(adrCAN + CANCTL1) = (bi.cane << 7) | (bi.loopb << 5 ) | +00294 (bi.listen << 4) | (bi.wupm << 2); +00295 /* Initialize the filters for received msgs */ +00296 /* We should decide to accept all the msgs */ +00297 canInitFilter(adrCAN, bi.fi); +00298 /* Before to modify CANCTL0, we must leave the init mode */ +00299 canInitModeQ(adrCAN); +00300 /* Init CANCTL0 register. MSCAN must not be in init mode */ +00301 /* Do not change the value of wupe (should be 0) and slprq (should be 1) */ +00302 /* Do not change the value of initrq (should be 0) */ +00303 /* rxfrm is cleared, mupe also (should be before)*/ +00304 IO_PORTS_8(adrCAN + CANCTL0) &= 0x53; /* Clr the bits that may be modified */ +00305 IO_PORTS_8(adrCAN + CANCTL0) = (bi.cswai << 5) | (bi.time << 3); +00306 canSetInterrupt(adrCAN); +00307 canInitModeQ(adrCAN); /* Leave the init mode */ +00308 canSleepModeQ(adrCAN); /* Leave the sleep mode */ +00309 return 0; +00310 } +00311 +00312 /***************************************************************************/ +00313 char canInitClock(UNS16 adrCAN, canBusTime clk) +00314 { +00315 if (! canTestInitMode(adrCAN)) { +00316 /* Not in Init mode */ +00317 MSG_WAR(0X2601, "not in init mode ", 0); +00318 return 1; +00319 } +00320 /* Set or reset CLKSRC (register CANCTL1). Does not change the other bits*/ +00321 clk.clksrc = clk.clksrc << 6; +00322 IO_PORTS_8(adrCAN + CANCTL1) &= 0xBF; +00323 IO_PORTS_8(adrCAN + CANCTL1) |= clk.clksrc; +00324 /* Build the CANBTR0 register */ +00325 IO_PORTS_8(adrCAN + CANBTR0) = 0x00; /* Clear before changes */ +00326 IO_PORTS_8(adrCAN + CANBTR0) = (clk.sjw << 6) | (clk.brp); +00327 /* Build the CANBTR1 register */ +00328 IO_PORTS_8(adrCAN + CANBTR1) = 0x00; /* Clear before changes */ +00329 IO_PORTS_8(adrCAN + CANBTR1) = (clk.samp << 7) | (clk.tseg2 << 4) | +00330 (clk.tseg1); +00331 return 0; +00332 } +00333 +00334 /***************************************************************************/ +00335 char canInit1Filter(UNS16 adrCAN, UNS8 nFilter, UNS16 ar, UNS16 mr) +00336 { +00337 if (! canTestInitMode(adrCAN)) { +00338 /* Error because not init mode */ +00339 MSG_WAR(0X2602, "not in init mode ", 0); +00340 return 1; +00341 } +00342 switch (nFilter) { +00343 case 0: +00344 nFilter = CANIDAR0; /* First bank */ +00345 break; +00346 case 1: +00347 nFilter = CANIDAR2; /* First bank */ +00348 break; +00349 case 2: +00350 nFilter = CANIDAR4; /* Second bank */ +00351 break; +00352 case 3: +00353 nFilter = CANIDAR6; /* Second bank */ +00354 } +00355 /* address of CANIDARx */ +00356 IO_PORTS_8(adrCAN + nFilter) = (UNS8) (ar >> 8); +00357 IO_PORTS_8(adrCAN + nFilter + 1) = (UNS8) (ar); +00358 IO_PORTS_8(adrCAN + nFilter + 4) = (UNS8) (mr >> 8); +00359 IO_PORTS_8(adrCAN + nFilter + 5) = (UNS8) (mr); +00360 return 0; +00361 } +00362 +00363 /***************************************************************************/ +00364 char canInitFilter(UNS16 adrCAN, canBusFilterInit fi) +00365 { +00366 if (! canTestInitMode(adrCAN)) { +00367 /* Error because not init mode */ +00368 MSG_WAR(0X2603, "not in init mode ", 0); +00369 return 1; +00370 } +00371 IO_PORTS_8(adrCAN + CANIDAC) = fi.idam << 4; +00372 IO_PORTS_8(adrCAN + CANIDAR0) = fi.canidar0; +00373 IO_PORTS_8(adrCAN + CANIDMR0) = fi.canidmr0; +00374 IO_PORTS_8(adrCAN + CANIDAR1) = fi.canidar1; +00375 IO_PORTS_8(adrCAN + CANIDMR1) = fi.canidmr1; +00376 IO_PORTS_8(adrCAN + CANIDAR2) = fi.canidar2; +00377 IO_PORTS_8(adrCAN + CANIDMR2) = fi.canidmr2; +00378 IO_PORTS_8(adrCAN + CANIDAR3) = fi.canidar3; +00379 IO_PORTS_8(adrCAN + CANIDMR3) = fi.canidmr3; +00380 IO_PORTS_8(adrCAN + CANIDAR4) = fi.canidar4; +00381 IO_PORTS_8(adrCAN + CANIDMR4) = fi.canidmr4; +00382 IO_PORTS_8(adrCAN + CANIDAR5) = fi.canidar5; +00383 IO_PORTS_8(adrCAN + CANIDMR5) = fi.canidmr5; +00384 IO_PORTS_8(adrCAN + CANIDAR6) = fi.canidar6; +00385 IO_PORTS_8(adrCAN + CANIDMR6) = fi.canidmr6; +00386 IO_PORTS_8(adrCAN + CANIDAR7) = fi.canidar7; +00387 IO_PORTS_8(adrCAN + CANIDMR7) = fi.canidmr7; +00388 return 0; +00389 } +00390 +00391 /***************************************************************************/ +00392 char canInitMode(UNS16 adrCAN) +00393 { +00394 IO_PORTS_8(adrCAN + CANCTL0) |= 0x01; /* Set the bit INITRQ */ +00395 while (! canTestInitMode(adrCAN)) { +00396 } +00397 return 0; +00398 } +00399 +00400 /***************************************************************************/ +00401 char canInitModeQ(UNS16 adrCAN) +00402 { +00403 IO_PORTS_8(adrCAN + CANCTL0) &= 0xFE; /* Clear the bit INITRQ */ +00404 while (canTestInitMode(adrCAN)) { +00405 } +00406 return 0; +00407 } +00408 +00409 /***************************************************************************/ +00410 char canMsgTransmit(UNS16 adrCAN, Message msg) +00411 { +00412 /* Remind : only CAN A msg implemented. ie id on 11 bits, not 29 */ +00413 UNS8 cantflg; +00414 UNS8 i; +00415 /* Looking for a free buffer */ +00416 cantflg = IO_PORTS_8(adrCAN + CANTFLG); +00417 if ( cantflg == 0) { /* all the TXEx are set */ +00418 MSG_WAR(0X2604, "No buffer free. Msg to transmit is losted ", 0); +00419 return 1; /* No buffer free */ +00420 } +00421 else{ +00422 /* Selecting a buffer */ +00423 IO_PORTS_8(adrCAN + CANTBSEL) = cantflg; +00424 /* We put ide = 0 because id is on 11 bits only */ +00425 IO_PORTS_8(adrCAN + CANTRSID) = (UNS8)(msg.cob_id.w >> 3); +00426 IO_PORTS_8(adrCAN + CANTRSID + 1) = (UNS8)((msg.cob_id.w << 5)| +00427 (msg.rtr << 4)); +00428 +00429 IO_PORTS_8(adrCAN + CANTRSLEN) = msg.len & 0X0F; +00430 /* For the priority, we put the highter bits of the cob_id */ +00431 IO_PORTS_8(adrCAN + CANTRSPRI) = IO_PORTS_8(adrCAN + CANTRSID); +00432 for (i = 0 ; i < msg.len ; i++) { +00433 IO_PORTS_8(adrCAN + CANTRSDTA + i) = msg.data[i]; +00434 } +00435 /* Transmitting the message */ +00436 cantflg = IO_PORTS_8(adrCAN + CANTBSEL);/* to know which buf is selected */ +00437 IO_PORTS_8(adrCAN + CANTBSEL) = 0x00; +00438 IO_PORTS_8(adrCAN + CANTFLG) = cantflg; /* Ready to transmit ! */ +00439 +00440 } +00441 return 0; +00442 } +00443 +00444 /***************************************************************************/ +00445 char canSetInterrupt(UNS16 adrCAN) +00446 { +00447 IO_PORTS_8(adrCAN + CANRIER) = 0X01; /* Allow interruptions on receive */ +00448 IO_PORTS_8(adrCAN + CANTIER) = 0X00; /* disallow interruptions on transmit */ +00449 return 0; +00450 } +00451 /***************************************************************************/ +00452 char canSleepMode(UNS16 adrCAN) +00453 { +00454 IO_PORTS_8(adrCAN + CANCTL0) &= 0xFB; /* clr the bit WUPE to avoid a wake-up*/ +00455 IO_PORTS_8(adrCAN + CANCTL0) |= 0x02; /* Set the bit SLPRQ. go to Sleep !*/ +00456 +00457 // IO_PORTS_8(adrCAN + CANCTL1) |= 0x04; +00458 // IO_PORTS_8(adrCAN + CANCTL0) |= 0x02; /* Set the bit SLPRQ */ +00459 while ( ! canTestSleepMode(adrCAN)) { +00460 } +00461 +00462 return 0; +00463 } +00464 +00465 /***************************************************************************/ +00466 char canSleepModeQ(UNS16 adrCAN) +00467 { +00468 if (canTestInitMode(adrCAN)) { +00469 /* Error because in init mode */ +00470 MSG_WAR(0X2606, "not in init mode ", 0); +00471 return 1; +00472 } +00473 IO_PORTS_8(adrCAN + CANCTL0) &= 0xFD; /* clr the bit SLPRQ */ +00474 while ( canTestSleepMode(adrCAN)) { +00475 } +00476 return 0; +00477 } +00478 +00479 /***************************************************************************/ +00480 char canSleepWupMode(UNS16 adrCAN) +00481 { +00482 if (canTestInitMode(adrCAN)) { +00483 MSG_WAR(0X2607, "not in init mode ", 0); +00484 return 1; +00485 } +00486 IO_PORTS_8(adrCAN + CANCTL0) |= 0x06; /* Set the bits WUPE & SLPRQ */ +00487 while ( ! canTestSleepMode(adrCAN)) { +00488 } +00489 return 0; +00490 } +00491 +00492 /***************************************************************************/ +00493 char canTestInitMode(UNS16 adrCAN) +00494 { +00495 return IO_PORTS_8(adrCAN + CANCTL1) & 0x01; /* Test the bit INITAK */ +00496 } +00497 +00498 /***************************************************************************/ +00499 char canTestSleepMode(UNS16 adrCAN) +00500 { +00501 return IO_PORTS_8(adrCAN + CANCTL1) & 0x02; /* Test the bit SLPAK */ +00502 } +00503 +00504 /***************************************************************************/ +00505 UNS8 canSend(UNS8 notused, Message *m) +00506 { +00507 canMsgTransmit(CANOPEN_LINE_NUMBER_USED, *m); +00508 return 0; +00509 } +00510 +00511 +00512 /**************************************************************************/ +00513 UNS8 f_can_receive(UNS8 notused, Message *msgRcv) +00514 { +00515 UNS8 i, j; +00516 +00517 switch (CANOPEN_LINE_NUMBER_USED) { +00518 case CAN0 : j = 0; break; +00519 case CAN1 : j = 1; break; +00520 case CAN2 : j = 2; break; +00521 case CAN3 : j = 3; break; +00522 case CAN4 : j = 4; break; +00523 } +00524 +00525 /* See if a message is pending in the stack */ +00526 if (ptrMsgRcv[j].r == ptrMsgRcv[j].w) +00527 return 0x0; // No new message +00528 +00529 /* Increment the reading pointer of the stack */ +00530 if (ptrMsgRcv[j].r == (MAX_STACK_MSG_RCV - 1)) +00531 ptrMsgRcv[j].r = 0; +00532 else +00533 ptrMsgRcv[j].r ++; +00534 +00535 /* Store the message from the stack*/ +00536 msgRcv->cob_id.w = stackMsgRcv[j][ptrMsgRcv[j].r].cob_id.w; +00537 msgRcv->len = stackMsgRcv[j][ptrMsgRcv[j].r].len; +00538 msgRcv->rtr = stackMsgRcv[j][ptrMsgRcv[j].r].rtr; +00539 for (i = 0 ; i < stackMsgRcv[j][ptrMsgRcv[j].r].len ; i++) +00540 msgRcv->data[i] = stackMsgRcv[j][ptrMsgRcv[j].r].data[i]; +00541 return 0xFF; +00542 } +00543 +00544 +00545 /****************************************************************************** +00546 ******************************* CAN INTERRUPT *******************************/ +00547 +00548 void __attribute__((interrupt)) can0HdlTra (void) +00549 { +00550 +00551 } +00552 +00553 void __attribute__((interrupt)) can0HdlRcv (void) +00554 { +00555 UNS8 i; +00556 lock(); +00557 IO_PORTS_8(PORTB) &= ~ 0x40; // led 6 port B : ON +00558 UNS8 NewPtrW; +00559 /* We are obliged to save the message while the interruption is pending */ +00560 /* Increment the writing stack pointer before writing the msg */ +00561 if (ptrMsgRcv[0].w == (MAX_STACK_MSG_RCV - 1)) +00562 NewPtrW = 0; +00563 else +00564 NewPtrW = ptrMsgRcv[0].w + 1; +00565 +00566 if (NewPtrW == ptrMsgRcv[0].r) { +00567 /* The stack is full. The last msg received before this one is lost */ +00568 MSG_WAR(0X1620, "Stack for received msg is full", 0); +00569 //IO_PORTS_8(PORTB) &= ~0x40; // led 6 : ON (for debogue) +00570 } +00571 else +00572 ptrMsgRcv[0].w = NewPtrW; +00573 +00574 /* Store the message */ +00575 stackMsgRcv[0][ptrMsgRcv[0].w].cob_id.w = IO_PORTS_16(CAN0 + CANRCVID) >> 5; +00576 stackMsgRcv[0][ptrMsgRcv[0].w].len = IO_PORTS_8(CAN0 + CANRCVLEN) & 0x0F; +00577 stackMsgRcv[0][ptrMsgRcv[0].w].rtr = (IO_PORTS_8(CAN0 + CANRCVID + 1) >> 4) & 0x01; +00578 for (i = 0 ; i < stackMsgRcv[0][ptrMsgRcv[0].w].len ; i++) +00579 stackMsgRcv[0][ptrMsgRcv[0].w].data[i] = IO_PORTS_8(CAN0 + CANRCVDTA + i); +00580 +00581 // The message is stored , so +00582 // we can now release the receive foreground buffer +00583 // and acknowledge the interruption +00584 IO_PORTS_8(CAN0 + CANRFLG) |= 0x01; +00585 // Not very usefull +00586 IO_PORTS_8(CAN0 + CANCTL0) |= 0x80; +00587 IO_PORTS_8(PORTB) |= 0x40; // led 6 port B : OFF +00588 unlock(); +00589 } +00590 +00591 void __attribute__((interrupt)) can0HdlWup (void) +00592 { +00593 +00594 } +00595 +00596 void __attribute__((interrupt)) can0HdlErr (void) +00597 { +00598 +00599 } +00600 +00601 void __attribute__((interrupt)) can1HdlTra (void) +00602 { +00603 +00604 } +00605 +00606 void __attribute__((interrupt)) can1HdlRcv (void) +00607 { +00608 UNS8 i; +00609 lock(); +00610 UNS8 NewPtrW; +00611 /* We are obliged to save the message while the interruption is pending */ +00612 /* Increment the writing stack pointer before writing the msg */ +00613 if (ptrMsgRcv[1].w == (MAX_STACK_MSG_RCV - 1)) +00614 NewPtrW = 0; +00615 else +00616 NewPtrW = ptrMsgRcv[1].w + 1; +00617 +00618 if (NewPtrW == ptrMsgRcv[1].r) { +00619 /* The stack is full. The last msg received before this one is lost */ +00620 MSG_WAR(0X2620, "Stack for received msg is full", 0); +00621 } +00622 else +00623 ptrMsgRcv[1].w = NewPtrW; +00624 +00625 /* Store the message */ +00626 stackMsgRcv[1][ptrMsgRcv[1].w].cob_id.w = IO_PORTS_16(CAN1 + CANRCVID) >> 5; +00627 stackMsgRcv[1][ptrMsgRcv[1].w].len = IO_PORTS_8(CAN1 + CANRCVLEN) & 0x0F; +00628 stackMsgRcv[0][ptrMsgRcv[0].w].rtr = (IO_PORTS_8(CAN1 + CANRCVID + 1) >> 4) & 0x01; +00629 for (i = 0 ; i < stackMsgRcv[1][ptrMsgRcv[1].w].len ; i++) +00630 stackMsgRcv[1][ptrMsgRcv[1].w].data[i] = IO_PORTS_8(CAN1 + CANRCVDTA + i); +00631 +00632 // The message is stored , so +00633 // we can now release the receive foreground buffer +00634 // and acknowledge the interruption +00635 IO_PORTS_8(CAN1 + CANRFLG) |= 0x01; +00636 // Not very usefull +00637 IO_PORTS_8(CAN1 + CANCTL0) |= 0x80; +00638 unlock(); +00639 } +00640 +00641 void __attribute__((interrupt)) can1HdlWup (void) +00642 { +00643 +00644 } +00645 +00646 void __attribute__((interrupt)) can1HdlErr (void) +00647 { +00648 +00649 } +00650 +00651 void __attribute__((interrupt)) can2HdlTra (void) +00652 { +00653 +00654 } +00655 +00656 void __attribute__((interrupt)) can2HdlRcv (void) +00657 { +00658 +00659 } +00660 +00661 void __attribute__((interrupt)) can2HdlWup (void) +00662 { +00663 +00664 } +00665 +00666 void __attribute__((interrupt)) can2HdlErr (void) +00667 { +00668 +00669 } +00670 +00671 void __attribute__((interrupt)) can3HdlTra (void) +00672 { +00673 +00674 } +00675 +00676 void __attribute__((interrupt)) can3HdlRcv (void) +00677 { +00678 +00679 } +00680 +00681 void __attribute__((interrupt)) can3HdlWup (void) +00682 { +00683 +00684 } +00685 +00686 void __attribute__((interrupt)) can3HdlErr (void) +00687 { +00688 +00689 } +00690 +00691 void __attribute__((interrupt)) can4HdlTra (void) +00692 { +00693 +00694 } +00695 +00696 void __attribute__((interrupt)) can4HdlRcv (void) +00697 { +00698 +00699 } +00700 +00701 void __attribute__((interrupt)) can4HdlWup (void) +00702 { +00703 +00704 } +00705 +00706 void __attribute__((interrupt)) can4HdlErr (void) +00707 { +00708 +00709 } +00710 +00711 +00712 +