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?

Parents
  • 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

Reply
  • 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

Children
More questions in this forum