I am using stm32f103rct6 to interface spi flash. I have written code in CMSIS core and trying to read JEDEC ID of spi flash.
Here is my SPI Write Function.
uint8_t SPI3_Write(uint8_t value)
{
uint8_t retVal; //Initializing variable to store return value
while (!(SPI3->SR & SPI_SR_TXE)); //Wait till Transmit buffer is Empty
SPI3->DR = value; //Send SPI data
while (!(SPI3->SR & SPI_SR_RXNE)); //Wait till receive buffer is Empty
retVal = SPI3->DR & 0xFF; //As frame format is 8 bit, storing LSB - Bit[0:7]
return(retVal); //Returning the value recieved
}
Here is how i’m reading JEDEC ID
uint32_t Read_ID()
{
uint32_t Temp = 0, Temp0 = 0, Temp1 = 0, Temp2 = 0;
CS_LOW();
SPI3_Write(DEVICE_ID); //DEVICE_ID = 0x9F
//DUMMY_BYTE = 0x00
Temp0 = SPI3_Write(DUMMY_BYTE);
Temp1 = SPI3_Write(DUMMY_BYTE);
Temp2 = SPI3_Write(DUMMY_BYTE);
CS_HIGH();
Temp = (Temp0 << 16) | (Temp1 << 8) | Temp2;
return Temp;
}
According to the DATASHEET
and values will be like(as i m a new user cant put 2 images it’s all in winbond data sheet : https://www.winbond.com/resource-files/w25q16dv_revi_nov1714_web.pdf
page-22 7.2.4 Instruction Set Table 3 (ID, Security Instructions) )
Temp0 will be MF7-MF0, Temp1 will be ID15-ID8 and Temp2 will be ID7-ID0
therefore, Temp0 = 0xEF, Temp1 = 0x40 and Temp2 = 0x15 and Temp = 0x00EF4015 (not sure)
but i am getting Temp as 0.(While i am sending DUMMY_BYTE through SPI i am not getting anything back and reading the same value form the SPIx->DR register thinking that slave has sent me something cuz as SPI is full duplex I should get a value for a value)
I guess there is some thing wrong with my SPI_Write() function
My SPI init be like.
void SPI3_Init()
{
RCC->APB1ENR |= RCC_APB1ENR_SPI3EN; //Initialize clocks
SPI3->CR1 |= SPI_CR1_BR_2; //Set Prescale for SPI
SPI3->CR1 |= SPI_CR1_BIDIMODE; //Select SPI as Bi-Directional as to read and write
SPI3->CR1 |= SPI_CR1_MSTR; //Select Device as master
SPI3->CR1 &= ~SPI_CR1_DFF; //Select 8-Bit Data
/*For Software NSS*/
SPI3->CR1 |= SPI_CR1_SSM; //Set SSM bit
SPI3->CR1 |= SPI_CR1_SSI; //Clear SSI bit
SPI3->CR1 &= ~SPI_CR1_LSBFIRST; //Select MSB first
SPI3->CR1 |= SPI_CR1_CPOL; //Select CPOL (clock polarity) High CK to 1 when idle
SPI3->CR1 |= SPI_CR1_CPHA; //Select CPHA (clock Phase) to The second clock transition is the first data capture edge
}
My GPIO Init Be like
void GPIO_Init()
{
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN; //Clock for Port A - as PA15 is CS
RCC->APB2ENR |= RCC_APB2ENR_IOPBEN; //Clock for Port B - as PB3(SCK), PB4(MISO) & PB5(MOSI)
RCC->APB2ENR |= RCC_APB2ENR_AFIOEN; //ENABLE clock for alternate function
/*LED Configuration - PA8*/
GPIOA->CRH |= GPIO_CRH_MODE8; /Output mode, max speed 50 MHz.
GPIOA->CRH &= ~GPIO_CRH_CNF8; //General purpose output push-pull
/*CS Configuration - PA15*/
GPIOA->CRH |= GPIO_CRH_MODE15; //Output mode, max speed 50 MHz.
GPIOA->CRH &= ~GPIO_CRH_CNF15; //General purpose output push-pull
/*MISO Configuration - PB4(MISO)*/
GPIOB->CRL |= GPIO_CRL_MODE4; //Output mode, max speed 50 MHz.
GPIOB->CRL |= GPIO_CRL_CNF4_1; //Alternate Function output push-pull
/*MOSI Configuration - PB5(MOSI)*/
GPIOB->CRL |= GPIO_CRL_MODE5; //Output mode, max speed 50 MHz.
GPIOB->CRL |= GPIO_CRL_CNF5_1; //Alternate Function output push-pull
/*SCK Configuration - PB3(SCK)*/
GPIOB->CRL |= GPIO_CRL_MODE3; //Output mode, max speed 50 MHz.
GPIOB->CRL |= GPIO_CRL_CNF3_1; //Alternate Function output push-pull
}
And my Main is:
int main(void)
{
SPI3_Init();
GPIO_Init();
AFIO->MAPR |= AFIO_MAPR_SWJ_CFG_1;
SPI_ENABLE();
LED_LOW();
Blink_Led(1000);
CS_LOW();
uint32_t ID = Read_ID();
if (ID == 0x00EF4015)
{
LED_HIGH();
}
else
{
LED_LOW();
}
while(1)
{
}
}
Any suggestion will be really helpful
Thanks in advance