Measurement Studio for VC++

cancel
Showing results for 
Search instead for 
Did you mean: 

XNET Configuraring custom baud rates and timing parameters for CAN PXI-8513

I am using Visual C++ and attempting to use the nixnet visual C examples modified slightly to achieve a custom baud rate. Looking through the function prototypes I can see the macro for calculating an setting a custom baud.

 

nxAdvCANBaudRate_Set(TimeQuantum, TimeSeg0, TimeSeg1, SyncJumpWidth)

 

using this and the set property function I can get the code to execute but keep geeting the error that timing parameters are incorrect. I looked at MAX for CAN0 and can set the values manually to get my desired baud rate of 666.6667K, which are respectively 1,2,9,2,1 per the direct entry lists in MAX. I try to use these values to set the can0 port via software though and get the error.

I have tried setting the baud directly using the nxSetProperty using a fixed value 666666 and also tried 666667 , both also give an error invalid baud rate.

 

I was told by NI that I could program custom baud rates via software development using the XNET driver , but so far this doesn't seem to work.. Any Ideas what I am missing/ not seeing..?

 

I also have issues with the example data base "nixnet_example" It states in the software manual for XNET C API that the data base has a baud rate but implies it doesn't need to have that parameter..I find it does or database is read as invalid. Anyone know anything on this? Too, you can not seem to set the database value to a custom value. It only accepts what it knows as the "common" baudrates for CAN.  

 

Any help appreciated, Thanks!

0 Kudos
Message 1 of 14
(8,745 Views)

Hi,

 

I have looked for a while to try and find documentation on the nxAdvCANBaudRate_Set function that you mentioned, but I coudl not find anything.  What example program are you modifying?  

 

Looking through the xnet manual, changing the interface baud rate is discused in chapter 5, page 304 (for C).

 

http://www.ni.com/pdf/manuals/372840d.pdf

 

There is alos a Knowledge Base article that talks about setting nonstandard baud rates on xnet devices:

 

http://digital.ni.com/public.nsf/allkb/EED45251DB3B870786257736006A722B?OpenDocument

 

Also, both articles mention a few places where you have too add one to some things in hardware, have you tried this?

 

 

Ryan D.

 

 

Applications Engineer
National Instruments
0 Kudos
Message 2 of 14
(8,735 Views)

The macro comes directly from the nixnet.h  The example I am working with is directly from the NI examples loaded with the XNET 1.4

C:\Users\Public\Documents\National Instruments\NI-XNET\Examples\MS Visual C\CAN\CAN Signal Single Point Output

 

On a Win 7 x64 system Visual C++ Express 2010.

 

/***********************************************************************
   C O N S T A N T S   F O R   S E S S I O N   P R O P E R T I E S
***********************************************************************/

// Session properties (including runtime interface properties)

   // Macro to set nxPropSession_IntfBaudRate for an advanced CAN baud rate (bit timings)
   // If you pass a basic baud rate like 125000 or 500000, NI-XNET calculates bit timings for you
#define nxAdvCANBaudRate_Set(TimeQuantum, TimeSeg0, TimeSeg1, SyncJumpWidth) ( \
            (((u32)TimeQuantum) & 0x0000FFFF) | \
            (((u32)TimeSeg0 << 16) & 0x000F0000) | \
            (((u32)TimeSeg1 << 20) & 0x00700000) | \
            (((u32)SyncJumpWidth << 24) & 0x03000000) | \
            ((u32)0x80000000) )

 

I use that to define the value for  l_pSelectBaud variable as such..

 

u32 l_pSelectBaud= nxAdvCANBaudRate_Set(1,9,2,2);

 

then I set the property: ( of course having all parameters defined proior but for ease of discussion )

 

g_Status=nxSetProperty (g_SessionRef,nxPropSession_IntfBaudRate,sizeof nxGetPropertySize(g_SessionRef,nxPropSession_IntfBaudRate,PS),&l_pSelectedBaud);

 

 

I did add 1 to the values for timing parameters also so 1->2, 9->10, etc...I also tried subtracting one in case it was adding one . No go.. I think I may see that in order to get around the database baud rate I have to create the values in memory instead of in a DB file. I am working on creating signals and converting frames into those signasl via code, then writing those signal singlepoint values iterating through the list stored directly in memory. Not ideal, but all I could think to try.  I looked at the advanced baud rate info in the XNET manual but did not find a solution. I originally worked from the principals in the manual, but I got the same errors. I will have another look at it maybe I misssed something.

 

Thanks,

 

0 Kudos
Message 3 of 14
(8,729 Views)

Are you able to run the example VI at all in its original state?  With your modifications, are you able to change the timing at all, or do all combinations throw the same error?

 

Ryan

Applications Engineer
National Instruments
0 Kudos
Message 4 of 14
(8,721 Views)

In the original form, if I set our receiving equipment to match the example baud rate of 125K then it works fine.  The main issue is we must have a custom baud rate of 666.667K to test a custom project. I have tried setting the baud in the example code without modification of the code beyound changing the l_pSelectBaudRate, and in the example database  . This fails with the reported errors.

 

I also tried using the macro to set the timing parameters to get the desired baud rate. Using XNET, no combination has worked. I get the same error if I try any non-standard baud rate timing parameters. It seems if the baud rate is not in the standard list (i.e. 125000,250000, etc..) then the XNET library throughs an error that it is an invalid baud rate or invalid timing parameters.

 

At this time I am attempting a work around solution of programming the database direct to memory by using  ":memory:" , and setting clusters, frames and signals up manually in the code, then outputting direct from the CAN1 interface.

 

 

I do see under the older NI-CAN, that setting custom baud rate is simple, and have found references that it works well, unfortunately, the 8513 is XNET and I can't use the older code.

0 Kudos
Message 5 of 14
(8,718 Views)

I think I may see something that is a possible cause for the issue I am having.  The nixnet_example XML database has the parameter <fx:SPEED>  </fx:SPEED> which is the baud rate. If you use the database editor it represents say 250000 as 250 Kbaud , so the tag above looks like <fx:SPEED>250000 </fx:SPEED>. Okay,  if you set the tag directly to <fx:SPEED>666667 </fx:SPEED>, then save the database, then open it in the editor, instead of 666.667 kbaud you get <666667>.  It appears that the database functionality can not interpret anything it does not know, i.e. coded to recognize. So if it isn't in the array of baud rate values it's been told, i.e. 125000,250000,etc.. it will not accept the value. 

 

The limitation is either in XNET , or the 8513 , or both.  No matter what I try, it simply will not accept any custom baud rate. If it isn't in the array of "standard" values it knows, it errors with invalid baud rate. In my opinion, this is a bug, since it is explicitly represented as being able to program custom baud rates on the 8513 using XNET, and we purchased multiple cards on the basis that 666.667 kbaud was well within the capability of the XNET and 8513 card.

 

 

 

0 Kudos
Message 6 of 14
(8,716 Views)

Hi,

 

After digging and discussing this with some others, we have something for you to try.  when you pass the time quanta to the function, are you passing a small number, like 2?  Reading the documentation, this specifies that this number must be in increments of 125 (ns).  so if the number you where passing was 2, you would instead pass 250, if you where passing 3, pass 375, etc.  This would also explain the error you are getting fairly well, if it does say that your timing parameter is invalid.

 

Ryan

Applications Engineer
National Instruments
0 Kudos
Message 7 of 14
(8,703 Views)

I saw that but didn't quite follow it since in MAX it assigns the integer 2 for the time quanta. then off to the side it shows ( tq=0.125), I had tried 0.125 but wasn't thinking to actually indicate it as 125. I will give that a try. Although , I still would like to be able to set the baud rate in the database or by simply stating the cluster baud rate as an actual value , i.e 666667 , by direct entry into DB or from the nxSetProperty.

 

I will let you know what I find. Thanks,

0 Kudos
Message 8 of 14
(8,701 Views)

Is there anyone that can check me on my  VC++ code , I have it working sort off, but having trouble getting the right input values, and the using the Get Property function.

 

void main(int argc,char *argv[])
{
    
   // Declare all variables for function
   f64 i = 0;
   int l_typedChar;
   char *l_pSelectedInterface = "CAN1";
   char *l_pSignalArray = NULL;
   char *l_pSelectedDatabase = "nixnet_example";
   char *l_pSelectedCluster = "CAN_Cluster";
   char *l_pSelectedSignal1 = "CANEventSignal1";
   char *l_pSelectedSignal2 = "CANEventSignal2";
   f64 *l_pValueBuffer;
   u32 sessionbaud = nxAdvCANBaudRate_Set(125, 8, 1, 1);
   u32 PropertyValue;


// I THINK this is correct HEX interpretation from XNET manual chapter 5 page 305 to get baudrate of 666.667Kbaud

  u32 AdvBdRt=0x8114007D;
   
 


     // Display parameters that will be used for the example.    
   printf("Interface: %s\n",l_pSelectedInterface);
   printf("Database: %s\n",l_pSelectedDatabase);
   printf("Signal1: %s\n",l_pSelectedSignal1);
   printf("Signal2: %s\n",l_pSelectedSignal2);
   
   // Create the signal array to create the session
   l_pSignalArray = (char *) malloc(strlen(l_pSelectedSignal1) + strlen(l_pSelectedSignal2)+ 2);
   l_pSignalArray[0] = 0;
   l_pSignalArray = strcat(l_pSignalArray,l_pSelectedSignal1);
   l_pSignalArray[strlen(l_pSelectedSignal1)] = ',';
   l_pSignalArray[strlen(l_pSelectedSignal1)+1] = 0;
   l_pSignalArray = strcat(l_pSignalArray, l_pSelectedSignal2);
         
   // Create an xnet session for Signal Output
   g_Status = nxCreateSession (l_pSelectedDatabase,l_pSelectedCluster,l_pSignalArray,l_pSelectedInterface,nxMode_SignalOutSinglePoint,&g_SessionRef);
   if(nxSuccess != g_Status)
   {
      PrintStat(g_Status,"nxCreateSession");  
   }
   
   printf("Session Created Sucessfully.\n");

   g_Status=nxSetProperty (g_SessionRef,nxPropSession_IntfBaudRate,sizeof(u32),&AdvBdRt);
    if(nxSuccess != g_Status)
   {
      PrintStat(g_Status,"nxSetProperty");  
   }
    printf("Set Sucessfully.\n");

 

 

// GET TO HERE Fine BUT the GetProperty function doesn't return anything;

 

    g_Status=nxGetProperty(g_SessionRef,nxPropSession_IntfBaudRate,sizeof(nxPropSession_IntfBaudRate),&PropertyValue);
  if(nxSuccess != g_Status)
   {
      PrintStat(g_Status,"nxCreateSession");  
   }

 

Inttostring(PropertyValue);

 

 

void PrintStat(nxStatus_t l_status, char *source)
{
   char statusString[1024];
     
   if (nxSuccess != l_status)
   {  
     nxStatusToString (l_status,sizeof(statusString),statusString);
     printf("NI-XNET Status: %s",statusString);
     nxClear(g_SessionRef);
     printf("\nPress any key to quit\n");
     _getch();
     exit(1);
   }
}

void Inttostring(int k)
{
 char  buffer[200];
 int j;
 j += sprintf( buffer + j, "   Integer:   %d\n", k );
 printf("BaudRate: \n");
}

 

Any help pointing me in the right direction would be appreciated..Thanks

0 Kudos
Message 9 of 14
(8,694 Views)

Hi,

 

I have some things to check.

 

The first is regarding the hex number you create.  To me, you create it twice, and then use only one version.  The two variables AdvBdRt and sessionbaud seem like they should be identical.  Are they?

 

Next, looking through the manual I see in the nxGetProperty function, they recommend using the nxGetPropertySize function, can you confirm that you are getting the same output from teh function you are using?

 

Now, you say your nxGetProperty function does not return anything.  When you say return, are you talking about not returning a status, or not placing anything in the PropertyValue?  How are you verifying this?

 

After that call, you call a function InttoString.  Here you are type-casting your u32 to an int, which will change the value you see.  Is this how you are checking your functionality?

 

When you get a chance, let me know what your thoughts are.

 

Ryan

Applications Engineer
National Instruments
Message 10 of 14
(8,681 Views)