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