MiniCAN MiniCAN: minican.c Source File Documentation

minican.c

Go to the documentation of this file.
00001 
00006 #pragma option -r-
00007 
00008 #define _RTLIB_ 
00009 #include "max_lib.h"
00010 #include "x_error.h"
00011 #include "x_mdd.h"
00012 #include "dos.h"
00013 #include "stdlib.h"
00014 #include "string.h"
00015 #include "minican.h"
00016 
00017 
00026 typedef struct
00027 {
00028         MAX_PDT_HEAD    rcHead;     
00029         void* MAXEXPORT main_proc;  
00030         void* MAXEXPORT auto_init;  
00031         void* MAXEXPORT Start;          
00032         void* MAXEXPORT Stop;           
00033         void* MAXEXPORT Read0;          
00034         void* MAXEXPORT Write0;         
00035         void* MAXEXPORT Read1;          
00036         void* MAXEXPORT Write1;         
00037 } PDT_t;
00038 PDT_t rcPDT; 
00039 
00047 typedef struct 
00048 {
00049         MAX_TDT_TYPE rcTDT;                 
00050         // offset 0
00051         MAX_ERROR   Error;                  
00052         // offset 2
00053         ULONG       ulTimeStampHi;          
00054         // offset 6
00055         ULONG       ulTimeStampLo;          
00056         // offset 10
00057         CAN_INTERFACE_PARAMETERS arcCanParameters[2]; 
00058         // offset 50
00059         USHORT      usSlot;                 
00060         // offset 52
00061         XCAN_BIT_PARAMS arcBitTiming[2];    
00062         // offset 80
00063         CAN_INTERFACE_STATE arcIfcState[2]; 
00064         // offset 104
00065         ULONG       ulCbFilterCount[2];     
00066         // offset 112
00067         ULONG       ulCbCtrlCount[2];       
00068         // offset 120
00069         ULONG       ulTmtPending[2];        
00070         MAXMDDHND   hMdd;                   
00071         MAXCHLHND   hCtrl[2];               
00072         MAXCHLHND   hIn11[2];               
00073         MAXCHLHND   hIn29[2];               
00074         MAXCHLHND   hOut[2];                
00075         MAXBUFHND   hBuf[2];                
00076         MAXMODHND   hMyself;                
00077         MAX_OS_INFO rcOsX;                  
00078 } parameter_t;
00079 parameter_t parameter; 
00080 
00081 
00082 //*****************************************************************************
00083 // GetBitTiming
00089 //*****************************************************************************
00090 MAX_ERROR GetBitTiming(USHORT usInterface, XCAN_BIT_PARAMS *prcBitParam)
00091 {
00092         // bit timing from bit rate
00093     prcBitParam->SpB       = 1;
00094     switch (parameter.arcCanParameters[usInterface].ulBitRate)
00095     {
00096     case 10000:
00097         prcBitParam->Tq    = 5000;
00098         prcBitParam->Tseg1 = 16;
00099         prcBitParam->Tseg2 = 3;
00100         prcBitParam->Tsjw  = 2;
00101                 break;
00102     case 20000:
00103         prcBitParam->Tq    = 2500;
00104         prcBitParam->Tseg1 = 16;
00105         prcBitParam->Tseg2 = 3;
00106         prcBitParam->Tsjw  = 2;
00107                 break;
00108     case 50000:
00109         prcBitParam->Tq    = 1000;
00110         prcBitParam->Tseg1 = 16;
00111         prcBitParam->Tseg2 = 3;
00112         prcBitParam->Tsjw  = 2;
00113                 break;
00114     case 80000:
00115         prcBitParam->Tq    = 625;
00116         prcBitParam->Tseg1 = 16;
00117         prcBitParam->Tseg2 = 3;
00118         prcBitParam->Tsjw  = 2;
00119                 break;
00120     case 83300:
00121         prcBitParam->Tq    = 750;
00122         prcBitParam->Tseg1 = 13;
00123         prcBitParam->Tseg2 = 2;
00124         prcBitParam->Tsjw  = 1;
00125                 break;
00126     case 100000:
00127         prcBitParam->Tq    = 500;
00128         prcBitParam->Tseg1 = 16;
00129         prcBitParam->Tseg2 = 3;
00130         prcBitParam->Tsjw  = 2;
00131                 break;
00132     case 125000:
00133         prcBitParam->Tq    = 500;
00134         prcBitParam->Tseg1 = 13;
00135         prcBitParam->Tseg2 = 2;
00136         prcBitParam->Tsjw  = 1;
00137                 break;
00138     case 250000:
00139         prcBitParam->Tq    = 250;
00140         prcBitParam->Tseg1 = 13;
00141         prcBitParam->Tseg2 = 2;
00142         prcBitParam->Tsjw  = 1;
00143                 break;
00144     case 500000:
00145         prcBitParam->Tq    = 125;
00146         prcBitParam->Tseg1 = 13;
00147         prcBitParam->Tseg2 = 2;
00148         prcBitParam->Tsjw  = 1;
00149                 break;
00150     case 666000:
00151         prcBitParam->Tq    = 125;
00152         prcBitParam->Tseg1 = 9;
00153         prcBitParam->Tseg2 = 2;
00154         prcBitParam->Tsjw  = 1;
00155                 break;
00156     case 800000:
00157         prcBitParam->Tq    = 125;
00158         prcBitParam->Tseg1 = 7;
00159         prcBitParam->Tseg2 = 2;
00160         prcBitParam->Tsjw  = 1;
00161                 break;
00162     case 1000000:
00163         prcBitParam->Tq    = 125;
00164         prcBitParam->Tseg1 = 5;
00165         prcBitParam->Tseg2 = 2;
00166         prcBitParam->Tsjw  = 1;
00167                 break;
00168     default:
00169         return ERR_INVALID_PARAMETER;
00170     }
00171         
00172         if (parameter.arcCanParameters[usInterface].ulRbus == 0)
00173                 prcBitParam->Rbus      = 0;
00174         else
00175                 prcBitParam->Rbus      = 1;
00176         
00177         if (parameter.arcCanParameters[usInterface].ulFormat == 11L)
00178                 prcBitParam->MsgFormat = 11;
00179         if (parameter.arcCanParameters[usInterface].ulFormat == 29L)
00180                 prcBitParam->MsgFormat = 29;
00181         if (parameter.arcCanParameters[usInterface].ulFormat == 31L)
00182                 prcBitParam->MsgFormat = XCAN_MIXED_FORMAT;
00183 
00184         //copy to parameter space
00185         memcpy(&parameter.arcBitTiming[usInterface], prcBitParam, sizeof(XCAN_BIT_PARAMS));
00186         
00187         return ERR_OK;
00188 }
00189 
00190 
00191 //*****************************************************************************
00192 // CbFilter
00200 //*****************************************************************************
00201 #pragma argsused
00202 MAX_CALLBACK CbFilter(MAXCHLHND hChannel, ULONG ulParam, ULONG ulSize, void* prcCanMessage)
00203 {
00204     XCAN_MESSAGE  *prcMsg = (XCAN_MESSAGE*)prcCanMessage;
00205         CAN_INTERFACE_READ rcCanMessage;
00206         ULONG ulSizeTmp, ulValid, ulFree;
00207         USHORT usIndex;
00208         MAX_ERROR Error;
00209         
00210         //get interface index
00211         usIndex = (USHORT)(ulParam >> 16);
00212 
00213         // check parameter
00214         if (usIndex > 1)
00215                 return;
00216 
00217         //apply timestamp
00218         rcCanMessage.ulTimeStampLo = parameter.ulTimeStampLo;
00219         rcCanMessage.ulTimeStampHi = parameter.ulTimeStampHi;
00220 
00221         //check if there is still free space in the buffer
00222         parameter.Error = max_get_buffer_status(parameter.hBuf[usIndex], &ulValid, &ulFree);
00223         if (ulFree < sizeof(CAN_INTERFACE_READ) * 2)
00224         {
00225                 //set message size
00226                 rcCanMessage.ulDataSize = sizeof(MAX_ERROR);
00227                 //set invalid message id
00228                 rcCanMessage.ulId = 0xffffffffL;
00229                 //set invalid message format
00230                 rcCanMessage.ulFormat = 0xffffffffL;
00231                 //copy message data
00232                 Error = ERR_OSX_BUFFER_FULL;
00233                 memcpy(&rcCanMessage.aucData[0], &Error, rcCanMessage.ulDataSize);
00234         }
00235         else
00236         {
00237                 //get message size
00238                 rcCanMessage.ulDataSize = prcMsg->usDataSize;
00239                 //get message id
00240                 rcCanMessage.ulId = prcMsg->ulCanId;
00241                 //get message format
00242                 rcCanMessage.ulFormat = ulParam & 0x0000ffffL;
00243                 //copy message data
00244                 memcpy(&rcCanMessage.aucData[0], &(prcMsg->aucData[0]), rcCanMessage.ulDataSize);
00245         }
00246 
00247         //store message in ring buffer
00248         ulSizeTmp = sizeof(rcCanMessage);
00249     parameter.Error = max_set_buffer(parameter.hBuf[usIndex], MAX_BUFFER_MOVE_ABS, &ulSizeTmp, &rcCanMessage);
00250 
00251         //count message
00252         parameter.ulCbFilterCount[usIndex]++;
00253 }
00254 
00255 
00256 //*****************************************************************************
00257 // CbControl
00265 //*****************************************************************************
00266 #pragma argsused
00267 MAX_CALLBACK CbControl(MAXCHLHND hChannel, ULONG ulParam, ULONG ulSize, void *pData)
00268 {
00269     // check parameter
00270     if (ulParam > 1)
00271         return;
00272 
00273     // copy state
00274     memcpy(&parameter.arcIfcState[ulParam].usBusState, pData, sizeof(ULONG));
00275     // set time stamp
00276         parameter.arcIfcState[ulParam].ulTimeStampHi = parameter.ulTimeStampHi;
00277         parameter.arcIfcState[ulParam].ulTimeStampLo = parameter.ulTimeStampLo;
00278 
00279         //count callback
00280         parameter.ulCbCtrlCount[ulParam]++;
00281 }
00282 
00283 
00284 //*****************************************************************************
00285 // CbAcknowledge
00293 //*****************************************************************************
00294 #pragma argsused
00295 MAX_CALLBACK CbAcknowledge(MAXCHLHND hChannel, ULONG ulParam, ULONG ulSize, void* pVoid)
00296 {
00297         // check parameter
00298     if (ulParam > 1)
00299         return;
00300 
00301         //a message was sent
00302         parameter.ulTmtPending[ulParam]--;
00303 }
00304 
00305 
00306 //*****************************************************************************
00307 // MainProc
00314 //*****************************************************************************
00315 void MAXEXPORT MainProc(void)
00316 {
00317         max_entry_proc();
00318         
00319         parameter.ulTimeStampLo++;
00320         if (parameter.ulTimeStampLo == 0)
00321                 parameter.ulTimeStampHi++;
00322         
00323         max_exit_proc();
00324 }
00325 
00326 
00327 //*****************************************************************************
00328 // AutoInit
00335 //*****************************************************************************
00336 void MAXEXPORT AutoInit(void)
00337 {
00338         MAX_BUFFER_TYPE rcBuffer;
00339         MAX_TI_TYPE rcTaskParams;
00340         ULONG   ulSize;
00341         USHORT usTask;
00342         
00343         usTask = max_entry_proc();
00344         
00345         //init global timestamp
00346         parameter.ulTimeStampHi = 0;
00347         parameter.ulTimeStampLo = 0;
00348         //init interface parameters
00349         parameter.arcCanParameters[0].ulBitRate = 250000L; //default: 250kBit
00350         parameter.arcCanParameters[1].ulBitRate = 250000L; //default: 250kBit
00351         parameter.arcCanParameters[0].ulFormat  = 11;      //default: 11 bit IDs
00352         parameter.arcCanParameters[1].ulFormat  = 11;      //default: 11 bit IDs
00353         parameter.arcCanParameters[0].ulRbus    = 1;       //default: termination on
00354         parameter.arcCanParameters[1].ulRbus    = 1;       //default: termination on
00355     parameter.arcCanParameters[0].ulCanId   = 0;       //default: receive all
00356         parameter.arcCanParameters[1].ulCanId   = 0;       //default: receive all
00357         parameter.arcCanParameters[0].ulCanMask = 0;       //default: receive all
00358         parameter.arcCanParameters[1].ulCanMask = 0;       //default: receive all
00359         //init handles
00360         parameter.hMdd     = 0;
00361         parameter.hCtrl[0] = 0;
00362         parameter.hCtrl[1] = 0;
00363         parameter.hIn11[0] = 0;
00364         parameter.hIn11[1] = 0;
00365         parameter.hIn29[0] = 0;
00366         parameter.hIn29[1] = 0;
00367         parameter.hOut[0]  = 0;
00368         parameter.hOut[1]  = 0;
00369         //default for CANbox
00370         parameter.usSlot = 2;
00371         //init callback counters
00372         parameter.ulCbFilterCount[0] = 0;
00373         parameter.ulCbFilterCount[1] = 0;
00374         parameter.ulTmtPending[0]    = 0;
00375         parameter.ulTmtPending[1]    = 0;
00376         parameter.ulCbCtrlCount[0]   = 0;
00377         parameter.ulCbCtrlCount[1]   = 0;
00378 
00379         max_init_lib(0);
00380 
00381         // get a handle for the X-MAX-1
00382         parameter.Error = max_connect_cpu (0, MAX_MYSELF, 0,&parameter.rcOsX, &parameter.hMyself);
00383         if (parameter.Error != ERR_OK)
00384                 goto exit_auto_init;
00385         
00386         //allocate RCV buffer for interface 0
00387         ulSize = CAN_RCV_BUFFER_SIZE;
00388         rcBuffer.usStrategy = MAX_ALLOC_DOWN_ABS;
00389         rcBuffer.usAlignment = 2;
00390         rcBuffer.usTask = usTask;
00391         parameter.Error = max_create_buffer(parameter.hMyself, &rcBuffer, &ulSize, &parameter.hBuf[0]);
00392         if (parameter.Error != ERR_OK)
00393                 goto exit_auto_init;
00394 
00395         //allocate RCV buffer for interface 1
00396         ulSize = CAN_RCV_BUFFER_SIZE;
00397         rcBuffer.usStrategy = MAX_ALLOC_DOWN_ABS;
00398         rcBuffer.usAlignment = 2;
00399         rcBuffer.usTask = usTask;
00400         parameter.Error = max_create_buffer(parameter.hMyself, &rcBuffer, &ulSize, &parameter.hBuf[1]);
00401         if (parameter.Error != ERR_OK)
00402                 goto exit_auto_init;
00403         
00404         //wakeup myself
00405         if ((rcPDT.rcHead.usFlags & 0x0003) == MAX_TI_TASK)
00406         {
00407                 if (parameter.Error == ERR_OK) 
00408                 {
00409                         rcTaskParams.usPriority  = 0;
00410                         rcTaskParams.ulHoldOff   = 0;
00411                         rcTaskParams.ulIntervall = 1; // = 1ms
00412                         rcTaskParams.ulCalls     = 0;
00413                         parameter.Error = max_wakeup_ti_task(parameter.hMyself, usTask, &rcTaskParams);
00414                 }
00415         }
00416         if ((rcPDT.rcHead.usFlags & 0x0003) == MAX_NI_TASK)
00417         {
00418                 if (parameter.Error == ERR_OK) 
00419                 {
00420                         parameter.Error = max_wakeup_ni_task(parameter.hMyself, usTask, 1);
00421                 }
00422         }
00423 
00424 exit_auto_init:
00425         
00426         max_exit_proc();
00427 }
00428 
00429 //*****************************************************************************
00430 // Start
00439 //*****************************************************************************
00440 void MAXEXPORT Start(void)
00441 {
00442         ULONG ulSize, ulParam;
00443         CPS_XCAN rcCps;
00444         XCAN_BIT_PARAMS rcBitParam;
00445         ULONG ulIndex;
00446         
00447         max_entry_proc();
00448         
00449         //load MDD
00450         if (parameter.hMdd == NULL)
00451                 parameter.Error = max_load_mdd(parameter.hMyself, parameter.usSlot, 0, 0, 0x803A, NULL, &parameter.hMdd);
00452         if (parameter.Error != ERR_OK)
00453         {
00454                 max_clear_error();
00455                 max_exit_proc();
00456         }
00457         
00458         for (ulIndex=0; ulIndex<2; ulIndex++)
00459         {
00460                 if (parameter.arcCanParameters[ulIndex].ulBitRate != 0)
00461                 {
00462                         // open control channel
00463                         rcCps.usDevice       = DEVICE_CTRL;
00464                         rcCps.usChannel      = ulIndex;
00465                         rcCps.usIndexFirst   = XCAN_BUS_CTRL_INDEX;
00466                         rcCps.usIndexLast    = XCAN_BUS_CTRL_INDEX;
00467                         rcCps.usFlags        = 0;
00468                         
00469                         if (parameter.hCtrl[ulIndex] == NULL)
00470                                 parameter.Error = max_open_channel(parameter.hMdd,  sizeof(rcCps), &rcCps, CbControl, ulIndex, &parameter.hCtrl[ulIndex]);
00471                         if (parameter.Error != ERR_OK)
00472                         {
00473                                 max_clear_error();
00474                                 break;
00475                         }
00476                         
00477                         // config interface
00478                         ulSize = sizeof(XCAN_BIT_PARAMS);
00479                         parameter.Error = GetBitTiming((USHORT)ulIndex, &rcBitParam);
00480                         if (parameter.Error != ERR_OK)
00481                         {
00482                                 max_clear_error();
00483                                 break;
00484                         }
00485                         parameter.Error = max_write_channel_block(parameter.hCtrl[ulIndex], &ulSize, &rcBitParam);
00486                         if (parameter.Error != ERR_OK)
00487                         {
00488                                 max_clear_error();
00489                                 break;
00490                         }
00491                         
00492                         //open acceptance filter
00493                         //11 bit
00494                         if ((parameter.arcCanParameters[ulIndex].ulFormat & 11L) == 11L)
00495                         {
00496                                 rcCps.usDevice               = DEVICE_CTRL;
00497                 rcCps.usIndexFirst           = 0;
00498                 rcCps.usIndexLast            = 0;
00499                 rcCps.usChannel              = (USHORT)ulIndex;
00500                 rcCps.ulCanID                = parameter.arcCanParameters[ulIndex].ulCanId;
00501                 rcCps.usFlags                = _CP_SYNC_CALLBACK;
00502                                 ulParam = 11;         //give format info in low word
00503                                 ulParam |= (ulIndex << 16); //give interface index in high word
00504                                 parameter.Error = max_open_channel(parameter.hMdd,  sizeof(rcCps), &rcCps, CbFilter, ulParam, &parameter.hIn11[ulIndex]);
00505                                 if (parameter.Error != ERR_OK)
00506                                 {
00507                                         max_clear_error();
00508                                         break;
00509                                 }
00510                                 parameter.Error = max_write_channel_ulong(parameter.hIn11[ulIndex], parameter.arcCanParameters[ulIndex].ulCanMask); 
00511                                 if (parameter.Error != ERR_OK)
00512                                 {
00513                                         max_clear_error();
00514                                         break;
00515                                 }
00516                         }
00517                         //29 bit
00518                         if ((parameter.arcCanParameters[ulIndex].ulFormat & 29L) == 29L)
00519                         {
00520                                 rcCps.usDevice               = DEVICE_CTRL;
00521                 rcCps.usIndexFirst           = 0;
00522                 rcCps.usIndexLast            = 0;
00523                 rcCps.usChannel              = (USHORT)ulIndex;
00524                 rcCps.ulCanID                = parameter.arcCanParameters[ulIndex].ulCanId;
00525                 rcCps.usFlags                = XCAN_29BIT_ID | _CP_SYNC_CALLBACK;
00526                                 ulParam = 29;         //give format info in low word
00527                                 ulParam |= (ulIndex << 16); //give interface index in high word
00528                                 parameter.Error = max_open_channel(parameter.hMdd,  sizeof(rcCps), &rcCps, CbFilter, ulParam, &parameter.hIn29[ulIndex]);
00529                                 if (parameter.Error != ERR_OK)
00530                                 {
00531                                         max_clear_error();
00532                                         break;
00533                                 }
00534                                 parameter.Error = max_write_channel_ulong(parameter.hIn29[ulIndex], parameter.arcCanParameters[ulIndex].ulCanMask); 
00535                                 if (parameter.Error != ERR_OK)
00536                                 {
00537                                         max_clear_error();
00538                                         break;
00539                                 }
00540                         }
00541 
00542                         //open universal sender
00543                         rcCps.usDevice               = DEVICE_BUS_OUT;
00544             rcCps.usChannel              = ulIndex;
00545             rcCps.ulCanID                = XCAN_GENERAL_ID;
00546             rcCps.usFlags                = _CP_EXCLUSIVE;
00547             rcCps.usTimeout              = 1000; //1ms
00548                         parameter.Error = max_open_channel(parameter.hMdd,  sizeof(rcCps), &rcCps, CbAcknowledge, ulIndex, &parameter.hOut[ulIndex]);
00549                         if (parameter.Error != ERR_OK)
00550                         {
00551                                 max_clear_error();
00552                                 break;
00553                         }
00554                                                 
00555                         //start bus
00556                         parameter.Error = max_channel_control(parameter.hCtrl[ulIndex], CMD_START, 0, NULL);
00557                 }//if (parameter.arcCanParameters[ulIndex].ulBitRate != 0)
00558         }//for (ulIndex=0; ulIndex<2; ulIndex++)
00559         
00560         
00561         max_exit_proc();
00562 }
00563 
00564 
00565 //*****************************************************************************
00566 // Stop
00575 //*****************************************************************************
00576 void MAXEXPORT Stop(void)
00577 {
00578         USHORT i;
00579         
00580         max_entry_proc();
00581 
00582         if (parameter.Error != ERR_OK)
00583                 max_clear_error();
00584 
00585         //loop over all interfaces
00586         for (i=0; i<2; i++)
00587         {
00588                 //interface is open
00589                 if (parameter.hCtrl[i] != NULL)
00590                 {
00591                         //stop bus
00592                         parameter.Error = max_channel_control(parameter.hCtrl[i], CMD_STOP, 0, NULL);
00593                         if (parameter.Error != ERR_OK)
00594                                 max_clear_error();
00595 
00596                         //close channels
00597                         parameter.Error = max_close_channel(&parameter.hOut[i]);
00598                         if (parameter.Error != ERR_OK)
00599                                 max_clear_error();
00600                         parameter.hOut[i] = NULL;
00601 
00602                         if (parameter.hIn11[i] != NULL)
00603                         {
00604                                 parameter.Error = max_close_channel(&parameter.hIn11[i]);
00605                                 if (parameter.Error != ERR_OK)
00606                                         max_clear_error();
00607                                 parameter.hIn11[i] = NULL;
00608                         }
00609                         if (parameter.hIn29[i] != NULL)
00610                         {
00611                                 parameter.Error = max_close_channel(&parameter.hIn29[i]);
00612                                 if (parameter.Error != ERR_OK)
00613                                         max_clear_error();
00614                                 parameter.hIn29[i] = NULL;
00615                         }
00616                         parameter.Error = max_close_channel(&parameter.hCtrl[i]);
00617                         if (parameter.Error != ERR_OK)
00618                                 max_clear_error();
00619                         parameter.hCtrl[i] = NULL;
00620 
00621                         //clear ring buffer
00622                         parameter.Error = max_clear_buffer(parameter.hBuf[i]);
00623                         if (parameter.Error != ERR_OK)
00624                                 max_clear_error();
00625                 }//if (parameter.hCtrl[i] != NULL)
00626         }//for (i=0; i<2; i++)
00627         
00628         max_exit_proc();
00629 }
00630 
00631 
00632 //*****************************************************************************
00633 // Write0
00644 //*****************************************************************************
00645 #pragma argsused
00646 void MAXEXPORT Write0(USHORT *pusLength, CAN_INTERFACE_WRITE *prcCanMsg, USHORT *pusRetsize, void *pRetData)
00647 {
00648         XCAN_MESSAGE rcCanMessage;
00649         ULONG ulSize;
00650         
00651         max_entry_func();
00652 
00653         //check buffer size
00654         if (*pusLength < sizeof(CAN_INTERFACE_WRITE))
00655                 max_exit_func(ERR_WRONG_NUMBER_OF_INPUTS);
00656         
00657         //compose message for sending
00658         rcCanMessage.ulCanId = prcCanMsg->ulId;
00659         rcCanMessage.usDataSize = (USHORT)prcCanMsg->ulDataSize;
00660         if (prcCanMsg->ulFormat == 11L)
00661                 rcCanMessage.usFlags = 0;
00662         else
00663                 rcCanMessage.usFlags = XCAN_29BIT_ID;
00664         
00665         memcpy(&rcCanMessage.aucData[0], &(prcCanMsg->aucData[0]), rcCanMessage.usDataSize);
00666         
00667         //send message
00668         ulSize = sizeof(rcCanMessage);
00669         parameter.Error = max_write_channel_block(parameter.hOut[0], &ulSize, &rcCanMessage);
00670 
00671         if (parameter.Error == ERR_OK)
00672                 parameter.ulTmtPending[0]++;
00673         else
00674                 max_clear_error();
00675         
00676         max_exit_func(parameter.Error);
00677 }
00678 
00679 
00680 //*****************************************************************************
00681 // Write1
00692 //*****************************************************************************
00693 #pragma argsused
00694 void MAXEXPORT Write1(USHORT *pusLength, CAN_INTERFACE_WRITE *prcCanMsg, USHORT *pusRetsize, void *pRetData)
00695 {
00696         XCAN_MESSAGE rcCanMessage;
00697         ULONG ulSize;
00698         
00699         max_entry_func();
00700 
00701         //check buffer size
00702         if (*pusLength < sizeof(CAN_INTERFACE_WRITE))
00703                 max_exit_func(ERR_WRONG_NUMBER_OF_INPUTS);
00704         
00705         //compose message for sending
00706         rcCanMessage.ulCanId = prcCanMsg->ulId;
00707         rcCanMessage.usDataSize = (USHORT)prcCanMsg->ulDataSize;
00708         if (prcCanMsg->ulFormat == 11L)
00709                 rcCanMessage.usFlags = 0;
00710         else
00711                 rcCanMessage.usFlags = XCAN_29BIT_ID;
00712         
00713         memcpy(&rcCanMessage.aucData[0], &(prcCanMsg->aucData[0]), rcCanMessage.usDataSize);
00714         
00715         //send message
00716         ulSize = sizeof(rcCanMessage);
00717         parameter.Error = max_write_channel_block(parameter.hOut[1], &ulSize, &rcCanMessage);
00718 
00719         if (parameter.Error == ERR_OK)
00720                 parameter.ulTmtPending[1]++;
00721         else
00722                 max_clear_error();
00723         
00724         max_exit_func(parameter.Error);
00725 }
00726 
00727 //*****************************************************************************
00728 // Read0
00739 //*****************************************************************************
00740 #pragma argsused
00741 void MAXEXPORT Read0(USHORT *pusLength, void *pIn, USHORT *pusRetsize, CAN_INTERFACE_READ *prcCanMsg)
00742 {
00743         ULONG ulValid, ulFree, ulSize;
00744 
00745         max_entry_func();
00746 
00747         //check buffer size
00748         if (*pusRetsize < sizeof(CAN_INTERFACE_READ))
00749                 max_exit_func(ERR_WRONG_NUMBER_OF_RETURNS);
00750         
00751         //check if there are messages in the buffer
00752         parameter.Error = max_get_buffer_status(parameter.hBuf[0], &ulValid, &ulFree);
00753         if (ulValid >= sizeof(CAN_INTERFACE_READ))
00754         {
00755                 //limit read size to max. available data
00756                 if ((ULONG)*pusRetsize > ulValid)
00757                         *pusRetsize = (USHORT)ulValid;
00758                 //align read size to multiples of sizeof(CAN_INTERFACE_READ)
00759                 ulSize = (ULONG)*pusRetsize / sizeof(CAN_INTERFACE_READ);
00760                 ulSize *= sizeof(CAN_INTERFACE_READ);
00761 
00762                 parameter.Error = max_get_buffer(parameter.hBuf[0], MAX_BUFFER_MOVE_ABS, &ulSize, (void*)prcCanMsg);
00763                 *pusRetsize = (USHORT)ulSize;
00764         }
00765         else
00766         {
00767                 *pusRetsize = (USHORT)0;
00768         }
00769 
00770         if (parameter.Error != ERR_OK)
00771                 max_clear_error();
00772         
00773         max_exit_func(parameter.Error);
00774 }
00775 
00776 
00777 //*****************************************************************************
00778 // Read1
00789 //*****************************************************************************
00790 #pragma argsused
00791 void MAXEXPORT Read1(USHORT *pusLength, void *pIn, USHORT *pusRetsize, CAN_INTERFACE_READ *prcCanMsg)
00792 {
00793         ULONG ulValid, ulFree, ulSize;
00794         max_entry_func();
00795         
00796         //check buffer size
00797         if (*pusRetsize < sizeof(CAN_INTERFACE_READ))
00798                 max_exit_func(ERR_WRONG_NUMBER_OF_RETURNS);
00799 
00800         //check if there are messages in the buffer
00801         parameter.Error = max_get_buffer_status(parameter.hBuf[1], &ulValid, &ulFree);
00802         if (ulValid >= sizeof(CAN_INTERFACE_READ))
00803         {
00804                 //limit read size to max. available data
00805                 if ((ULONG)*pusRetsize > ulValid)
00806                         *pusRetsize = (USHORT)ulValid;
00807                 //align read size to multiples of sizeof(CAN_INTERFACE_READ)
00808                 ulSize = (ULONG)*pusRetsize / sizeof(CAN_INTERFACE_READ);
00809                 ulSize *= sizeof(CAN_INTERFACE_READ);
00810 
00811                 parameter.Error = max_get_buffer(parameter.hBuf[1], MAX_BUFFER_MOVE_ABS, &ulSize, (void*)prcCanMsg);
00812                 *pusRetsize = (USHORT)ulSize;
00813         }
00814         else
00815         {
00816                 *pusRetsize = (USHORT)0;
00817         }
00818 
00819         if (parameter.Error != ERR_OK)
00820                 max_clear_error();
00821         
00822         max_exit_func(parameter.Error);
00823 }
00824 
00825 
00826 //*****************************************************************************
00827 // main
00833 //*****************************************************************************
00834 void main ()
00835 {
00836         // the PDT-flags determine the task-type and
00837         // information how the data and parameter range are allocated
00838         
00839         //set flags for task type
00840         rcPDT.rcHead.usFlags         = MAX_TI_TASK | MAXPDT_PARAMETER_IN_PROG;
00841         
00842         // interrupt source
00843         if ((rcPDT.rcHead.usFlags & 0x0003) == MAX_TI_TASK)
00844                 rcPDT.rcHead.usInterrupt     = MAX1_IRQ_TIMERC;
00845         else
00846                 rcPDT.rcHead.usInterrupt     = 0;
00847         
00848         // the program number identifies the program uniquely
00849         rcPDT.rcHead.usProgNo        = PROGRAMM_NUMBER;
00850         
00851         // number of global task procedures in the PDT
00852         rcPDT.rcHead.usProcedures    = (sizeof(rcPDT) - sizeof (MAX_PDT_HEAD)) / 4;
00853         
00854         // the following lines are just for documentation and information purpose
00855         rcPDT.rcHead.ucType          = 1;   // always !
00856         rcPDT.rcHead.ucSize          = sizeof(MAX_PDT_HEAD);
00857         rcPDT.rcHead.cVersion        = VERSION;
00858         rcPDT.rcHead.cRevision       = REVISION;
00859         rcPDT.rcHead.ucCPU           = MAX_CPU486;
00860         rcPDT.rcHead.ucCoProc        = _NOCOPROC;
00861         rcPDT.rcHead.ucLanguage      = MAXRT_LANGUAGE_C;
00862         rcPDT.rcHead.ucProgType      = 0;   // not used
00863         rcPDT.rcHead.ulRes1          = 0;
00864         rcPDT.rcHead.ulRes2          = 0;
00865         rcPDT.rcHead.ulHyperAdr      = 0;   // feature not available yet
00866         
00867         // address and size of the tasks data range
00868         // only when MAXPDT_DATA_IN_PROG is set in PDT-flags
00869         rcPDT.rcHead.ulDataAdr       = 0;
00870         rcPDT.rcHead.ulDataSize      = 0;
00871         
00872         // address and size of the tasks parameter range
00873         // only when MAXPDT_PARAMETER_IN_PROG is set in PDT-flags
00874         rcPDT.rcHead.ulParAdr  = max_get_physical_addr(&parameter) + sizeof(MAX_TDT_TYPE);
00875         rcPDT.rcHead.usParSize = sizeof(parameter) - sizeof(MAX_TDT_TYPE);
00876         
00877         // initialize global procedure addresses in PDT
00878         rcPDT.main_proc        = MainProc;
00879         rcPDT.auto_init        = AutoInit;
00880         rcPDT.Start            = Start;
00881         rcPDT.Stop             = Stop;
00882         rcPDT.Read0            = Read0;
00883         rcPDT.Read1            = Read1;
00884         rcPDT.Write0           = Write0;
00885         rcPDT.Write1           = Write1;
00886         
00887         // transfer PDT information to the OsX
00888         max_init_program ((MAX_PDT_HEAD*)&rcPDT);
00889 }

24 Sep 2008SORCUS Computer GmbH