This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

SPI wont idle low. STM32F103VET6

Hi.

I have probably overlooked something very basic here. For some reason my SPI brings up a mode fault, just after I enable the peripheral whenever I try get get it to idle low.

If I idle high or change any of the other switches (polarity, baud etc) it works fine.

I don't suppose anyone has come across this problem?

  • I've switched between idle-high and idle-low at will, and no 'mode faults' have occurred. (using the STM32F103ZE chip).

    Below is my little on-the-fly configuration routine for switching between idle-high/low and rising/falling edges for the various SPI peripherals I have. ... and it figures--they're all different.

    The thing to note here is that you need to write out a dummy SPI value in order for the SPI peripheral to change modes.

    #define SPI1_CR1_CPOL_SET    ((u16)0x0002)  // ref data-sheet bit locations
    #define SPI1_CR1_CPOL_MASK   ((u16)0xFFFD)
    #define SPI1_CR1_EDGE_SET    ((u16)0x0001)
    #define SPI1_CR1_EDGE_MASK   ((u16)0xFFFE)
    
    /*
    **======================================================================
    **      Config_SPI_ADC
    **======================================================================
    **
    **  Configure the SPI clock and edge for the external ADC interface
    **
    **----------------------------------------------------------------------
    **
    **  Parameters Passed:      <void>
    **  Parameters Returned:    <void>
    **
    **  Notes:
    **          A dummy write on the SPI port is written if any of the
    **      configuration parameters need to be updated.
    **
    **----------------------------------------------------------------------
    */
    void Config_SPI_ADC( void )
    {
        /*------------------------------------------------------------------.
        ;  Test to see if the SPI comm is already set before altering       ;
        '------------------------------------------------------------------*/
        if( (SPI1_CR1 & SPI1_CR1_CPOL_SET) != 0 )   // it is a CPOL == 1 situation
        {
            SPI1_CR1 &= SPI1_CR1_CPOL_MASK);        // CPOL = 0 (idle low)
    
            /*--------------------------------------------------------------.
            ;  Determine the edge: need Rising edge.  This is coupled with  ;
            ; the CPOL value since this processor determines 'rising' with  ;
            ; 'first' or 'second' edge.                                     ;
            '--------------------------------------------------------------*/
            if( (SPI1_CR1 & SPI1_CR1_EDGE_SET) != 0 )//Configured for the first edge?
            {
                SPI1_CR1 &= SPI1_CR1_EDGE_MASK; // second edge: rising edge (CPOL=1)
            }
    
            /*--------------------------------------------------------------.
            ;  Must send dummy byte out the SPI port to set new configs.    ;
            ; (this is not in the data-sheets, but an observed phenominon   ;
            ;  while testing: must write deviation report.)                 ;
            '--------------------------------------------------------------*/
            SPI_I2S_SendData( SPI1, 0 ); // CAUTION: ST's Library! (rework later)
            (void) Wait_For_SPI_Byte_Transfer( ); // don't allow an overwrite
        }
    }
    

    The biggest SPI problem I found on the STM32F103x micros is the NSS signal must be manually controlled (via software). Their hardware fails to perform the NSS assertions automatically.

    --Cpt. Vince Foster
    2nd Cannon Place
    Fort Marcy Park, VA

  • I assume here that NSS is the slave-select signal.

    Slave select is always a problem. Some chips wants the select for each individual byte. Some chips wants it for a full packet. Some chips have specific timing requirements for activation and/or deactivation of the signal.

    Alas, the SPI master almost always have too few options for automatically controlling the slave select.

  • Yup "NSS" is the slave select. I don't mind if the Slave Select signal doesn't comply with the "standard", but only if it is documented not to do so. ST Microelectronics' data-sheets don't actually tell you that it doesn't work. You have to discover that yourself: and go to their forums and find out that other people have had the same problem. The Age-Old 'undocumented feature' issue.

    Although SPI is an interface 'standard' I am amused on how many variations there are in capability and functionality on both the master and slave ends of the 'standard' communications.

    --Cpt. Vince Foster
    2nd Cannon Place
    Fort Marcy Park, VA

  • Thanks for the feedback.

    I actualy found the problem just after I sent this thread. As I said origionaly I probably overlooked something.

    Section 18.3.8 on page 423 of the reference manual states "Master Mode fault occurs when the master device has its NSS pin pulled low (in hardware mode) or SSI bit low (in software mode), this automaticaly sets the MODF bit".

    We are the using the SPI to communicate to multiple devices so the NSS pin is just floating in this project. I made the incorrect assumption that keeping it low in my port setup would be sufficient.

    I have adjusted the NSS pin to read high and it now works on low polarity.

    I am still worried about this, I would think from the statement above it should not work in either polarity states. I am reading further to make sure there isn't something else I have missed.