2012-04-04 04:00 PM
Hi, I need some ideas on a problem I'm experiencing.
I have an STM32F2xx based product (an automotive sensor of sorts) which has just started field testing. The electrical interface to the product is 4 wires - +V, GND, CAN+ and CAN-.Most of the time the product starts fine (as observed by the CAN stream), but every so often the product does not appear to start. I have not yet personally observed the fault - only seen the evidence of it. There are two variations:1) If the product starts correctly, then it does not appear to stop working at any stage.2) If the product doesn't start, then it wont recover until the next power cycle.I am suspicious that the STM32 is somehow entering boot loader mode on startup. I have 10K pull down resistors on Boot 0 and Boot 1. The boot loader mode does not appear to have any sort of time out, which could explain why it gets stuck.Has anybody else experienced anything similar?Regards,Carl.2012-04-04 06:43 PM
Now, presuming you've got a handle on potential load-dump issues, and a thresholding power-on-reset.
It's most likely not going into the boot loader. Much more likely is an issue with a crystal not starting, or it getting stuck in one of a number of unbounded while() loops ST has in the start up code, for HSE, PLL lock, clock switch, etc. If possible try just using the 8 MHz HSI, or signalling where you are in the boot process with some GPIO/LED sequencing. The HSI doesn't have the tolerance for CAN, but might be sufficient to see if the device gets into the hang up mode. Consider if you can use a WatchDog to reset, or if a power cycle is needed.2012-04-10 05:23 PM
Hi Clive, and thank you for your insights.
You've certainly given me a bit more to think about; although I believe that I've allowed for most of the potential pitfalls you mention.I may have stumbled on the problem by accident in another project, and looking back at some code from late last year I notice I have a workaround that points to the same issue as well (except that back then I was an STM32F2 noob and didn't investigate further). I think the problem is with the initialisation of the GPIO peripherals. In my code I have the following sequence for setting up the GPIOs:RCC->AHB1ENR |= RCC_AHB1Periph_GPIOA;
GPIOA->MODER = 0x02A80000; GPIOA->OTYPER = 0x0000; GPIOA->OSPEEDR = 0x0114FFFF; GPIOA->PUPDR = 0x54550000; GPIOA->AFR[0] = 0x00000000; GPIOA->AFR[1] = 0x00099770;It seems that the MODER register is not always being set. In the various projects, different GPIO ports fail, and sometimes the process doesn't fail at all. If I insert a delay between setting the GPIO clock and setting it's registers, then all seems to be fine.
I went back to the reference manual, and while race issues are mentioned for other peripheral registers, there are no mentions for the GPIO that I can find. However, for me, I'll be including a short delay between setting peripheral clock, and accessing its registers from now on.Regards,Carl.2012-04-10 05:50 PM
Hi Carl,
That would sound like a pipeline or write-buffer issue. Add into that transitioning between buses with disparate rates. The APB access will take 4 cycles, the reads/writes should occur in program order, but might be interspersed with instruction fetches. The library avoids some of this by masking on bits in a Read-Modify-Write fashion, and breaking linear code flow, ie popping registers, branching back from subroutines. One of the hazards that's easy to generate is clearing an interrupt immediately prior to exiting the service routine, the NVIC/peripheral doesn't clear quickly enough, and you tail chain with a spurious interrupt, ie it re-enters, but nothing is actually pending. Perhaps another reason to use the library, it's these kinds of things that can sink a lot of time.2012-05-02 01:25 AM
I've seen the same problem in my application, and nailed it down quite carefully and precisely. Adding two NOPs between the store to AHB1ENR and the store to GPIOB_MODER (in my case) reliably works fine. Adding one or zero NOPs between the stores fails reliably, at least on the 16 MHz HSI.