2013-04-23 01:41 PM
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
2013-04-25 01:49 PM
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?
2013-04-25 02:10 PM
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.2013-04-26 04:38 PM
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.
2013-05-01 12:59 PM
Thanks for your reply but I still doesn't work. How do you initialize your GPIOs? Maybe the problem is there
2013-05-02 02:21 AM
/*
* 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;