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

canapi.c

Go to the documentation of this file.
00001 /*============================================================================*
00002  * FILE:                      canapi.c
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:    Source file for the highest level of the CAN api
00023  *
00024  * Author:      Christopher McKenzie
00025  * 
00026  * MAINTENANCE NOTES:
00027  * 
00028  *============================================================================*/
00029 #include"..\interfaces\interfaces.h"
00030 #include"..\includes\defines.h"
00031 #include"..\includes\canapi.h"
00032 #include<string.h>
00033 #include<stdio.h>
00034 #include<windows.h>
00035 
00036 extern int _offsets[B__MAX];
00037 extern int if_channel_count;
00038 extern int _bit_width[B__MAX];
00039 extern struct _s_interface*interfaces;
00040 extern struct _if_channel       channel[CAN_MAXCHANNELS];
00041 extern unsigned char*_errors[S__MAX];
00042 extern unsigned char*_errframe[10];
00043 extern int if_board_count;
00044 FILE*tracefile;
00045 int api_channel_count=0;
00046 
00047 int _get_offsets()
00048 {       static int      done=0,
00049                                 acc=0,
00050                                 ix=0;
00051         if(done==1)
00052                 return 1;
00053         _offsets[0]=0;
00054         for(ix=1;ix<B__MAX;ix++)
00055         {       _offsets[ix]=           //current offset
00056                         _offsets[ix-1]+ //place of last offset
00057                         _bit_width[ix-1];       //size of last data structure
00058         }
00059         done=1;
00060         return 1;
00061 }
00062 
00063 int seterror(char*buffer,int toset)
00064 {       strcpy(buffer,_errors[toset]);
00065         return 1;
00066 }
00067 
00068 int isinvalid(int handle)
00069 {       if(handle>if_channel_count|| handle<0)
00070         {       return S_ERR_INV_HANDLE;
00071         }
00072         if(!channel[handle].isopen)
00073         {       channel[handle].error.last=S_ERR_INV_HANDLE;
00074                 return S_ERR_INV_HANDLE;
00075         }
00076         return 0;
00077 }
00078 
00079 //
00080 // This takes a can 2.0 B frame and converts it to a
00081 // bit packed raw frame
00082 //
00083 // look in doc/CAN20b_rawformat.txt for reference
00084 //
00085 int can_can2raw(can_frame*frame,unsigned char*raw)      //TESTTEST
00086 {       int offset=_GETBYTE(_bit_width[B_DAT])-frame->control.dlc;
00087 
00088         if(!frame)
00089         {       return S_ERR_INVARG1;
00090         }
00091         if(!raw)
00092         {       return S_ERR_INVARG2;
00093         }
00094         //Otherwise, we assume everything is awesome
00095         _get_offsets();
00096 
00097         setatbit(raw,(unsigned char*)frame->sof,                                                _offsets[B_SOF],_bit_width[B_SOF]); //SOF
00098         setatbit(raw,(unsigned char*)frame->arbitration.identifier11bit,_offsets[B_ID], _bit_width[B_ID]); //ID
00099         setatbit(raw,(unsigned char*)frame->arbitration.srr,                    _offsets[B_SRR],_bit_width[B_SRR]); //SRR
00100         setatbit(raw,(unsigned char*)frame->arbitration.ide,                    _offsets[B_IDE],_bit_width[B_IDE]); //IDE
00101         setatbit(raw,(unsigned char*)frame->arbitration.identifier18bit,_offsets[B_EXT],_bit_width[B_EXT]); //EXT
00102         setatbit(raw,(unsigned char*)frame->arbitration.rtr,                    _offsets[B_RTR],_bit_width[B_RTR]); //RTR
00103         setatbit(raw,(unsigned char*)frame->control.r0,                                 _offsets[B_RES],_bit_width[B_RES]); //RES
00104         setatbit(raw,(unsigned char*)frame->control.dlc,                                _offsets[B_DLC],_bit_width[B_DLC]); //DLC
00105 
00106         //Things get trickier
00107         setatbit(raw,(unsigned char*)frame->data,                       _offsets[B_DAT],frame->control.dlc); //DAT
00108         setatbit(raw,(unsigned char*)frame->crc.sequence,       _offsets[B_CRC],_bit_width[B_CRC]-offset); //CRC
00109         setatbit(raw,(unsigned char*)frame->ack.slot,           _offsets[B_ACK],_bit_width[B_ACK]-offset); //ACK
00110         setatbit(raw,(unsigned char*)frame->eof,                        _offsets[B_EOF],_bit_width[B_EOF]-offset); //EOF
00111 
00112         return S_SUCCESS;
00113 }
00114 
00115 int can_raw2can(unsigned char*raw,can_frame*frame)      //FIXME
00116 {       return 1;
00117 }
00118 
00119 int can_setchanneloptions(int handle,int option,int status)
00120 {       if(!isinvalid(handle))
00121         {       if(option<C__MAX&&option>0)
00122                         return boardchangestatus(handle,option,status);
00123                 SETERROR(S_ERR_INVARG2);
00124                 return S_ERR_INVARG2;
00125         }
00126         return S_ERR_INV_HANDLE;
00127 }
00128 
00129 int can_getchanneloptions(int handle, int option, int*status)
00130 {       if(!isinvalid(handle))
00131         {       boardupdatestatus(handle);      //might as well
00132                 switch(option)
00133                 {       case C_TXERROR:
00134                                 (*status)=channel[handle].txerror;
00135                                 break;
00136                         case C_RXERROR:
00137                                 (*status)=channel[handle].rxerror;
00138                                 break;
00139                         case C_BAUDRATE:
00140                                 (*status)=channel[handle].baudrate;
00141                                 break;
00142                         case C_MASK:
00143                                 (*status)=channel[handle].filter.mask;
00144                                 break;
00145                         case C_CODE:
00146                                 (*status)=channel[handle].filter.code;
00147                                 break;
00148                         case C_RXQUEUE:
00149                                 (*status)=channel[handle].rxqueue;
00150                                 break;
00151                         case C_TXQUEUE:
00152                                 (*status)=channel[handle].txqueue;
00153                                 break;
00154                         case C_HIDEERRORS:
00155                                 (*status)=channel[handle].baudrate;
00156                                 break;
00157                         case C_HIDECHIP:
00158                                 (*status)=channel[handle].baudrate;
00159                                 break;
00160                         case C_BLOCKTIMEOUT:
00161                                 (*status)=channel[handle].blocktimeout;
00162                                 break;
00163                         case C_BOARDSTATE:
00164                                 (*status)=channel[handle].board->status;
00165                                 break;
00166                         default:
00167                                 SETERROR(S_ERR_INVARG2);
00168                                 return S_ERR_INVARG2;
00169                                 break;
00170                 }
00171                 return S_SUCCESS;
00172         }
00173         return S_ERR_INV_HANDLE;
00174 }
00175 
00176 int can_probebus(can_list list,char*errbuf)
00177 {       int ix;
00178                 
00179         if(list)
00180         {       memset(list,0,CAN_MAXCHANNELS*CAN_MAXBUFFER);
00181                 if_channel_count=0;
00182                 if_board_count=0;
00183                 if(!boardprobe())
00184                 {       seterror(errbuf,S_ERR_UNKNOWN);
00185                         return -1;
00186                 }
00187                 for(ix=0;ix<if_channel_count;ix++)
00188                 {       strcpy(list[ix],channel[ix].name);
00189                 }
00190         }else
00191                 seterror(errbuf,S_ERR_INVARG1);
00192         return if_channel_count;
00193 }
00194 
00195 int can_openchannel(char*device,char*errbuf)
00196 {       int ix;
00197         for(ix=0;ix<if_channel_count;ix++)
00198         {       if(!strcmp(device,channel[ix].name))
00199                 {       boardopenchannel(ix);
00200                         return ix;
00201                 }
00202         }
00203         seterror(errbuf,S_ERR_HW_NOT_PRESENT);
00204         return -1;
00205 }
00206 
00207 int can_readchannel(int handle,can_frame*frame)
00208 {       if(!isinvalid(handle))
00209         {       if(frame)
00210                         return boardread(handle,frame);
00211                 SETERROR(S_ERR_INVARG2);
00212                 return S_ERR_INVARG2;
00213         }
00214         return S_ERR_INV_HANDLE;
00215 }
00216 
00217 int can_writechannel(int handle,can_frame*frame)
00218 {       if(!isinvalid(handle))
00219         {       if(frame)
00220                         return boardwrite(handle,frame);
00221                 SETERROR(S_ERR_INVARG2);
00222                 return S_ERR_INVARG2;
00223         }
00224         return S_ERR_INV_HANDLE;
00225 }
00226 
00227 int can_closechannel(int handle)
00228 {       if(!isinvalid(handle))
00229                 return boardshutdown(handle);
00230         return S_ERR_INV_HANDLE;
00231 }
00232 
00233 int can_getlasterror(int handle,char*errbuf)
00234 {       if(!isinvalid(handle))
00235         {       errbuf[0]=0;
00236                 if(channel[handle].error.last&0x8000)
00237                 {       int ix=0,mask=1,err=channel[handle].error.last;
00238                         do
00239                         {       if(err&mask)
00240                                         sprintf(errbuf,"%s %s",errbuf,_errframe[ix]);
00241                                 mask=mask<<1;
00242                                 ix++;
00243                         }while(_errframe[ix]);
00244                         return S_SUCCESS;
00245                 }
00246                 strcpy(errbuf,_errors[channel[handle].error.last]);
00247                 channel[handle].error.last=0;
00248                 return S_SUCCESS;
00249         }
00250         return S_ERR_INV_HANDLE;
00251 }
00252 
00253 int can_getlastassoc (int handle, as_ts*timestamp)
00254 {       if(!isinvalid(handle))
00255         {       timestamp->can_ts_nsec=channel[handle].lastsync.can_ts_nsec;
00256                 timestamp->can_ts_sec=channel[handle].lastsync.can_ts_sec;
00257                 timestamp->irig_ts_nsec=channel[handle].lastsync.irig_ts_nsec;
00258                 timestamp->irig_ts_sec=channel[handle].lastsync.irig_ts_sec;
00259                 return S_SUCCESS;
00260         }
00261         return S_ERR_INV_HANDLE;
00262 }
00263 
00264 int __stdcall DllMain(HANDLE hmodule, DWORD dwReason, PVOID pvReserved)
00265 {       
00266         switch (dwReason)
00267     {
00268     case DLL_PROCESS_ATTACH:
00269                 tracefile=fopen("trace.txt","w");
00270         break;
00271     case DLL_THREAD_ATTACH:
00272                 break;
00273     case DLL_PROCESS_DETACH:
00274                 fclose(tracefile);
00275         break;
00276     case DLL_THREAD_DETACH:
00277                 break;
00278     default:
00279 //        Bug("DllMain() called with unrecognized dwReason.");
00280         return FALSE;
00281     }
00282         return 1;
00283 }
00284 
00285 int b_can_bitsizes[]=
00286 {       1,      //gateway
00287         8,      //group
00288         12,     //message
00289         8       //status
00290 };
00291 
00292 int can_getfield (can_frame*frame,int type,int*ret)
00293 {       static int      offsetdone=0,
00294                                 offsets[sizeof(b_can_bitsizes)];
00295         
00296         unsigned int    smashed=0;
00297 
00298         unsigned char buffer[4];
00299         
00300         if(!ret)
00301         {       
00302                 return S_ERR_INVARG3;
00303         }
00304 
00305         if(!offsetdone)
00306         {       int ix;
00307                 //calculate offsets
00308                 offsets[0]=0;
00309                 for(ix=1;ix<sizeof(b_can_bitsizes);ix++)
00310                 {       offsets[ix]=offsets[ix-1]+b_can_bitsizes[ix-1];//TESTTEST
00311                 }
00312                 offsetdone=1;   //only once though
00313         }
00314         //
00315         // smash together base and extended
00316         //
00317 
00318         //
00319         // First we throw in the 11 bit identifier
00320         //
00321         smashed=frame->arbitration.identifier11bit;
00322         
00323         //
00324         // Bitshift it 18 left
00325         //
00326         smashed<<=18;
00327         
00328         //
00329         // or it with the 18 bit identifier
00330         //
00331         smashed|=frame->arbitration.identifier18bit;
00332 
00333         //
00334         // Now pretend its a char* cause we can use our awesome function
00335         //
00336         getatbit(
00337                 (unsigned char*)&smashed,
00338                 (unsigned char*)&buffer,
00339                 offsets[type],
00340                 b_can_bitsizes[type]);
00341 
00342         //
00343         // so now buffer has the field data - do some black magic to
00344         // make it an int
00345         //
00346         *ret=(int)buffer;
00347 
00348         //
00349         // and ya' know, return success...
00350         //
00351         return S_SUCCESS;
00352 }

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