Jump to content

As of July 17, 2015, the LabJack forums here at forums.labjack.com are shut down. New registrations, topics, and replies are disabled. All forums are in a read-only state for archive purposes.

Please visit our current forums at labjack.com/forums to view and make new posts. To post on the current forums, use your labjack.com login account. Your old LabJack forums login credentials have been retired. There are no longer separate logins for labjack.com and LabJack forums.


Photo

Segmentation fault on LJUSB_WRITE when trying to use SPI

UE9 SPI

  • Please log in to reply
4 replies to this topic

#1 francoisdt

francoisdt
  • Members
  • 12 posts

Posted 11 June 2015 - 07:30 AM

Greetings, 

 

I'm trying to send SPI command through UE9, with a program written in C++, but sadly it crashes during execution during the call of LJUSB_WRITE. Since it's a straight seg fault on a function I don't have control on, I don't really have a clue on what could be the cause. Here is a code snippet I used : 

 

  int NumSPIBytesToTransfer = 2;
  uint8 NumSPIWords = (uint8)ceil(NumSPIBytesToTransfer/2);
  uint8 sendBuff[16];
  int checksum = 0;
  int sendChars;
    

  sendBuff[1] = (uint8)(0xF8);
  sendBuff[2] = (uint8)(4+NumSPIWords);
  sendBuff[3] = (uint8)(0x3A);
  sendBuff[6] = (uint8)(0x83); //10000011
  sendBuff[7] = (uint8)(256); //Clock frequency
  sendBuff[8] = (uint8)(0); // Reserved 
  sendBuff[9] = (uint8)(_CSPinNum);
  sendBuff[10] = (uint8)(_CLKPinNum);
  sendBuff[11] = (uint8)(_MISOPinNum);
  sendBuff[12]= (uint8)(_MOSIPinNum);
  sendBuff[13] = (uint8)NumSPIBytesToTransfer;

  /*****************TEST***********************/
  sendBuff[14] = (uint8)(0);
  sendBuff[15] = (uint8)(255);

  checksum = calculateChecksum16(sendBuff, 16);
  sendBuff[4] = (uint8)( checksum & 0xff );
  sendBuff[5] = (uint8)( (checksum / 256) & 0xff );
    
  sendBuff[0] = calculateChecksum8(sendBuff);


  //Sending command to UE9
  sendChars = LJUSB_Write(_hDevice, sendBuff, 16);



 

The functions I used to calculate the checksums where provided in a C code example for UE9, they are the following : 

 

BYTE calculateChecksum8(BYTE* buffer){
    int i; // For loops
    int temp; // For holding a value while we working.
    int checksum = 0;
    
    for( i = 1; i < 6; i++){
        checksum += buffer[i];
    }
    
    temp = checksum/256;
    checksum = ( checksum - 256 * temp ) + temp;
    temp = checksum/256;
    
    return (BYTE)( ( checksum - 256 * temp ) + temp );
}

// Calculates the checksum16
int calculateChecksum16(BYTE* buffer, int len){
    int i;
    int checksum = 0;
    
    for( i = 6; i < len; i++){
        checksum += buffer[i];
    }
    
    return checksum;
}

 

Maybe the problem could come from the eight byte of the sendBuff array, which is marked as "Reserved" in the documentation, so I put it to 0 since I didn't know what to do with it. 

 

If you have any idea of the origin of the problem, or maybe an implementation of SPI dialog with UE9, it would be very welcome :)



#2 LabJack Support

LabJack Support
  • Admin
  • 8677 posts

Posted 11 June 2015 - 01:48 PM

Passing an invalid/random handle to LJUSB_Write can cause a seg. fault, otherwise I don't see an issue with the command code you provided and the array you are passing. Make sure that your _handle variable's value is a valid handle from LJUSB_OpenDevice and that your code doesn't change the _handle value or close it before using your LJUSB_Write/Read calls. 

 

Based on your code, here is some code that I was able to run. If you wire your UE9's  FIO0 to FIO1, the below code's MISO line (FIO1) will read what you wrote out through the MOSI line (FIO0). Also, before running further code with your UE9, disconnect and reconnect it to your computer to put it back in its power up default state:

  HANDLE _hDevice;
  int NumSPIBytesToTransfer = 2;
  uint8 NumSPIWords = (uint8)ceil(NumSPIBytesToTransfer/2);
  uint8 _CSPinNum = 3;
  uint8 _CLKPinNum = 4;
  uint8 _MISOPinNum = 1; //FIO1
  uint8 _MOSIPinNum = 0; //FIO0
  uint8 sendBuff[16];
  uint8 recBuff[10];
  int checksum = 0;
  int sendChars = 0;
  int recChars = 0;
  int i = 0;

  //Opening first found UE9 over USB
  _hDevice = LJUSB_OpenDevice(1, 0, UE9_PRODUCT_ID);
  if(_hDevice == NULL)
  {
    printf("Couldn't open/find first found device\n");
    goto done;
  }

  sendBuff[1] = (uint8)(0xF8);
  sendBuff[2] = (uint8)(4+NumSPIWords);
  sendBuff[3] = (uint8)(0x3A);
  sendBuff[6] = (uint8)(0x83); //10000011
  sendBuff[7] = (uint8)(256); //Clock frequency
  sendBuff[8] = (uint8)(0); // Reserved
  sendBuff[9] = (uint8)(_CSPinNum);
  sendBuff[10] = (uint8)(_CLKPinNum);
  sendBuff[11] = (uint8)(_MISOPinNum);
  sendBuff[12]= (uint8)(_MOSIPinNum);
  sendBuff[13] = (uint8)NumSPIBytesToTransfer;

  /*****************TEST***********************/
  sendBuff[14] = (uint8)(56);
  sendBuff[15] = (uint8)(129);

  checksum = calculateChecksum16(sendBuff, 16);
  sendBuff[4] = (uint8)( checksum & 0xff );
  sendBuff[5] = (uint8)( (checksum / 256) & 0xff );
   
  sendBuff[0] = calculateChecksum8(sendBuff);

  //Sending command to UE9
  sendChars = LJUSB_Write(_hDevice, sendBuff, 16);
  if( sendChars < 16 )
  {
    if( sendChars == 0 )
      printf("Write error : write failed (%d)\n", errno);
    else
      printf("Write error : did not write all of the buffer\n");
    goto close;
  }

  recChars = LJUSB_Read(_hDevice, recBuff, 10);
  if( recChars < 10 )
  {
    if( recChars == 0 )
      printf("Read error: read failed\n");
    else
      printf("Read error: did not read all of the buffer\n");
    goto close;
  }
 
  //Display response bytes
  for(i = 0; i < 10; i++)
  {
    printf("%d\n", recBuff[i]);
  }

close:
    LJUSB_CloseDevice(_hDevice);
done:
    return 0;


#3 francoisdt

francoisdt
  • Members
  • 12 posts

Posted 12 June 2015 - 03:03 AM

Thank you for your answer :)

 

Okay, the issue mainly was that in the constructof of my class (in which I initialized the handle, and all the pins numbers), I also tried to store the calibration information in a class attribute by doing : 

if(getCalibrationInfo(_hDevice, &_caliInfo)<0){
  std::cerr<<"Could not retrieve calibration information"<<std::endl;
  goto close;
}

(With _caliInfo being of type ue9CalibrationInfo)

 

For some reason, this causes a seg fault at the next use of _hDevice. I solved the problem by getting the calibration info just before the function that needed it, and it worked. Will I have to repeat this every time I want to call a function recquiring calibration info? Isn't there a way to store it as a class attribute?

 

Also, are the functions I used to calculate the checksum a good way to do it? Because when I latter verify the checksum by calling normalChecksum8 on the received buffer, it doesn't correspond with the first cell of the buffer (though the result of calculateChecksum8 does).



#4 LabJack Support

LabJack Support
  • Admin
  • 8677 posts

Posted 12 June 2015 - 10:47 AM

You only need to read the calibration constants once after opening your UE9, and can store the calibration in your class. Storing it in class member variable should work. I'm not sure why exactly having getCalibrationInfo in your constructor is causing following usages of _hDevice to cause seg. faults. Check the value _hDevice before your getCalibrationInfo call and then before the code that causes the seg. fault to see if the value has change. If it has changed then something in the code is corrupting the handle value.

 

As for the checksums, most of the low-level functions (command/response) should use the extendedChecksum8 function in ue9.h/c which does the checksum of bytes 1 to 5. Basically if the low-level function has a Checkum8 and Checksum16 use the extended checksum functions, and if it only has a Checksum8 only, like SingleIO, use the normal checksum function.



#5 francoisdt

francoisdt
  • Members
  • 12 posts

Posted 15 June 2015 - 01:37 AM

Thank you again for your answer. My issue was that the code was always entering a goto that was closing the USB connection, even if everything went well. It's fixed and working properly now. 





Also tagged with one or more of these keywords: UE9, SPI

0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users