00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00094
00095
00096 #ifdef __GNUC__
00097
00098 #include <string.h>
00099 #include <sys/heap.h>
00100 #include <sys/thread.h>
00101 #include <sys/event.h>
00102 #include <sys/atom.h>
00103 #include <sys/timer.h>
00104 #include <sys/semaphore.h>
00105 #include <sys/nutconfig.h>
00106
00107 #include <dev/irqreg.h>
00108 #include <dev/can_dev.h>
00109 #include <dev/sja1000.h>
00110 #include <cfg/arch/avr.h>
00111
00112
00113 #ifndef SJA_SIGNAL
00114 #define SJA_SIGNAL sig_INTERRUPT7
00115 #endif
00116
00117 #ifndef SJA_EICR
00118 #define SJA_EICR EICRB
00119 #endif
00120
00121 #ifndef SJA_SIGNAL_BIT
00122 #define SJA_SIGNAL_BIT 7
00123 #endif
00124
00125 #ifndef SJA_BASE
00126 #define SJA_BASE 0x8800
00127 #endif
00128
00129 CANINFO dcb_sja1000;
00130
00131 volatile u_short sja_base = 0x0000;
00132
00133
00134 struct _CANBuffer {
00135 CANFRAME *dataptr;
00136 u_short size;
00137 u_short datalength;
00138 u_short dataindex;
00139 SEM empty;
00140 SEM full;
00141 };
00142
00143 typedef struct _CANBuffer CANBuffer;
00144
00145 #ifndef CAN_BufSize
00146 #define CAN_BufSize 64
00147 #endif
00148
00149 CANBuffer CAN_RX_BUF;
00150 CANBuffer CAN_TX_BUF;
00151
00152 void CANBufferInit(CANBuffer * buffer,u_short size)
00153 {
00154 NutSemInit(&buffer->full, 0);
00155 NutSemInit(&buffer->empty, CAN_BufSize - 1);
00156
00157 buffer->dataptr = NutHeapAlloc(size * sizeof(CANFRAME));
00158 buffer->size = size;
00159
00160 buffer->dataindex = 0;
00161 buffer->datalength = 0;
00162 }
00163
00164
00165
00166 CANFRAME CANBufferGetMutex(CANBuffer * buffer)
00167 {
00168 CANFRAME data;
00169
00170 NutSemWait(&buffer->full);
00171
00172
00173 if (buffer->datalength) {
00174
00175 data = buffer->dataptr[buffer->dataindex];
00176
00177 buffer->dataindex++;
00178 if (buffer->dataindex >= buffer->size) {
00179 buffer->dataindex %= buffer->size;
00180 }
00181 buffer->datalength--;
00182 }
00183
00184 NutSemPost(&buffer->empty);
00185
00186 return data;
00187 }
00188
00189 void CANBufferPutMutex(CANBuffer * buffer, CANFRAME * data)
00190 {
00191 NutSemWait(&buffer->empty);
00192
00193
00194
00195 if (buffer->datalength < buffer->size) {
00196
00197 buffer->dataptr[(buffer->dataindex + buffer->datalength) % buffer->size] = *data;
00198
00199 buffer->datalength++;
00200
00201 }
00202
00203
00204 NutSemPost(&buffer->full);
00205 }
00206
00207 CANFRAME CANBufferGet(CANBuffer * buffer)
00208 {
00209 CANFRAME data;
00210
00211
00212 if (buffer->datalength) {
00213
00214 data = buffer->dataptr[buffer->dataindex];
00215
00216 buffer->dataindex++;
00217 if (buffer->dataindex >= buffer->size) {
00218 buffer->dataindex %= buffer->size;
00219 }
00220 buffer->datalength--;
00221 }
00222
00223 return data;
00224 }
00225
00226 void CANBufferPut(CANBuffer * buffer, CANFRAME * data)
00227 {
00228
00229 if (buffer->datalength < buffer->size) {
00230
00231 buffer->dataptr[(buffer->dataindex + buffer->datalength) % buffer->size] = *data;
00232
00233 buffer->datalength++;
00234
00235 }
00236 }
00237
00238 u_short CANBufferFree(CANBuffer * buffer)
00239 {
00240
00241
00242 return (buffer->size - buffer->datalength);
00243 }
00244
00252 inline u_char SJARxAvail(NUTDEVICE * dev)
00253 {
00254 return CAN_RX_BUF.datalength;
00255 }
00256
00264 inline u_char SJATxFree(NUTDEVICE * dev)
00265 {
00266 return CANBufferFree(&CAN_TX_BUF);
00267 }
00268
00281 void SJAOutput(NUTDEVICE * dev, CANFRAME * frame)
00282 {
00283 CANINFO *ci;
00284
00285 ci = (CANINFO *) dev->dev_dcb;
00286
00287 CANBufferPutMutex(&CAN_TX_BUF, frame);
00288 NutEventPostAsync(&ci->can_tx_rdy);
00289 }
00290
00305 u_char SJAInput(NUTDEVICE * dev, CANFRAME * frame)
00306 {
00307 u_char ready = 0;
00308 CANINFO *ci;
00309
00310 ci = (CANINFO *) dev->dev_dcb;
00311 while (!ready)
00312 {
00313 if (CAN_RX_BUF.datalength==0)
00314 {
00315 u_long timeout = ((IFCAN *) (dev->dev_icb))->can_rtimeout;
00316
00317 if (NutEventWait(&ci->can_rx_rdy, timeout))
00318 return 1;
00319 }
00320 NutEnterCritical();
00321 if (CAN_RX_BUF.datalength)
00322 {
00323 *frame = CANBufferGet(&CAN_RX_BUF);
00324 ready = 1;
00325 }
00326 NutExitCritical();
00327 }
00328 SJA1000_IEN |= (RIE_Bit);
00329 return 0;
00330 }
00331
00344 void SJASetAccCode(NUTDEVICE * dev, u_char * ac)
00345 {
00346 memcpy(((IFCAN *) (dev->dev_icb))->can_acc_code, ac, 4);
00347
00348 while ((SJA1000_MODECTRL & RM_RR_Bit) == 0x00)
00349 SJA1000_MODECTRL = (RM_RR_Bit | SJA1000_MODECTRL);
00350
00351 SJA1000_AC0 = ac[0];
00352 SJA1000_AC1 = ac[1];
00353 SJA1000_AC2 = ac[2];
00354 SJA1000_AC3 = ac[3];
00355 SJA1000_MODECTRL = (AFM_Bit);
00356
00357
00358
00359 do {
00360 SJA1000_MODECTRL = 0x00;
00361 }
00362 while ((SJA1000_MODECTRL & RM_RR_Bit) != 0x00);
00363 }
00364
00375 void SJASetAccMask(NUTDEVICE * dev, u_char * am)
00376 {
00377 memcpy(((IFCAN *) (dev->dev_icb))->can_acc_mask, am, 4);
00378
00379 while ((SJA1000_MODECTRL & RM_RR_Bit) == 0x00)
00380 SJA1000_MODECTRL = (RM_RR_Bit | SJA1000_MODECTRL);
00381
00382 SJA1000_AM0 = am[0];
00383 SJA1000_AM1 = am[1];
00384 SJA1000_AM2 = am[2];
00385 SJA1000_AM3 = am[3];
00386 SJA1000_MODECTRL = (AFM_Bit);
00387
00388
00389
00390 do {
00391 SJA1000_MODECTRL = 0x00;
00392 }
00393 while ((SJA1000_MODECTRL & RM_RR_Bit) != 0x00);
00394 }
00395
00407 u_char SJASetBaudrate(NUTDEVICE * dev, u_long baudrate)
00408 {
00409 u_char result = 0;
00410
00411 ((IFCAN *) (dev->dev_icb))->can_baudrate = baudrate;
00412
00413 while ((SJA1000_MODECTRL & RM_RR_Bit) == 0x00)
00414 SJA1000_MODECTRL = (RM_RR_Bit | SJA1000_MODECTRL);
00415
00416 switch (baudrate)
00417 {
00418 case CAN_SPEED_10K:
00419 SJA1000_BT0 = 113;
00420 SJA1000_BT1 = 28;
00421 break;
00422 case CAN_SPEED_20K:
00423 SJA1000_BT0 = 88;
00424 SJA1000_BT1 = 28;
00425 break;
00426 case CAN_SPEED_50K:
00427 SJA1000_BT0 = 73;
00428 SJA1000_BT1 = 28;
00429 break;
00430 case CAN_SPEED_100K:
00431 SJA1000_BT0 = 68;
00432 SJA1000_BT1 = 28;
00433 break;
00434 case CAN_SPEED_125K:
00435 SJA1000_BT0 = 67;
00436 SJA1000_BT1 = 28;
00437 break;
00438 case CAN_SPEED_250K:
00439 SJA1000_BT0 = 65;
00440 SJA1000_BT1 = 28;
00441 break;
00442 case CAN_SPEED_500K:
00443 SJA1000_BT0 = 64;
00444 SJA1000_BT1 = 28;
00445 break;
00446 case CAN_SPEED_800K:
00447 SJA1000_BT0 = 64;
00448 SJA1000_BT1 = 22;
00449 break;
00450 case CAN_SPEED_1M:
00451 SJA1000_BT0 = 64;
00452 SJA1000_BT1 = 20;
00453 break;
00454 default:
00455 result = 1;
00456 }
00457
00458 do {
00459 SJA1000_MODECTRL = 0x00;
00460 }
00461 while ((SJA1000_MODECTRL & RM_RR_Bit) != 0x00);
00462
00463 return result;
00464 }
00465
00475 void SJATxFrame(CANFRAME * CAN_frame)
00476 {
00477 u_long temp_id;
00478
00479
00480 if (CAN_frame->ext) {
00481 temp_id = CAN_frame->id << 3;
00482 SJA1000_TxFrameInfo = CAN_frame->len | CAN_29 | (CAN_frame->rtr ? CAN_RTR : 0);
00483
00484 SJA1000_Tx1 = (uint8_t) (temp_id >> 24);
00485 SJA1000_Tx2 = (uint8_t) (temp_id >> 16);
00486 SJA1000_Tx3 = (uint8_t) (temp_id >> 8);
00487 SJA1000_Tx4 = (uint8_t) (temp_id & 0x00F8);
00488
00489 SJA1000_Tx5 = CAN_frame->byte[0];
00490 SJA1000_Tx6 = CAN_frame->byte[1];
00491 SJA1000_Tx7 = CAN_frame->byte[2];
00492 SJA1000_Tx8 = CAN_frame->byte[3];
00493 SJA1000_Tx9 = CAN_frame->byte[4];
00494 SJA1000_Tx10 = CAN_frame->byte[5];
00495 SJA1000_Tx11 = CAN_frame->byte[6];
00496 SJA1000_Tx12 = CAN_frame->byte[7];
00497
00498 } else {
00499 temp_id = CAN_frame->id << 21;
00500 SJA1000_TxFrameInfo = CAN_frame->len | (CAN_frame->rtr ? CAN_RTR : 0);
00501
00502 SJA1000_Tx1 = (uint8_t) (temp_id >> 24);
00503 SJA1000_Tx2 = (uint8_t) (temp_id >> 16) & 0xE0;
00504
00505 SJA1000_Tx3 = CAN_frame->byte[0];
00506 SJA1000_Tx4 = CAN_frame->byte[1];
00507 SJA1000_Tx5 = CAN_frame->byte[2];
00508 SJA1000_Tx6 = CAN_frame->byte[3];
00509 SJA1000_Tx7 = CAN_frame->byte[4];
00510 SJA1000_Tx8 = CAN_frame->byte[5];
00511 SJA1000_Tx9 = CAN_frame->byte[6];
00512 SJA1000_Tx10 = CAN_frame->byte[7];
00513 }
00514 SJA1000_CMD = TR_Bit;
00515 }
00516
00525 void SJARxFrame(CANFRAME * CAN_frame)
00526 {
00527 u_char FrameInfo = SJA1000_RxFrameInfo;
00528 CAN_frame->len = FrameInfo & 0x0F;
00529 CAN_frame->ext = FrameInfo & CAN_29 ? 1 : 0;
00530 CAN_frame->rtr = FrameInfo & CAN_RTR ? 1 : 0;
00531
00532 if (CAN_frame->ext) {
00533 CAN_frame->id = (((uint32_t) SJA1000_Rx1 << 24) |
00534 ((uint32_t) SJA1000_Rx2 << 16) |
00535 ((uint32_t) SJA1000_Rx3 << 8) |
00536 ((uint32_t) SJA1000_Rx4 & 0xF8)) >> 3;
00537
00538
00539 CAN_frame->byte[0] = SJA1000_Rx5;
00540 CAN_frame->byte[1] = SJA1000_Rx6;
00541 CAN_frame->byte[2] = SJA1000_Rx7;
00542 CAN_frame->byte[3] = SJA1000_Rx8;
00543 CAN_frame->byte[4] = SJA1000_Rx9;
00544 CAN_frame->byte[5] = SJA1000_Rx10;
00545 CAN_frame->byte[6] = SJA1000_Rx11;
00546 CAN_frame->byte[7] = SJA1000_Rx12;
00547 } else {
00548 CAN_frame->id = (((uint32_t) SJA1000_Rx1 << 24) |
00549 (uint32_t) SJA1000_Rx2 << 16) >> 21;
00550
00551 CAN_frame->byte[0] = SJA1000_Rx3;
00552 CAN_frame->byte[1] = SJA1000_Rx4;
00553 CAN_frame->byte[2] = SJA1000_Rx5;
00554 CAN_frame->byte[3] = SJA1000_Rx6;
00555 CAN_frame->byte[4] = SJA1000_Rx7;
00556 CAN_frame->byte[5] = SJA1000_Rx8;
00557 CAN_frame->byte[6] = SJA1000_Rx9;
00558 CAN_frame->byte[7] = SJA1000_Rx10;
00559 }
00560 SJA1000_CMD = RRB_Bit;
00561 }
00562
00563
00564
00573 THREAD(CAN_Tx, arg)
00574 {
00575 NUTDEVICE *dev;
00576 CANINFO *ci;
00577 CANFRAME out_frame;
00578
00579 dev = arg;
00580 ci = (CANINFO *) dev->dev_dcb;
00581
00582 NutThreadSetPriority(16);
00583
00584 while (1) {
00585 NutEventWait(&ci->can_tx_rdy, NUT_WAIT_INFINITE);
00586 while ((SJA1000_STATUS & TBS_Bit) == TBS_Bit)
00587 {
00588 out_frame = CANBufferGetMutex(&CAN_TX_BUF);
00589 SJATxFrame(&out_frame);
00590 ci->can_tx_frames++;
00591 }
00592 }
00593 }
00594
00603 static void SJAInterrupt(void *arg)
00604 {
00605 CANINFO *ci;
00606 volatile u_char irq = SJA1000_INT;
00607 CANFRAME in_frame;
00608
00609 ci = (CANINFO *) (((NUTDEVICE *) arg)->dev_dcb);
00610
00611 ci->can_interrupts++;
00612
00613 if (((irq & TI_Bit) == TI_Bit))
00614 {
00615 NutEventPostFromIrq(&ci->can_tx_rdy);
00616 }
00617
00618 if ((irq & RI_Bit) == RI_Bit)
00619 {
00620 if (CAN_RX_BUF.size-CAN_RX_BUF.datalength > 0)
00621 {
00622 SJARxFrame(&in_frame);
00623 CANBufferPut(&CAN_RX_BUF, &in_frame);
00624 if (CAN_RX_BUF.size==CAN_RX_BUF.datalength)
00625 SJA1000_IEN &= (~RIE_Bit);
00626 NutEventPostFromIrq(&ci->can_rx_rdy);
00627 ci->can_rx_frames++;
00628 }
00629 }
00630
00631 if ((irq & EI_Bit) == EI_Bit)
00632 {
00633 ci->can_errors++;
00634
00635 } else if ((irq & DOI_Bit) == DOI_Bit)
00636 {
00637 ci->can_overruns++;
00638 SJA1000_CMD = CDO_Bit;
00639
00640 }
00641 }
00642
00654 int SJAInit(NUTDEVICE * dev)
00655 {
00656 IFCAN *ifc;
00657 CANINFO *ci;
00658 volatile u_char temp;
00659
00660 sja_base = dev->dev_base;
00661
00662 if (sja_base == 0x0000) sja_base = SJA_BASE;
00663
00664 ifc = dev->dev_icb;
00665
00666 memset(dev->dev_dcb, 0, sizeof(CANINFO));
00667 ci = (CANINFO *) dev->dev_dcb;
00668
00669 CANBufferInit(&CAN_RX_BUF, CAN_BufSize);
00670 CANBufferInit(&CAN_TX_BUF, CAN_BufSize);
00671
00672 while ((SJA1000_MODECTRL & RM_RR_Bit) == 0x00)
00673 SJA1000_MODECTRL = (RM_RR_Bit | SJA1000_MODECTRL);
00674
00675 SJA1000_CLK_DIV = (CANMode_Bit | CBP_Bit | DivBy2 | ClkOff_Bit);
00676
00677 SJA1000_IEN = (ClrIntEnSJA);
00678
00679 SJA1000_AC0 = ifc->can_acc_code[0];
00680 SJA1000_AC1 = ifc->can_acc_code[1];
00681 SJA1000_AC2 = ifc->can_acc_code[2];
00682 SJA1000_AC3 = ifc->can_acc_code[3];
00683
00684 SJA1000_AM0 = ifc->can_acc_mask[0];
00685 SJA1000_AM1 = ifc->can_acc_mask[1];
00686 SJA1000_AM2 = ifc->can_acc_mask[2];
00687 SJA1000_AM3 = ifc->can_acc_mask[3];
00688
00689 switch (ifc->can_baudrate)
00690 {
00691 case CAN_SPEED_10K:
00692 SJA1000_BT0 = 113;
00693 SJA1000_BT1 = 28;
00694 break;
00695 case CAN_SPEED_20K:
00696 SJA1000_BT0 = 88;
00697 SJA1000_BT1 = 28;
00698 break;
00699 case CAN_SPEED_50K:
00700 SJA1000_BT0 = 73;
00701 SJA1000_BT1 = 28;
00702 break;
00703 case CAN_SPEED_100K:
00704 SJA1000_BT0 = 68;
00705 SJA1000_BT1 = 28;
00706 break;
00707 case CAN_SPEED_125K:
00708 SJA1000_BT0 = 67;
00709 SJA1000_BT1 = 28;
00710 break;
00711 case CAN_SPEED_250K:
00712 SJA1000_BT0 = 65;
00713 SJA1000_BT1 = 28;
00714 break;
00715 case CAN_SPEED_500K:
00716 SJA1000_BT0 = 64;
00717 SJA1000_BT1 = 28;
00718 break;
00719 case CAN_SPEED_800K:
00720 SJA1000_BT0 = 64;
00721 SJA1000_BT1 = 22;
00722 break;
00723 case CAN_SPEED_1M:
00724 SJA1000_BT0 = 64;
00725 SJA1000_BT1 = 20;
00726 break;
00727 default:
00728 return errCAN_INVALID_BAUD;
00729 }
00730
00731 SJA1000_OUTCTRL = (Tx1Float | Tx0PshPull | NormalMode);
00732
00733 SJA1000_IEN = (RIE_Bit | TIE_Bit | EIE_Bit | DOIE_Bit );
00734
00735 SJA1000_MODECTRL = (AFM_Bit);
00736
00737
00738
00739 do {
00740 SJA1000_MODECTRL = 0x00;
00741 }
00742 while ((SJA1000_MODECTRL & RM_RR_Bit) != 0x00);
00743
00744 NutEnterCritical();
00745
00746 if (NutRegisterIrqHandler(&SJA_SIGNAL, SJAInterrupt, dev)) {
00747 NutExitCritical();
00748 return -1;
00749 }
00750
00751 cbi(EIMSK, SJA_SIGNAL_BIT);
00752 if (SJA_SIGNAL_BIT < 4)
00753 {
00754 #ifdef __AVR_ENHANCED__
00755 cbi(EICRA, (SJA_SIGNAL_BIT << 1));
00756 cbi(EICRA, (SJA_SIGNAL_BIT << 1) + 1);
00757 #endif
00758 } else {
00759 cbi(EICR, ((SJA_SIGNAL_BIT - 4) << 1));
00760 cbi(EICR, ((SJA_SIGNAL_BIT - 4) << 1) + 1);
00761 }
00762 temp = SJA1000_INT;
00763 sbi(EIMSK, SJA_SIGNAL_BIT);
00764 sbi(PORTE, SJA_SIGNAL_BIT);
00765 NutThreadCreate("sjacantx", CAN_Tx, dev, 256);
00766
00767 NutExitCritical();
00768
00769 return 0;
00770 }
00771
00772
00781 IFCAN ifc_sja1000 = {
00782 CAN_IF_2B,
00783 CAN_SPEED_500K,
00784 {0xFF, 0xFF, 0xFF, 0xFF}
00785 ,
00786 {0x00, 0x00, 0x00, 0x00}
00787 ,
00788 NUT_WAIT_INFINITE,
00789 SJARxAvail,
00790 SJATxFree,
00791 SJAInput,
00792 SJAOutput,
00793 SJASetAccCode,
00794 SJASetAccMask,
00795 SJASetBaudrate
00796 };
00797
00805 NUTDEVICE devSJA1000 = {
00806 0,
00807 {'s', 'j', 'a', '1', '0', '0', '0', 0, 0}
00808 ,
00809 IFTYP_CAN,
00810 0,
00811 0,
00812 &ifc_sja1000,
00813 &dcb_sja1000,
00814 SJAInit,
00815 0,
00816 0,
00817 0,
00818 0,
00819 0,
00820 0,
00821 0
00822 };
00823
00824 #else
00825 void keep_icc_happy(void)
00826 {
00827 }
00828
00829 #endif
00830