2012-06-06 11:55 PM
I have read through many posts about SPI problems and configuration questions. I feel I have everything configured correctly, however I do not receive any data transferred across the MISO line. Below shows the configuration code used:
/////////////////////////////////////////////////////////////// Begin Config////////////////////////////////////////////////////////////////////////////////GPIO_InitTypeDef GPIO_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;SPI_InitTypeDef SPI_InitStructure; /* Enable the SPI clock */ SPIx_CLK_INIT(SPIx_CLK, ENABLE); /* Enable GPIO clocks */ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOI | RCC_AHB1Periph_GPIOC , ENABLE); /* Connect SPI pins to AF5 */ GPIO_PinAFConfig(GPIOI, GPIO_PinSource1, GPIO_AF_SPI2); // SPI SCLK GPIO_PinAFConfig(GPIOC, GPIO_PinSource3, GPIO_AF_SPI2); // MOSI GPIO_PinAFConfig(GPIOC, GPIO_PinSource2, GPIO_AF_SPI2); // MISO GPIO_PinAFConfig(GPIOI, GPIO_PinSource2, GPIO_AF_SPI2); // CS /* SPI CS pin configuration */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init (GPIOI, &GPIO_InitStructure); /* SPI SCK pin configuration */ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; GPIO_Init(GPIOI, &GPIO_InitStructure); /* SPI MOSI pin configuration */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; GPIO_Init(GPIOC, &GPIO_InitStructure); /* SPI MISO pin configuration */ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; GPIO_Init(GPIOC, &GPIO_InitStructure); /* SPI configuration -------------------------------------------------------*/ SPI_I2S_DeInit(SPI2); 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_2; SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; SPI_InitStructure.SPI_CRCPolynomial = 7; SPI_InitStructure.SPI_Mode = SPI_Mode_Master; SPI_Init(SPI2, &SPI_InitStructure); /* Configure the Priority Group to 1 bit */ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); /* Configure the SPI interrupt priority */ NVIC_InitStructure.NVIC_IRQChannel = SPIx_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure);//////////////////////////////////////////////////////////////////END CONFIG /////////////////////////////////////////////////////////ok so after this config (assuming its correct) I set the CS pin high and enable spi and interrupts :GPIO_WriteBit(GPIOI,GPIO_Pin_2, Bit_SET);SPI_Cmd(SPI2, ENABLE);SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_TXE, ENABLE);SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_RXNE, ENABLE);Next I Transmit a 0x9F out to an EEPROM to read the device ID. ( CS is active low and is MSB first) GPIO_WriteBit(GPIOI,GPIO_Pin_2, Bit_RESET); // CS LOW SPI_I2S_SendData(SPI2, 0x9F); // Send DataEvery time the TxE is empty it sends out the 9F. The RXNE does go high and i read the first received 512 bytes in the DR as follows: if (SPI_I2S_GetITStatus(SPI2, SPI_I2S_IT_RXNE) == SET) { if (Rx_Idx < 512) { RxBuffer[Rx_Idx++] = SPI_I2S_ReceiveData(SPI2); } else { SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_RXNE, DISABLE); GPIO_WriteBit(GPIOI,GPIO_Pin_2, Bit_SET);// CS HIGH int x = 0; }}On the oscilloscope I do see data across the MISO line ( Device ID ) but I do not receive it in the micro rx buffer.Any suggestions would be of great help; Maybe I overlooked something. Thanks in advanced for your help #spi #stm322012-06-07 02:47 AM
The topic line is slightly misleading: you are trying to use the SPI module in I2S mode, and that makes a substantial difference.
Please read the user manual, chapter 25.2.2 I2S features, the very first line states: ''Simplex communication (only transmitter or receiver). You would need to use two SPI modules, one as master transmitter and other as slave receiver (with appropriately connected clock pins) to achieve a 4/5-wire full-duplex ISP connection. On the other hand, your remark: > Next I Transmit a 0x9F out to an EEPROM to read the device ID. leads me to think that you simply misunderstood the purpose of I2S. JW2012-06-07 06:28 AM
Where does it indicate that i am using I2S mode?
I need to be using SPI where the MC is the master and EEPROM is the Slave. I am a little confused by your response. Maybe your right but can you please explain a little more? Thanks2012-06-07 06:58 AM
> Where does it indicate that i am using I2S mode?
Nowhere, indeed. I must have been obsessed by I2S after having spent a day of hunting down errors in it... :) Sorry. JW2012-06-07 07:34 AM
2012-12-06 07:29 AM
Rob,
Did you find a solution? I'm seeing the same issue. I can see the data on MISO, but I can't capture it for whatever reason. Any help greatly appreciated. Thanks Bob2012-12-06 08:46 AM
Did you find a solution? I'm seeing the same issue. I can see the data on MISO, but I can't capture it for whatever reason. Any help greatly appreciated.
With METOO issues it always helps to explain your specific situation, and provide code and connectivity details. There are thousands of reasons why things don't work, and they are not always identical.2012-12-10 01:45 PM
I'm trying to read and write data to the ST 95M02 EEProm, using SPI2 port on a stm32f051 processor. A simple test is to write to the status register and read back. I can see data from MOSI on the scope, but can't latch it in. The value returned is always 00h. Another issue is that the EEprom datasheet has some figures missing for flash read and flash write (even though they are referred to) which doesn't help matters.
If I could read the status register, then it would be a good start. From Main calling function .... // SPI configuration ------------------------------------------------------ SPI_Config(); WriteEnable(); SPI_statusReg_Write(0x01, 0x06); // Just a loop to monitor received data and view on scope for (ee_add = 0; ee_add<1000; ee_add++) { spi_rd_data = SPI_statusReg_Read(0x05); printf(''\n\r Spi data = %d'', spi_rd_data); } // Rest of calling function void SPI_Config(void) { SPI_InitTypeDef SPI_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; /* Enable the SPI peripheral */ // RCC_APB1PeriphClockCmd(SPIx_CLK, ENABLE); /* Enable SPI clock, SPI2 */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE); /* Enable SCK, MOSI, MISO and NSS GPIO clocks */ RCC_AHBPeriphClockCmd(SPIx_SCK_GPIO_CLK | SPIx_MISO_GPIO_CLK | SPIx_MOSI_GPIO_CLK | SPIx_NSS_GPIO_CLK , ENABLE); /* SPI pin mappings */ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_3; /* SPI SCK pin configuration */ GPIO_InitStructure.GPIO_Pin = SPIx_SCK_PIN; GPIO_Init(GPIOB, &GPIO_InitStructure); /* SPI MOSI pin configuration */ GPIO_InitStructure.GPIO_Pin = SPIx_MOSI_PIN; GPIO_Init(GPIOB, &GPIO_InitStructure); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE); /* SPI MISO pin configuration */ GPIO_InitStructure.GPIO_Pin = SPIx_MISO_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; // This needs to have a PULL-UP otherwise only driven to half the required level GPIO_Init(GPIOB, &GPIO_InitStructure); /* SPI NSS pin configuration */ // GPIO_InitStructure.GPIO_Pin = SPIx_NSS_PIN; // GPIO_Init(GPIOB, &GPIO_InitStructure); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE); /* Configure CS pin as output floating */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOB, &GPIO_InitStructure); /* SPI configuration -------------------------------------------------------*/ SPI_I2S_DeInit(SPIx); 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_Soft; SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4; SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; SPI_Init(SPIx, &SPI_InitStructure); SPI_SSOutputCmd(SPIx, ENABLE); SPI_Cmd(SPIx, ENABLE); } void WriteEnable(void) { EEPROM_CS_LOW; SPI_SendData8(SPIx, 0x06); // Wait for SPI Tx buffer empty while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_TXE) != SET); // Clear receive buffer Clr_Rcv_Buf(); EEPROM_CS_HIGH; uint8_t SPI_statusReg_Write(uint8_t ins, uint8_t data) { EEPROM_CS_LOW; // Send SPI instruction SPI_SendData8(SPIx, ins); while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_TXE) != SET); Clr_Rcv_Buf(); SPI_SendData8(SPIx, data); while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_TXE) != SET); Clr_Rcv_Buf(); EEPROM_CS_HIGH; return (1); } uint8_t SPI_statusReg_Read(uint8_t ins) { // Delay between instruction and data read back uint8_t spi_rd_data; EEPROM_CS_LOW; // Send SPI instruction SPI_SendData8(SPIx, ins); // Wait for SPI Tx buffer empty while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_TXE) != SET); Clr_Rcv_Buf(); // Send Dummy Byte for Clocks SPI_SendData8(SPIx, 0xFF); // Wait for the data while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_RXNE) == RESET); // read the received data from the register spi_rd_data = SPI_ReceiveData8(SPIx); // wait for finish while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_BSY) == SET); EEPROM_CS_HIGH; return (spi_rd_data); } void Clr_Rcv_Buf(void) { uint8_t spi_rd_data; /* Clears the receive buffer or we would get overrun errors */ if (SPI_I2S_GetFlagStatus(SPIx,SPI_I2S_FLAG_RXNE) == SET) spi_rd_data = SPI_ReceiveData8(SPIx); }2012-12-10 06:19 PM
Bit of a mish-mash of styles there, absent the defines it's hard to clear up. You only need to enable a GPIO clock once, but it must occur prior to configuring the pins. You also need to route the SPI function to the pin's AF section using GPIO_PinAFConfig(GPIOx, GPIO_PinSourceX, GPIO_AF_X)
2012-12-11 12:53 AM
I had the following statements just after the GPIO pins configuration, but it made no difference so I removed them....The chip select wouldn't pulse so I had to drive it as an ordinary GPIO pin..hence the different styles.
GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, SPIx_SCK_AF); GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, SPIx_MISO_AF); GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, SPIx_MOSI_AF); GPIO_PinAFConfig(GPIOB, GPIO_PinSource12, SPIx_NSS_AF); Definitions follow #define EEPROM_CS_LOW GPIO_WriteBit(GPIOB,GPIO_Pin_12,Bit_RESET); #define EEPROM_CS_HIGH GPIO_WriteBit(GPIOB,GPIO_Pin_12,Bit_SET); #define SPI_DATASIZE SPI_DataSize_8b #define SPI_DATAMASK (uint8_t)0xFF #define SPIx SPI2 #define SPIx_CLK RCC_APB2Periph_SPI2 #define SPIx_SCK_PIN GPIO_Pin_13 #define SPIx_SCK_GPIO_PORT GPIOB #define SPIx_SCK_GPIO_CLK RCC_AHBPeriph_GPIOB #define SPIx_SCK_SOURCE GPIO_PinSource13 #define SPIx_SCK_AF GPIO_AF_0 #define SPIx_MISO_PIN GPIO_Pin_14 #define SPIx_MISO_GPIO_PORT GPIOB #define SPIx_MISO_GPIO_CLK RCC_AHBPeriph_GPIOB #define SPIx_MISO_SOURCE GPIO_PinSource14 #define SPIx_MISO_AF GPIO_AF_0 #define SPIx_MOSI_PIN GPIO_Pin_15 #define SPIx_MOSI_GPIO_PORT GPIOB #define SPIx_MOSI_GPIO_CLK RCC_AHBPeriph_GPIOB #define SPIx_MOSI_SOURCE GPIO_PinSource15 #define SPIx_MOSI_AF GPIO_AF_0 #define SPIx_NSS_PIN GPIO_Pin_12 #define SPIx_NSS_GPIO_PORT GPIOB #define SPIx_NSS_GPIO_CLK RCC_AHBPeriph_GPIOB #define SPIx_NSS_SOURCE GPIO_PinSource12 #define SPIx_NSS_AF GPIO_AF_0