sja1000.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2004 by Ole Reinhardt <ole.reinhardt@kernelconcepts.de>,
00003  *                       Kernelconcepts http://www.kernelconcepts.de
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  *
00009  * 1. Redistributions of source code must retain the above copyright
00010  *    notice, this list of conditions and the following disclaimer.
00011  * 2. Redistributions in binary form must reproduce the above copyright
00012  *    notice, this list of conditions and the following disclaimer in the
00013  *    documentation and/or other materials provided with the distribution.
00014  * 3. Neither the name of the copyright holders nor the names of
00015  *    contributors may be used to endorse or promote products derived
00016  *    from this software without specific prior written permission.
00017  *
00018  * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH AND CONTRIBUTORS
00019  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00020  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00021  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL EGNITE
00022  * SOFTWARE GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00023  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00024  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
00025  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
00026  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00027  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
00028  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00029  * SUCH DAMAGE.
00030  *
00031  * For additional information see http://www.ethernut.de/
00032  *
00033  */
00034 
00047 /*
00048  * $Log: sja1000.c,v $
00049  * Revision 1.6  2007/10/04 19:32:52  olereinhardt
00050  * SJA_BASE (base address for sja1000 driver) can now be set in configurator
00051  *
00052  * Revision 1.5  2007/09/08 03:00:17  hwmaier
00053  * Optional time-out for receiving added
00054  *
00055  * Revision 1.4  2007/09/06 19:02:48  olereinhardt
00056  * Corrected handling of 11bit standard IDs
00057  *
00058  * Revision 1.3  2006/10/08 16:48:08  haraldkipp
00059  * Documentation fixed
00060  *
00061  * Revision 1.2  2005/10/24 18:02:34  haraldkipp
00062  * Fixes for ATmega103.
00063  *
00064  * Revision 1.1  2005/07/26 18:02:40  haraldkipp
00065  * Moved from dev.
00066  *
00067  * Revision 1.8  2005/05/27 14:09:56  olereinhardt
00068  * Fixed a bug in irq initialisation
00069  *
00070  * Revision 1.7  2005/01/24 21:12:04  freckle
00071  * renamed NutEventPostFromIRQ into NutEventPostFromIrq
00072  *
00073  * Revision 1.6  2005/01/21 16:49:45  freckle
00074  * Seperated calls to NutEventPostAsync between Threads and IRQs
00075  *
00076  * Revision 1.5  2004/11/12 16:27:42  olereinhardt
00077  * Added critical section around NutEventPostAsync
00078  *
00079  * Revision 1.4  2004/09/17 14:31:37  olereinhardt
00080  * Compile only if __GNUC__ defined
00081  *
00082  * Revision 1.3  2004/06/08 14:50:25  olereinhardt
00083  * Removed receive thread and moved input data handling into irq handler. Much faster now on reception.
00084  *
00085  * Revision 1.1  2004/06/07 15:11:49  olereinhardt
00086  * Initial checkin
00087  *
00088  */
00089 
00094 
00095 /* Not ported. */
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;          // the physical memory address where the buffer is stored
00136     u_short size;               // the allocated size of the buffer
00137     u_short datalength;         // the length of the data currently in the buffer
00138     u_short dataindex;          // the index into the buffer where the data starts
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     // set start pointer of the buffer
00157     buffer->dataptr = NutHeapAlloc(size * sizeof(CANFRAME));
00158     buffer->size = size;
00159     // initialize index and length
00160     buffer->dataindex = 0;
00161     buffer->datalength = 0;
00162 }
00163 
00164 // access routines
00165 
00166 CANFRAME CANBufferGetMutex(CANBuffer * buffer)
00167 {
00168     CANFRAME data;
00169 
00170     NutSemWait(&buffer->full);
00171 //    NutSemWait(&buffer->mutex);
00172     // check to see if there's data in the buffer
00173     if (buffer->datalength) {
00174         // get the first frame from buffer
00175         data = buffer->dataptr[buffer->dataindex];
00176         // move index down and decrement length
00177         buffer->dataindex++;
00178         if (buffer->dataindex >= buffer->size) {
00179             buffer->dataindex %= buffer->size;
00180         }
00181         buffer->datalength--;
00182     }
00183 //    NutSemPost(&buffer->mutex);
00184     NutSemPost(&buffer->empty);
00185     // return
00186     return data;
00187 }
00188 
00189 void CANBufferPutMutex(CANBuffer * buffer, CANFRAME * data)
00190 {
00191     NutSemWait(&buffer->empty);
00192 //    NutSemWait(&buffer->mutex);
00193 
00194     // make sure the buffer has room
00195     if (buffer->datalength < buffer->size) {
00196         // save frame at end of buffer
00197         buffer->dataptr[(buffer->dataindex + buffer->datalength) % buffer->size] = *data;
00198         // increment the length
00199         buffer->datalength++;
00200         // return success
00201     }
00202 
00203 //    NutSemPost(&buffer->mutex);
00204     NutSemPost(&buffer->full);
00205 }
00206 
00207 CANFRAME CANBufferGet(CANBuffer * buffer)
00208 {
00209     CANFRAME data;
00210 
00211     // check to see if there's data in the buffer
00212     if (buffer->datalength) {
00213         // get the first frame from buffer
00214         data = buffer->dataptr[buffer->dataindex];
00215         // move index down and decrement length
00216         buffer->dataindex++;
00217         if (buffer->dataindex >= buffer->size) {
00218             buffer->dataindex %= buffer->size;
00219         }
00220         buffer->datalength--;
00221     }
00222     // return
00223     return data;
00224 }
00225 
00226 void CANBufferPut(CANBuffer * buffer, CANFRAME * data)
00227 {
00228     // make sure the buffer has room
00229     if (buffer->datalength < buffer->size) {
00230         // save frame at end of buffer
00231         buffer->dataptr[(buffer->dataindex + buffer->datalength) % buffer->size] = *data;
00232         // increment the length
00233         buffer->datalength++;
00234         // return success
00235     }
00236 }
00237 
00238 u_short CANBufferFree(CANBuffer * buffer)
00239 {
00240     // check to see if the buffer has room
00241     // return true if there is room
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);       // enables IRQ since buffer has space
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)      // enter reset state
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     //*** Note - if you change SJA1000_MODECTRL, change it in
00357     // functions CAN_Init and CAN_SetAccMask also.
00358 
00359     do {
00360         SJA1000_MODECTRL = 0x00;
00361     }
00362     while ((SJA1000_MODECTRL & RM_RR_Bit) != 0x00);     // leave reset state
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)      // enter reset state
00380         SJA1000_MODECTRL = (RM_RR_Bit | SJA1000_MODECTRL);
00381 
00382     SJA1000_AM0 = am[0];
00383     SJA1000_AM1 = am[1];        // mask off lower nibble (SJA manual p44)
00384     SJA1000_AM2 = am[2];
00385     SJA1000_AM3 = am[3];
00386     SJA1000_MODECTRL = (AFM_Bit);
00387     //*** Note - if you change SJA1000_MODECTRL, change it in
00388     // functions CAN_Init and CAN_SetAccCode also.
00389 
00390     do {
00391         SJA1000_MODECTRL = 0x00;
00392     }
00393     while ((SJA1000_MODECTRL & RM_RR_Bit) != 0x00);     // leave reset state
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)      // enter reset state
00414         SJA1000_MODECTRL = (RM_RR_Bit | SJA1000_MODECTRL);
00415 
00416     switch (baudrate)           // setting actual bustiming
00417     {                           // all @ 16 Mhz
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);     // leave reset state
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);        // load High Byte
00485         SJA1000_Tx2 = (uint8_t) (temp_id >> 16);        // load High Byte
00486         SJA1000_Tx3 = (uint8_t) (temp_id >> 8);     // load High Byte
00487         SJA1000_Tx4 = (uint8_t) (temp_id & 0x00F8);     // Low Byte and ignore bit 0-2
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);        // load High Byte
00503         SJA1000_Tx2 = (uint8_t) (temp_id >> 16) & 0xE0; // Low Byte and ignore bit 0-4
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;     // Start Transmission
00515 }
00516 
00525 void SJARxFrame(CANFRAME * CAN_frame)
00526 {
00527     u_char FrameInfo = SJA1000_RxFrameInfo;
00528     CAN_frame->len = FrameInfo & 0x0F;  // frame info mask off higher 4 bits
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;      // just fill the whole struct, less CPU cycles
00547     } else {
00548         CAN_frame->id = (((uint32_t) SJA1000_Rx1 << 24) | 
00549                           (uint32_t) SJA1000_Rx2 << 16) >> 21;   // id_h and id_l
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;      // just fill the whole struct, less CPU cycles
00559     }
00560     SJA1000_CMD = RRB_Bit;      // release the receive buffer
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)   // if transmit buffer released
00587         {
00588             out_frame = CANBufferGetMutex(&CAN_TX_BUF);
00589             SJATxFrame(&out_frame);     // using SJA1000 TX buffer
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))     // transmit IRQ fired
00614     {
00615         NutEventPostFromIrq(&ci->can_tx_rdy);
00616     }
00617 
00618     if ((irq & RI_Bit) == RI_Bit)       // Receive IRQ fired
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);      // Disable RX IRQ until data has been poped from input buffer
00626             NutEventPostFromIrq(&ci->can_rx_rdy);
00627             ci->can_rx_frames++;
00628         }
00629     }
00630 
00631     if ((irq & EI_Bit) == EI_Bit)               //Error IRQ fired
00632     {
00633         ci->can_errors++;
00634         // TODO: Handle error
00635     } else if ((irq & DOI_Bit) == DOI_Bit)      //Error IRQ fired
00636     {
00637         ci->can_overruns++;
00638         SJA1000_CMD = CDO_Bit;                  // Clear DO status;
00639         // TODO: Handle overrun
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)      // entering reset mode
00673         SJA1000_MODECTRL = (RM_RR_Bit | SJA1000_MODECTRL);
00674 
00675     SJA1000_CLK_DIV = (CANMode_Bit | CBP_Bit | DivBy2 | ClkOff_Bit);    // sets clock divide register
00676 
00677     SJA1000_IEN = (ClrIntEnSJA);        // Disables CAN IRQ
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)  // setting actual bustiming
00690     {                           // all @ 16 Mhz
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);     // Set up Output Control Register
00732 
00733     SJA1000_IEN = (RIE_Bit | TIE_Bit | EIE_Bit | DOIE_Bit );       // Enables receive IRQ
00734 
00735     SJA1000_MODECTRL = (AFM_Bit);       // set single filter mode + sleep
00736     // *** Note - if you change SJA1000_MODECTRL, change it in
00737     // functions SJASetAccMask and SJASetAccCode also.
00738     
00739     do {
00740         SJA1000_MODECTRL = 0x00;
00741     }
00742     while ((SJA1000_MODECTRL & RM_RR_Bit) != 0x00);     // leaves reset mode
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)     // Set corresponding interrupt to low
00753     {                           // level interrupt
00754 #ifdef __AVR_ENHANCED__
00755         cbi(EICRA, (SJA_SIGNAL_BIT << 1));
00756         cbi(EICRA, (SJA_SIGNAL_BIT << 1) + 1);
00757 #endif /* __AVR_ENHANCED__ */
00758     } else {
00759         cbi(EICR, ((SJA_SIGNAL_BIT - 4) << 1));
00760         cbi(EICR, ((SJA_SIGNAL_BIT - 4) << 1) + 1);
00761     }
00762     temp = SJA1000_INT;         // Read interrupt register to clear pendin bits    
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 

© 2000-2007 by egnite Software GmbH - visit http://www.ethernut.de/