2011-04-18 06:29 AM
2011-05-17 05:31 AM
Hey
What do you mean what part?2011-05-17 05:31 AM
What do you mean what part?
Which EXTERNAL FLASH MEMORY part are you using? It might help for someone here to read the specifications, and suggest some part appropriate settings.
2011-05-17 05:31 AM
Im using the Winbond W25X16 spiflash!
Here's the datasheet: http://www.winbond-usa.com/products/Nexflash/pdfs/datasheets/W25X16_32_64h.pdf I have connected /WP with /HOLD and VCC. (at the top on page 5) VCC: +3V Thanks for your help!2011-05-17 05:31 AM
For starters, it's definitely an 8-bit MSB device.
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; So 0x90 goes out most significant bit first (ie not using 0x09) The data clocks out on the rising clock edge, and read back on the falling clock. while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE)==RESET){} SPI_I2S_SendData(SPI1,0x9F); // 1001 1111 = hex 9F while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE)==RESET){} SPI_I2S_ReceiveData(SPI1); // Clear out any pending RX data SPI_I2S_SendData(SPI1,0x00); // Junk Byte while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE)==RESET){} mfg = SPI_I2S_ReceiveData(SPI1); // Manufactuer ID 0xEF while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE)==RESET){} SPI_I2S_SendData(SPI1,0x00); // Junk Byte while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE)==RESET){} memtype = SPI_I2S_ReceiveData(SPI1); while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE)==RESET){} SPI_I2S_SendData(SPI1,0x00); // Junk Byte while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE)==RESET){} capacity = SPI_I2S_ReceiveData(SPI1);2011-05-17 05:31 AM
Hey clive1, first i really wanna thank you for helping me with this!
I tried your code and my main looks like this right now: ============================================= int main(void) { uint16_t mfg = 0, memtype = 0, capacity = 0; //NVIC_Configuration(); RCC_Configuration(); GPIO_Configuration(); SPI_Configuration(); //memory ChipSelect must set high and thn low after powerup GPIO_SetBits(GPIOA, GPIO_Pin_4);//Chip select set high GPIO_ResetBits(GPIOA, GPIO_Pin_4);//Chip select set low for(;;){ //Chip select set low GPIO_ResetBits(GPIOA, GPIO_Pin_4); while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE)==RESET){} SPI_I2S_SendData(SPI1,0x9F); // 1001 1111 = hex 9F while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE)==RESET){} SPI_I2S_ReceiveData(SPI1); // Clear out any pending RX data SPI_I2S_SendData(SPI1,0x00); // Junk Byte while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE)==RESET){} mfg = SPI_I2S_ReceiveData(SPI1); // Manufactuer ID 0xEF while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE)==RESET){} SPI_I2S_SendData(SPI1,0x00); // Junk Byte while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE)==RESET){} memtype = SPI_I2S_ReceiveData(SPI1); while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE)==RESET){} SPI_I2S_SendData(SPI1,0x00); // Junk Byte while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE)==RESET){} capacity = SPI_I2S_ReceiveData(SPI1); //Chip select set high GPIO_SetBits(GPIOA, GPIO_Pin_4); } } ================================================ And the spi-config: ================================================ void SPI_Configuration(void) { SPI_InitTypeDef SPI_InitStructure; /* SPI_MASTER 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_2Edge; SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4; // 4 = 5Mhz SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; SPI_InitStructure.SPI_CRCPolynomial = 7; SPI_Init(SPI_COMMS, &SPI_InitStructure); /* Enable SPI_MASTER TXE interrupt */ SPI_I2S_ITConfig(SPI_COMMS, SPI_I2S_IT_TXE, ENABLE); /* Enable SPI_MASTER */ SPI_Cmd(SPI_COMMS, ENABLE); } ================================================= I dont know why you are sending 0x9F on your second row of the code but i tried it and my MISO is still dead. I also tried 0x90 but it didn't change anything. Here's a screenshot of the oscilloscope when sending 0x90: https://picasaweb.google.com/reckan/20Apr2011#5597560089271622738EDIT: I think i managed to attach the photo here aswell! Look under attachments! channel one (yellow) showing clock signal channel two (purple) showing data out (MOSI) channel three (blue) showing chip select channel four (green) showing data in (MISO) Its pretty zoomed out but it shows one loop. Im sending 0x90 first, followed by 3 0x00 junk bytes but channel 4 (green) is still not showing any signs of data being transferred. I also read in the datasheet, that to be able to receive the manufacturer and device id, you need to do following: ''The instruction is initiated by driving the /CS pin low and shifting the instruction code ''90h'' followedby a 24-bit address(A23-A0) of 000000h. After which, the Manufacturer ID for Winbond (Efh) and the Device ID are shifted out on the falling edge of CLK with most significant bit (MSB) first as shown in figure 18.'' So i have also tried sending: ============================= SPI_I2S_SendData(SPI1,0x90); // 1001 0000 = hex 90 while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE)==RESET){} SPI_I2S_SendData(SPI1,0x00); // 0000 0000 = hex 00 while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE)==RESET){} SPI_I2S_SendData(SPI1,0x00); // 0000 0000 = hex 00 while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE)==RESET){} SPI_I2S_SendData(SPI1,0x00); // 0000 0000 = hex 00 while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE)==RESET){} But that didn't change anything. So what else could be wrong? Once again, thanks for your help! //Fredrik
2011-05-17 05:31 AM
No one knows what could be wrong?
//Fredrik2011-05-17 05:31 AM
Check the HOLD line on flash memory. Flash memory gives response only if there is high state on this line.
2015-05-06 06:18 AM
Hello Clive,
I am trying to get the ID of Winbond SPI flash W25Q128FV. Here is my code. But I am not getting the SPI flash ID i.e EF4018 instead i am getting some random values. the value of ''Temp'' is changed when ever i want to debug the code.#include ''stm32f4_discovery.h''void Delay(uint32_t time);void SPI_GPIO();void SPI_Config();uint8_t SPI_SendByte(uint8_t byte);uint32_t mfg = 0, memtype = 0, capacity = 0;uint8_t DUMMY_BYTE = 0xFF;int main(void){ SPI_Config(); GPIO_InitTypeDef GPIO_InitStructure; /* Configure PD12, PD13, PD14 and PD15 in output pushpull mode */ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13| GPIO_Pin_14| GPIO_Pin_15; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOD, &GPIO_InitStructure); while(1) { GPIO_SetBits(GPIOA,GPIO_Pin_4); /*!< Deselect the FLASH: Chip Select high */ // Identity Check GPIO_ResetBits(GPIOA,GPIO_Pin_4); /*!< Select the FLASH: Chip Select Low */ SPI_SendByte(0x90); /*!< Read a byte from the FLASH */ Temp0 = SPI_SendByte(DUMMY_BYTE); /*!< Read a byte from the FLASH */ Temp1 = SPI_SendByte(DUMMY_BYTE); /*!< Read a byte from the FLASH */ Temp2 = SPI_SendByte(DUMMY_BYTE); /*!< Deselect the FLASH: Chip Select high */ GPIO_SetBits(GPIOA,GPIO_Pin_4); /*!< Deselect the FLASH: Chip Select high */ Temp = (Temp0 << 16) | (Temp1 << 8) | Temp2; GPIO_ToggleBits(GPIOD,GPIO_Pin_12| GPIO_Pin_13| GPIO_Pin_14| GPIO_Pin_15); Delay(5000000); }}void SPI_Config(){ SPI_InitTypeDef SPI_InitStructure; SPI_GPIO(); GPIO_SetBits(GPIOA,GPIO_Pin_4); /*!< Deselect the FLASH: Chip Select high */ // SPI Configuration SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; // Set to full duplex SPI_InitStructure.SPI_Mode = SPI_Mode_Master; // Transmit in master mode SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; // One packet of data is 8 bits wide SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; // Clock is Low when idle SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; // Data sampled at First edge SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; // Set the NSS Soft SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4; // SPI Frequency is SPI Bus Clock/4 SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; // Data is transmitted MSB first SPI_InitStructure.SPI_CRCPolynomial = 7; /*!< Specifies the polynomial used for the CRC calculation. */ SPI_Init(SPI1 , &SPI_InitStructure); SPI_Cmd(SPI1 , ENABLE);} void SPI_GPIO(){ GPIO_InitTypeDef GPIO_InitStructure; /* SPI Periph clock enable */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); /* Enable clock for used SPI IO pins */ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); /*!< Connect SPI pins to AF5 */ GPIO_PinAFConfig(GPIOA,GPIO_PinSource5,GPIO_AF_SPI1); // SCK GPIO_PinAFConfig(GPIOA,GPIO_PinSource6,GPIO_AF_SPI1); // MISO GPIO_PinAFConfig(GPIOA,GPIO_PinSource7,GPIO_AF_SPI1); // MOSI /* Pin 5=SCK, 6=MISO, 7=MOSI*/ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; GPIO_Init(GPIOA, &GPIO_InitStructure); /*!< Configure CS pin in output pushpull mode ********************/ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOA, &GPIO_InitStructure);}uint8_t SPI_SendByte(uint8_t byte){ /*!< Loop while DR register in not empty */ while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET); /*!< Send byte through the SPI1 peripheral */ SPI_I2S_SendData(SPI1, byte); /*!< Wait to receive a byte */ while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET); /*!< Return the byte read from the SPI bus */ return SPI_I2S_ReceiveData(SPI1);}void Delay(uint32_t time){ int i = 100000; for(; time != 0; time--) while(i!=0) i--; }2015-05-06 09:02 AM
If you want the 3 bytes returned to mean something why not use command 0x9F (JEDEC ID)
For 0x90 the FOURTH byte returned is 0x00, and the FIFTH and SIXTH are the IDPage 25 of the Manual might be instructivehttps://www.pjrc.com/teensy/W25Q128FV.pdf