2013-01-18 10:00 AM
Hi, I have this situatiom:
I have the original library of SPI for STM32F1 ''SPIRIT1_Library_Project'' In the file ''SDK_EVAL_Spirit_Spi_Driver.c'' I have a function ''SpiritSpiWriteRegisters(....)'' When porting this function is STM32F0 this function non work! Why , Are there a difference of F1 and F0 for SPI ? I do configure the SPI for STM32F0 in this mode:#define SPIRIT_SPI_PERIPH_NB SPI1
#define SPIRIT_SPI_PERIPH_RCC RCC_APB2Periph_SPI1
/* Defines for MOSI pin*/
#define SPIRIT_SPI_PERIPH_MOSI_PORT GPIOA
#define SPIRIT_SPI_PERIPH_MOSI_PIN GPIO_Pin_7
#define SPIRIT_SPI_PERIPH_MOSI_AF GPIO_AF_0
#define SPIRIT_SPI_PERIPH_MOSI_RCC RCC_AHBPeriph_GPIOA
#define SPIRIT_SPI_PERIPH_MOSI_RCC_SOURCE GPIO_PinSource7
/* Defines for MISO pin */
#define SPIRIT_SPI_PERIPH_MISO_PORT GPIOA
#define SPIRIT_SPI_PERIPH_MISO_PIN GPIO_Pin_6
#define SPIRIT_SPI_PERIPH_MISO_AF GPIO_AF_0
#define SPIRIT_SPI_PERIPH_MISO_RCC RCC_AHBPeriph_GPIOA
#define SPIRIT_SPI_PERIPH_MISO_RCC_SOURCE GPIO_PinSource6
/* Defines for SCLK pin */
#define SPIRIT_SPI_PERIPH_SCLK_PORT GPIOA
#define SPIRIT_SPI_PERIPH_SCLK_PIN GPIO_Pin_5
#define SPIRIT_SPI_PERIPH_SCLK_AF GPIO_AF_0
#define SPIRIT_SPI_PERIPH_SCLK_RCC RCC_AHBPeriph_GPIOA
#define SPIRIT_SPI_PERIPH_SCLK_RCC_SOURCE GPIO_PinSource5
/* Defines for chip select pin */
#define SPIRIT_SPI_PERIPH_CS_PORT GPIOA
#define SPIRIT_SPI_PERIPH_CS_PIN GPIO_Pin_8
#define SPIRIT_SPI_PERIPH_CS_RCC RCC_AHBPeriph_GPIOA
void SpiritSpiInit(void)
{
SPI_InitTypeDef SPI_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable SPI periph clock */ //ok
RCC_APB2PeriphClockCmd(SPIRIT_SPI_PERIPH_RCC, ENABLE);
/* Enable SCLK, MOSI, MISO and CS GPIO clocks */
RCC_AHBPeriphClockCmd(SPIRIT_SPI_PERIPH_MOSI_RCC | SPIRIT_SPI_PERIPH_MISO_RCC | SPIRIT_SPI_PERIPH_SCLK_RCC | SPIRIT_SPI_PERIPH_CS_RCC, ENABLE);
/* Configure the AF for MOSI, MISO and SCLK GPIO pins*/ //ok
GPIO_PinAFConfig(SPIRIT_SPI_PERIPH_MOSI_PORT, SPIRIT_SPI_PERIPH_MOSI_RCC_SOURCE, SPIRIT_SPI_PERIPH_MOSI_AF);
GPIO_PinAFConfig(SPIRIT_SPI_PERIPH_MISO_PORT, SPIRIT_SPI_PERIPH_MISO_RCC_SOURCE, SPIRIT_SPI_PERIPH_MISO_AF);
GPIO_PinAFConfig(SPIRIT_SPI_PERIPH_SCLK_PORT, SPIRIT_SPI_PERIPH_SCLK_RCC_SOURCE, SPIRIT_SPI_PERIPH_SCLK_AF);
/* Configure SPI pins:SCLK, MISO and MOSI */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; // GPIO_PuPd_UP;// G
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_3;
GPIO_InitStructure.GPIO_Pin = SPIRIT_SPI_PERIPH_SCLK_PIN;
GPIO_Init(SPIRIT_SPI_PERIPH_SCLK_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = SPIRIT_SPI_PERIPH_MISO_PIN;
GPIO_Init(SPIRIT_SPI_PERIPH_MISO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = SPIRIT_SPI_PERIPH_MOSI_PIN;
GPIO_Init(SPIRIT_SPI_PERIPH_MOSI_PORT, &GPIO_InitStructure);
/* Configure SPI pin: CS */
GPIO_InitStructure.GPIO_Pin = SPIRIT_SPI_PERIPH_CS_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_3;
GPIO_Init(SPIRIT_SPI_PERIPH_CS_PORT, &GPIO_InitStructure);
/* Configure SPI peripheral */
SPI_I2S_DeInit(SPIRIT_SPI_PERIPH_NB);
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
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_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64; //SPI_BaudRatePrescaler_4; /*Baud_Rate= fpclk/4=32MHz/4=8MHZ*/
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPIRIT_SPI_PERIPH_NB, &SPI_InitStructure);
SPI_Cmd(SPIRIT_SPI_PERIPH_NB, ENABLE); /* SPIRIT_SPI enable */
SpiritSPICSHigh();
}
but when run this function for read and write not work:
send function for read (write function some problem)
SpiritStatus SpiritSpiReadRegisters(uint8_t cRegAddress, uint8_t cNbBytes, uint8_t* pcBuffer)
{
uint16_t tmpstatus = 0x0000;
SpiritStatus *status=(SpiritStatus *)&tmpstatus;
uint8_t header[2];
uint8_t dummy=0xFF;
/* Built the header bytes */
header[0]=READ_HEADER;
header[1]=cRegAddress;
SPI_ENTER_CRITICAL();
/* Put the SPI chip select low to start the transaction */
SpiritSPICSLow();
for(volatile uint16_t i=0;i<CS_TO_SCLK_DELAY;i++);
/* Write the header bytes and read the SPIRIT status bytes */
for(int i=0; i<2; i++)
{
while (SPI_I2S_GetFlagStatus(SPIRIT_SPI_PERIPH_NB, SPI_I2S_FLAG_TXE) == RESET);
SPI_SendData8(SPIRIT_SPI_PERIPH_NB, header[i]);
while (SPI_I2S_GetFlagStatus(SPIRIT_SPI_PERIPH_NB, SPI_I2S_FLAG_RXNE) == RESET);
tmpstatus += ((uint16_t)(SPI_ReceiveData8(SPIRIT_SPI_PERIPH_NB)))<<((1-i)*8);
}
/* Read the registers according to the number of bytes */
for(int index=0; index<cNbBytes; index++)
{
while (SPI_I2S_GetFlagStatus(SPIRIT_SPI_PERIPH_NB, SPI_I2S_FLAG_TXE) == RESET);
SPI_SendData8(SPIRIT_SPI_PERIPH_NB, dummy);
while (SPI_I2S_GetFlagStatus(SPIRIT_SPI_PERIPH_NB, SPI_I2S_FLAG_RXNE) == RESET);
*pcBuffer = SPI_ReceiveData8(SPIRIT_SPI_PERIPH_NB);
pcBuffer++;
}
while (SPI_I2S_GetFlagStatus(SPIRIT_SPI_PERIPH_NB, SPI_I2S_FLAG_TXE) == RESET);
/* Put the SPI chip select high to end the transaction */
SpiritSPICSHigh();
SPI_EXIT_CRITICAL();
return *status;
}
2013-01-18 01:10 PM
Code itself doesn't look unreasonable.
Suggest you review the hardware connections, power, signal, and stick a scope on the interface and check it out.2013-01-19 12:59 AM
Thanks for
reply
, I modified codein this
way and
it seems to work
,is wrong?
SpiritStatus SpiritSpiReadRegisters(uint8_t cRegAddress, uint8_t cNbBytes, uint8_t* pcBuffer)
{
uint16_t tmpstatus = 0x0000;
SpiritStatus *status=(SpiritStatus *)&tmpstatus;
uint8_t header[2];
uint8_t dummy=0xFF;
/* Built the header bytes */
header[0]=READ_HEADER;
header[1]=cRegAddress;
SPI_ENTER_CRITICAL();
/* Put the SPI chip select low to start the transaction */
SpiritSPICSLow();
for(volatile uint16_t i=0;i<
CS_TO_SCLK_DELAY
;i++);
/* Write the header bytes and read the SPIRIT status bytes */
for(int
i
=
0
; i<2; i++)
{
SPI_SendData8(SPIRIT_SPI_PERIPH_NB, header[i]);
while (!(SPIRIT_SPI_PERIPH_NB->SR & SPI_SR_TXE));
while (SPIRIT_SPI_PERIPH_NB->SR & SPI_SR_BSY);
tmpstatus += ((uint16_t)(SPI_ReceiveData8(SPIRIT_SPI_PERIPH_NB)))<<((1-i)*8);
}
/* Read the registers according to the number of bytes */
for(int index=0; index<
cNbBytes
; index++)
{
SPI_SendData8(SPIRIT_SPI_PERIPH_NB, dummy);
while (!(SPIRIT_SPI_PERIPH_NB->SR & SPI_SR_TXE));
while (SPIRIT_SPI_PERIPH_NB->SR & SPI_SR_BSY);
*pcBuffer = SPI_ReceiveData8(SPIRIT_SPI_PERIPH_NB);
pcBuffer++;
}
// while (SPI_I2S_GetFlagStatus(SPIRIT_SPI_PERIPH_NB, SPI_I2S_FLAG_TXE) == RESET);
/* Put the SPI chip select high to end the transaction */
SpiritSPICSHigh();
SPI_EXIT_CRITICAL();
return *status;
}
2013-01-19 03:08 AM
I noticed with
original function ,
the software after
3 or 4
read / write
cycle , hangs in this point: while (SPI_I2S_GetFlagStatus(SPIRIT_SPI_PERIPH_NB, SPI_I2S_FLAG_RXNE) == RESET);2013-01-21 12:15 AM
From reading the manual (RM0091), the F0s have a more advanced SPI/I2S module than the rest. One of the differences is the FIFO. The RXNE event is governed by FRXTH bit in SPI_CR2, yet the ''library'' fails to set it according to the data size.
I just wonder how could it go to the 3-4th transmission; IMHO it should've hung immediately. JW2013-01-21 05:40 AM
wowww!! you are right''!!! ...thank you!
The library have a bug! Why ST not upgrade library?!?!2013-01-21 07:00 AM
Why ST not upgrade library?!?!
They must find bug first, being oversights after all. Hindsight can't retroactively fix things.2013-01-28 07:37 AM
F0 implements a new SPI peripheral. This is highlighted in the ''
''. Try to re-check again if you still have any updates to do according to this AN, then go back to us with more details on the said ''bug''. ST.MCUTo give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.