cancel
Showing results for 
Search instead for 
Did you mean: 

Adapting SPI from F1 to F0

contact239955_stm1_st
Associate II
Posted on April 23, 2013 at 22:41

Hi,

I have some working code on STM32F103 that I want to use with a STM32F051 (Discovery board) but I have some troubles to get the SPI communication working. The program get stuck when waiting for an incoming data. This is the initialization code :


SPI_InitTypeDef SPI_InitStructure;

GPIO_InitTypeDef GPIO_InitStructure;


//enable SPI2, GPIOA & GPIOB clocks.

RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB, ENABLE);


//SCK, MISO, MOSI AF

GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_0);

GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_0);

GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_0);


//SCK, MISO, MOSI (AF, PP, NO PULL)

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 |GPIO_Pin_14 |GPIO_Pin_15;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOB, &GPIO_InitStructure);


// CSN (OUT, PP, NO PULL)

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;

GPIO_Init(GPIOB, &GPIO_InitStructure);


//CE (OUT PP, NO PULL)

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;

GPIO_Init(GPIOA, &GPIO_InitStructure);


//IRQ (IN, NO PULL)

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;

GPIO_Init(GPIOA, &GPIO_InitStructure);


SPI2_releaseChip();


SPI_Cmd(SPI2, DISABLE);

/* SPI2 configuration */

SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;

SPI_InitStructure.SPI_Mode = SPI_Mode_Master;

SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;

SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;

SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;

SPI_InitStructure.SPI_NSS = SPI_NSS_Hard;

SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;

SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;

SPI_InitStructure.SPI_CRCPolynomial = 7;

SPI_Init(SPI2, &SPI_InitStructure);


SPI_RxFIFOThresholdConfig(SPI2, SPI_RxFIFOThreshold_QF);


/* Enable SPI2 */

SPI_Cmd(SPI2, ENABLE);

and then the read/write function :


unsigned 
char
SPI2_readWriteByte(unsigned 
char
byte)

{

while
(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);

/* Send byte through the SPI2 peripheral */

SPI_SendData8(SPI2, byte);

/* Wait to receive a byte */

while
(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET);

/* Return the byte read from the SPI bus */

return
SPI_ReceiveData8(SPI2);

}

The program hang on line 7. I'm trying to communicate with an nRF24L01 but I also tried to connect MOSI to MISO directly with the same result. Am I doing something wrong? Thanks
5 REPLIES 5
contact239955_stm1_st
Associate II
Posted on April 25, 2013 at 22:49

Little update, I tried a bit-banging method and it works like a charm so it's not a wiring problem or something like that. Any idea?

Posted on April 25, 2013 at 23:10

Any idea?

Hard to say, I haven't done too much with the F0 parts. You might want to look at the SPI Examples for the EVAL series boards, and also look how your NSS Hard setting, and the FIFO setting impact the behaviour of the SPI peripheral.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
carl2399
Associate II
Posted on April 27, 2013 at 01:38

Hi,

I also struggled a bit with the SPI on F0, but have got it working. I used the following initialisation code:

void
InitSPIs(
void
)
{
SPI_InitTypeDef set;
RCC->APB2ENR |= RCC_APB2Periph_SPI1;
set.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
set.SPI_Mode = SPI_Mode_Master;
set.SPI_DataSize = SPI_DataSize_8b;
set.SPI_CPOL = SPI_CPOL_Low;
set.SPI_CPHA = SPI_CPHA_1Edge;
set.SPI_NSS = SPI_NSS_Soft;
set.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;
set.SPI_FirstBit = SPI_FirstBit_MSB;
set.SPI_CRCPolynomial = 7;
SPI_Init(SPI1, &set);
SPI_RxFIFOThresholdConfig(SPI1, SPI_RxFIFOThreshold_QF);
SPI_Cmd(SPI1, ENABLE);
}

And use the following code in normal usage:

void
SPI1_Put(u8 
const
ch)
{
while
((SPI1->SR & 0x0600)) 
// Clear Rx Buffer
SPI_ReceiveData8(SPI1); 
SPI_SendData8(SPI1, ch);
while
((SPI1->SR & 0x0080)); 
// Wait for not busy
while
((SPI1->SR & 0x0600)) 
// Receive incoming char
SPI_ReceiveData8(SPI1); 
}
u8 SPI1_PutGet(u8 
const
ch)
{
SPI_SendData8(SPI1, ch);
while
((SPI1->SR & 0x0600) == 0); 
// Wait for character in Rx Buffer 
return
SPI_ReceiveData8(SPI1);
}

Hope it helps to shed a little extra light.

contact239955_stm1_st
Associate II
Posted on May 01, 2013 at 21:59

Thanks for your reply but I still doesn't work. How do you  initialize your GPIOs? Maybe the problem is there

carl2399
Associate II
Posted on May 02, 2013 at 11:21 Yeah, I realised after posting that the GPIO initialisation stuff is not there. I use the following: My method of pin configuration is: 1) Fill in the comments section. 2) Generate the register contents.

/* 
* PORT B Pins
* MO O OS PU AFR 
* PB0 - 00 0 00 01 0 - Unused
* PB1 - 00 0 00 01 0 - Unused
* PB2 - 00 0 00 01 0 - Unused
* PB3 - 10 0 00 01 0 - Output - SPI1-SCK
* PB4 - 10 0 00 01 0 - Input - SPI1-MISO
* PB5 - 10 0 00 01 0 - Output - SPI1-MOSI
#if UART1_REMAP==1
* PB6 - 10 0 00 01 0 - Output - U1-TX
* PB7 - 10 0 00 01 0 - Input - U1-RX
#else
* PB6 - 00 0 00 01 0 - Unused - U1-Tx
* PB7 - 00 0 00 01 0 - Unused - U1-Rx
#endif
* PB8 - 00 0 00 01 0 - Unused
* PB9 - 00 0 00 01 0 - Unused
* PB10 - 00 0 00 01 0 - Unused
* PB11 - 00 0 00 01 0 - Unused
* PB12 - 00 0 00 01 0 - Unused
* PB13 - 00 0 00 01 0 - Unused
* PB14 - 00 0 00 01 0 - Unused
* PB15 - 00 0 00 01 0 - Unused
*/
// Enable GPIO clocks
RCC->AHBENR |= RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB;
#if UART1_REMAP==1
GPIOB->MODER = 0x0000AA80;
#else
GPIOB->MODER = 0x00000A80;
#endif
GPIOB->OTYPER = 0x0000;
GPIOB->OSPEEDR = 0x00000000;
GPIOB->PUPDR = 0x55555555;
GPIOB->AFR[0] = 0x00000000;
GPIOB->AFR[1] = 0x00000000;