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
00091
00092
00093 #ifdef __GNUC__
00094
00095 #include <string.h>
00096 #include <sys/heap.h>
00097 #include <sys/thread.h>
00098 #include <sys/event.h>
00099 #include <sys/atom.h>
00100 #include <sys/timer.h>
00101 #include <sys/semaphore.h>
00102 #include <sys/nutconfig.h>
00103
00104 #include <dev/irqreg.h>
00105 #include <dev/can_dev.h>
00106 #include <dev/sja1000.h>
00107 #include <cfg/arch/avr.h>
00108
00109
00110 #ifndef SJA_SIGNAL
00111 #define SJA_SIGNAL sig_INTERRUPT7
00112 #endif
00113
00114 #ifndef SJA_EICR
00115 #define SJA_EICR EICRB
00116 #endif
00117
00118 #ifndef SJA_SIGNAL_BIT
00119 #define SJA_SIGNAL_BIT 7
00120 #endif
00121
00122 CANINFO dcb_sja1000;
00123
00124 volatile u_short sja_base = 0x0000;
00125
00126
00127 struct _CANBuffer {
00128 CANFRAME *dataptr;
00129 u_short size;
00130 u_short datalength;
00131 u_short dataindex;
00132 SEM empty;
00133 SEM full;
00134 };
00135
00136 typedef struct _CANBuffer CANBuffer;
00137
00138 #ifndef CAN_BufSize
00139 #define CAN_BufSize 64
00140 #endif
00141
00142 CANBuffer CAN_RX_BUF;
00143 CANBuffer CAN_TX_BUF;
00144
00145 void CANBufferInit(CANBuffer * buffer,u_short size)
00146 {
00147 NutSemInit(&buffer->full, 0);
00148 NutSemInit(&buffer->empty, CAN_BufSize - 1);
00149
00150 buffer->dataptr = NutHeapAlloc(size * sizeof(CANFRAME));
00151 buffer->size = size;
00152
00153 buffer->dataindex = 0;
00154 buffer->datalength = 0;
00155 }
00156
00157
00158
00159 CANFRAME CANBufferGetMutex(CANBuffer * buffer)
00160 {
00161 CANFRAME data;
00162
00163 NutSemWait(&buffer->full);
00164
00165
00166 if (buffer->datalength) {
00167
00168 data = buffer->dataptr[buffer->dataindex];
00169
00170 buffer->dataindex++;
00171 if (buffer->dataindex >= buffer->size) {
00172 buffer->dataindex %= buffer->size;
00173 }
00174 buffer->datalength--;
00175 }
00176
00177 NutSemPost(&buffer->empty);
00178
00179 return data;
00180 }
00181
00182 void CANBufferPutMutex(CANBuffer * buffer, CANFRAME * data)
00183 {
00184 NutSemWait(&buffer->empty);
00185
00186
00187
00188 if (buffer->datalength < buffer->size) {
00189
00190 buffer->dataptr[(buffer->dataindex + buffer->datalength) % buffer->size] = *data;
00191
00192 buffer->datalength++;
00193
00194 }
00195
00196
00197 NutSemPost(&buffer->full);
00198 }
00199
00200 CANFRAME CANBufferGet(CANBuffer * buffer)
00201 {
00202 CANFRAME data;
00203
00204
00205 if (buffer->datalength) {
00206
00207 data = buffer->dataptr[buffer->dataindex];
00208
00209 buffer->dataindex++;
00210 if (buffer->dataindex >= buffer->size) {
00211 buffer->dataindex %= buffer->size;
00212 }
00213 buffer->datalength--;
00214 }
00215
00216 return data;
00217 }
00218
00219 void CANBufferPut(CANBuffer * buffer, CANFRAME * data)
00220 {
00221
00222 if (buffer->datalength < buffer->size) {
00223
00224 buffer->dataptr[(buffer->dataindex + buffer->datalength) % buffer->size] = *data;
00225
00226 buffer->datalength++;
00227
00228 }
00229 }
00230
00231 u_short CANBufferFree(CANBuffer * buffer)
00232 {
00233
00234
00235 return (buffer->size - buffer->datalength);
00236 }
00237
00245 inline u_char SJARxAvail(NUTDEVICE * dev)
00246 {
00247 return CAN_RX_BUF.datalength;
00248 }
00249
00257 inline u_char SJATxFree(NUTDEVICE * dev)
00258 {
00259 return CANBufferFree(&CAN_TX_BUF);
00260 }
00261
00274 void SJAOutput(NUTDEVICE * dev, CANFRAME * frame)
00275 {
00276 CANINFO *ci;
00277
00278 ci = (CANINFO *) dev->dev_dcb;
00279
00280 CANBufferPutMutex(&CAN_TX_BUF, frame);
00281 NutEventPostAsync(&ci->can_tx_rdy);
00282 }
00283
00298 u_char SJAInput(NUTDEVICE * dev, CANFRAME * frame)
00299 {
00300 u_char ready = 0;
00301 CANINFO *ci;
00302
00303 ci = (CANINFO *) dev->dev_dcb;
00304 while (!ready)
00305 {
00306 if (CAN_RX_BUF.datalength==0)
00307 {
00308 u_long timeout = ((IFCAN *) (dev->dev_icb))->can_rtimeout;
00309
00310 if (NutEventWait(&ci->can_rx_rdy, timeout))
00311 return 1;
00312 }
00313 NutEnterCritical();
00314 if (CAN_RX_BUF.datalength)
00315 {
00316 *frame = CANBufferGet(&CAN_RX_BUF);
00317 ready = 1;
00318 }
00319 NutExitCritical();
00320 }
00321 SJA1000_IEN |= (RIE_Bit);
00322 return 0;
00323 }
00324
00337 void SJASetAccCode(NUTDEVICE * dev, u_char * ac)
00338 {
00339 memcpy(((IFCAN *) (dev->dev_icb))->can_acc_code, ac, 4);
00340
00341 while ((SJA1000_MODECTRL & RM_RR_Bit) == 0x00)
00342 SJA1000_MODECTRL = (RM_RR_Bit | SJA1000_MODECTRL);
00343
00344 SJA1000_AC0 = ac[0];
00345 SJA1000_AC1 = ac[1];
00346 SJA1000_AC2 = ac[2];
00347 SJA1000_AC3 = ac[3];
00348 SJA1000_MODECTRL = (AFM_Bit);
00349
00350
00351
00352 do {
00353 SJA1000_MODECTRL = 0x00;
00354 }
00355 while ((SJA1000_MODECTRL & RM_RR_Bit) != 0x00);
00356 }
00357
00368 void SJASetAccMask(NUTDEVICE * dev, u_char * am)
00369 {
00370 memcpy(((IFCAN *) (dev->dev_icb))->can_acc_mask, am, 4);
00371
00372 while ((SJA1000_MODECTRL & RM_RR_Bit) == 0x00)
00373 SJA1000_MODECTRL = (RM_RR_Bit | SJA1000_MODECTRL);
00374
00375 SJA1000_AM0 = am[0];
00376 SJA1000_AM1 = am[1];
00377 SJA1000_AM2 = am[2];
00378 SJA1000_AM3 = am[3];
00379 SJA1000_MODECTRL = (AFM_Bit);
00380
00381
00382
00383 do {
00384 SJA1000_MODECTRL = 0x00;
00385 }
00386 while ((SJA1000_MODECTRL & RM_RR_Bit) != 0x00);
00387 }
00388
00400 u_char SJASetBaudrate(NUTDEVICE * dev, u_long baudrate)
00401 {
00402 u_char result = 0;
00403
00404 ((IFCAN *) (dev->dev_icb))->can_baudrate = baudrate;
00405
00406 while ((SJA1000_MODECTRL & RM_RR_Bit) == 0x00)
00407 SJA1000_MODECTRL = (RM_RR_Bit | SJA1000_MODECTRL);
00408
00409 switch (baudrate)
00410 {
00411 case CAN_SPEED_10K:
00412 SJA1000_BT0 = 113;
00413 SJA1000_BT1 = 28;
00414 break;
00415 case CAN_SPEED_20K:
00416 SJA1000_BT0 = 88;
00417 SJA1000_BT1 = 28;
00418 break;
00419 case CAN_SPEED_50K:
00420 SJA1000_BT0 = 73;
00421 SJA1000_BT1 = 28;
00422 break;
00423 case CAN_SPEED_100K:
00424 SJA1000_BT0 = 68;
00425 SJA1000_BT1 = 28;
00426 break;
00427 case CAN_SPEED_125K:
00428 SJA1000_BT0 = 67;
00429 SJA1000_BT1 = 28;
00430 break;
00431 case CAN_SPEED_250K:
00432 SJA1000_BT0 = 65;
00433 SJA1000_BT1 = 28;
00434 break;
00435 case CAN_SPEED_500K:
00436 SJA1000_BT0 = 64;
00437 SJA1000_BT1 = 28;
00438 break;
00439 case CAN_SPEED_800K:
00440 SJA1000_BT0 = 64;
00441 SJA1000_BT1 = 22;
00442 break;
00443 case CAN_SPEED_1M:
00444 SJA1000_BT0 = 64;
00445 SJA1000_BT1 = 20;
00446 break;
00447 default:
00448 result = 1;
00449 }
00450
00451 do {
00452 SJA1000_MODECTRL = 0x00;
00453 }
00454 while ((SJA1000_MODECTRL & RM_RR_Bit) != 0x00);
00455
00456 return result;
00457 }
00458
00468 void SJATxFrame(CANFRAME * CAN_frame)
00469 {
00470 u_long temp_id;
00471
00472
00473 if (CAN_frame->ext) {
00474 temp_id = CAN_frame->id << 3;
00475 SJA1000_TxFrameInfo = CAN_frame->len | CAN_29 | (CAN_frame->rtr ? CAN_RTR : 0);
00476
00477 SJA1000_Tx1 = (uint8_t) (temp_id >> 24);
00478 SJA1000_Tx2 = (uint8_t) (temp_id >> 16);
00479 SJA1000_Tx3 = (uint8_t) (temp_id >> 8);
00480 SJA1000_Tx4 = (uint8_t) (temp_id & 0x00F8);
00481
00482 SJA1000_Tx5 = CAN_frame->byte[0];
00483 SJA1000_Tx6 = CAN_frame->byte[1];
00484 SJA1000_Tx7 = CAN_frame->byte[2];
00485 SJA1000_Tx8 = CAN_frame->byte[3];
00486 SJA1000_Tx9 = CAN_frame->byte[4];
00487 SJA1000_Tx10 = CAN_frame->byte[5];
00488 SJA1000_Tx11 = CAN_frame->byte[6];
00489 SJA1000_Tx12 = CAN_frame->byte[7];
00490
00491 } else {
00492 temp_id = CAN_frame->id << 21;
00493 SJA1000_TxFrameInfo = CAN_frame->len | (CAN_frame->rtr ? CAN_RTR : 0);
00494
00495 SJA1000_Tx1 = (uint8_t) (temp_id >> 24);
00496 SJA1000_Tx2 = (uint8_t) (temp_id >> 16) & 0xE0;
00497
00498 SJA1000_Tx3 = CAN_frame->byte[0];
00499 SJA1000_Tx4 = CAN_frame->byte[1];
00500 SJA1000_Tx5 = CAN_frame->byte[2];
00501 SJA1000_Tx6 = CAN_frame->byte[3];
00502 SJA1000_Tx7 = CAN_frame->byte[4];
00503 SJA1000_Tx8 = CAN_frame->byte[5];
00504 SJA1000_Tx9 = CAN_frame->byte[6];
00505 SJA1000_Tx10 = CAN_frame->byte[7];
00506 }
00507 SJA1000_CMD = TR_Bit;
00508 }
00509
00518 void SJARxFrame(CANFRAME * CAN_frame)
00519 {
00520 u_char FrameInfo = SJA1000_RxFrameInfo;
00521 CAN_frame->len = FrameInfo & 0x0F;
00522 CAN_frame->ext = FrameInfo & CAN_29 ? 1 : 0;
00523 CAN_frame->rtr = FrameInfo & CAN_RTR ? 1 : 0;
00524
00525 if (CAN_frame->ext) {
00526 CAN_frame->id = (((uint32_t) SJA1000_Rx1 << 24) |
00527 ((uint32_t) SJA1000_Rx2 << 16) |
00528 ((uint32_t) SJA1000_Rx3 << 8) |
00529 ((uint32_t) SJA1000_Rx4 & 0xF8)) >> 3;
00530
00531
00532 CAN_frame->byte[0] = SJA1000_Rx5;
00533 CAN_frame->byte[1] = SJA1000_Rx6;
00534 CAN_frame->byte[2] = SJA1000_Rx7;
00535 CAN_frame->byte[3] = SJA1000_Rx8;
00536 CAN_frame->byte[4] = SJA1000_Rx9;
00537 CAN_frame->byte[5] = SJA1000_Rx10;
00538 CAN_frame->byte[6] = SJA1000_Rx11;
00539 CAN_frame->byte[7] = SJA1000_Rx12;
00540 } else {
00541 CAN_frame->id = (((uint32_t) SJA1000_Rx1 << 24) |
00542 (uint32_t) SJA1000_Rx2 << 16) >> 21;
00543
00544 CAN_frame->byte[0] = SJA1000_Rx3;
00545 CAN_frame->byte[1] = SJA1000_Rx4;
00546 CAN_frame->byte[2] = SJA1000_Rx5;
00547 CAN_frame->byte[3] = SJA1000_Rx6;
00548 CAN_frame->byte[4] = SJA1000_Rx7;
00549 CAN_frame->byte[5] = SJA1000_Rx8;
00550 CAN_frame->byte[6] = SJA1000_Rx9;
00551 CAN_frame->byte[7] = SJA1000_Rx10;
00552 }
00553 SJA1000_CMD = RRB_Bit;
00554 }
00555
00556
00557
00566 THREAD(CAN_Tx, arg)
00567 {
00568 NUTDEVICE *dev;
00569 CANINFO *ci;
00570 CANFRAME out_frame;
00571
00572 dev = arg;
00573 ci = (CANINFO *) dev->dev_dcb;
00574
00575 NutThreadSetPriority(16);
00576
00577 while (1) {
00578 NutEventWait(&ci->can_tx_rdy, NUT_WAIT_INFINITE);
00579 while ((SJA1000_STATUS & TBS_Bit) == TBS_Bit)
00580 {
00581 out_frame = CANBufferGetMutex(&CAN_TX_BUF);
00582 SJATxFrame(&out_frame);
00583 ci->can_tx_frames++;
00584 }
00585 }
00586 }
00587
00596 static void SJAInterrupt(void *arg)
00597 {
00598 CANINFO *ci;
00599 volatile u_char irq = SJA1000_INT;
00600 CANFRAME in_frame;
00601
00602 ci = (CANINFO *) (((NUTDEVICE *) arg)->dev_dcb);
00603
00604 ci->can_interrupts++;
00605
00606 if (((irq & TI_Bit) == TI_Bit))
00607 {
00608 NutEventPostFromIrq(&ci->can_tx_rdy);
00609 }
00610
00611 if ((irq & RI_Bit) == RI_Bit)
00612 {
00613 if (CAN_RX_BUF.size-CAN_RX_BUF.datalength > 0)
00614 {
00615 SJARxFrame(&in_frame);
00616 CANBufferPut(&CAN_RX_BUF, &in_frame);
00617 if (CAN_RX_BUF.size==CAN_RX_BUF.datalength)
00618 SJA1000_IEN &= (~RIE_Bit);
00619 NutEventPostFromIrq(&ci->can_rx_rdy);
00620 ci->can_rx_frames++;
00621 }
00622 }
00623
00624 if ((irq & EI_Bit) == EI_Bit)
00625 {
00626 ci->can_errors++;
00627
00628 } else if ((irq & DOI_Bit) == DOI_Bit)
00629 {
00630 ci->can_overruns++;
00631 SJA1000_CMD = CDO_Bit;
00632
00633 }
00634 }
00635
00647 int SJAInit(NUTDEVICE * dev)
00648 {
00649 IFCAN *ifc;
00650 CANINFO *ci;
00651 volatile u_char temp;
00652
00653 sja_base = dev->dev_base;
00654
00655 ifc = dev->dev_icb;
00656
00657 memset(dev->dev_dcb, 0, sizeof(CANINFO));
00658 ci = (CANINFO *) dev->dev_dcb;
00659
00660 CANBufferInit(&CAN_RX_BUF, CAN_BufSize);
00661 CANBufferInit(&CAN_TX_BUF, CAN_BufSize);
00662
00663 while ((SJA1000_MODECTRL & RM_RR_Bit) == 0x00)
00664 SJA1000_MODECTRL = (RM_RR_Bit | SJA1000_MODECTRL);
00665
00666 SJA1000_CLK_DIV = (CANMode_Bit | CBP_Bit | DivBy2 | ClkOff_Bit);
00667
00668 SJA1000_IEN = (ClrIntEnSJA);
00669
00670 SJA1000_AC0 = ifc->can_acc_code[0];
00671 SJA1000_AC1 = ifc->can_acc_code[1];
00672 SJA1000_AC2 = ifc->can_acc_code[2];
00673 SJA1000_AC3 = ifc->can_acc_code[3];
00674
00675 SJA1000_AM0 = ifc->can_acc_mask[0];
00676 SJA1000_AM1 = ifc->can_acc_mask[1];
00677 SJA1000_AM2 = ifc->can_acc_mask[2];
00678 SJA1000_AM3 = ifc->can_acc_mask[3];
00679
00680 switch (ifc->can_baudrate)
00681 {
00682 case CAN_SPEED_10K:
00683 SJA1000_BT0 = 113;
00684 SJA1000_BT1 = 28;
00685 break;
00686 case CAN_SPEED_20K:
00687 SJA1000_BT0 = 88;
00688 SJA1000_BT1 = 28;
00689 break;
00690 case CAN_SPEED_50K:
00691 SJA1000_BT0 = 73;
00692 SJA1000_BT1 = 28;
00693 break;
00694 case CAN_SPEED_100K:
00695 SJA1000_BT0 = 68;
00696 SJA1000_BT1 = 28;
00697 break;
00698 case CAN_SPEED_125K:
00699 SJA1000_BT0 = 67;
00700 SJA1000_BT1 = 28;
00701 break;
00702 case CAN_SPEED_250K:
00703 SJA1000_BT0 = 65;
00704 SJA1000_BT1 = 28;
00705 break;
00706 case CAN_SPEED_500K:
00707 SJA1000_BT0 = 64;
00708 SJA1000_BT1 = 28;
00709 break;
00710 case CAN_SPEED_800K:
00711 SJA1000_BT0 = 64;
00712 SJA1000_BT1 = 22;
00713 break;
00714 case CAN_SPEED_1M:
00715 SJA1000_BT0 = 64;
00716 SJA1000_BT1 = 20;
00717 break;
00718 default:
00719 return errCAN_INVALID_BAUD;
00720 }
00721
00722 SJA1000_OUTCTRL = (Tx1Float | Tx0PshPull | NormalMode);
00723
00724 SJA1000_IEN = (RIE_Bit | TIE_Bit | EIE_Bit | DOIE_Bit );
00725
00726 SJA1000_MODECTRL = (AFM_Bit);
00727
00728
00729
00730 do {
00731 SJA1000_MODECTRL = 0x00;
00732 }
00733 while ((SJA1000_MODECTRL & RM_RR_Bit) != 0x00);
00734
00735 NutEnterCritical();
00736
00737 if (NutRegisterIrqHandler(&SJA_SIGNAL, SJAInterrupt, dev)) {
00738 NutExitCritical();
00739 return -1;
00740 }
00741
00742 cbi(EIMSK, SJA_SIGNAL_BIT);
00743 if (SJA_SIGNAL_BIT < 4)
00744 {
00745 #ifdef __AVR_ENHANCED__
00746 cbi(EICRA, (SJA_SIGNAL_BIT << 1));
00747 cbi(EICRA, (SJA_SIGNAL_BIT << 1) + 1);
00748 #endif
00749 } else {
00750 cbi(EICR, ((SJA_SIGNAL_BIT - 4) << 1));
00751 cbi(EICR, ((SJA_SIGNAL_BIT - 4) << 1) + 1);
00752 }
00753 temp = SJA1000_INT;
00754 sbi(EIMSK, SJA_SIGNAL_BIT);
00755 sbi(PORTE, SJA_SIGNAL_BIT);
00756 NutThreadCreate("sjacantx", CAN_Tx, dev, 256);
00757
00758 NutExitCritical();
00759
00760 return 0;
00761 }
00762
00763
00772 IFCAN ifc_sja1000 = {
00773 CAN_IF_2B,
00774 CAN_SPEED_500K,
00775 {0xFF, 0xFF, 0xFF, 0xFF}
00776 ,
00777 {0x00, 0x00, 0x00, 0x00}
00778 ,
00779 NUT_WAIT_INFINITE,
00780 SJARxAvail,
00781 SJATxFree,
00782 SJAInput,
00783 SJAOutput,
00784 SJASetAccCode,
00785 SJASetAccMask,
00786 SJASetBaudrate
00787 };
00788
00796 NUTDEVICE devSJA1000 = {
00797 0,
00798 {'s', 'j', 'a', '1', '0', '0', '0', 0, 0}
00799 ,
00800 IFTYP_CAN,
00801 0,
00802 0,
00803 &ifc_sja1000,
00804 &dcb_sja1000,
00805 SJAInit,
00806 0,
00807 0,
00808 0,
00809 0,
00810 0,
00811 0,
00812 0
00813 };
00814
00815 #else
00816 void keep_icc_happy(void)
00817 {
00818 }
00819
00820 #endif
00821