2013-08-15 08:25 PM
I am using the STM32F103 to interface with a FPGA over SPI and I am having the following issue.
When I am reading a 32 bit variable from the FPGA (4 bytes) it seems to work fine with the first communication and then have a problem with the remaining time I read it. It looks like it is still using data from the previous read in to the new one. If I reset the STM32 in debug (not doing anything to the FPGA) it will read correctly for 1 time again. Here is an example read: Data sent is 56787 First read : 00 00 DD C0 (correct) Second read: C0 00 DD C0 (not right) My SPI code is the following uint32_t FPGASendVelocity(uint32_t velocityCommand ) { uint32_t i; uint32_t remaining = 0; uint8_t src_addr[5]; uint8_t inBuff[5] = {0,0,0,0,0}; uint8_t temp1, temp2, temp3, temp4; src_addr[0] = 2; // Send the set velocity command first // Send the 24 bit value src_addr[1] = velocityCommand >> 16; src_addr[2] = velocityCommand >> 8; src_addr[3] = velocityCommand; GPIO_WriteBit(GPIOC, GPIO_Pin_6, 0); // Set SSEL pin low for(delay=0; delay<SPIDELAY; delay++); // Delay due to timing issuse? for ( i = 0; i < 4; i++ ) { // Data out while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET); SPI_I2S_SendData(SPI1, src_addr[i]); // Data in while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET); inBuff[i] = SPI_I2S_ReceiveData(SPI1); for(delay=0; delay<SPIDELAY; delay++); } GPIO_WriteBit(GPIOC, GPIO_Pin_6, 1); // Set SSEL pin high remaining |= (inBuff[0] << 24); remaining |= (inBuff[1] << 16); remaining |= (inBuff[2] << 8); remaining |= (inBuff[3]); return remaining; } Any help would be appreciated Dave2013-08-16 01:57 PM
My Config is as follows:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC | RCC_APB2Periph_SPI1, ENABLE); void SPI_Configuration(void) { SPI_InitTypeDef SPI_InitStructure; 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_128; SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; SPI_Init(SPI1, &SPI_InitStructure); SPI_Cmd(SPI1, ENABLE); } /* Configure SPI1 pins: SCK, MISO and MOSI -------------------------------*/ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); // SSEL Pin GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOC, &GPIO_InitStructure);2013-08-16 02:25 PM
I'd probably do two things here:
Make sure I got RXNE clear before I started. Review two of these 32-bit transactions on a logic analyzer or scope, to better understand what was happening on the pins.2013-08-17 08:36 AM
Well I took your advice and I think the problem is in my FPGA code.
Checking for RXNE first did not fix the problem so I attached the scope and found the following. When I reset the STM32 it must toggle the chip select pin a few times and properly reset the send registers in the FPGA, after the reset the scope send looks good and the second sent looks like the data that I am getting on the STM32. Here it is after the reset: And here is the second transfer:2013-08-17 08:42 AM
I added this to the beginning of the send / receive function at it seems to have ''fixed'' the problem
GPIO_WriteBit(GPIOC, GPIO_Pin_6, 0); // Set SSEL pin low for(delay=0; delay<20; delay++); GPIO_WriteBit(GPIOC, GPIO_Pin_6, 1); // Set SSEL pin high for(delay=0; delay<20; delay++); So it looks like I need to do a proper code fix on the FPGA Thanks for the help Dave