Because of the Thanksgiving holiday in the U.S., TI E2E™ design support forum responses may be delayed from November 25 through December 2. Thank you for your patience.

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.

TPS92682-Q1: parity bit calculation for SPI communication question

Part Number: TPS92682-Q1

Hi everyone!

I'm started firmware development from communication with TPS92682 and did not understand one moment with parity calculation. As I can see from datasheet, it has to be calculated from CMD, address and data bits. I guess that when reading, it's being calculated from address field, and when writing - from data field. Successfully tried to read and write some registers, and started to write an initialization routine.

But, when tried to reset all register contents using 0x26 address and 0xC3 command, I noticed that it does not reset, but sent me SPE bit. 

I also tried another registers with this value, and get same issue with 0x1C reg. Also tried to change value and register combination. Get same result with 0x1B (reg) - 0xC4 (val), and some others.

My question is, how the parity bit should be calculated correctly? I didn't get an algorithm from the received results.

  • Add to Phrasebook
    • No word lists for Arabic -> Russian...
    • Create a new word list...
  • Copy
  • Hello Vadym,

    When it's sending you a SPE bit that means that you have an error in your SPI communication.  When you are sending a command of either a read or a write to the part you have to do your own calculation on the parity bit. 

    If you are getting an error then you are having an issue with you command and please see section 7.5.4 to see of the possible error and check your SSN, SCK and MOSI to verify that it satisfy the communication protocol.

    Thanks Tuan

  • Hi Tuan!

    It seems that SPI protocol have been set correctly, and the issue is in incorrect parity bit calculation.

    Today I moved forward a little bit, and now I have at least correct algorithm to calculate parity bit for write commands. But, surprisingly, it does not work for read commands! See there:  The last variant is for read operation, and parity bit has to be 0.

    Why does this happens?

  • Hi Vadym,

    We know that the TPS92682 SPI communication works correctly and we do not have any of this issue with other users.  Please verify your SPI interface with the data sheet again. 

    Thanks Tuan

  • I have double checked SPI connection with logic analyzer, and everything seems to be ok.

    My question is: how to calculate parity bit in correct way? If you have software example - it will be nice. I have an ability to check it, and if there are some issues on my side, it will not work.

  • I made an example to check all values which may be written to a register, and here is results.

    You may see implementation of data transmission functions below in "code"section.

    /*!****************************************************************************
    * @brief    Write data to register
    */
    eDrvError writeReg(uint8_t addr, uint8_t data){
        eDrvError exitStatus = drvUnknownError, drvExStatus;
        uint8_t rxData[TRANSACTION_BYTES], txData[TRANSACTION_BYTES];
        
        //Compose command bit, address and parity bit
        txData[0] = composeCmdByte(CMD_BIT_WRITE, addr, data);
        txData[1] = data;
        //Perform transaction with received packet checking
        hw_wrap_spiTxRx(txData, rxData, TRANSACTION_BYTES);
        drvExStatus = hw_wrap_spiTxRx(txData, rxData, TRANSACTION_BYTES);
        if(drvExStatus == drvNoError){
            txData[0] = txData[0] >> PARITY_BIT_POS;
            if(((rxData[0] & ((~SPI_ERROR_BIT) & BYTE_MASK)) == txData[0]) && (rxData[1] == txData[1]) && ((rxData[0] & SPI_ERROR_BIT) == 0)){
                exitStatus = drvNoError;
            }else if((rxData[0] & SPI_ERROR_BIT) != 0){
                //TO DO: implement errors proccessing
                exitStatus = drvHwError;
            }
        }
        
        return exitStatus;
    }
    
    /*!****************************************************************************
    * @brief    Compose command byte of cmd bit, address and parity bit
    * @param    Commmand bit
    * @param    6-bit address
    * @param    Data-to-transmit byte
    */
    uint8_t composeCmdByte(uint8_t cmd, uint8_t addr, uint8_t data){
        uint8_t cmdByte, parity;
        
        //Compose command byte
        cmdByte = ((addr & ADDRESS_MSK) << PARITY_BIT_POS) | (cmd << CMD_BIT_POS);
        //Calculate parity bit
        parity = (~(addr ^ data ^ cmd)) & LSB_MASK;
        
        return cmdByte |= parity;
    }

    /*!***************************************************************************** @brief    Write data to register*/eDrvError writeReg(uint8_t addr, uint8_t data){    eDrvError exitStatus = drvUnknownError, drvExStatus;    uint8_t rxData[TRANSACTION_BYTES], txData[TRANSACTION_BYTES];        //Compose command bit, address and parity bit    txData[0] = composeCmdByte(CMD_BIT_WRITE, addr, data);    txData[1] = data;    //Perform transaction with received packet checking    hw_wrap_spiTxRx(txData, rxData, TRANSACTION_BYTES);    drvExStatus = hw_wrap_spiTxRx(txData, rxData, TRANSACTION_BYTES);    if(drvExStatus == drvNoError){        txData[0] = txData[0] >> PARITY_BIT_POS;        if(((rxData[0] & ((~SPI_ERROR_BIT) & BYTE_MASK)) == txData[0]) && (rxData[1] == txData[1]) && ((rxData[0] & SPI_ERROR_BIT) == 0)){            exitStatus = drvNoError;        }else if((rxData[0] & SPI_ERROR_BIT) != 0){            //TO DO: implement errors proccessing            exitStatus = drvHwError;        }    }        return exitStatus;}
    /*!***************************************************************************** @brief    Compose command byte of cmd bit, address and parity bit* @param    Commmand bit* @param    6-bit address* @param    Data-to-transmit byte*/uint8_t composeCmdByte(uint8_t cmd, uint8_t addr, uint8_t data){    uint8_t cmdByte, parity;        //Compose command byte    cmdByte = ((addr & ADDRESS_MSK) << PARITY_BIT_POS) | (cmd << CMD_BIT_POS);    //Calculate parity bit    parity = (~(addr ^ data ^ cmd)) & LSB_MASK;        return cmdByte |= parity;}

  • Actually this helped and resolved my issue:

    parity = (~getParity((~(addr ^ data ^ cmd)) & BYTE_MASK)) & LSB_MASK;

    Where getParity() function is following:

    uint8_t getParity(uint8_t n){ 
        uint8_t parity = 0;
        
        while(n){
            parity = !parity;
            n = n & (n - 1);
        }
        
        return parity;
    }

    It isn't obvious from datasheet that I have to calculate the parity of one's in byte from XNOR result, and I get this result by guessing. I hope this answer will help somebody else.

  • Hello,

    I am glad to hear you have resolved your issue.

    Thanks Tuan