00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #define DEBUG_WAR_CONSOLE_ON
00024 #define DEBUG_ERR_CONSOLE_ON
00025
00026 #include <stddef.h>
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
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();
00082
00083
00084 IO_PORTS_8(TIOS) |= 0x10;
00085 IO_PORTS_8(TCTL1) &= ~(0x01 + 0x02);
00086 IO_PORTS_8(TIE) |= 0x10;
00087 IO_PORTS_8(TSCR2) |= 0X05;
00088
00089
00090
00091 IO_PORTS_8(TSCR1) |= 0x80;
00092 unlock();
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;
00101
00102
00103
00104
00105
00106 {
00107
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;
00120 IO_PORTS_8(SCI0 + SCICR2) = 0x08;
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;
00129 IO_PORTS_8(SCI1 + SCICR2) = 0x08;
00130 }
00131
00132
00133
00134 char *
00135 hex_convert (char *buf, unsigned long value, char lastCar)
00136 {
00137
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);
00170 IO_PORTS_8(sci + SCIDRL) = 13;
00171 }
00172 while ((IO_PORTS_8(sci + SCISR1) & 0X80) == 0);
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
00188 void initPLL(void)
00189 {
00190 IO_PORTS_8(CLKSEL) &= ~0x80;
00191 IO_PORTS_8(PLLCTL) |= 0X60;
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
00219 MSG_WAR(0X2600, "Not in init mode ", 0);
00220 return 1;
00221 }
00222 switch (nFilter) {
00223 case 0:
00224 nFilter = CANIDAR0;
00225 break;
00226 case 1:
00227 nFilter = CANIDAR2;
00228 break;
00229 case 2:
00230 nFilter = CANIDAR4;
00231 break;
00232 case 3:
00233 nFilter = CANIDAR6;
00234 }
00235 if (! IO_PORTS_16(adrCAN + nFilter)) {
00236
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
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;
00246 return 0;
00247 }
00248
00249
00250 char canChangeFilter(UNS16 adrCAN, canBusFilterInit fi)
00251 {
00252
00253 if (! canTestInitMode(adrCAN)) {
00254 canSleepMode(adrCAN);
00255 canInitMode(adrCAN);
00256 }
00257
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
00269
00270
00271
00272 IO_PORTS_8(adrCAN + CANCTL1) = 0X80;
00273 return 0;
00274 }
00275
00276
00277 char canInit(UNS16 adrCAN, canBusInit bi)
00278 {
00279
00280 if (! canTestInitMode(adrCAN)) {
00281 canSleepMode(adrCAN);
00282 canInitMode(adrCAN);
00283 }
00284
00285 canEnable(adrCAN);
00286
00287
00288
00289
00290 canInitClock(adrCAN, bi.clk);
00291
00292 IO_PORTS_8(adrCAN + CANCTL1) &=0xC4;
00293 IO_PORTS_8(adrCAN + CANCTL1) = (bi.cane << 7) | (bi.loopb << 5 ) |
00294 (bi.listen << 4) | (bi.wupm << 2);
00295
00296
00297 canInitFilter(adrCAN, bi.fi);
00298
00299 canInitModeQ(adrCAN);
00300
00301
00302
00303
00304 IO_PORTS_8(adrCAN + CANCTL0) &= 0x53;
00305 IO_PORTS_8(adrCAN + CANCTL0) = (bi.cswai << 5) | (bi.time << 3);
00306 canSetInterrupt(adrCAN);
00307 canInitModeQ(adrCAN);
00308 canSleepModeQ(adrCAN);
00309 return 0;
00310 }
00311
00312
00313 char canInitClock(UNS16 adrCAN, canBusTime clk)
00314 {
00315 if (! canTestInitMode(adrCAN)) {
00316
00317 MSG_WAR(0X2601, "not in init mode ", 0);
00318 return 1;
00319 }
00320
00321 clk.clksrc = clk.clksrc << 6;
00322 IO_PORTS_8(adrCAN + CANCTL1) &= 0xBF;
00323 IO_PORTS_8(adrCAN + CANCTL1) |= clk.clksrc;
00324
00325 IO_PORTS_8(adrCAN + CANBTR0) = 0x00;
00326 IO_PORTS_8(adrCAN + CANBTR0) = (clk.sjw << 6) | (clk.brp);
00327
00328 IO_PORTS_8(adrCAN + CANBTR1) = 0x00;
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
00339 MSG_WAR(0X2602, "not in init mode ", 0);
00340 return 1;
00341 }
00342 switch (nFilter) {
00343 case 0:
00344 nFilter = CANIDAR0;
00345 break;
00346 case 1:
00347 nFilter = CANIDAR2;
00348 break;
00349 case 2:
00350 nFilter = CANIDAR4;
00351 break;
00352 case 3:
00353 nFilter = CANIDAR6;
00354 }
00355
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
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;
00395 while (! canTestInitMode(adrCAN)) {
00396 }
00397 return 0;
00398 }
00399
00400
00401 char canInitModeQ(UNS16 adrCAN)
00402 {
00403 IO_PORTS_8(adrCAN + CANCTL0) &= 0xFE;
00404 while (canTestInitMode(adrCAN)) {
00405 }
00406 return 0;
00407 }
00408
00409
00410 char canMsgTransmit(UNS16 adrCAN, Message msg)
00411 {
00412
00413 UNS8 cantflg;
00414 UNS8 i;
00415
00416 cantflg = IO_PORTS_8(adrCAN + CANTFLG);
00417 if ( cantflg == 0) {
00418 MSG_WAR(0X2604, "No buffer free. Msg to transmit is losted ", 0);
00419 return 1;
00420 }
00421 else{
00422
00423 IO_PORTS_8(adrCAN + CANTBSEL) = cantflg;
00424
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
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
00436 cantflg = IO_PORTS_8(adrCAN + CANTBSEL);
00437 IO_PORTS_8(adrCAN + CANTBSEL) = 0x00;
00438 IO_PORTS_8(adrCAN + CANTFLG) = cantflg;
00439
00440 }
00441 return 0;
00442 }
00443
00444
00445 char canSetInterrupt(UNS16 adrCAN)
00446 {
00447 IO_PORTS_8(adrCAN + CANRIER) = 0X01;
00448 IO_PORTS_8(adrCAN + CANTIER) = 0X00;
00449 return 0;
00450 }
00451
00452 char canSleepMode(UNS16 adrCAN)
00453 {
00454 IO_PORTS_8(adrCAN + CANCTL0) &= 0xFB;
00455 IO_PORTS_8(adrCAN + CANCTL0) |= 0x02;
00456
00457
00458
00459 while ( ! canTestSleepMode(adrCAN)) {
00460 }
00461
00462 return 0;
00463 }
00464
00465
00466 char canSleepModeQ(UNS16 adrCAN)
00467 {
00468 if (canTestInitMode(adrCAN)) {
00469
00470 MSG_WAR(0X2606, "not in init mode ", 0);
00471 return 1;
00472 }
00473 IO_PORTS_8(adrCAN + CANCTL0) &= 0xFD;
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;
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;
00496 }
00497
00498
00499 char canTestSleepMode(UNS16 adrCAN)
00500 {
00501 return IO_PORTS_8(adrCAN + CANCTL1) & 0x02;
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
00526 if (ptrMsgRcv[j].r == ptrMsgRcv[j].w)
00527 return 0x0;
00528
00529
00530 if (ptrMsgRcv[j].r == (MAX_STACK_MSG_RCV - 1))
00531 ptrMsgRcv[j].r = 0;
00532 else
00533 ptrMsgRcv[j].r ++;
00534
00535
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
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;
00558 UNS8 NewPtrW;
00559
00560
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
00568 MSG_WAR(0X1620, "Stack for received msg is full", 0);
00569
00570 }
00571 else
00572 ptrMsgRcv[0].w = NewPtrW;
00573
00574
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
00582
00583
00584 IO_PORTS_8(CAN0 + CANRFLG) |= 0x01;
00585
00586 IO_PORTS_8(CAN0 + CANCTL0) |= 0x80;
00587 IO_PORTS_8(PORTB) |= 0x40;
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
00612
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
00620 MSG_WAR(0X2620, "Stack for received msg is full", 0);
00621 }
00622 else
00623 ptrMsgRcv[1].w = NewPtrW;
00624
00625
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
00633
00634
00635 IO_PORTS_8(CAN1 + CANRFLG) |= 0x01;
00636
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