Main Page | Modules | Data Structures | Directories | File List | Data Fields | Globals

vector_canboard.c

Go to the documentation of this file.
00001 /*============================================================================*
00002  * FILE:                      vector_canboard.h
00003  *============================================================================*
00004  *
00005  *                      COPYRIGHT (C) 2006  BY
00006  *          CONDOR ENGINEERING, INC., SANTA BARBARA, CALIFORNIA
00007  *          ALL RIGHTS RESERVED.
00008  *
00009  *          THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND
00010  *          COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH
00011  *          THE INCLUSION OF THE ABOVE COPYRIGHT NOTICE.  THIS SOFTWARE OR ANY
00012  *          OTHER COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE
00013  *          AVAILABLE TO ANY OTHER PERSON.  NO TITLE TO AND OWNERSHIP OF THE
00014  *          SOFTWARE IS HEREBY TRANSFERRED.
00015  *
00016  *          THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT
00017  *          NOTICE AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY CONDOR
00018  *          ENGINEERING.
00019  *
00020  *============================================================================*
00021  *
00022  * FUNCTION:    API -> interfaces.c for the Vector CANBoard XL
00023  *
00024  * Author:      Christopher McKenzie
00025  * 
00026  * MAINTENANCE NOTES:
00027  * 
00028  *============================================================================*/
00029 #include<windows.h>
00030 #include<stdio.h>
00031 #include"..\interfaces.h"
00032 #include"..\..\vendor_api\vector_canboard\vxlapi.h"
00033 #include"..\..\includes\canapi.h"
00034 #include"..\..\includes\debug.h"
00035 
00036 #define TIMESCALE       1000000000
00037 
00038 extern FILE*tracefile;
00039 extern struct _if_channel       channel[CAN_MAXCHANNELS];
00040 extern struct _if_board         cancard[MAX_CARDS];
00041 extern int if_channel_count;
00042 extern int if_board_count;
00043 
00044 int statuslookup[][2]=
00045 {       { XL_CAN_MSG_FLAG_ERROR_FRAME,  S_TYPE_ERROR    },
00046         { XL_CAN_MSG_FLAG_OVERRUN,              S_TYPE_OVER             },
00047         { XL_CAN_MSG_FLAG_NERR,                 S_ERR_LINE              },
00048         { XL_CAN_MSG_FLAG_WAKEUP,               S_TYPE_WAKEUP   },
00049         { XL_CAN_MSG_FLAG_REMOTE_FRAME, S_TYPE_REMOTE   },
00050         { XL_SYNC_PULSE,                                S_TYPE_SYNC             },
00051         { XL_CAN_MSG_FLAG_TX_COMPLETED, S_COMPLETE              },
00052         { XL_CAN_MSG_FLAG_TX_REQUEST,   S_QUEUED                },
00053         { XL_SUCCESS,                                   S_SUCCESS               },
00054         { XL_PENDING,                                   S_PENDING               },
00055         { XL_ERR_QUEUE_IS_EMPTY,                S_ERR_QUEUE_IS_EMPTY    },
00056         { XL_ERR_QUEUE_IS_FULL,                 S_ERR_QUEUE_IS_FULL             },
00057         { XL_ERR_TX_NOT_POSSIBLE,               S_ERR_TX_NOT_POSSIBLE   },
00058         { XL_ERR_NO_LICENSE,                    S_ERR_UNKNOWN                   },
00059         { XL_ERR_WRONG_PARAMETER,               S_ERR_INVARGS                   },
00060         { XL_ERR_TWICE_REGISTER,                S_ERR_TWICE_REGISTER    },
00061         { XL_ERR_INVALID_CHAN_INDEX,    S_ERR_INVALID_CHAN_INDEX},
00062         { XL_ERR_INVALID_ACCESS,                S_ERR_INVALID_ACCESS    },
00063         { XL_ERR_PORT_IS_OFFLINE,               S_ERR_PORT_IS_OFFLINE   },
00064         { XL_ERR_CHAN_IS_ONLINE,                S_ERR_CHAN_IS_ONLINE    },
00065         { XL_ERR_NOT_IMPLEMENTED,               S_ERR_NOT_IMPLEMENTED   },
00066         { XL_ERR_INVALID_PORT,                  S_ERR_INVALID_PORT              },
00067         { XL_ERR_HW_NOT_READY,                  S_ERR_HW_NOT_READY              },
00068         { XL_ERR_CMD_TIMEOUT,                   S_ERR_CMD_TIMEOUT               },
00069         { XL_ERR_HW_NOT_PRESENT,                S_ERR_HW_NOT_PRESENT    },
00070         { XL_ERR_NOTIFY_ALREADY_ACTIVE, S_ERR_NOTIFY_ALREADY_ACTIVE},
00071         { XL_ERR_NO_RESOURCES,                  S_ERR_NO_RESOURCES              },
00072         { XL_ERR_WRONG_CHIP_TYPE,               S_ERR_UNKNOWN                   },
00073         { XL_ERR_WRONG_COMMAND,                 S_ERR_UNKNOWN                   },
00074         { XL_ERR_INVALID_HANDLE,                S_ERR_INV_HANDLE                },
00075         { XL_ERR_CANNOT_OPEN_DRIVER,    S_ERR_CANNOT_OPEN_DRIVER},
00076         { -1, -1 }
00077 };
00078 
00079 #define ACCESSMASK(n)   (1<<(channel[n].hwChannelIndex))
00080 #define CANRETVAL       channel[which].error.toreturn
00081 enum
00082 {       I_ERRS          =       0x00000001,
00083         I_STATE         =       0x00000002
00084 };
00085 
00086 int g_msgsrx=1;
00087 //
00088 // According to the doc
00089 //      Baudrate = f/(2*presc*(1+tseg1+tseg2))
00090 //      presc :         CAN-Prescaler                                   [1..64]
00091 //      sjw :           CAN-Synchronisation-Jump-Width  [1..4] 
00092 //      tseg 1:         CAN-Time-Segment-1                              [1..16] 
00093 //      tseg 2:         CAN-Time-Segment-2                              [1..8]
00094 //      sam :           CAN-Sample-Mode                                 1:3
00095 //      Sample f :      crystal frequency is 16 MHz
00096 //
00097 
00098 //
00099 // classic linear programming problem that I don't know how to do
00100 //
00101 int vector_baudrate_calc(int desiredbaud,XLchipParams*touse)
00102 {       int frequency=16000000;
00103         return IF_SUCCESS;
00104 }
00105 
00106 int vector_checkstatus(int tocheck,int handle)
00107 {       int ix;
00108         if(tocheck==XL_SUCCESS)
00109         {       return IF_SUCCESS;
00110         }
00111 
00112         channel[handle].error.last=S_ERR_UNKNOWN;
00113         for(ix=0;statuslookup[ix][0]!=-1;ix++)
00114         {       if(statuslookup[ix][0]==tocheck)
00115                 {       channel[handle].error.last=statuslookup[ix][1];
00116                         break;
00117                 }
00118         }
00119         return IF_FAILURE;
00120 }
00121 
00122 //needs to compile list
00123 int vector_canboardprobe()
00124 {       int ix,max;
00125         long status;
00126         struct _if_board*bd;
00127         XLdriverConfig  drvcfg; 
00128         
00129         status=xlGetDriverConfig(&drvcfg);
00130         if(status!=XL_SUCCESS)
00131                 return IF_FAILURE;
00132                 
00133         max=drvcfg.channelCount;
00134 
00135         bd=&cancard[if_board_count];
00136         bd->boardtype=CANBOARDXL;
00137         bd->channelcount=max;
00138         bd->index=if_board_count;
00139         
00140         for(ix=0;ix<max;ix++)
00141         {       bd->channel[ix]=                        &channel[ix+if_channel_count];
00142                 bd->channel[ix]->hwChannel=     drvcfg.channel[ix].hwChannel;
00143                 bd->channel[ix]->board=         bd;
00144                 bd->channel[ix]->serialNumber=drvcfg.channel[ix].serialNumber;
00145                 bd->channel[ix]->articleNumber=drvcfg.channel[ix].articleNumber;
00146                 bd->channel[ix]->bustype=drvcfg.channel[ix].connectedBusType;
00147                 bd->channel[ix]->hwTransType=drvcfg.channel[ix].transceiverType;
00148                 bd->channel[ix]->hwTransState=drvcfg.channel[ix].transceiverState;
00149 
00150                 bd->channel[ix]->buscapabilities=drvcfg.channel[ix].channelBusCapabilities;
00151                 bd->channel[ix]->capabilities=drvcfg.channel[ix].channelCapabilities;
00152                 bd->channel[ix]->bustype=drvcfg.channel[ix].connectedBusType;
00153 
00154                 bd->channel[ix]->hwChannelIndex=drvcfg.channel[ix].channelIndex;
00155                 
00156                 bd->channel[ix]->blocktimeout=10;
00157 
00158                 bd->channel[ix]->rxqueuesize=IF_DEFAULT_RXQUEUE;
00159                 bd->channel[ix]->baudrate=IF_DEFAULT_BAUD;
00160                 
00161                 sprintf(
00162                         bd->channel[ix]->name,
00163                         "%s %d",
00164                         drvcfg.channel[ix].name,
00165                         ix+if_board_count);
00166                 
00167                 sprintf(
00168                         bd->channel[ix]->transceiverName,
00169                         "%s %d",
00170                         drvcfg.channel[ix].transceiverName,
00171                         ix+if_board_count);     
00172         
00173 /*              memset(bd->channel[ix]->name,0,MAX_BUFFER);
00174                 memcpy(bd->channel[ix]->name,
00175                         drvcfg.channel[ix].name,
00176                         
00177                         (MAX_BUFFER > strlen(drvcfg.channel[ix].name)) ?
00178                                 strlen(drvcfg.channel[ix].name) :
00179                                 MAX_BUFFER);
00180 
00181                 memset(bd->channel[ix]->transceiverName,0,MAX_BUFFER);
00182                 memcpy(bd->channel[ix]->transceiverName,
00183                         drvcfg.channel[ix].transceiverName,
00184                         
00185                         (MAX_BUFFER > strlen(drvcfg.channel[ix].transceiverName)) ?
00186                                 strlen(drvcfg.channel[ix].transceiverName)      :
00187                                 MAX_BUFFER);
00188 */
00189                 bd->channel[ix]->hwType=
00190                         (unsigned int)drvcfg.channel[ix].hwType;
00191         
00192                 bd->channel[ix]->hwIndex=
00193                         (unsigned int)drvcfg.channel[ix].hwIndex;
00194 
00195         }
00196 
00197         if_channel_count+=max;
00198         if_board_count++;
00199         return IF_SUCCESS;
00200 }
00201 int vector_canboardstartup()
00202 {       long n;
00203 
00204         n= xlOpenDriver();
00205         
00206         if(n==XL_SUCCESS)
00207                 return IF_SUCCESS;
00208         else
00209                 return IF_FAILURE;
00210 }
00211 
00212 int vector_canboardopenchannel(int which)
00213 {       char    *app    = "api";
00214         unsigned __int64        perm=ACCESSMASK(which);
00215         for(;;)
00216         {       // we take all hardware we found and
00217                 // check that we have only CAN cabs/piggy's
00218                 if(!channel[which].buscapabilities & XL_BUS_ACTIVE_CAP_CAN)
00219                          break;
00220 
00221                 // open ONE port including all channels
00222                 if(vector_checkstatus(xlOpenPort(
00223                         &channel[which].hwHandle, 
00224                         app,
00225                         ACCESSMASK(which),
00226                         &perm,
00227                         channel[which].rxqueuesize,
00228                         XL_INTERFACE_VERSION,
00229                         XL_BUS_TYPE_CAN),
00230                         which)!=IF_SUCCESS)
00231                         return IF_FAILURE;
00232 
00233                 if ( (channel[which].error.last) || (channel[which].hwHandle == XL_INVALID_PORTHANDLE) )
00234                         break;
00235 
00236 //
00237 // set baudrate
00238 //
00239                 if (perm)
00240                 {       if(vector_checkstatus(xlCanSetChannelBitrate(
00241                                 channel[which].hwHandle, 
00242                                 ACCESSMASK(which), 
00243                                 channel[which].baudrate),which)!=IF_SUCCESS)
00244                                 return IF_FAILURE;
00245                 }
00246 //
00247 // activate the channel
00248 //
00249                 if(vector_checkstatus(xlActivateChannel(
00250                         channel[which].hwHandle,
00251                         ACCESSMASK(which),
00252                         XL_BUS_TYPE_CAN,
00253                         XL_ACTIVATE_RESET_CLOCK),which)!=IF_SUCCESS)
00254                         return IF_FAILURE;
00255 
00256 //
00257 // setup the blocking
00258 //
00259                 if(vector_checkstatus(xlSetNotification(
00260                         channel[which].hwHandle,
00261                         &channel[which].blockinghandle,1),which)!=IF_SUCCESS)
00262                         return IF_FAILURE;
00263 
00264 //
00265 // default to accept all packets
00266 //
00267                 if(vector_checkstatus(xlCanSetChannelAcceptance(
00268                         channel[which].hwHandle,
00269                         ACCESSMASK(which),
00270                         0x000,
00271                         0x000,
00272                         XL_CAN_EXT),which)!=IF_SUCCESS)
00273                         return IF_FAILURE;
00274 
00275                 break;
00276         }
00277         return IF_SUCCESS;
00278 }
00279 
00280 int vector_canboardclosechannel(int which)
00281 {       return vector_checkstatus(xlClosePort(channel[which].hwHandle),which);
00282 }
00283 
00284 //FIXME
00285 int vector_canboardshutdown()
00286 {       return vector_checkstatus(xlCloseDriver(),0);
00287 }
00288 
00289 void dumpevent(XLevent*todump)
00290 {       fprintf(tracefile,"tag: %d",todump->tag);
00291         dumpmem("tagdata",&todump->tagData,32,HEX|ASCII);
00292 }
00293 int vector_canboardread(int which, can_frame*out)
00294 {       unsigned char   *addr;
00295 
00296         unsigned int    trick,
00297                                         ix,
00298                                         fcrc,
00299                                         msgrx=1,
00300                                         size=20;        //FIXME
00301         XLevent         xlEvent;
00302         XLstatus status;
00303         long ret;
00304         out->control.dlc=0;
00305         
00306         if(channel[which].blocktimeout)
00307         {       ret=WaitForSingleObject(channel[which].blockinghandle,channel[which].blocktimeout);     
00308                 ret=WaitForSingleObject(channel[which].blockinghandle,channel[which].blocktimeout);     
00309         }
00310 
00311         status=xlReceive(channel[which].hwHandle, &msgrx, &xlEvent);
00312         
00313         //FIXME gets XLERROR sometimes...
00314 
00315         //we have the chance
00316         channel[which].txerror=xlEvent.tagData.chipState.txErrorCounter;
00317         channel[which].rxerror=xlEvent.tagData.chipState.rxErrorCounter;
00318         channel[which].board->status=xlEvent.tagData.chipState.busStatus;
00319 dumpmem("flags",&xlEvent.tagData.msg.flags,2,HEX);
00320         if(status==XL_ERR_QUEUE_IS_EMPTY||xlEvent.tag==XL_CHIP_STATE)
00321                 return 0;
00322         if(status==XL_ERROR)
00323         {       vector_checkstatus(XL_ERROR,which);
00324                 return -1;
00325         }
00326         //if(xlEvent.tag==XL_CHIP_STATE)
00327         //{     printf("<%04x>",xlEvent.tagData.msg.flags);
00328         //}
00329         printf("\n");
00330         //fprintf(tracefile,"%s\n", xlGetEventString(&xlEvent));
00331         if(xlEvent.tag==XL_SYNC_PULSE)
00332         {       channel[which].lastsync.can_ts_sec=(xlEvent.timeStamp/TIMESCALE);
00333                 channel[which].lastsync.can_ts_nsec=(xlEvent.timeStamp-channel[which].lastsync.can_ts_sec*TIMESCALE);
00334                 vector_checkstatus(XL_SYNC_PULSE,which);
00335                 return -1;//XL_SYNC_PULSE;
00336         }
00337         
00338         if(xlEvent.tagData.msg.flags&XL_CAN_MSG_FLAG_ERROR_FRAME)
00339         {       vector_checkstatus(XL_CAN_MSG_FLAG_ERROR_FRAME,which);
00340                 return -1;//-XL_CAN_MSG_FLAG_ERROR_FRAME;
00341         }
00342         
00343         if(xlEvent.tagData.msg.flags&XL_CAN_MSG_FLAG_OVERRUN)
00344         {       vector_checkstatus(XL_CAN_MSG_FLAG_OVERRUN,which);
00345                 return -1;//XL_CAN_MSG_FLAG_OVERRUN;
00346         }
00347         //NO_ERROR; 
00348         
00349         out->control.dlc=strlen(xlEvent.tagData.msg.data);
00350 
00351         out->sof=0;     //Faked, dominant
00352         
00353         addr=(unsigned char*)&xlEvent.tagData.msg.id;
00354 
00355         out->arbitration.identifier11bit=0;
00356         out->arbitration.identifier11bit=(unsigned short)(xlEvent.tagData.msg.id>>20);
00357         
00358         out->arbitration.srr=GRABBIT(addr[1],4);
00359         out->arbitration.ide=GRABBIT(addr[1],5);
00360         
00361         out->arbitration.identifier18bit=0;
00362         
00363         //Check this - it may not work
00364         trick=(unsigned int)out->arbitration.identifier18bit;
00365         trick>>=2;
00366         out->arbitration.identifier18bit=((trick<<13)>>13);
00367 
00368         out->control.dlc=xlEvent.tagData.msg.dlc;
00369         out->control.r0=(unsigned short)xlEvent.tagData.msg.res1;
00370         out->control.r1=(unsigned short)xlEvent.tagData.msg.res2;
00371 
00372         memset(out->data,0,8);
00373         memcpy(out->data,xlEvent.tagData.msg.data,out->control.dlc);
00374 
00375         fakecrc(out->data,&fcrc);       //Faked, fakecrc()
00376         out->crc.sequence=fcrc;
00377         out->crc.delimeter=0x01;        //Faked, recessive
00378         
00379         out->ack.slot=0x01;                     //Faked, recessive
00380         out->ack.delimeter=0x01;        //Faked, recessive
00381         
00382         out->eof=0xF8;                          //Faked, recessive
00383         
00384         out->oob.ts.ts_sec=xlEvent.timeStamp/TIMESCALE;
00385         out->oob.ts.ts_nsec=xlEvent.timeStamp-out->oob.ts.ts_sec*TIMESCALE;
00386 
00387         out->oob.txid=xlEvent.transId;
00388 
00389         out->oob.msgtype=0;
00390         for(ix=0;statuslookup[ix][0];ix++)
00391         {       if(xlEvent.tagData.msg.flags&statuslookup[ix][0])
00392                         out->oob.msgtype|=statuslookup[ix][1];
00393         }
00394         if(out->oob.msgtype&XL_CAN_MSG_FLAG_REMOTE_FRAME)
00395                 out->arbitration.rtr=0x01;      //faked, recessive if remote
00396         else
00397                 out->arbitration.rtr=0x00;      //faked, dominant if data
00398 
00399         //
00400         // Time to fess up
00401         //
00402         out->oob.isfake=        FAKED_SOF       |
00403                                                 FAKED_RTR       |
00404                                                 FAKED_CRC       |
00405                                                 FAKED_ACK       |
00406                                                 FAKED_EOF;
00407         return 543;//size;
00408 }
00409 //
00410 //      [0000000001111111111222222222233]
00411 //      [1234567890123456789012345678901]
00412 //   [          ][                  ]
00413 //              [ ]
00414 //             [ ]
00415 //
00416 int vector_canboardwrite(int which, can_frame*in)
00417 {       XLevent       xlEvent;
00418         unsigned int  messageCount = 1;
00419         unsigned long   arbitration=0;
00420         arbitration=in->arbitration.identifier11bit;
00421         arbitration<<=1;
00422         arbitration|=in->arbitration.srr;
00423         arbitration<<=1;
00424         arbitration|=in->arbitration.ide;
00425         arbitration<<=18;
00426         arbitration|=in->arbitration.identifier18bit;
00427 
00428         xlEvent.tag                 = XL_TRANSMIT_MSG;
00429         xlEvent.tagData.msg.id      = arbitration;
00430         xlEvent.tagData.msg.dlc     = in->control.dlc;
00431         xlEvent.tagData.msg.flags   = 0;
00432         memset(xlEvent.tagData.msg.data,0,8);
00433         memcpy(xlEvent.tagData.msg.data,in->data,in->control.dlc);
00434         
00435         if(vector_checkstatus(xlCanTransmit(
00436                 channel[which].hwHandle,
00437                 ACCESSMASK(which),
00438                 &messageCount,
00439                 &xlEvent),
00440                 which)!=IF_SUCCESS)
00441                 return -1;
00442 
00443         return IF_SUCCESS;
00444 }
00445 
00446 int vector_canboardupdatestatus(int which)
00447 {       XLdriverConfig  drvcfg; 
00448 //      XLevent         xlEvent; 
00449         int g_msgrx=1;
00450         
00451         if(vector_checkstatus(xlGetDriverConfig(&drvcfg),which)!=IF_SUCCESS)
00452                 return IF_FAILURE;
00453 
00454         channel[which].baudrate=
00455                 drvcfg.channel[channel[which].hwHandle].busParams.data.can.bitRate;
00456         
00457         if(vector_checkstatus(xlCanRequestChipState(
00458                 channel[which].hwHandle,
00459                 ACCESSMASK(which)),
00460                 which)!=IF_SUCCESS)
00461                 return IF_FAILURE;
00462                 
00463         //Update rxqueue
00464         if(vector_checkstatus(xlGetReceiveQueueLevel(
00465                 channel[which].hwHandle,
00466                 &channel[which].rxqueue),
00467                 which)!=IF_SUCCESS)
00468                 return IF_FAILURE;
00469         
00470         //channel[which].txqueue
00471         return IF_SUCCESS;
00472 }
00473 
00474 int vector_canboardchangestatus(int which,int type,int status)
00475 {       switch(type)
00476         {       case C_TXERROR:
00477                         return vector_checkstatus(S_ERR_NOT_IMPLEMENTED,which);
00478                         break;
00479                 case C_RXERROR:
00480                         return vector_checkstatus(S_ERR_NOT_IMPLEMENTED,which);
00481                         break;
00482                 case C_BAUDRATE:
00483                         if(vector_checkstatus(xlCanSetChannelBitrate(
00484                                 channel[which].hwHandle,
00485                                 ACCESSMASK(which),
00486                                 status),
00487                                 which)!=IF_SUCCESS)
00488                                 return IF_FAILURE;
00489                         break;
00490                 case C_MASK:
00491                         channel[which].filter.mask=status;
00492                         return vector_checkstatus(xlCanSetChannelAcceptance(
00493                                 channel[which].hwHandle,
00494                                 ACCESSMASK(which),
00495                                 channel[which].filter.code,
00496                                 status,
00497                                 1),
00498                                 which);
00499                         break;
00500                 case C_CODE:
00501                         channel[which].filter.code=status;
00502                         return vector_checkstatus(xlCanSetChannelAcceptance(
00503                                 channel[which].hwHandle,
00504                                 ACCESSMASK(which),
00505                                 status,
00506                                 channel[which].filter.mask,
00507                                 1),
00508                                 which);
00509                         break;
00510                 case C_RXQUEUE:
00511                         if(status==0)
00512                                 return vector_checkstatus(xlFlushReceiveQueue(channel[which].hwHandle),which);
00513                         break;
00514                 case C_TXQUEUE:
00515                         if(status==0)
00516                                 return vector_checkstatus(xlCanFlushTransmitQueue(channel[which].hwHandle,ACCESSMASK(which)),which);
00517                         break;
00518                 case C_HIDEERRORS:
00519                         return 1;
00520                         /*vector_checkstatus(*/xlCanSetReceiveMode(
00521                                 channel[which].hwHandle,
00522                                 (char)status,
00523                                 (char)((channel[which].flags&I_STATE)?1:0));/*,
00524                                 which);*/
00525                         if(status)
00526                                 channel[which].flags|=I_ERRS;
00527                         else
00528                                 channel[which].flags&=~I_ERRS;
00529                         break;
00530                 case C_HIDECHIP:
00531                         return vector_checkstatus(xlCanSetReceiveMode(
00532                                 channel[which].hwHandle,
00533                                 (char)((channel[which].flags&I_ERRS)?1:0),
00534                                 (char)status),
00535                                 which);
00536                         if(status)
00537                                 channel[which].flags|=I_STATE;
00538                         else
00539                                 channel[which].flags&=~I_STATE;
00540                         break;
00541                 case C_BLOCKTIMEOUT:
00542                         channel[which].blocktimeout=status;
00543                         break;
00544                 default:
00545                         return vector_checkstatus(S_ERR_NOT_IMPLEMENTED,which);
00546                         break;
00547         }
00548         return IF_SUCCESS;
00549 }

Generated on Wed Feb 22 13:31:25 2006 for CANapi by  doxygen 1.4.4