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.5  2007/09/08 03:00:17  hwmaier
00050  * Optional time-out for receiving added
00051  *
00052  * Revision 1.4  2007/09/06 19:02:48  olereinhardt
00053  * Corrected handling of 11bit standard IDs
00054  *
00055  * Revision 1.3  2006/10/08 16:48:08  haraldkipp
00056  * Documentation fixed
00057  *
00058  * Revision 1.2  2005/10/24 18:02:34  haraldkipp
00059  * Fixes for ATmega103.
00060  *
00061  * Revision 1.1  2005/07/26 18:02:40  haraldkipp
00062  * Moved from dev.
00063  *
00064  * Revision 1.8  2005/05/27 14:09:56  olereinhardt
00065  * Fixed a bug in irq initialisation
00066  *
00067  * Revision 1.7  2005/01/24 21:12:04  freckle
00068  * renamed NutEventPostFromIRQ into NutEventPostFromIrq
00069  *
00070  * Revision 1.6  2005/01/21 16:49:45  freckle
00071  * Seperated calls to NutEventPostAsync between Threads and IRQs
00072  *
00073  * Revision 1.5  2004/11/12 16:27:42  olereinhardt
00074  * Added critical section around NutEventPostAsync
00075  *
00076  * Revision 1.4  2004/09/17 14:31:37  olereinhardt
00077  * Compile only if __GNUC__ defined
00078  *
00079  * Revision 1.3  2004/06/08 14:50:25  olereinhardt
00080  * Removed receive thread and moved input data handling into irq handler. Much faster now on reception.
00081  *
00082  * Revision 1.1  2004/06/07 15:11:49  olereinhardt
00083  * Initial checkin
00084  *
00085  */
00086 
00091 
00092 /* Not ported. */
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;          // the physical memory address where the buffer is stored
00129     u_short size;               // the allocated size of the buffer
00130     u_short datalength;         // the length of the data currently in the buffer
00131     u_short dataindex;          // the index into the buffer where the data starts
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     // set start pointer of the buffer
00150     buffer->dataptr = NutHeapAlloc(size * sizeof(CANFRAME));
00151     buffer->size = size;
00152     // initialize index and length
00153     buffer->dataindex = 0;
00154     buffer->datalength = 0;
00155 }
00156 
00157 // access routines
00158 
00159 CANFRAME CANBufferGetMutex(CANBuffer * buffer)
00160 {
00161     CANFRAME data;
00162 
00163     NutSemWait(&buffer->full);
00164 //    NutSemWait(&buffer->mutex);
00165     // check to see if there's data in the buffer
00166     if (buffer->datalength) {
00167         // get the first frame from buffer
00168         data = buffer->dataptr[buffer->dataindex];
00169         // move index down and decrement length
00170         buffer->dataindex++;
00171         if (buffer->dataindex >= buffer->size) {
00172             buffer->dataindex %= buffer->size;
00173         }
00174         buffer->datalength--;
00175     }
00176 //    NutSemPost(&buffer->mutex);
00177     NutSemPost(&buffer->empty);
00178     // return
00179     return data;
00180 }
00181 
00182 void CANBufferPutMutex(CANBuffer * buffer, CANFRAME * data)
00183 {
00184     NutSemWait(&buffer->empty);
00185 //    NutSemWait(&buffer->mutex);
00186 
00187     // make sure the buffer has room
00188     if (buffer->datalength < buffer->size) {
00189         // save frame at end of buffer
00190         buffer->dataptr[(buffer->dataindex + buffer->datalength) % buffer->size] = *data;
00191         // increment the length
00192         buffer->datalength++;
00193         // return success
00194     }
00195 
00196 //    NutSemPost(&buffer->mutex);
00197     NutSemPost(&buffer->full);
00198 }
00199 
00200 CANFRAME CANBufferGet(CANBuffer * buffer)
00201 {
00202     CANFRAME data;
00203 
00204     // check to see if there's data in the buffer
00205     if (buffer->datalength) {
00206         // get the first frame from buffer
00207         data = buffer->dataptr[buffer->dataindex];
00208         // move index down and decrement length
00209         buffer->dataindex++;
00210         if (buffer->dataindex >= buffer->size) {
00211             buffer->dataindex %= buffer->size;
00212         }
00213         buffer->datalength--;
00214     }
00215     // return
00216     return data;
00217 }
00218 
00219 void CANBufferPut(CANBuffer * buffer, CANFRAME * data)
00220 {
00221     // make sure the buffer has room
00222     if (buffer->datalength < buffer->size) {
00223         // save frame at end of buffer
00224         buffer->dataptr[(buffer->dataindex + buffer->datalength) % buffer->size] = *data;
00225         // increment the length
00226         buffer->datalength++;
00227         // return success
00228     }
00229 }
00230 
00231 u_short CANBufferFree(CANBuffer * buffer)
00232 {
00233     // check to see if the buffer has room
00234     // return true if there is room
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);       // enables IRQ since buffer has space
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)      // enter reset state
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     //*** Note - if you change SJA1000_MODECTRL, change it in
00350     // functions CAN_Init and CAN_SetAccMask also.
00351 
00352     do {
00353         SJA1000_MODECTRL = 0x00;
00354     }
00355     while ((SJA1000_MODECTRL & RM_RR_Bit) != 0x00);     // leave reset state
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)      // enter reset state
00373         SJA1000_MODECTRL = (RM_RR_Bit | SJA1000_MODECTRL);
00374 
00375     SJA1000_AM0 = am[0];
00376     SJA1000_AM1 = am[1];        // mask off lower nibble (SJA manual p44)
00377     SJA1000_AM2 = am[2];
00378     SJA1000_AM3 = am[3];
00379     SJA1000_MODECTRL = (AFM_Bit);
00380     //*** Note - if you change SJA1000_MODECTRL, change it in
00381     // functions CAN_Init and CAN_SetAccCode also.
00382 
00383     do {
00384         SJA1000_MODECTRL = 0x00;
00385     }
00386     while ((SJA1000_MODECTRL & RM_RR_Bit) != 0x00);     // leave reset state
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)      // enter reset state
00407         SJA1000_MODECTRL = (RM_RR_Bit | SJA1000_MODECTRL);
00408 
00409     switch (baudrate)           // setting actual bustiming
00410     {                           // all @ 16 Mhz
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);     // leave reset state
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);        // load High Byte
00478         SJA1000_Tx2 = (uint8_t) (temp_id >> 16);        // load High Byte
00479         SJA1000_Tx3 = (uint8_t) (temp_id >> 8);     // load High Byte
00480         SJA1000_Tx4 = (uint8_t) (temp_id & 0x00F8);     // Low Byte and ignore bit 0-2
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);        // load High Byte
00496         SJA1000_Tx2 = (uint8_t) (temp_id >> 16) & 0xE0; // Low Byte and ignore bit 0-4
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;     // Start Transmission
00508 }
00509 
00518 void SJARxFrame(CANFRAME * CAN_frame)
00519 {
00520     u_char FrameInfo = SJA1000_RxFrameInfo;
00521     CAN_frame->len = FrameInfo & 0x0F;  // frame info mask off higher 4 bits
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;      // just fill the whole struct, less CPU cycles
00540     } else {
00541         CAN_frame->id = (((uint32_t) SJA1000_Rx1 << 24) | 
00542                           (uint32_t) SJA1000_Rx2 << 16) >> 21;   // id_h and id_l
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;      // just fill the whole struct, less CPU cycles
00552     }
00553     SJA1000_CMD = RRB_Bit;      // release the receive buffer
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)   // if transmit buffer released
00580         {
00581             out_frame = CANBufferGetMutex(&CAN_TX_BUF);
00582             SJATxFrame(&out_frame);     // using SJA1000 TX buffer
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))     // transmit IRQ fired
00607     {
00608         NutEventPostFromIrq(&ci->can_tx_rdy);
00609     }
00610 
00611     if ((irq & RI_Bit) == RI_Bit)       // Receive IRQ fired
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);      // Disable RX IRQ until data has been poped from input buffer
00619             NutEventPostFromIrq(&ci->can_rx_rdy);
00620             ci->can_rx_frames++;
00621         }
00622     }
00623 
00624     if ((irq & EI_Bit) == EI_Bit)               //Error IRQ fired
00625     {
00626         ci->can_errors++;
00627         // TODO: Handle error
00628     } else if ((irq & DOI_Bit) == DOI_Bit)      //Error IRQ fired
00629     {
00630         ci->can_overruns++;
00631         SJA1000_CMD = CDO_Bit;                  // Clear DO status;
00632         // TODO: Handle overrun
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)      // entering reset mode
00664         SJA1000_MODECTRL = (RM_RR_Bit | SJA1000_MODECTRL);
00665 
00666     SJA1000_CLK_DIV = (CANMode_Bit | CBP_Bit | DivBy2 | ClkOff_Bit);    // sets clock divide register
00667 
00668     SJA1000_IEN = (ClrIntEnSJA);        // Disables CAN IRQ
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)  // setting actual bustiming
00681     {                           // all @ 16 Mhz
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);     // Set up Output Control Register
00723 
00724     SJA1000_IEN = (RIE_Bit | TIE_Bit | EIE_Bit | DOIE_Bit );       // Enables receive IRQ
00725 
00726     SJA1000_MODECTRL = (AFM_Bit);       // set single filter mode + sleep
00727     // *** Note - if you change SJA1000_MODECTRL, change it in
00728     // functions SJASetAccMask and SJASetAccCode also.
00729     
00730     do {
00731         SJA1000_MODECTRL = 0x00;
00732     }
00733     while ((SJA1000_MODECTRL & RM_RR_Bit) != 0x00);     // leaves reset mode
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)     // Set corresponding interrupt to low
00744     {                           // level interrupt
00745 #ifdef __AVR_ENHANCED__
00746         cbi(EICRA, (SJA_SIGNAL_BIT << 1));
00747         cbi(EICRA, (SJA_SIGNAL_BIT << 1) + 1);
00748 #endif /* __AVR_ENHANCED__ */
00749     } else {
00750         cbi(EICR, ((SJA_SIGNAL_BIT - 4) << 1));
00751         cbi(EICR, ((SJA_SIGNAL_BIT - 4) << 1) + 1);
00752     }
00753     temp = SJA1000_INT;         // Read interrupt register to clear pendin bits    
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 

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