2015-10-21 03:24 PM
Good day everybody,
I'm having an usual problem on STM32F407 SPI. I'm using a STM32F407 discovery board with a custom made breakout board (SPI2 pins used are PB13, PB14 and PB15 and are connected to a AD7190 ADC through 100ohm resistors). Compiled program (about 4k) is downloaded to RAM and executed. Until now the board gave me no problem. A basic description of the problem is that the SPI stops to work after a (seemingly random) number of bytes send. Stripped down code is: int main(void) { initializeUSART(&USART0); putString(&USART0,''Usart ok''); putNewLine(&USART0); RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE); GPIO_PinAFConfig(GPIOB,GPIO_PinSource12,GPIO_AF_SPI2); GPIO_PinAFConfig(GPIOB,GPIO_PinSource13,GPIO_AF_SPI2); GPIO_PinAFConfig(GPIOB,GPIO_PinSource14,GPIO_AF_SPI2); GPIO_PinAFConfig(GPIOB,GPIO_PinSource15,GPIO_AF_SPI2); GPIO_InitTypeDef setting; GPIO_StructInit(&setting); setting.GPIO_Pin=GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15; setting.GPIO_Mode = GPIO_Mode_AF; setting.GPIO_OType = GPIO_OType_PP; setting.GPIO_Speed = GPIO_Speed_50MHz; setting.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOB, &setting); SPI_I2S_DeInit (SPI2); SPI_InitTypeDef spiSetting; SPI_StructInit (&spiSetting); spiSetting.SPI_BaudRatePrescaler=SPI_BaudRatePrescaler_2; spiSetting.SPI_Direction=SPI_Direction_2Lines_FullDuplex; spiSetting.SPI_Mode=SPI_Mode_Master; spiSetting.SPI_DataSize=SPI_DataSize_8b; spiSetting.SPI_CPOL=SPI_CPOL_High; // 1 when clock is idle spiSetting.SPI_CPHA=SPI_CPHA_2Edge; // Transmit data on second edge spiSetting.SPI_NSS=SPI_NSS_Hard; spiSetting.SPI_FirstBit=SPI_FirstBit_MSB; SPI_Init(SPI2,&spiSetting); SPI_Cmd(SPI2,ENABLE); //putNewLine(&USART0); for(int i=0;;i++) { while(SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_TXE)==RESET) { //msleep(100); putString(&USART0,''.''); } putNewLine(&USART0); putInt(&USART0,i,10); putNewLine(&USART0); SPI_I2S_SendData(SPI2,0x55); } } With this code i get correct signals for some (random?) number of bytes the suddenly SPI (the program stalls on while loop). Example outputs are: Usart ok 0 . 1 . 2 [...] 144 .................................................... (loop is blocked) Consecutive execution of program gave me following number of bytes sent and approximate time from start to program start: 1 350uS 172 16.2ms 256 24.7ms 271 26.2ms 179 17ms 108 9.8ms 245 23.6ms and so on. Can anybody think of a possible cause for this problem?2015-10-21 04:42 PM
Further strip down of problem. I removed the custom expansion board, connected oscilloscope directly to discovery board PB13 (clock). I kept code only for initializing the SPI and replaced calls to send data and query flags with direct writes/reads from register.
My problem is that if some time passes between consecutive writes to data register SPI locks. The following code still halts (after sending data for about 400-800ms, still random). Commenting the busy wait line makes program run (and send SPI data) forever. I really doubt it can be an hardware problem so it is probably something stupid done in initialization. Since i do not own a second board could anybody check if it is a common problem? Thank you and regards #include ''stm32f4xx_rcc.h'' #include ''stm32f4xx_gpio.h'' #include ''stm32f4xx_spi.h'' void initialize(void) { } int main(void) { RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE); GPIO_PinAFConfig(GPIOB,GPIO_PinSource12,GPIO_AF_SPI2); GPIO_PinAFConfig(GPIOB,GPIO_PinSource13,GPIO_AF_SPI2); GPIO_PinAFConfig(GPIOB,GPIO_PinSource14,GPIO_AF_SPI2); GPIO_PinAFConfig(GPIOB,GPIO_PinSource15,GPIO_AF_SPI2); GPIO_InitTypeDef setting; GPIO_StructInit(&setting); setting.GPIO_Pin=GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15; setting.GPIO_Mode = GPIO_Mode_AF; setting.GPIO_OType = GPIO_OType_PP; setting.GPIO_Speed = GPIO_Speed_50MHz; setting.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOB, &setting); SPI_I2S_DeInit (SPI2); SPI_InitTypeDef spiSetting; SPI_StructInit (&spiSetting); spiSetting.SPI_BaudRatePrescaler=SPI_BaudRatePrescaler_64; spiSetting.SPI_Direction=SPI_Direction_2Lines_FullDuplex; spiSetting.SPI_Mode=SPI_Mode_Master; spiSetting.SPI_DataSize=SPI_DataSize_8b; spiSetting.SPI_CPOL=SPI_CPOL_High; // 1 when clock is idle spiSetting.SPI_CPHA=SPI_CPHA_2Edge; // Transmit data on second edge spiSetting.SPI_NSS=SPI_NSS_Hard; spiSetting.SPI_FirstBit=SPI_FirstBit_MSB; SPI_Init(SPI2,&spiSetting); SPI_Cmd(SPI2,ENABLE); for(;;) { volatile int j; while(SPI2->SR&0x80); //0x02 for TXE for(j=0;j<5000;j++); // Comment this line to make everything work SPI2->DR=0x55; } }2015-10-21 09:46 PM
You wrote in your post that you run the code from RAM. How do you locate it there? Where are the variables and the stack located (don't they overlap the code?)
Do you have any interrupt in action? Disassembler is your friend. JW