cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F103RET6 bare metal SPI3 pins not configuring and not functional

joesnyder
Associate III

This is a follow up to my previous post at:

https://community.st.com/t5/stm32-mcus-products/stm32f103ret6-bare-metal-spi3/m-p/819878#M282227

I got the boards built, and I'm starting testing.  SPI3 is not functional, so I started stepping through and checking SFRs.  One problem I'm having is that PB3 (SCK) and PB5 (MOSI) refuse to configure as alternate function push pull. 

In lines 26-33 below, PA15 goes to output, alternate function push pull just fine.  But PB3 and PB5 will only go to output, and open drain.  In line 35, I even tried to force the mode bits to "10" (alternate function push pull), and when I observe the mode bits for PA3 and PA5, they get set to "11" (alternate function output open drain).  My current attempt at SPI3 initialization is:

void init_spi3(void)
{

	// Note on ref manual page 699: need to disable JTAG because SPI3 conflicts with JTAG pins
	
	// Enable AFIO clock
	RCC->APB2ENR |= RCC_APB2ENR_AFIOEN; 	//(VERIFIED set properly by stepping through)
	// Page 177 of ref manual, free up PA15 by setting SWJ_CFG[2:0] to 100
	// -> Page 184 of ref manual, SWJ_CFG[2:0] is bits 26..24 of AFIO_MAPR
	AFIO->MAPR |= AFIO_MAPR_SWJ_CFG_JTAGDISABLE; //(VERIFIED set properly by stepping through)

	//SPI3, want master transmit-only:
	//PA15 NSS
	//PB3 SCK
	//PB5 MOSI

    RCC->APB2ENR    |= RCC_APB2ENR_IOPAEN;  // enable GPIOA clock (VERIFIED set properly by stepping through)
    RCC->APB2ENR    |= RCC_APB2ENR_IOPBEN;  // enable GPIOB clock (VERIFIED set properly by stepping through)
    RCC->APB1ENR    |= RCC_APB1ENR_SPI3EN;  // Page 116 of ref manual set RCC_APB1ENR_SPI3EN to enable SPI3 (VERIFIED set properly by stepping through)

    //Table 25 on page 167 of reference manual, for SPIx:
    //PA15 SPI3 NSS -> Want alternate function push-pull
    //PB3 SPI3 SCK -> Want alternate function push-pull
    //PB5 SPI3 MOSI -> Want alternate function push-pull

    // init PA15 NSS  - Mode = 01 (10Mhz output), CNF = 10 = alternate function push-pull...ref manual pg 171
    GPIOA->CRH |= (GPIO_CRH_MODE15_0 | GPIO_CRH_CNF15_1);  	//***(VERIFIED, MODE goes to 01 (output 10MHz), and CNF goes to 10 (alternate function push pull)

    // init PB3 SCK  - Mode = 01 (10Mhz output), CNF = 10 = alternate function push-pull...ref manual pg 171
    ///GPIOB->CRL |= (GPIO_CRL_MODE3_0 | GPIO_CRL_CNF3_1);		//***(MODE goes to 01, but CNF goes to 11, which is alternate function open drain)

    // init PB5 MOSI  - Mode = 01 (10Mhz output), CNF = 10 = alternate function push-pull...ref manual pg 171
    ///GPIOB->CRL |= (GPIO_CRL_MODE5_0 | GPIO_CRL_CNF5_1);		//***(MODE goes to 01, but CNF goes to 11, which is alternate function open drain)

    GPIOB->CRL |=  0x00909000;	//***Try forcing the bits manually, MODE still goes to 01, and CNF still goes to 11

    GPIOA->BSRR = GPIO_BSRR_BS15;            // set the NSS pin high

    // initialize the SPI configuration register (sequence page 707, SPI_CR1 register on page 742)
    SPI3->CR1  =  SPI_CR1_DFF   // 16-bit data frame
                | SPI_CR1_SSM   // software slave management enabled
                | SPI_CR1_SSI   // internal slave select
                | SPI_CR1_MSTR  // SPI master mode
                | SPI_CR1_BR_2; // bit rate prescale /32 (72MHz/32 = 2.25MHz)

    SPI3->CR1  |= SPI_CR1_SPE;  // enable SPI
}

 There is also some strange behavior with line 37.  After I step through and execute:

GPIOA->BSRR = GPIO_BSRR_BS15; // set the NSS pin high

...PA15 does not set high.  I have combed through the reference manual and I am positive I am missing something big.  Hopefully someone can help me please.

For reference, I'm trying to execute an SPI transmit by calling:

spi3_transmit_reg_byte(0x09,0xFF);

It gets through the function call, but nothing is happening on any of the pins.  The code for that is here:

void spi3_transmit_reg_byte(uint8_t reg, uint8_t reg_byte)  //16 bit data frame, register followed by byte
{
    uint16_t data = ( (reg << 8) | reg_byte );

    GPIOA->BSRR = GPIO_BSRR_BR15;        // reset NSS pin

    SPI3->DR = data;                    // send data out SPI
    while( !(SPI3->SR & SPI_SR_TXE) );  // wait until transmit buffer empty
    while( SPI3->SR & SPI_SR_BSY );     // wait until SPI not busy

    GPIOA->BSRR = GPIO_BSRR_BS15;        // set NSS pin
}

 

1 ACCEPTED SOLUTION

Accepted Solutions
TDK
Super User

> // init PA15 NSS - Mode = 01 (10Mhz output), CNF = 10 = alternate function push-pull...ref manual pg 171
> GPIOA->CRH |= (GPIO_CRH_MODE15_0 | GPIO_CRH_CNF15_1); //***(VERIFIED, MODE goes to 01 (output 10MHz), and CNF goes to 10 (alternate function push pull)

If PA15 is configured as AF, you can't control it with BSRR. It needs to be set as a regular GPIO output. Hardware master NSS mode isn't very useful on this chip.

If you feel a post has answered your question, please click "Accept as Solution".

View solution in original post

4 REPLIES 4
TDK
Super User

The default value of the CRL and CRH registers is not 0. You're only setting bits--you need to reset bits that are already set as well.

TDK_0-1754498401418.png

 

If you feel a post has answered your question, please click "Accept as Solution".

You are correct sir!  I changed that to:

    GPIOB->CRL |=  0x00909000;	//***Force MODE and CNF bits manually
    GPIOB->CRL &= ~0x00404000;

And the SPI module is alive and transmitting now.  However, the chip select on PA15 is still not responding.  

joesnyder_0-1754499483779.png

I'm getting a clock, and I'm getting data, but something is still going on with PA15.  I think it has to do with that conflict on reference manual page 699.  Does anyone see anything wrong with how I'm disabling the JTAG and trying to use PA15?  

 

TDK
Super User

> // init PA15 NSS - Mode = 01 (10Mhz output), CNF = 10 = alternate function push-pull...ref manual pg 171
> GPIOA->CRH |= (GPIO_CRH_MODE15_0 | GPIO_CRH_CNF15_1); //***(VERIFIED, MODE goes to 01 (output 10MHz), and CNF goes to 10 (alternate function push pull)

If PA15 is configured as AF, you can't control it with BSRR. It needs to be set as a regular GPIO output. Hardware master NSS mode isn't very useful on this chip.

If you feel a post has answered your question, please click "Accept as Solution".

Ok, awesome, that did it.  All is good for now, I think.  Thank you very much!