cancel
Showing results for 
Search instead for 
Did you mean: 

Query on External flash memory interfacing with STM32F072XX over SPI bus

gmate1
Associate II
Posted on October 23, 2015 at 14:25

I've a custom board with STM32F073C8 SOC [1] and Spansion flash memory [2] among other things. This external flash memory (Spansion) on board is connected to STM32F072C8 over SPI bus. I'm planning to use STM32 as master and spansion flash memory as slave.

The pin connection is as follows:

STM SPANSION PURPOSE

PA.4 NCS Chip select (Negative logic)

PA.5 SCK Clock

PA.6 SI MOSI (Master out, Slave in)

PA.7 SO MISO (Master in, Slave out)

PB.0 NWP Write protect (Negative logic)

The setup is as follows:

1: Enable clock for GPIOA.

2: Configure GPIOA pins PA.{4,5,6,7} in Alternate function mode (AF_1)

3: Enable clock for GPIOB

4: Configure GPIOB, PB.0 as output mode

5: Configure SPI1 with NSS (Negative slave select as 'soft')

6: Reset chip select (in this case PA.4) and read configuration register (For spansion memory, it is RDCR(0x35) )

7: Send some consecutive dummy bytes (For this, I refered some example for a different flash memory, but I think, sending the dummy bytes are for timing purpose)

However, based on the above understanding and using some sample code in public domain, I tried to implement this communication between STM and Spansion, but I don't get anything (I think, I'm getting stuck in the loop, while trying to read the SPI flag status).

Please let me know, what am i missing? Code snip is below:

/* Spansion specific commands */
#define FLASH_RDCR 0x35 /* Read Configuration Register */
/* Dummy cycles read */
#define sFLASH_DUMMY_BYTE 0xA5
#define sFLASH_CS_LOW() GPIO_ResetBits(sFLASH_CS_GPIO_PORT, sFLASH_CS_PIN)
#define sFLASH_CS_HIGH() GPIO_SetBits(sFLASH_CS_GPIO_PORT, sFLASH_CS_PIN)
#define sFLASH_SPI SPI1
#define sFLASH_SPI_CLK RCC_APB2Periph_SPI1
#define sFLASH_SPI_SCK_PIN GPIO_Pin_5 /* PA.05 */
#define sFLASH_SPI_SCK_GPIO_PORT GPIOA /* GPIOA */
#define sFLASH_SPI_SCK_GPIO_CLK RCC_AHBPeriph_GPIOA
#define sFLASH_SPI_MISO_PIN GPIO_Pin_6 /* PA.06 */
#define sFLASH_SPI_MISO_GPIO_PORT GPIOA /* GPIOA */
#define sFLASH_SPI_MISO_GPIO_CLK RCC_AHBPeriph_GPIOA
#define sFLASH_SPI_MOSI_PIN GPIO_Pin_7 /* PA.07 */
#define sFLASH_SPI_MOSI_GPIO_PORT GPIOA /* GPIOA */
#define sFLASH_SPI_MOSI_GPIO_CLK RCC_AHBPeriph_GPIOA
#define sFLASH_CS_PIN GPIO_Pin_4 /* PA.04 */
#define sFLASH_CS_GPIO_PORT GPIOA /* GPIOA */
#define sFLASH_CS_GPIO_CLK RCC_AHBPeriph_GPIOA
#define sFLASH_SPI_WREN_PIN GPIO_Pin_0 /* PB.0 */
#define sFLASH_SPI_WREN_GPIO_PORT GPIOB 
#define sFLASH_WREN_GPIO_CLK RCC_AHBPeriph_GPIOB
void
sFLASH_LowLevel_Init(
void
)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable GPIOA PA.{4,5,6,7}*/
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
/* Write protect GPIOB PB.0*/
RCC_AHBPeriphClockCmd(sFLASH_WREN_GPIO_CLK, ENABLE);
/*!< sFLASH_SPI Periph clock enable SPI1 */
RCC_APB2PeriphClockCmd(sFLASH_SPI_CLK, ENABLE);
/*!< Configure GPIOA pins: SCK,MOSI,MISO,CS */
GPIO_InitStructure.GPIO_Pin = sFLASH_SPI_SCK_PIN|sFLASH_SPI_MOSI_PIN|sFLASH_SPI_MISO_PIN|sFLASH_CS_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_Init(sFLASH_SPI_SCK_GPIO_PORT, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource4, GPIO_AF_1);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_1);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_1);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_1);
/*!< Configure sFLASH_SPI pins: WREN */
GPIO_InitStructure.GPIO_Pin = sFLASH_SPI_WREN_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; 
GPIO_Init(sFLASH_SPI_WREN_GPIO_PORT, &GPIO_InitStructure);
}
void
sFLASH_Init(
void
)
{
SPI_InitTypeDef SPI_InitStructure;
sFLASH_LowLevel_Init();
/*!< Deselect the FLASH: Chip Select high */
sFLASH_CS_HIGH();
/*!< SPI 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_High;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(sFLASH_SPI, &SPI_InitStructure);
/*!< Enable the sFLASH_SPI */
SPI_Cmd(sFLASH_SPI, ENABLE);
}
uint8_t sFLASH_SendByte(uint8_t 
byte
)
{
/*!< Loop while DR register in not empty */
while
(SPI_I2S_GetFlagStatus(sFLASH_SPI, SPI_I2S_FLAG_TXE) == RESET);
/*!< Send byte through the SPI1 peripheral */
SPI_SendData8(sFLASH_SPI, 
byte
);
/*!< Wait to receive a byte */
while
(SPI_I2S_GetFlagStatus(sFLASH_SPI, SPI_I2S_FLAG_RXNE) == RESET);
/*!< Return the byte read from the SPI bus */
return
SPI_ReceiveData8(sFLASH_SPI);
}
uint32_t sFLASH_ReadID(
void
)
{
uint32_t Temp = 0, Temp0 = 0, Temp1 = 0, Temp2 = 0;
/*!< Select the FLASH: Chip Select low */
sFLASH_CS_LOW();
/*!< Send ''RDID '' instruction */
sFLASH_SendByte(FLASH_RDCR);
/*!< Read a byte from the FLASH */
Temp0 = sFLASH_SendByte(sFLASH_DUMMY_BYTE);
/*!< Read a byte from the FLASH */
Temp1 = sFLASH_SendByte(sFLASH_DUMMY_BYTE);
/*!< Read a byte from the FLASH */
Temp2 = sFLASH_SendByte(sFLASH_DUMMY_BYTE);
/*!< Deselect the FLASH: Chip Select high */
sFLASH_CS_HIGH();
Temp = (Temp0 << 16) | (Temp1 << 8) | Temp2;
return
Temp;
}
int
main(
void
)
{
sFLASH_Init();
/* i think, it does not return */
uint32_t ret = sFLASH_ReadID();
while
(1);
}

 
 [1] http://www.st.com/web/catalog/mmc/FM141/SC1169/SS1574/LN1823/PF259609
 [2] https://www.spansion.com/Support/Datasheets/S25FL128S_256S_00.pdf
 Thanks a lot for your help. 
 
#stm32f072 #stm32 #spi #solved
17 REPLIES 17
hainguyen9x4
Associate II
Posted on June 16, 2016 at 12:08

Have you success in this problem, i try to interface with flash spansion memory!

Could you give me some code interface with this flash memory, thank you

waiyang93
Associate II
Posted on July 19, 2016 at 08:55

Did you check your data with CRC? If yes how would you check and where to save it?

Posted on July 21, 2016 at 21:55

> Did you check your data with CRC? If yes how would you check and where to save it?

Please start your own thread. It's unlikely the OP watches this thread after several months.

JW

Posted on July 21, 2016 at 22:11

It would seem reasonably apparent that he isn't using the CRC

The STM32 SPI CRC works by accumulating a value as the transfer proceed, and when you are done you either switch the SPI data mode so it emits the CRC as the next byte, or you physically read the CRC accumulator and then send it as a byte.

So:

Does the SPI device you are using expect a CRC?

What device is this, and what CRC polynomial does it use?

Do you have any experience with CRCs in some other, non-STM32, context.

If you are just trying to CRC some arbitrary memory transfer, and write the CRC byte into memory, then you'd reset the CRC, send your N bytes of data, and then for the N+1 byte you'd supply the CRC. When reading you'd reset the CRC, pull you N bytes of data, and the N+1 byte, and the CRC register should be ZERO. ie you've done this mathematical long-division, and the value you wrote is perfectly divisible leaving a zero remainder/residual.

You could also generate your own 16-bit or 32-bit CRC for data you write, and append it after the data it describes.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
hainguyen9x4
Associate II
Posted on July 27, 2016 at 12:22

I'm using your code and I 

 erase->write->read I 

success

But I can't select one sector to read data, I erase sector(60)  and write to it

then I erase sector (44) an write to it

So now, I want to read data from sector(60) but I can't

Some one help me how to select one sector to read data from it,Pleases!!!

Thank!

Posted on July 27, 2016 at 14:04

Ok,

What STM32 part are you using?

What SPI Flash are you using?

Have you thoroughly reviewed the documentation for the flash part?

How is it connected?

Can you show the commands (bytes to/from the device) used to initialize it?

Can you show the ID and settings from the device?

Can you show the test code that does the Erase, Write, Read, Erase? Your test code, not the library/driver.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
hainguyen9x4
Associate II
Posted on July 28, 2016 at 05:32

Thank you!

I'm using FL256SAIF100, 

 Parameter 4-kB Sector Erase- 4P4E, Sector Erase 4SE DC,

I use SPI interface with ARM stm32f103vct6

So can you help me: Can select one sector to read or write

example: Select sector 40: write some data to it, then select sector 66 to write data, then back select sector 40 to read data!

What is command send by SPI interface to select one sector

Thank you!

Posted on July 28, 2016 at 06:53

So can you help me

Well it is not a part I have, and I'm not going to spend my time writing and debugging code for you, if that is what you are expecting. I can help you with some of the datasheet stuff, but you're going to have to understand enough of the basics for that to work.

The programming (write) commands are typically byte addresses within the memory, sent as 24-bit or 32-bit addresses.

What I might do with a blank device is write a data pattern across the memory, confirm I can read that back, and that I could read random bytes within the array properly. Then I'd try the erase commands, erase one sector, and then see how much of the array it erased.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..