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.

Using the TPS65381 on the same spi bus as another chip

Other Parts Discussed in Thread: TMS570LS0332, HALCOGEN

Hi,

I am using the TPS65381 on a TMS570LS0332.  On the same bus I have an IO expander chip.

 

I have a task (running freeRTOS) that services the  TPS Q and A watchdog.  So on startup I initialize the TPS driver and tell the TPS chip to stay in the diagnostic state.  Then I start servicing the watchdog and once the fail count gets to 0 I tell it to go to the active state and then continue to service the watchdog.

This works fine when it is the only thing running.

If I add in code that initializes an IO expander on the same spi bus (but after that never touch the bus),  the first TPS call I make after that I have to make a few times until it goes through without failing and then the TPS task works OK.

It is failing the check in TpsIf_SendCommandOverSPI

 if (NO_ERROR
                        == BFU8_GET(u8SAFETY_STAT_4, BF_SPI_ERR_START,
                                BF_SPI_ERR_LENGTH))
                {
                    /*checking whether there were no errors in the previous SPI transfer phase*/
                    if ((MULTIBITKEY_SET
                            == BFU8_GET(u8SPIPreviousStatus,
                                    BF_MULTIBITKEY_START, BF_MULTIBITKEY_LENGTH))
                            && (0u
                                    == BFU8_GET(u8SPIPreviousStatus,
                                            BF_SPI_ERRFLAG_START,
                                            BF_SPI_ERRFLAG_LENGTH)))
                    {
                        blRetVal = TRUE;/*Sth is wrong with the previous SPI transfer*/
                    }
                    else
                    {
                        blRetVal = FALSE;
                        TPS_SendDebugText(ERROR,
                                "TpsIf_SendCommandOverSPI SPIPreviousStatus error",
                                (uint32) u8SPIPreviousStatus);
                    }
                }
                else
                {
                    blRetVal = FALSE;
                    TPS_SendDebugText(ERROR,
                            "TpsIf_SendCommandOverSPI SPI ERR  ",
                            (uint32) u8SAFETY_STAT_4);
                    TPS_SendDebugText(ERROR,
                            "TpsIf_SendCommandOverSPI  u8SPIPreviousStatus is",
                            (uint32) (uint32) u8SPIPreviousStatus);
                }

So it falls into the bottom else.  The value of u8SAFETY_STAT_4 is 0x4C, and the value of u8SPIPreviousStatus is 0xA4, which I think indicates an SDO error on the previous transmission.  Doesn't an SDO error mean that the output on the SDO pin doesn't match what it should be shifting out?

When I comment out initializing the IO expander, u8SPIPreviousStatus = 0xA0 and u8SAFETY_STAT_4  = 0x0C.

 

The simplified flow of my program is this:

 

- Create an executive task

- Run the scheduler, exec task starts

- Initialize TPS - returns no error (calls TPS_DriverInit and TPS_SetMCUSoftwareDebugMode)

- Initialize IO expander chip - This is the only thing outside of the TPS code that accesses the spi, it only sets a few registers and then is done.

- create a task for the TPS watchdog

- Exec tasks main is nothing but a sleep, so TPS watchdog task runs

- Call TPS_GetCurrentTPSDeviceState - This is where I see the behavior above.  Nothing else is accessing the spi at this point.  When I make the call to TPS_GetCurrentTPSDeviceState again, it passes with values of 0xA0, 0x0C, and after that it is OK. 

However, if I create another task which blinks a led through the IO expander at 1 Hz, then I see the same failure later in the code when the TPS code is trying to send the wdog answer, so it always fails.

I first started this in the Hercules forum, and from Anthony Seely

"Hi David,
If it is the SDO error then I would post on the automotive forum and ask the TPS team for help.
I did dig up earlier a few slides from a field apps engineer talking about false SDO errors that were triggered by clock activity while NCS was inactive (i.e. talking to another SPI device) but I wasn't able to find anything about this in a silicon errata on the TPS product folder.   So it may be something like you having pre-production silicon with this issue but it's cleaned up in the production silicon.   That's just speculation though - best to get the answer from the team directly responsible from the TPS65381.   They monitor the automotive forum.  But if you don't get an answer from there - I can try to get you a contact.

Best Regards,
Anthony Seely

"

I took out all of my error handling and acted as if all calls returned true.  The TPS chip seems to acknowledge my watchdog answers and responds correctly to all queries.  Is there a possible false error occurring?  Is there anything I can do besides ignoring the output from the TPS driver?

Thanks,

David

  • Hi David,

    Have you enabled the Diagnostic MUX output on the TPS65381? That is the only case I know of SDO conflicts. We have added the following statement to the TPS65381 Safety Manual Rev A and will add it for the next revision of the datasheet.

    SPI Interface Note: when enabling DIAG_OUT MUX while using SPI communication: the SDO is not in high
    impedance while NCS = High and DIAG_OUT MUX is enabled. Software or hardware modification may be
    required. For hardware modifications, check the SDO threshold level and drive capability if resistors are
    used to adjust the voltage level of SDO on the SPI bus.

    Have you checked with a logic analyzer or MSO that once the IO expander is enabled that it isn't causing timing differences either in the SPI physical signaling or that other SPI routines are not changing the SPI WD timing?

    - Scott
  • Hi Scott,

    I don't think I have diagnostic mux output enabled. To be sure I called TPS_DisableMUXDiagnostic() right after initialization but I see the same issue.

    It will take me a couple days, but I will get set up so I can take a look at the spi signals and see if they look as I would expect, or if they may be influenced by the spi accessing the io expander chip.

    Very quickly I took out my error checking, and things seem to work OK (although I haven't checked to see if all of my reads are actually done twice (they are in a loop)), but the Q and A watchdog seems to be serviced OK if I don't pay attention to the SDO error.

    Thanks,
    David
  • Hi David,

    I was just informed of some SDO issues on early revisions of the TPS65381 silicon.  Lets check and see if you have one of those.  Can you let me know what hardware you are doing this test on, ie a TI TPS65381 EVM, other HW development kit or your own PCB. 

    Second, can you read the electrical device revision informaiton from the TPS65381 you are using.  It is the Device Revision and ID register call DEV_REV and can be read with RD_DEV_REV command.  Alternatively you can let me know the lot trace code on the top side device symbolization.  It will be the numbers that are not TPS65381. 

    - Scott

  • Hi Scott,

    This is on my own PCB.

    The device revision is 0x30, device id 0x01
    The lot trace code is 43CQKDT

    - David
  • The device is a final production silicon revision so the SDO issues I had learned about should not be applicable except for the comment on using SPI with Diagnostic MUX output enabled. Please let us know when you get some more data on the signals and what is going on and we'll try to help.

    -Scott
  • Hi Scott,

    I have some more data, and I have outlined it below with some scope screen shots.

    A quick recap:

    - I have the TPS65381 on an spi bus that is also used by an IO expander chip using the TMS570LS0332.

    - The IO expander chip seems to work when it is on its own.  So does the TPS chip.  But when I have both of them run, I see an error.

    - I am using the spi in the polling mode (using spi 2).

    - The program flow  is:

    -- initialize the TPS chip through the TI driver and set it to stay in the diagnostic state

    -- initialize the IO expander chip (set some registers)

    -- Create two tasks, one for the TPS watchdog, one to blink an LED connected to the IO expander once a second.

    -- Once the TPS watchdog task is called, the first thing I do is check that the TPS chip is in the diagnostic state by calling TPS_GetCurrentTPSDeviceState from the TPS driver. This is in a while loop until it returns that it is in the diagnostic state (0x7)

    So, what I am seeing is that the first time it is called, I get an error on the spi transmission.  The second loop through it is OK.

    The function TPSGetCurrentTPSDeviceState makes two transmissions to the TPS chip.  The first is to query the device state, the second reads the Safety Stat 4 register.  This read shows an error.  You can see this in the first picture below

    Blue trace - this is the chip select for the IO expander chip.  I put a probe on this to make sure it wasn't going active during the transfer, and it isn't, it remains high.

    Green trace - data from the Hercules to the TPS chip

    Red trace - clock

    Yellow trace - data from the TPS chip to the Hercules

    The screen shot below is stepping over the function the second time, everything is OK in it.

     

     

    Finally, here is a screen shot if I don't do anything related to the IO expander chip, and only communicate with the TPS chip, I only call the function to read the dev state once here.

     

    I don't know why it thinks there is error in the transmission..it looks ok to me..do you see anything that doesn't look right?

     

    Thanks for your help,

    David

  • Hi David,

    There doesn't seem to be anything obvious to me at this point.  Our system engineer is out until next week.  I'll follow up with him as he knows a lot more about the internal monitoring of the SPI for faults and how the logic is actually implemented and should be able to give me more clues as to where to dig into finding the issue.

    - Scott

  • Hi Scott,

    Thanks for following up. We have several boards we are designing that rely on the TPS chip as an external watchdog in conjunction with the TI Hercules MCU to be safety certified, and we are in trouble if I can't get this working.

    Thanks,
    David
  • Hi David, can you provide a schematic of how the TPS65381 and the IO expander are connected to each other and the Hercules SPI. That might provide some insight as well. Thanks. Scott
  • Hi Scott,

    I can, but it needs to be in a private conversation because it is proprietary.

    Thanks,
    David
  • Hi David,

    A few follow up questions.  On the blue chip select scope shot we do not see any rising edges on the nCS which was documented as the IO expander output and I presume the nCS input to the TPS65381.  Our device needs to see the nCS rise after each SPI transaction to determine the end of the frame.  We start a frame on the nCS falling edge and to end it we need the rising edge or the device will not see this as a valid transaction. 

    Could you look at the nCS behaviour per 16 bit SPI transfer and see if there is a rising edge after every frame and when using the IO expander the nCS is left low for multiple frames. 

    Thanks,

    Scott

  • Hi Scott,

     

    I think I was unclear.  The blue trace is solely the chip select for the IO expander chip, and does not provide the chip select input to the TPS chip.  I included it in the scope capture because I was looking to see if perhaps it was being pulled low during a transfer to the TPS chip and that was causing the problem.

     

    I should be able to get a scope capture that includes the chip select for the TPS chip in the next couple of days.

     

    Thanks,

    David

  • Hi David,

    One other thing to look into I just learned from an unpublished draft app note from the TMS570 team is that if the SDO lines become to capacitiviely loaded you may also need to add a pull down on the SDO line to make sure the TPS65381 internal circuits that monitor the SDO output see the correct levels within the necessary timing. You may want to zoom in on the SDO line and see if due to what I assume is a large number of devices on the SDO that the timing might become off just enough for this internal feedback circuit to read the SDO levels wrong.

    The quote from the app note is "It is relevant that the SDI pin of the TPS65381 is connected to the SIMO pin of the Hercules device and the SDO pin of the TPS65381 is connected to the SOMI pin of the Hercules device. The connected pull-down resistor (i.e. 10k) between SDO and SOMI prevents the possible incorrect occurrence of SPI SDO error flags during a SPI communication."

    I'm checking with the Hercules team to see if I can post the draft version of the app note.

    Thanks, Scott
  • Hi Scott,

    I enabled pull downs through Halcogen, but I don't see a change in behavior. I'm working on getting scope shots which include the TPS chip select, I may have them later today or tomorrow.

    David
  • David,

    The key is the internal pull downs may not be enough to overcome the capacitive loading of many devices on the SPI bus.  The app note called for an external 10k ohm pull down in addition to the internal pull downs.  

    Attached is the draft version of the app note, keep in mind this was written with very early TPS65381 silicon and it still may not work in all cases but should be very helpful.  

    SPI Communication of Hercules Microcontrollers with TPS65381 DRAFT.pdf

    I'm trying to figure out a way to confirm the bug mentioned in this app note for version 1.1 of the TPS silicon was fixed but our normal set up is an SPI directly connected to our EVM so I have to find a way to blue wire a second SPI on and play with our GUI and the other SPI to get SPI traffic going on the SPI bus without setting the nCS to the TPS and see if the bug was in fact fixed or is still an errata that isn't documented.  This may take some time since we're an analog / power team not an embedded processor team. 

    - Scott

  • I'll see if the electrical guys can add the external pull downs and I will read the app note, thanks for passing it along.

    Thanks for your help,
    David
  • Hi Scott,

    After reading the document, the last note in it:

    NOTE: Due to a limitation the internal SPI error detection of the TPS65381 flags an SDO error on SPI frame occurrence, if the chip select signal is inactive high. This results in a SDO error flag in the first SPI frame of the next SPI transfer with the TPS65381. This SDO error flag needs to be ignored by the SPI master software.

    Seems to indicate that the SDO error flag just needs to be ignored if there is activity on the bus while the TPS CS is high (which I will constantly have). If that is the case, I can modify the TPS library that TI supplies to always suppress the error.

    I hate having to customize the library, but perhaps that is the solution.

    I will have the pull down resistor installed on my board tomorrow morning and will check if that solves the issue, but if not I will just ignore the error.
  • Hi David,

    That was comment that we will try to verify. That bug should have been fixed in the latest silicon, but we want to verify it. I hope to have a valid lab set up by end of the week to verify either the bug still exists or it was fixed as it was supposed to be. The TMS570 app note was written using the first revision of TPS65381 silicon and has not been updated to reflect the final silicon of TPS65381. The key difference would be if that last note applies or not in the final production released TPS65381 silicon which you are using. The external pull down will still be needed, assuming that is what is wrong with your set up and if the capacitive loading of the SPI violates the SDO timing of the internal self monitoring from TPS65381.

    - Scott
  • Thanks for the clarification.

    I had the pull down resistor added, with no change in the behavior.  I stepped through the TI TPS library and verified that the Hercules is correctly reading the data (0xA007) from the SPI bus.  I also verified that the TPS chip select is OK, and that the two chip selects aren't active at the same time.

    Thanks,

    David

  • Hi David,

    I tested the latest silicon of the TPS65381 (production version) yesterday by sending SPI frames by the device while the nCS was high and I never saw an SDO error in this test set up so at least from that testing I can confirm the bug mentioned in the app note for the TMS570 was fixed so I do not think that is the issue unless you have data showing otherwise making it SPI data dependent.  I was just using a SPI frame generating GUI tool TI has to seen several frames by the device while it was not selected then sending a single read command to the TPS65381 and looking in the Device Status Flag Byte Response at the SDO error bit to confirm it wasn't set.   

    Can you confirm the colors of the traces above.  I assume blue=nCS, Green = SDO, Red = SCLK, Yellow = SDI.  What is concerning is the slow fall time on the end of the first SPI frame on the green trace.  If that is SDO the internal circuitry may be seeing that last edge wrong.  Is there any chance to zoom in on that and get an accurate timing shot?

    - Scott

  • Hi Scott,

    Thanks for getting the test set up and checking.

    You are correct on the colors of the traces. I am travelling today, but should be able to get you a scope shot zoomed in on that to get a better look on Monday.

    Previously there was a pull up on the line, so after the response (0xA007) the line remained high and we were seeing the error, so that may make sense if the internal circuitry is expecting the line to be low but because of the slow fall time it reads high.

     

    The piece I don't understand is that if I don't communicate with the other chip on the spi bus, the trace looks the same but I don't see the SDO error.  Also, if I do back to back calls to the lib function to get the device state, the first pair shows an SDO error, but the second does not.  I will triple check this on Monday and see if I can get a nice capture on the scope.
     
    Thanks,
    David

  • Below are a couple more scope shots (with a 10K pull down).  I'm back in IL now, so getting that swapped out is more difficult, but I'll see what I can do.

    The traces should be the same colors as before ( blue=nCS, Green = SDO, Red = SCLK, Yellow = SDI)

     

    This is a close up of the end of the first transfer (a read of the device state register).  In case you can't read it, the time base is 2 us / div.

     

    I also took a shot that includes 4 transfers.  When the TI lib does a transfer, it also does a second transfer to read the safety stat 4 register.  So the shot below shows a read of the safety stat 5 register and the safety stat 4 register, then that sequence again.  You can see that the second time the two registers are read it does not show the SDO error, but the traces look the same in terms of timing and the fall time from the read to the safety stat 5 register.  I can get a closer shot of any part of the signal if it would help, I know this one is pretty far away but I wanted to include all of the transfers. Time base here is 20 us / div

     

     

    [EDIT] As I have been stepping through the TI lib and doing more analysis, I noticed that on the second transfer ( a read of safety stat 4) It is returning a value of 0x4C.  Which indicates

    Bit 2 - WD ERR - It doesn't surprise me that the wdog fail count is 7

    Bit 3 - MCU ERR - Not sure what is causing this or if it is an issue

    Bit[7:6] - Command Error - This concerns me.  I don't know what exactly a command error is, or if it is an artifact / related to the SDO error. 

    Thanks,
    David

  • Hi David,

    Interesting. I'll have to have some more discussions with folks who know the insides of the device in detail. Command error is normally something wrong in the command portion of the SPI frame, like calling a command that doesn't exist. MCU ERR is showing that there was a failure on the ERROR pin which must be monitoring for the signal from MCU safety mechanism that should either be giving out the low pusle for TMS570 mode or the PWM for other modes. This is described in the MCU ESM (Error Signal Monitor) section of the datasheet on page 5.4.1.15. If the code hasn't set this monitoring up it would likely be failing like the WD timer. Do you have the above 4 SPI transfer stored in a way that you could zoom in on each of the transfers so it is easier to see the clock & data and decode it manually?

    - Scott
  • Hi Scott,

    I have the error pin monitoring mode set to the MCU error signal low monitoring mode when I initialize the TPS device.

    Unfortunately one of the scope leads that was on the board came off, so I need to fix that, hopefully I can get to that today. I did go through one of the older shots and zoomed in to manually decode the traces. One thing that may be worth noting is that the transitions on the SDO line (from TPS to Hercules) occur at almost the exact time as the rising edge of the clock, while the SDI line (data from Hercules to TPS) is clearly at a stable level during the falling edge of the clock, which makes it much easier to read. I'm not sure if this could be contributing to the issue, but again, the timing and signals look the same when I haven't accessed the IO expander and I don't get the errors reported from the TPS.

    However, I decoded the signal, and also stepped through the TPS library to see what the Hercules chip is seeing, and they match.

    First transfer:
    SDI: 0xC000
    SDO: 0xA007

    Second transfer:
    SDI: 0xA500
    SDO: 0xA44C

    Third transfer:
    SDI: 0xC000
    SDO: 0xA007

    Fourth transfer:
    SDI: 0xA500
    SDO: 0xA00C

    As far as I can tell the commands are valid commands (with parity) to read the safety stat 5 register and the safety stat 4 register.

    Thanks,
    David
  • I thought it may be worth adding the following scope shot.  We have a second board (that uses the TMS570LS0332 as well) but this board does not have anything on the spi other than the TPS chip.  It is on SPI 2 as well, and all  of the TPS code is common between the two.  This has pull downs enabled in Halcogen, but no external pull down.  This is the same transfer sequence as all of the other scope shots, a read of safety stat 5 and then safety stat 4. I don't see the SDO error on this board and the library sees it as a valid transfer sequence and returns 0x7 as expected.

    David

    Blue - CS

    Green - Clock

    Red - Data Hercules to TPS

    Yellow - Data TPS to Hercules

  • Hi David,

    Could you try two experiments for us to try to narrow this down.  One theory may be the nCS timing to the SPI transfer, the other is the SDO error may depend on the SPI frame.  When I tried it in the lab our tool was limited to 8 bit SPI transfers and we assumed if there was an issue it would show on any SDO mis-match but that may not be the case.  So if you could try the following it would be helpful:

    1)  Board with SPI expander.  Extend the nCS timing greatly with respect to the actual SPI data.  If you can add a much longer delay from nCS going low until the SPI transfer and also extend the nCS going high after the SPI transfer we can rule out a timing issue due to the IO expander getting the nCS edges too close to the actual SPI frame.

    2) Board without SPI expander.  Can you send some of the same SPI frames that the board with the IO expander sends to other devices while nCS to TPS65381 is inactive (high)?  This board doesn't have the loading and works without extra SPI frames, if the device has an issue it should also show up on this board.  Let us know what the SPI data that isn't going to the TPS65381 is in terms of format so we can try to run something similiar by the device here if we need to.

    Thanks,

    Scott 

  • Hi Scott,

    1)  Board with SPI expander.  Extend the nCS timing greatly with respect to the actual SPI data.  If you can add a much longer delay from nCS going low until the SPI transfer and also extend the nCS going high after the SPI transfer we can rule out a timing issue due to the IO expander getting the nCS edges too close to the actual SPI frame.

    DS - I modified halcogen so the time from nCS going low to transmit start was as high as possible (3.2135 us) and the time from transmit end to nCS going high was 3.2 us.  The behavior is the same, see the scope shot  below.

    2) Board without SPI expander.  Can you send some of the same SPI frames that the board with the IO expander sends to other devices while nCS to TPS65381 is inactive (high)?  This board doesn't have the loading and works without extra SPI frames, if the device has an issue it should also show up on this board.  Let us know what the SPI data that isn't going to the TPS65381 is in terms of format so we can try to run something similiar by the device here if we need to.

    DS - I had to send that board back to our facility in MA, I should have it back Thursday or Friday and can run this.

     

    In the meantime, the data that goes to the IO expander is sent in 24 bit transfers.  I do this by sending 3 8-bit transfers back to back while holding the chip select for the device low.

    For a read - first byte - device opcode / read; second byte - address; third set of clock pulses is to clock in the data we want to read.

    For a write - first byte - device opcode / read; second byte - address; third byte - data to write

     

    Thanks,

    David

     

    Blue trace - data TPS -> hercules

    Green trace - data Hercules -> TPS

    Yellow trace - CS

    Red trace - clock

     

  • Hi @all,
    is there an update for this topic?
    We see exactly the same behaviour and so we are also interested to find a solution.

    Regards,
    Frank
  • Hi Frank,

    I haven't had a chance to try sending spi data out using a cs that isn't the TPS cs on the board that doesn't have anything else on the bus, I've had some other things come up I have had to look at.  Once I get that it should help tell us if it is a loading issue on the bus or if the TPS chip isn't monitoring the SDO line correctly.

    In the meantime, the workaround I have done is build the TPS library myself and comment out the error checking that the TPS driver does on a transfer, except that the most significant nibble is 0xA.  The change is in Tps_Interface.c.  I have attached the file I'm using so you can see what I have done.  Obviously it isn't ideal to ignore all of the error checking, but it has allowed me to continue on and I have the Q and A watchdog working fine.

    David

    Tps_Interface.c
    /**
     *  COPYRIGHT
     *  -------------------------------------------------------------------------------------------------------------------
     *  \verbatim
     *
     *                 TEXAS INSTRUMENTS INCORPORATED PROPRIETARY INFORMATION
     *
     *                 Property of Texas Instruments, Unauthorized reproduction and/or distribution
     *                 is strictly prohibited.  This product  is  protected  under  copyright  law
     *                 and  trade  secret law as an  unpublished work.
     *                 (C) Copyright Texas Instruments.  All rights reserved.
     *
     *  \endverbatim
     *  -------------------------------------------------------------------------------------------------------------------
     *
     *  ------------------------------------------------------------------------------------------------------------------
     *  FILE DESCRIPTION
     *  -------------------------------------------------------------------------------------------------------------------
     *         @file       TPS_Driver.c
     *         @version    2.1.0
     *         @component  TPS
     *         @module     TPS Library
     *         @generator  No Configuration
     *
     *         @brief      Interfacing API to directly send commands to the TPS device.
     *         @details    The TPS_Interface.c file provides the interface api's to\n
     *                     the TPS.It provides API to set,clear and verify the\n
     *                     registers of the TPS device.
     *
     *
     *---------------------------------------------------------------------------------------------------------------------
     * @author  Manoj
     *---------------------------------------------------------------------------------------------------------------------
     * Revision History
     *---------------------------------------------------------------------------------------------------------------------
     |Version       | Date        | Author           |    Change ID       | Description                 |
     |------------: |:-----------:|:----------------:|:------------------:|:----------------------------|
     |2.1.0         |  20Dec2012  | Manoj R          |    00000000000     | Initial version             |
     */
    /***************************************************************
     * INCLUDE FILES
     ****************************************************************/
    #include "TPS_Interface.h"
    #include "TPS_Priv.h"
    /*********************************************************
     * Local Functions prototypes
     **********************************************************/
    static boolean TpsIf_SendCommandOverSPI(uint16 u16Command, uint8* u8Data);
    
    /*********************************************************
     Defines / data types / structs / unions /enums
     **********************************************************/
    /** @var const TpsIf_COMMAND_t TpsIf_COMMAND[]
     *   @brief Commands
     *
     *   Tps command list.
     */
    
    static const TpsIf_COMMAND_t TpsIf_COMMAND[32] =
    {
        { RD_DEV_REV,               WR_COMMAND_NONE     },   /* 0x00: Tps_DEV_REV            */
        { RD_DEV_ID,                WR_COMMAND_NONE     },   /* 0x01: Tps_DEV_ID             */
        { RD_DEV_STAT,              WR_COMMAND_NONE     },   /* 0x02: Tps_DEV_STAT           */
        { RD_DEV_CFG1,              WR_DEV_CFG1         },   /* 0x03: DEV_CFG1               */
        { RD_DEV_CFG2,              WR_DEV_CFG2         },   /* 0x04: DEV_CFG2               */
        { RD_VMON_STAT_1,           WR_COMMAND_NONE     },   /* 0x05: Tps_VMON_STAT_1        */
        { RD_VMON_STAT_2,           WR_COMMAND_NONE     },   /* 0x06: Tps_VMON_STAT_2        */
        { RD_SAFETY_STAT_1,         WR_COMMAND_NONE     },   /* 0x07: Tps_SAFETY_STAT_1      */
        { RD_SAFETY_STAT_2,         WR_COMMAND_NONE     },   /* 0x08: Tps_SAFETY_STAT_2      */
        { RD_SAFETY_STAT_3,         WR_COMMAND_NONE     },   /* 0x09: Tps_SAFETY_STAT_3      */
        { RD_SAFETY_STAT_4,         WR_COMMAND_NONE     },   /* 0x0A: Tps_SAFETY_STAT_4      */
        { RD_SAFETY_STAT_5,         WR_COMMAND_NONE     },   /* 0x0B: Tps_SAFETY_STAT_5      */
        { RD_SAFETY_ERR_CFG,        WR_SAFETY_ERR_CFG   },   /* 0x0C: Tps_SAFETY_ERR_CFG     */
        { RD_SAFETY_BIST_CTRL,      WR_SAFETY_BIST_CTRL },   /* 0x0D: Tps_SAFETY_BIST_CTRL   */
        { RD_SAFETY_CHECK_CTRL,     WR_SAFETY_CHECK_CTRL},   /* 0x0E: Tps_SAFETY_CHECK_CTRL  */
        { RD_SAFETY_FUNC_CFG,       WR_SAFETY_FUNC_CFG  },   /* 0x0F: Tps_SAFETY_FUNC_CFG    */
        { RD_SAFETY_ERR_STAT,       WR_SAFETY_ERR_STAT  },   /* 0x10: Tps_SAFETY_ERR_STAT    */
        { RD_SAFETY_ERR_PWM_H,      WR_SAFETY_ERR_PWM_H },   /* 0x11: Tps_SAFETY_ERR_PWM_H   */
        { RD_SAFETY_ERR_PWM_L,      WR_SAFETY_ERR_PWM_L },   /* 0x12: Tps_SAFETY_ERR_PWM_L   */
        { RD_SAFETY_PWD_THR_CFG,    WR_SAFETY_PWD_THR_CFG},  /* 0x13: Tps_SAFETY_ERR_PWM_L   */
        { RD_SAFETY_CFG_CRC,        WR_SAFETY_CFG_CRC   },   /* 0x14: Tps_SAFETY_CFG_CRC     */
        { RD_DIAG_CFG_CTRL,         WR_DIAG_CFG_CTRL    },   /* 0x15: Tps_DIAG_CFG_CTRL      */
        { RD_DIAG_MUX_SEL,          WR_DIAG_MUX_SEL     },   /* 0x16: Tps_DIAG_MUX_SEL       */
        { RD_WDT_TOKEN_FDBCK,       WR_WDT_TOKEN_FDBCK  },   /* 0x17: Tps_WDT_TOKEN_FDBCK    */
        { RD_WD_WIN1_CFG,           WR_WD_WIN1_CFG      },   /* 0x18: Tps_WD_WIN1_CFG        */
        { RD_WD_WIN2_CFG,           WR_WD_WIN2_CFG      },   /* 0x19: Tps_WD_WIN2_CFG        */
        { RD_WDT_TOKEN_VALUE,       WR_COMMAND_NONE     },   /* 0x1A: Tps_WDT_TOKEN_VALUE    */
        { RD_WDT_STATUS,            WR_COMMAND_NONE     },   /* 0x1B: Tps_WDG_STATUS         */
        { RD_COMMAND_NONE,          WR_WDT_ANSWER       },   /* 0x1C: Tps_WDT_ANSWER         */
        { RD_SENS_CTRL,             WR_SENS_CTRL        },   /* 0x1D: Tps_SENS_CTRL          */
        { RD_COMMAND_NONE,          WR_SW_LOCK          },   /* 0x1E: Tps_SW_LOCK            */
        { RD_COMMAND_NONE,          WR_SW_UNLOCK        },   /* 0x1F: Tps_SW_UNLOCK          */
    };
    
    /*********************************************************
     Local  definitions
     **********************************************************/
    static send_recieve_data send_recieve_data_TPS;
    
    /*********************************************************
     Functions
     **********************************************************/
    /**
     * @brief   sends command over SPI.
     *
     * @description todo
     *
     * @image html  todo
     * @image rtf   todo
     * @image latex todo
     *
     * @param [in]  u16Command TPS command to be sent on SPI
     * @param [in] *u8Data data output for the SPI command
     *
     * @return      TRUE : no errors
     *              FALSE: Errors in execution
     *
     * Example Usage:
     * @code
     *      todo
     * @endcode
     *
     * @entrymode   todo
     * @exitmode    todo
     *
     * @seealso     todo
     *
     * **Note: todo**
     *
     * @destag      todo
     * @reqtag      todo
     */
    static boolean TpsIf_SendCommandOverSPI(uint16 u16Command, uint8* u8Data)
    {
        volatile uint16 u16Content = 0u;
        uint8 u8SPIPreviousStatus = 0U;
        uint32 u32size = 1U;
        boolean blRetVal = FALSE;
        uint16 u16tempcontent = u16Content;
        uint8 u8SAFETY_STAT_4 = 0U;
    
        /*Check that pointer values falls in range*/
        /*SAFETYMCUSW 439 S MR:11.3 <APPROVED> "Reason -  This is an advisory by MISRA.Verified validity of operation by review"*/
        /*SAFETYMCUSW 439 S MR:11.3 <APPROVED> "Reason -  This is an advisory by MISRA.Verified validity of operation by review"*/
        if (!CHECK_RANGE_RAM_PTR(u8Data))
        {
            blRetVal = FALSE;
            TPS_SendDebugText(ERROR,"TpsIf_SendCommandOverSPI null pointer data",(uint32)blRetVal);
    
        }
        else
        {
            /*send  and recieve command*/
            if (TRUE
                    == send_recieve_data_TPS(&u16Command, 1U, &u16Content,
                            &u32size))
            {
                u16tempcontent = u16Content;
                /*Extract the data*/
                *u8Data = (uint8) (u16tempcontent & TPSIF_DATA_MASK);
                u16Content = 0u;
                if (TRUE
                        == send_recieve_data_TPS(
                                &TpsIf_COMMAND[TPS_SAFETY_STAT_4].Read, 1U,
                                &u16Content, &u32size))
                {
                    u16tempcontent = u16Content;
                    /*Extract the data*/
                    u8SAFETY_STAT_4 = (uint8) (u16tempcontent & TPSIF_DATA_MASK);
                    /*Extract the spi transfer status flags byte*/
                    u8SPIPreviousStatus = (uint8) ((u16tempcontent
                            & TPSIF_STATUS_FLAG_RESPOSE_MASK) >> 8U);
                   /* if (NO_ERROR
                            == BFU8_GET(u8SAFETY_STAT_4, BF_SPI_ERR_START,
                                    BF_SPI_ERR_LENGTH))
                    {
                        /*checking whether there were no errors in the previous SPI transfer phase*/
                        if ((MULTIBITKEY_SET
                                == BFU8_GET(u8SPIPreviousStatus,
                                        BF_MULTIBITKEY_START, BF_MULTIBITKEY_LENGTH)))
                               /* && (0u
                                        == BFU8_GET(u8SPIPreviousStatus,
                                                BF_SPI_ERRFLAG_START,
                                                BF_SPI_ERRFLAG_LENGTH)))*/
                        {
                            blRetVal = TRUE;/*Sth is wrong with the previous SPI transfer*/
                        }
                        else
                        {
                            blRetVal = FALSE;
                            TPS_SendDebugText(ERROR,
                                    "TpsIf_SendCommandOverSPI SPIPreviousStatus error",
                                    (uint32) u8SPIPreviousStatus);
                        }
                    /*}
                    else
                    {
                        blRetVal = FALSE;
                        TPS_SendDebugText(ERROR,
                                "TpsIf_SendCommandOverSPI SPI ERR  ",
                                (uint32) u8SAFETY_STAT_4);
                        TPS_SendDebugText(ERROR,
                                "TpsIf_SendCommandOverSPI  u8SPIPreviousStatus is",
                                (uint32) (uint32) u8SPIPreviousStatus);
                    }*/
            }
            else
            {
               blRetVal = FALSE;
               TPS_SendDebugText(ERROR,"TpsIf_SendCommandOverSPI send_recieve_data_TPSR",(uint32)blRetVal);
            }
        }
        else
        {
            blRetVal = FALSE;/*Send data command failed*/
            TPS_SendDebugText(ERROR,"TpsIf_SendCommandOverSPI Send data command failed",(uint32)blRetVal);
    
        }
    }
    return blRetVal;
    }
    
    void TpsIf_Init(send_recieve_data snd_rcv_data_api)
    {
        send_recieve_data_TPS = snd_rcv_data_api;
    }
    
    boolean TpsIf_SetRegister(const TPS_Registers TPSReg, const uint8 u8value)
    {
        uint8 u8Data = 0U;
        boolean blRetVal = FALSE;
        uint16 u16Command = TpsIf_COMMAND[TPSReg].Write | u8value;
    
        /*write data to register*/
        if (TRUE == TpsIf_SendCommandOverSPI(u16Command, &u8Data))
        {
            blRetVal = TRUE;
        }
        else
        {
            blRetVal = FALSE;
        }
        return blRetVal;
    }
    
    boolean TpsIf_SetRegisterVerify(const TPS_Registers TPSReg, const uint8 u8value)
    {
        uint8 u8Data = 0U;
        boolean blRetVal = FALSE;
        uint16 u16Command = TpsIf_COMMAND[TPSReg].Write | u8value;
    
        /*write data to register*/
        if (TRUE == TpsIf_SendCommandOverSPI(u16Command, &u8Data))
        {
            u16Command = TpsIf_COMMAND[TPSReg].Read;
            /*read data from register*/
            if (TRUE == TpsIf_SendCommandOverSPI(u16Command, &u8Data))
            {
                if (u8value == u8Data)
                {
                    blRetVal = TRUE;
                }
                else
                {
                    blRetVal = FALSE;
                }
            }
            else
            {
                blRetVal = FALSE;
            }
        }
        else
        {
            blRetVal = FALSE;
        }
        return (blRetVal);
    }
    
    boolean TpsIf_SetRegisterBitField(const TPS_Registers TPSReg, const uint8 u8bfstart,
            const uint8 u8bflength, const uint8 u8value)
    {
        uint16 u16Command = TpsIf_COMMAND[TPSReg].Read;
        uint8 u8Data = 0U;
        boolean blRetVal = FALSE;
    
        /*get the data in the register*/
        if (TRUE == TpsIf_SendCommandOverSPI(u16Command, &u8Data))
        {
            BFU8_SET(u8Data, u8value, u8bfstart, u8bflength);
            u16Command = TpsIf_COMMAND[TPSReg].Write | (u8Data);
            /*write data back to the register*/
            if (TRUE == TpsIf_SendCommandOverSPI(u16Command, &u8Data))
            {
                blRetVal = TRUE;
            }
            else
            {
                blRetVal = FALSE;
            }
        }
        else
        {
            blRetVal = FALSE;
        }
        return (blRetVal);
    }
    
    boolean TpsIf_SetRegisterBitFieldVerify(const TPS_Registers TPSReg,
            const uint8 u8bfstart, const uint8 u8bflength, const uint8 u8value)
    {
        uint16 u16Command = TpsIf_COMMAND[TPSReg].Read;
        uint8 u8Data = 0U;
        boolean blRetVal = FALSE;
        /*get the data in the register*/
        if (TRUE == TpsIf_SendCommandOverSPI(u16Command, &u8Data))
        {
            BFU8_SET(u8Data, u8value, u8bfstart, u8bflength);
            u16Command = TpsIf_COMMAND[TPSReg].Write | (u8Data);
            /*write data back to the register*/
            if (TRUE == TpsIf_SendCommandOverSPI(u16Command, &u8Data))
            {
                blRetVal = TRUE;
                u16Command = TpsIf_COMMAND[TPSReg].Read;
                /*read the data back and verify whether it has been correctly written*/
                if (TRUE == TpsIf_SendCommandOverSPI(u16Command, &u8Data))
                {
                    if (u8value == BFU8_GET(u8Data,u8bfstart,u8bflength))
                    {
                        blRetVal = TRUE;
                    }
                    else
                    {
                        blRetVal = FALSE;
                    }
                }
                else
                {
                    blRetVal = FALSE;
                }
            }
            else
            {
                blRetVal = FALSE;
            }
        }
        else
        {
            blRetVal = FALSE;
        }
        return blRetVal;
    }
    
    boolean TpsIf_GetRegister(const TPS_Registers TPSReg, uint8* u8value)
    {
        uint16 u16Command = TpsIf_COMMAND[TPSReg].Read;
        uint8 u8Data = 0U;
        boolean blRetVal = FALSE;
    
        /*Check that pointer values falls in range*/
        /*SAFETYMCUSW 439 S MR:11.3 <APPROVED> "Reason -  This is an advisory by MISRA.Verified validity of operation by review"*/
        /*SAFETYMCUSW 439 S MR:11.3 <APPROVED> "Reason -  This is an advisory by MISRA.Verified validity of operation by review"*/
        if (!CHECK_RANGE_RAM_PTR(u8value))
        {
            blRetVal = FALSE;
        }
        else
        {
            if (TRUE == TpsIf_SendCommandOverSPI(u16Command, &u8Data))
            {
                blRetVal = TRUE;
                *u8value = u8Data;
            }
            else
            {
                blRetVal = FALSE;
            }
        }
        return blRetVal;
    }
    
    boolean TpsIf_GetRegisterBitField(const TPS_Registers TPSReg, const uint8 u8bfstart,
            const uint8 u8bflength, uint8* u8value)
    {
        uint16 u16Command = TpsIf_COMMAND[TPSReg].Read;
        uint8 u8Data = 0U;
        boolean blRetVal = FALSE;
    
        /*Check that pointer values falls in range*/
        /*SAFETYMCUSW 439 S MR:11.3 <APPROVED> "Reason -  This is an advisory by MISRA.Verified validity of operation by review"*/
        /*SAFETYMCUSW 439 S MR:11.3 <APPROVED> "Reason -  This is an advisory by MISRA.Verified validity of operation by review"*/
        if (!CHECK_RANGE_RAM_PTR(u8value))
        {
            blRetVal = FALSE;
        }
        else
        {
            if (TRUE == TpsIf_SendCommandOverSPI(u16Command, &u8Data))
            {
                blRetVal = TRUE;
                *u8value = BFU8_GET(u8Data,u8bfstart,u8bflength);
            }
            else
            {
                blRetVal = FALSE;
            }
        }
        return blRetVal;
    }
    
    /*SAFETYMCUSW 61 D MR: 8.10,8.11 <APPROVED> "This function will be called by application so not static" */
    boolean TpsIf_TestCommandParityLogic(TPS_Test_Result *selftest_result)
    {
        uint16 u16Command = RD_WRONG_PARITY;
        boolean blRetVal = FALSE;
        uint8 u8Data = 0U;
    
        /*Check that pointer values falls in range*/
        /*SAFETYMCUSW 439 S MR:11.3 <APPROVED> "Reason -  This is an advisory by MISRA.Verified validity of operation by review"*/
        /*SAFETYMCUSW 439 S MR:11.3 <APPROVED> "Reason -  This is an advisory by MISRA.Verified validity of operation by review"*/
        if (!CHECK_RANGE_RAM_PTR(selftest_result))
        {
            blRetVal = FALSE;
        }
        else
        {
            /* the transfer should fail as the parity is wrong the command being sent to TPS*/
            if (TRUE == TpsIf_SendCommandOverSPI(u16Command, &u8Data))
            {
                *selftest_result = TEST_FAIL;
            }
            else
            {
            	*selftest_result = TEST_PASS;
            }
            blRetVal = TRUE;
        }
        return blRetVal;
    }
    
    /*SAFETYMCUSW 61 D MR: 8.10,8.11 <APPROVED> "This function will be called by application so not static" */
    boolean TpsIf_TestWrongCommandLogic(TPS_Test_Result *selftest_result)
    {
        uint8 u8Data = 0U;
        uint16 u16Command = RD_WRONG_COMMAND;
        boolean blRetVal = TRUE;
    
        /*Check that pointer values falls in range*/
        /*SAFETYMCUSW 439 S MR:11.3 <APPROVED> "Reason -  This is an advisory by MISRA.Verified validity of operation by review"*/
        /*SAFETYMCUSW 439 S MR:11.3 <APPROVED> "Reason -  This is an advisory by MISRA.Verified validity of operation by review"*/
        if (!CHECK_RANGE_RAM_PTR(selftest_result))
        {
            blRetVal = FALSE;
        }
        else
        {
            /* the transfer should fail as the parity is wrong the command being sent to TPS*/
            if (TRUE == TpsIf_SendCommandOverSPI(u16Command, &u8Data))
            {
                *selftest_result = TEST_FAIL;
            }
            else
            {
                *selftest_result = TEST_PASS;
            }
            blRetVal = TRUE;
        }
        return blRetVal;
    }
    
    /*SAFETYMCUSW 61 D MR: 8.10,8.11 <APPROVED> "This function will be called by application so not static" */
    boolean TpsIf_SpiIFTestPwmlow(TPS_Test_Result *selftest_result)
    {
        uint8 u8Data =0U;
        boolean blRetVal = TRUE;
        uint8 u8bckup_safety_err_pwm_l = 0U;
        uint8 u8pwmi = 0U; /* iterator for iterating through the pwm value array*/
        uint8 u8Apwmvalue[4] =
        { 0xFFu, 0xAAu, 0x00u, 0x55u }; /* various values for pwm being tested*/
    
        /*Check that pointer values falls in range*/
        /*SAFETYMCUSW 439 S MR:11.3 <APPROVED> "Reason -  This is an advisory by MISRA.Verified validity of operation by review"*/
        /*SAFETYMCUSW 439 S MR:11.3 <APPROVED> "Reason -  This is an advisory by MISRA.Verified validity of operation by review"*/
        if (!CHECK_RANGE_RAM_PTR(selftest_result))
        {
            blRetVal = FALSE;
        }
        else
        {
            blRetVal = ((TpsIf_GetRegister(TPS_SAFETY_ERR_PWM_L,
                    &u8bckup_safety_err_pwm_l)) && blRetVal);
            /*write to pwmlow register and read the value back to verify that the writes to pwmlow register are working correctly*/
            for (u8pwmi = 0U; u8pwmi < (sizeof(u8Apwmvalue) / sizeof(uint8)); u8pwmi++)
            {
                if (TRUE
                        == TpsIf_SendCommandOverSPI(
                                WR_SAFETY_ERR_PWM_L | u8Apwmvalue[u8pwmi], &u8Data))
                {
                    if (TRUE
                            == TpsIf_SendCommandOverSPI(RD_SAFETY_ERR_PWM_L,
                                    &u8Data))
                    {
                        if (u8Apwmvalue[u8pwmi] == (u8Data))
                        {
                            *selftest_result = TEST_PASS;
                        }
                        else
                        {
                            *selftest_result = TEST_FAIL;
                            break;
                        }
                    }
                    else
                    {
                        *selftest_result = TEST_FAIL;
                        break;
                    }
                }
                else
                {
                    *selftest_result = TEST_FAIL;
                    break;
                }
            }
            /*restore pwm registers*/
            blRetVal = ((TpsIf_SetRegisterVerify(TPS_SAFETY_ERR_PWM_L,
                    u8bckup_safety_err_pwm_l)) && blRetVal);
        }
        return blRetVal;
    }
    
    

  • Hi David,

    thanks for your feedback. So we are both working with a workaround in this moment. By the way... I have not changed Tps_Interface.c but Tps_priv.h. By modifiing only Bit-Start and Bit-length defines I am able to neglect only "SPI SDO error" and "Command Error". So the Q&A Watchdog is working smoothly now.

    But at the end of the day I'm waiting for an "official" errata. Maybe it's the same but I need this for documentation. Out of my point of view it is possibile to compensate an invalid SPI transfer with other diagnostic actions.

    From my meassurement results I expect the problem internal of TPS65381. Because the error is constant there when there is another communication on an other CS-line. And the error is not there when not. But the load is the same in both cases.

    So you are not the only developer with this effect and hopefully it's reproducibil.

    Regards,

    Frank

     

     

  • Hi @all,
    I want to bring this Topic to front again.
    Is there an update/Statement from TI available?
    With latest TPSlib (2.2.0) and HALCoGen (04.03.00) the bug is still there.

    Regards,
    Frank
  • Hi Frank,

    We in the TPS65381 product team have recently run multiple scenarios past the the device on our EVMS using various SPI frame formats and trying to emulate multi-slave bus whith the devices chip select not being set and do not see the issues reported with the SPI and TMS570 devices. We have also looked into the logic code of the TPS65381 and it should be ignoring any SPI traffic when the nCS is high.

    I will try to work with the TMS570 team to see if they can isolate the case as it appears it may be a specific way the SPI data is formatted with the 570's or this code generation tool. We had also tried to get more detailed timing scenarios on the multi-SPI set ups customers were using to see if we could isolate it down to something.

    -Scott
  • Hi Scott,

    I think it's a pure TPS65381 Topic. I spend some hours for additional Investigation and can reduce the root cause for the error Response of TPS65381 to only one falling clock edge during SDO is held high (from external device not from TPS65381).

    I was able to create the pulses (~1us length) on Clock and SDO without HALCOGEN-Code and without SPI-Peripherie on TMS570. I used GIO commands. Please have a look to following code:


    If following code is running before a normal SPI communication (with HALCOGEN-Code and SPI-Peripherie) I get the error from TPS65381: (falling CLK edge before falling Data edge)
    spiREG1->PC0 = spiREG1->PC0 & 0xFFFFFDFF;//clk to io
    spiREG1->PC0 = spiREG1->PC0 & 0xFFFFF7FF;//Somi to io
    spiREG1->PC1 = spiREG1->PC1 | (uint32)((uint32)1U << 11U); //somi to output

    spiREG1->PC3 = spiREG1->PC3 | (uint32)((uint32)1U << 11U);// Somi drive 1
    spiREG1->PC3 = spiREG1->PC3 | (uint32)((uint32)1U << 9U);// CLK drive 1
    spiREG1->PC3 = spiREG1->PC3 & 0xFFFFFDFF;// CLK drive 0
    spiREG1->PC3 = spiREG1->PC3 & 0xFFFFF7FF;// Somi drive 0

    spiREG1->PC1 = spiREG1->PC1 & 0xFFFFF7FF; // somi to input
    spiREG1->PC0 = spiREG1->PC0 | (uint32)((uint32)1U << 11U);//Somi to SPI
    spiREG1->PC0 = spiREG1->PC0 | (uint32)((uint32)1U << 9U); /* CLK to SPI */


    also this code gives an error:(falling CLK edge before falling Data edge)
    spiREG1->PC0 = spiREG1->PC0 & 0xFFFFFDFF;//clk to io
    spiREG1->PC0 = spiREG1->PC0 & 0xFFFFF7FF;//Somi to io
    spiREG1->PC1 = spiREG1->PC1 | (uint32)((uint32)1U << 11U); //somi to output


    spiREG1->PC3 = spiREG1->PC3 | (uint32)((uint32)1U << 9U);// CLK drive 1
    spiREG1->PC3 = spiREG1->PC3 | (uint32)((uint32)1U << 11U);// Somi drive 1

    spiREG1->PC3 = spiREG1->PC3 & 0xFFFFFDFF;// CLK drive 0
    spiREG1->PC3 = spiREG1->PC3 & 0xFFFFF7FF;// Somi drive 0

    spiREG1->PC1 = spiREG1->PC1 & 0xFFFFF7FF; // somi to input
    spiREG1->PC0 = spiREG1->PC0 | (uint32)((uint32)1U << 11U);//Somi to SPI
    spiREG1->PC0 = spiREG1->PC0 | (uint32)((uint32)1U << 9U); /* CLK to SPI */


    this one gives NO Error: (only CLK has a single 1)
    spiREG1->PC0 = spiREG1->PC0 & 0xFFFFFDFF;//clk to io
    spiREG1->PC0 = spiREG1->PC0 & 0xFFFFF7FF;//Somi to io
    spiREG1->PC1 = spiREG1->PC1 | (uint32)((uint32)1U << 11U); //somi to output

    // spiREG1->PC3 = spiREG1->PC3 | (uint32)((uint32)1U << 11U);// Somi drive 1
    spiREG1->PC3 = spiREG1->PC3 | (uint32)((uint32)1U << 9U);// CLK drive 1
    spiREG1->PC3 = spiREG1->PC3 & 0xFFFFFDFF;// CLK drive 0
    spiREG1->PC3 = spiREG1->PC3 & 0xFFFFF7FF;// Somi drive 0

    spiREG1->PC1 = spiREG1->PC1 & 0xFFFFF7FF; // somi to input
    spiREG1->PC0 = spiREG1->PC0 | (uint32)((uint32)1U << 11U);//Somi to SPI
    spiREG1->PC0 = spiREG1->PC0 | (uint32)((uint32)1U << 9U); /* CLK to SPI */


    also this one gives NO Error: (only SOMI=SDO TPS65381 has a single 1)
    spiREG1->PC0 = spiREG1->PC0 & 0xFFFFFDFF;//clk to io
    spiREG1->PC0 = spiREG1->PC0 & 0xFFFFF7FF;//Somi to io
    spiREG1->PC1 = spiREG1->PC1 | (uint32)((uint32)1U << 11U); //somi to output

    spiREG1->PC3 = spiREG1->PC3 | (uint32)((uint32)1U << 11U);// Somi drive 1
    // spiREG1->PC3 = spiREG1->PC3 | (uint32)((uint32)1U << 9U);// CLK drive 1
    spiREG1->PC3 = spiREG1->PC3 & 0xFFFFFDFF;// CLK drive 0
    spiREG1->PC3 = spiREG1->PC3 & 0xFFFFF7FF;// Somi drive 0

    spiREG1->PC1 = spiREG1->PC1 & 0xFFFFF7FF; // somi to input
    spiREG1->PC0 = spiREG1->PC0 | (uint32)((uint32)1U << 11U);//Somi to SPI
    spiREG1->PC0 = spiREG1->PC0 | (uint32)((uint32)1U << 9U); /* CLK to SPI */


    also this one gives NO Error: (falling CLK edge after falling Data edge)
    spiREG1->PC0 = spiREG1->PC0 & 0xFFFFFDFF;//clk to io
    spiREG1->PC0 = spiREG1->PC0 & 0xFFFFF7FF;//Somi to io
    spiREG1->PC1 = spiREG1->PC1 | (uint32)((uint32)1U << 11U); //somi to output

    spiREG1->PC3 = spiREG1->PC3 | (uint32)((uint32)1U << 11U);// Somi drive 1
    spiREG1->PC3 = spiREG1->PC3 | (uint32)((uint32)1U << 9U);// CLK drive 1
    spiREG1->PC3 = spiREG1->PC3 & 0xFFFFF7FF;// Somi drive 0
    spiREG1->PC3 = spiREG1->PC3 & 0xFFFFFDFF;// CLK drive 0

    spiREG1->PC1 = spiREG1->PC1 & 0xFFFFF7FF; // somi to input
    spiREG1->PC0 = spiREG1->PC0 | (uint32)((uint32)1U << 11U);//Somi to SPI
    spiREG1->PC0 = spiREG1->PC0 | (uint32)((uint32)1U << 9U); /* CLK to SPI */

    You can see it is not necessary to have edges von CS or SDI of TPS65381!

    Can you please share your measurement results with me? May be I can Support you to reproduce the Bug on your testsystem.

    Regards,
    Frank

  • Hi David,
     
     

    I have just completed testing using a modified multi-slave SPI emulating type set up including the TPS65381 device with a lot more focused attention to some of the other reports and unfortunately can now confirm that the device does infact falsely report SDO Error flags matching earlier reported versions of silicon. One of the app notes from the early revision of this device mentioned the SDO error was in the first SPI frame of the next SPI transfer set with the TPS65381, it is actually the second frame in a sucessive set of SPI transfers.

    For now the best recommendation is to use the pull down on SDO to make sure it is low on any SCLK activity that isn't included in a SPI slave that isn't TPS65381 as recommended in preliminary app note on this topic.  The software note when using the device in mulit-slave SPI applications also applies with a couple of minor modifications / clarifications:  Due to a limitation the internal SPI error detection of the TPS65381 flags an SDO error on SPI frame occurrence, if the chip select signal is inactive high. This results in a SDO error flag in the second successive SPI frame of the next SPI transfer set with the TPS65381. This SDO error flag needs to be ignored by the SPI master software.

    It may be easier to just ignore the SPI SDO Error flag entirely if it is not needed.  We will try to work up an app note from our side and work with the TMS570 team to try and get their version released as well.

    Scott


     
    Scott

  • Scott,

    Thank you for your investigation. So far I am completely ignoring the SDO error flag and things to be OK. Since we plan on using the diagnostic mux output at some point as I understand it we would need to ignore it anyway.

    Thanks,
    David