2010-10-04 02:44 AM
STM32 system low temperature problem
2011-05-17 05:10 AM
Patrick, my problems seemed to clear up when I either added some delay before using the I2C and / or some delay before using the I2C.
I had suspected the crystal oscillator so added code to check it (it always worked fine). Also found that I could use the IWDG to reliably recover the system if it stalled at start up although with the code as shown, the IWDG doesn't fire - it just works OK. My code is below. I hate it that I couldn't pin down the problem to something specific but in the end just needed it to work and ship out! I put a request into ST technical support who were helpful but couldn't pin it on anything and (as you found) the part in general seems to work fine over a wide temperature range. Good luck with your problem. Please post if you find a solution. Thanks John F. int main(void) { //enable the Independent Watchdog IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); //access IWDG_PR and IWDG_RLR IWDG_SetPrescaler(IWDG_Prescaler_256); //256= ~156Hz (75% or 150% possible) IWDG_SetReload(1560); //12 bit down counter (0..n-1), ~10s (6.6s..13.3s) IWDG_ReloadCounter(); IWDG_Enable(); DBGMCU_Config(DBGMCU_IWDG_STOP, ENABLE); //Debug IWDG stopped when Core is halted //note SystemInit() was called in RCC_Configuration but is now called separately so that the //High Speed External Oscillator can be checked and action taken if it has not started SystemInit(); // //wait for ~1s (at 72MHz) with no compiler optimisation // for(Time = 0; Time < 2666666L; Time++); //bit RCC_CR_HSERDY will be set in RCC->CR if HSE has started, test and handle failure here if((RCC->CR & RCC_CR_HSERDY) == 0) HandleHSEFailure(); //else proceed as normal ... RCC_Configuration(); GPIO_Configuration(); USART_Configuration(); #ifdef STARTUP_MESSAGES Usart1SendString(''RCC, GPIO and Uart configured\r\n''); #endif ADC_Configuration(); #ifdef STARTUP_MESSAGES Usart1SendString(''ADC configured\r\n''); #endif DMA_Configuration(); #ifdef STARTUP_MESSAGES Usart1SendString(''DMA configured\r\n''); #endif NVIC_Configuration(); Timer1_Configuration(); Timer2_Configuration(); #ifdef STARTUP_MESSAGES Usart1SendString(''NVIC configured\r\n''); Usart1SendString(''TIM1 configured\r\n''); Usart1SendString(''TIM2 configured\r\n''); #endif I2C_Configuration(); #ifdef STARTUP_MESSAGES Usart1SendString(''I2C configured\r\n''); #endif2011-05-17 05:10 AM
Thanks for the code snippet John. I have a similar delay in my application, though mine is between 2 and 3 seconds long. I originally put it in to display a splash screen on the LCD, which also gives the SPI hardware time to ''power up'' before I actually start reading from it.
I'm considering this to be a hardware issue. I've been running back and forth to the freezer trying to test different things all night. There may be an issue with soldering since I retouched the terminals for the SPI with a soldering iron the device overcomes the SPI issue in a shorter manner of time. I'm not sure if it's my mind playing tricks on me, but I noticed above that there were some questions asked so I'll go into detail with that.
On my device, this is the first unit that I've varied the temperature, so before I go through the time an expense of building another one, I'd like to see if your device possesses any similarities since it seems that you and I are the only ones with almost identical issues.
1. Is your device hand soldered?
2. Do you have any other copies of the same device that have the same problem?
3. How far away is your I2C Peripheral from the STM32?
4. How thick are the traces between your I2C peripheral and the STM32?
5. Are there any other near by Peripherals or Power traces to your I2C Peripheral?
I'm sincerely hoping that it is not a fractured trace or electrical interference in the the design.
Thanks,
Patrick
2011-05-17 05:10 AM
I found the problem.
It was a hardware issue as I originally presumed. Well, a hardware issue that should've been handled by Software, an oversight on my part.
As I was trying to figure out the issue I found that if I took a can of compressed air and angled it so it would spray out only cold refrigerant onto the SPI Peripherals, then try and use the SPI, the MCU would freeze until the Peripheral warmed up.
I then tried alternating between the Cold Compressed air and the hot air from a Blow dryer to simulate hot and cold cycles, but only on the SPI Device, be it EEPROM or Flash in this case, and it would perform when warm, but freeze when cold.
I questioned heavily if the Chips that I was using on the SPI were faulty, but it didn't make any sense because I went through a number of different chips from different manufacturers with the same, or similar results.
Somewhere in the process I managed to zap my MCU with static electricity accidentally, so I had to go through the long process of building another board. As soon as the new board was up and running with all new components, I started testing, first with the refrigerator and had the same results. Then started cycling with Blow Dryer/Compressed air and had the same results.
I decided to take a look at all the lines on the Chip and see how I am controlling them. There are 6 lines commonly used on SPI, though it can run on as little as 4 lines with the other 2 lines held High.
The mandatory lines are SCK, MISO, MOSI and _CS
In my case I also had _HOLD and _W connected to the MCU on GPIOB Pins 10 and 11. After looking very closely at the circuit I found that these two pins would ''float.'' _W would almost always find its way up to VDD, but no matter what the condition, _HOLD would always seem to stay somewhere between Low and High.
I noticed that I wasn't controlling these pins at all in my Software. My mistake was that I took ST example SPI coding and slightly adapted it to work in my situation, but didn't address all of the pins.
With my new coding, on initialization I always force these pins HIGH with GPIO_Mode_Out_PP.
I also made another slight change and I'm not sure which one had the actual effect. My _CS line physically has a 100k pull up resistor as per the part Datasheets recommendation though the mode was set as Push Pull (GPIO_Mode_Out_PP). I switched this to Open Drain (GPIO_Mode_Out_OD), though it shouldn't make any difference as Push Pull on an Open Drain circuit should have the same effect, but I needed to make sure.
I did both tests, Freezer and the Compressed Air/Blow Dryer, none of which would hold up the device, it always ran flawlessly.
Long winded resolution with almost two full days of fighting to find the answer, but I'm happy that it now works reliably down to -10 Celsius and the weight is off my shoulders. Thanks for your help John. I hope this helps you in resolving your issue. If you do get a chance to work on this again, please let us know if you resolved the issue with any of my findings.
Thanks,
Patrick
2011-05-17 05:10 AM
Glad to hear your problem's fixed. Thanks for the comprehensive description. I still think my problems were some kind of race in the hardware which is avoided by the re-arrangement of initialisation. Nothing new to report.
John F.2011-05-17 05:10 AM
I have a correction
Correction: Regarding the last change that I made to my _CS line being placed on Open Drain. As open drain it would work fine for reading, but once I tried writing to the SPI it would freeze the MCU. I switched it back to Push Pull and I put it in the freezer for an hour. It works fine with reading and writing at my freezer temperature and there are no more startup issues.
So the only change that was necessary was making sure that my _W line and my _HOLD line were always held high, rather than their previous condition of Floating.
Thanks,
Patrick