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