This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CRC Errors using BISS-C feature of TMDXIDDK379D Design Drive Kit

Other Parts Discussed in Thread: CONTROLSUITE

I am getting CRC Errors on every transmission when interfacing to a Renishaw RA32BEA100B30A 32 bit absolute encoder with BISS interface. I seem to be getting position data though because I can rotate the encoder and watch the data go from min to max through one revolution and the reading is stable when stopped. That is with estop commented out, otherwise halts each time through loop.

biss.h  settings:  Biss_Position_Bits=32, ...CRC_Bits=6, ...CD_Interface=0, others are default. Biss clock freq should be 2 MHz with default divider 25.

Encoder connections: +/- MA to +/- CLK of kit, +/- SLO to +/- DATA of kit, + to +, - to -.

CCS v6.1.2.0015,  Control Suite section TMDSIDDK_v2.0,  IDDK_HwDevPkg_r2.2.1,  XDS100v2.

Please advise if I am using wrong settings or if there is a known issue with workaround or what additional information I can provide.

Thanks for your help,

Brent Andress

  • Hi Brent,

    Good to know that you are able to receive the data properly - which means that IDDK is able communicate to the Encoder.
    Regarding CRC errors - there could be multiple reasons. Can you check the following?

    - Can you check the polynomial used for CRC computation inside the encoder? You need to make sure the encoder and IDDK s/w use the same polynomial. Default ploynomial in example code is 0x03.

    - Can you share the data received, expected and actual CRC values?

    -Bharathi.
  • Hi Brent,

    Do the following other two major defines from bissc.h match your encoder:

    #define BISS_SCD_CRC_NBITS_POLY1       6
    #define BISS_SCD_CRC_POLY1             0x03   //x^6 + x + 1 (inverted output) 1000011

    (especially the polynomial)

    These are often very encoder specific.


    Thank you,
    Brett

  • Hi Bharathi,
    Thanks for your response.
    The encoder CRC is 6 bit and polynomial for position, error and warning is x^6 + x + 1, msb first and inverted.
    I set a breakpoint in the bissc_ receivePosition function at 'crcResult ==' and found it is always 0xFFFF. bissc_data_struct.scd_crc looks good so the equals test always fails. Up a line at numWordsPosCrc as I float over input vars I get 6 for position bits so result should be 2 but numWordsPosCrc is 0. This is one of the inputs to PM_bissc_getCRC() and may be why result fails. Also up 2 lines at scdBitsParsed I get 2 when it should be greater than 8.
    Could I have an incorrect or missing math setting that is causing computations to be wrong?
    -Brent
  • Hi Brent,

    So CRC polynomial is correct. No issues with that.
    why is the position bits set to 6? I think, you have already set to 32 in biss.h, correct?
    I think, issue is something to do with this - please double check/share values of positionBits, numWordsPosCrc, scdBitsParsed?
    I guess - you are receiving the data correctly, somewhere the CRC calculation is going wrong.

    -Bharathi.
  • Hi Brett,
    Yes, they match.
    I'm getting wrong math results, see above response. Is there a particular math setting needed for the biss module, fpu, tmu, 2nd core, etc?
    Thanks,
    Brent
  • Brent,

    No need for 2nd core and tmu etc. Can you look the questions I mentioned in previous post?

    -Bharathi.
  • Bharathi, I have not been able to identify why positionBits, numWordsPosCrc, scdBitsParsed seem to be overwritten with wrong values. I did notice that the Lika encoder, for which the bissc routine is configured by default, is an 18 bit encoder with 6 bit CRC. The positionBits is set for 24 for that encoder. So I changed the positionBits for the 32 bit Renishaw encoder to 38 (32 + 6). I now get certain encoder positions near the maximum count that pass the CRC check but it is only when the CRC value is 0x28, all others appear to fail. Does this give you any insight into what may be the problem?
    Thanks, Brent
  • Brent,

    You seem to do the right thing in configuring the 32 bits for position and 6 bit crc.
    Can you check all the parameters to the CRC function call?
    uint16_t PM_bissc_getCRC(uint16_t input_crc_accum, uint16_t nBitsData, uint16_t nBitsPoly, uint16_t * msg, uint16_t *crc_table, uint16_t rxLen);
    Particularly the rxLen - it should match the number of bytes of data for CRC calculation.
    It would be great if you can share some data - all the parameters being passed to this function and expected and actual CRC values.
    I do understand why  positionBits, numWordsPosCrc, scdBitsParsed are incorrect in your case.
    Will you be able to share the project?

    -Bharathi.

  • Bharathi,
    Thanks for your help. I have some data to share below, the parameters passed to the PM_bissc_getCRC() function and 3 extra:
    positionBits, ...NBITS_POLY, .scd_raw, numWordsPosCRC, crcResult, .sdc_crc, mask.
    6, 6, 3064804805, 0, FFFF, 14, FFFF
    6, 6, 3065393132, 0, FFFF, 14, FFFF
    6, 6, 3065208307, 0, FFFF, 14, FFFF
    6, 6, 3065476565, 0, FFFF, 14, FFFF
    6, 6, 3065156851, 0, FFFF, 28, FFFF
    6, 6, 3065306349, 0, FFFF, 28, FFFF
    6, 6, 3065378511, 0, FFFF, 28, FFFF
    6, 6, 3065393132, 0, FFFF, 28, FFFF
    The first 4 sets are read at breakpoint at "if(crcResult ==..." and the last 4 sets are read at a breakpoint at first line in the true portion "bissc_data_struct.scd_error =...". I presume .scd_crc is actual crc received and crcResult, which is the output of the getCRC function that we passed the params to is the expected caculated value. It looks like rxLen is always 0 and doesn't match the number of bytes of data in .scd_raw.
    I will share the project if you explain how I should do that. It is the default ControlSuite project with a few inits changed: #define BUILDLEVEL LEVEL3, CURRENT_SENSE SD_CURRENT_SENSE, BISSC_FREQ DIVIDER 50, ...CD_INTERFACE 0, BISS_POSITION_BITS 38, BISS_POSITION_CRC_BITS 6. RS, LS, Poles have been changed to match the PMSM motor with the BISS encoder on it.
    In case its relevant, I had some problems initially getting the debugger to update the Expressions window before I could build and run all the levels of the development kit. Had to delete cache files and delete debugger config files, etc. to finally get it to work.
    Thanks again,
    -Brent
  • Hi Brent,

    After looking at the code, it appears that the current software has a 30-bit position data limit.  The GetBits function and the biss_data_struct.scd_raw element would be the main troublemakers because they are 32bit data types.

    We will work to correct this in a future release of Position Manager within controlSUITE.

    However, I believe you can edit the bissc_receivePosition function within bissc.c to workaround most (if not all) of the problem.  I'm thinking something like the below.  Note that this would only allow you to get to 32 bit encoders (because then bissc_data_struct.position becomes a limiting factor).  Also note that I have not tested the below code - it is instead meant to give you an idea of what would be needed - largely because I don't have an encoder that has this much resolution handy :).

    uint16_t bissc_receivePosition(uint16_t positionBits, uint16_t crcBits)
    {
        uint16_t scdBitsParsed = 1;  //start with 1, we don't need to parse the start bit
        uint16_t crcResult = 0xFFFF;
        uint16_t mask = 0xFFFF;
        uint16_t receiveSuccessful = 0xFFFF;
        uint16_t numWordsPosCrc = 0;
        uint64_t scdRawWorkaround = 0;

        if(bissc_data_struct.cd_status == 1)
        {
            //if CD stream is active, receive CDS bits
            bissc_data_struct.cds_stream = bissc_data_struct.cds_stream << 1;
            bissc_data_struct.cds_stream |= PM_bissc_getBits(1, scdBitsParsed, SPI_FIFO_WIDTH);
        }
        scdBitsParsed++;  //we've now parsed the CDS bit (or didn't need to)

        //CRC is run on position + E + W, parse all these bits as one
        scdRawWorkaround = PM_bissc_getBits(positionBits+2-16, scdBitsParsed, SPI_FIFO_WIDTH)<<8;
        scdRawWorkaround = scdRawWorkaround<<8;   // may not NEED to split into two shifts
        scdBitsParsed = scdBitsParsed + positionBits + 2 - 16;

        scdRawWorkaround = scdRawWorkaround + PM_bissc_getBits(positionBits+2, scdBitsParsed, SPI_FIFO_WIDTH);
        scdBitsParsed = scdBitsParsed + 16;  //positionBits + E + W

        bissc_data_struct.scd_crc = PM_bissc_getBits(crcBits, scdBitsParsed, SPI_FIFO_WIDTH);

        //change the amount of words the CRC will run based on the amount of bits
        numWordsPosCrc = ((positionBits+2)/8)+1;

        crcResult =  PM_bissc_getCRC(0, positionBits+2, BISS_SCD_CRC_NBITS_POLY1, (uint16_t *)&scdRawWorkaround, bissCRCtableSCD, numWordsPosCrc);

        mask = (1 << crcBits) - 1;

        if(crcResult == ((~bissc_data_struct.scd_crc) & mask))
        {
            //crc was correct, so lets populate the following
            bissc_data_struct.scd_error = (~scdRawWorkaround) & 0x00000001;
            bissc_data_struct.scd_warning = ((~scdRawWorkaround) & 0x00000002) >> 1;
            bissc_data_struct.position = scdRawWorkaround >> 2;
            receiveSuccessful = 1;
        }
        else
        {
            receiveSuccessful = 0;
            bissc_data_struct.crc_incorrect_count++;
        }

        return(receiveSuccessful);
    }

    Hopefully this helps,
    Brett

  • Other thoughts based on your results:

    1. If you're debugging your setup with the complicated IDDK code, I might recommend starting with the simpler bissc example project.  It can be found at the below.  You can then use what you've learned and put it into the IDDK project once you get everything right.
      \controlSUITE\libs\app_libs\position_manager\

    2. Something odd is going on or I'm misinterpreting the data you wrote (in your 15Apr 10:38PM CST post).  For example, if you've set BISS_POSITION_BITS to 32 then numWordsCrc should not end up as 0.

    3. Based on the code I put in my last post, you could follow the below process to help prove the code is working.
      1. put the scdRawWorkaround variable into the watch window and change its type to Hex or Bin by clicking in the watch window.  As you rotate your encoder and view the variable, you should see all the 32 bits flip.
      2. similarly, assuming a 6bit CRC, you should see all 6 of the .scd_crc variable's bits flip as you rotate.
      3. Next you can see if crcResult and bissc_data_struct.scd_crc match. 
      4. Etc.


    Let us know if you get stuck along the way.


    Thanks,
    Brett

  • Thanks Brett for the workaround code. I was able to get it working in the system test environment with no crc errors, but when I brought it into the main project I'm getting occasional errors. When I break at equivalence test (if (crcResult==...) I get good result every time. When I break in else section I can see crcs don't match. Continuous refresh shows crc_incorrect_count slowly climbing with no break points. It seems like something might be interfering with the bissc_receivePosition () .
    Thanks, Brent
  • Hi Brent,

    It is good that you were able to get the SystemTest example working.  (and I assume you weren't seeing crc_incorrect_count increment in this project)

    ===

    Keep in mind that, in the IDDK project, the encoder is getting queried for new position data at the ISR frequency (10KHz).  This means that if you are only seeing crc_incorrect_count slowly increase, the errors are actually quite rare. (and this explains the breakpoint behavior you are reporting)

    Some thoughts:
    1) Does the specification of your encoder enable speeds of 2MHz?  If not, I can see how a project with no noise (like SystemTest) may have worked while a noisier system might fail.
    2) Because of the above (or just because of noise in general), I might recommend trying to run the BiSS encoder interface at 1MHz to see what happens by increasing BISS_FREQ_DIVIDER. 
    3) How long is the cabling between your encoder from the IDDK board? 
    (it is theoretically possible that the time taken to do the encoder communication is long enough that meeting the 10KHz sampling time is no longer feasible.  I don't think this is what you are seeing though)


    Thank you,
    Brett

  • Hi Brett,
    The encoder is spec is .25 - 10 MHz, cable is about 4m.
    I ran it at .25, .5, and 1 MHz. The error rate seemed like a few per sec at 1 and 2 MHz with periods of several
    sec with no errors and bursts of several thousand per sec at .25 and .5 MHz. I calc 64us at 1 MHz and 108us at .5 MHz for comm cycle which would confirm higher error rates below 1 MHz for 10kHz sample time.
    I'm using an unsheilded adaptor using two 5" long twisted pairs to connect clock and data, 1 wire connects enc shield to gnd, with dsub on one end and sip strips on the other to connect encoder to M12 on IDDK. I'm wondering if I need to improve the shielding.
    I notice there is some line delay compensation code in the endat module, once I eliminate the errors can I incorporate that feature for longer cable lengths?
    Thanks, Brent
  • Hi Brent,

    Notes:
    Delay compensation is directly built into the BiSS PM solution you are using.  Do note that, while the PM solution itself can handle high frequency at long cable lengths, the cable length will still have an effect on the time between when the C2000 sends out clocks and begins to receive data.  As a result, latency and back-to-back sampling capabilities are effected by longer cable lengths (there is a transit time, if you will).

    Thoughts on experiments:

    • Noise may very well be part or all of the problem and better shielding may very well help this.
      (it is odd that reducing the clock frequency is increasing the rate of problems; so this may not be all there is to your issue)
    • Just to confirm, when you run the SystemTest project, do you ever see any errors at any of the BISS_FREQ_DIVIDER choices that you experimented with?
    • The big difference between SystemTest project and the IDDK project is that the IDDK project is now imposing a 10kHz limit on the transaction.
      • Assuming that the SystemTest project works fully, I wonder what would happen if the PWM/ISR frequency was reduced to 5kHz.  The IDDK software will then only try to get new data from the encoder at half the speed it is currently.  This will provide more headroom for the system.
        (I'm also wondering if the workaround, and its usage of 64bit variables, has increased the amount of cycles being run in the bissc_receivePosition function - optimizations could be made in the workaround if desired)
      • You may want to experiment with increasing the frequency of the BiSS transaction - maybe to ~3-4MHz.  The rationale here is similar to the experiment above. 


    Thank you,
    Brett

  • Brett, thanks for the quick response.

    The system test project works with no errors at 2 MHz. I'll try some other frequencies soon.

    I increased the frequency of the  IDDK project to 3, 4, 5, 6 and 8 MHz. The crc error rate went down steadily as I went to 6 MHz. At 8 MHz there was huge increase in error rate.  I changed freq back to 2 MHz and set breakpoint at CRC failure section and noticed that about 2/3 of the time the scd_crc was 0 and the crcResult was normal. The rawWorkaround would have correspondingly large  strings of 0s toward the lsb.

    I'll send result of 5kHz update rate soon.Thanks, Brent.

  • Brett,

    Here's some more info. Biss System Test works with no errors from 250kHz to 7MHz. Substantial amount of CRC errors starting at 8MHz.

    IDDK project shows similar error rate at 10kHz, 5kHz and 1kHz pwm/sampling rate.

    Thanks for your continued help, Brent 

  • Brent,

    I'll continue to brainstorm with some of the members in my team.

    When running BiSS on the IDDK project, are you also running the motor?  Is HV DC power connected?  Are there positions in the encoder's physical range which demonstrate higher-error rates?

    FYI: the PM interface on the device will be able to run at a maximum speed of 8MHz (as mentioned in the documentation) - so what you are seeing is expected.


    Thank you,
    Brett

  • Hi Brett,

    Good news. I have the biss-c code working in the IDDK project without errors. The residual errors I was seeing was apparently due to a corrupted debug configuration file which I found was causing glitches when I went back to run the QEP module. I am going to start tuning the new motor with the biss-c feedback. I may need some help with that if I get stuck but I consider the biss-c interface assistance complete.

    Thank you so much for all your help and thanks to Bharathi as well,

    Brent

  • Hi Brent,

    That's great news.

    By debug configuration file, do you mean the target configuration .ccxml? 
    (just trying to better understand in case this is to come up again)


    Thank you,
    Brett