I'm working with the STM32L432KC and am relatively new to the embedded world. What happens if I write to a configuration register, wait some time, and then write to the register again with the same configuration. Does this have any effects?
For reference, I am using the STM32L432KC microcontroller. The register in question is the Reset and Clock Control (RCC), AHB2 Peripheral Clock Enable Register (RCC_AHB2ENR). I have a function that enables the clock for a GPIO port, by OR'ing in a bit. I am wondering if calling the function while the pin is active will have any effects.
There is no generic answer for all registers on all devices. The only correct course is to consult the data sheet or reference manual for the part concerned.
In the specific case of STM32L432 RCC_AHB2ENR all used bits are specified as "set and cleared by software" with no specific hardware action on read/write. This is true I believe for the RCC_AHB2ENR on all STM32. Note however that the unused bits are reserved and should not be set to any value other then the reset value - also defined in the reference manual and in this case all zero.
Some registers change value under hardware control, so re-writing a previously written value may have an effect. A simple example on your part is TIM1_CNT where if TIM1 is running the counter will have changed and rewriting it will effect its period and any capture/compare events or event output or PWM it may be used for.
Related
For my application (running on an STM32L082) I need accurate (relative) timestamping of a few types of interrupts. I do this by running a timer at 1 MHz and taking its count as soon as the ISR is run. They are all given the highest priority so they pre-empt less important interrupts. The problem I'm facing is that they may still be delayed by other interrupts at the same priority and by code that disables interrupts, and there seems to be no easy way to know this happened. It is no problem that the ISR was delayed, as long as I know that the particular timestamp is not accurate because of this.
My current approach is to let each ISR and each block of code with interrupts disabled check whether interrupts are pending using NVIC->ISPR[0] and flagging this for the pending ISR. Each ISR checks this flag and, if needed, flags the timestamp taken as not accurate.
Although this works, it feels like it's the wrong way around. So my question is: is there another way to know whether an IRQ was served immediately?
The IRQs in question are EXTI4-15 for a GPIO pin change and RTC for the wakeup timer. Unfortunately I'm not in the position to change the PCB layout and use TIM input capture on the input pin, nor to change the MCU used.
update
The fundamental limit to accuracy in the current setup is determined by the nature of the internal RTC calibration, which periodically adds/removes 32kHz ticks, leading to ~31 µs jitter. My goal is to eliminate (or at least detect) additional timestamping inaccuracies where possible. Having interrupts blocked incidentally for, say, 50+ µs is hard to avoid and influences measurements, hence the need to at least know when this occurs.
update 2
To clarify, I think this is a software question, asking if a particular feature exists and if so, how to use it. The answer I am looking for is one of: "yes it is possible, just check bit X of register Y", or "no it is not possible, but MCU ... does have such a feature, called ..." or "no, such a feature is generally not available on any platform (but the common workaround is ...)". This information will guide me (and future readers) towards a solution in software, and/or requirements for better hardware design.
In general
The ideal solution for accurate timestamping is to use timer capture hardware (built-in to the microcontroller, or an external implementation). Aside from that, using a CPU with enough priority levels to make your ISR always the highest priority could work, or you might be able to hack something together by making the DMA engine sample the GPIO pins (specifics below).
Some microcontrollers have connections between built-in peripherals that allow one peripheral to trigger another (like a GPIO pin triggering timer capture even though it isn't a dedicated timer capture input pin). Manufacturers have different names for this type of interconnection, but a general overview can be found on Wikipedia, along with a list of the various names. Exact capabilities vary by manufacturer.
I've never come across a feature in a microcontroller for indicating if an ISR was delayed by a higher priority ISR. I don't think it would be a commonly-used feature, because your ISR can be interrupted by a higher priority ISR at any moment, even after you check the hypothetical was_delayed flag. A higher priority ISR can often check if a lower priority interrupt is pending though.
For your specific situation
A possible approach is to use a timer and DMA (similar to audio streaming, double-buffered/circular modes are preferred) to continuously sample your GPIO pins to a buffer, and then you scan the buffer to determine when the pins changed. Note that this means the CPU must scan the buffer before it is overwritten again by DMA, which means the CPU can only sleep in short intervals and must keep the timer and DMA clocks running. ST's AN4666 is a relevant document, and has example code here (account required to download example code). They're using a different microcontroller, but they claim the approach can be adapted to others in their lineup.
Otherwise, with your current setup, I don't think there is a better solution than the one you're using (the flag that's set when you detect a delay). The ARM Cortex-M0+ NVIC does not have a feature to indicate if an ISR was delayed.
A refinement to your current approach might be making the ISRs as short as possible, so they only do the timestamp collection and then put any other work into a queue for processing by the main application at a lower priority (only applicable if the work is more complex than the enqueue operation, and if the work isn't time-sensitive). Eliminating or making the interrupts-disabled regions short should also help.
I have developed a custom STM32L475 board with one GPIO pin wired up for synchronization along some other circuitry for the synchronization, unfortunately we decided to route the generated sinus signal from module to module.
This is not optimal so I want to optimize so it is not the sinus signal which is routed from master module to slave modules, but to just transfer a digital trigger to restart the generation of a full sine wave.
To do this I need to be able to setup the MCU's to use the one GPIO pin on each MCU as both output and trigger for a timer.
To do this without an update of the HW I need to be able to combine:
1. Using the 3 pins (one from each MCU) as open drain outputs as an AND gate, this works.
2. I know the GPIO pin can be used as external trigger, triggering on a negative edge.
The question is, is it possible to trig a timer of an output pin using only one GPIO pin, to make the MCU which finalizes its sine generation first trigger itself and the other MCU's, and if so, how?
Please note, it must use the level of the output pin itself, eventhough it is an outputpin.
I am a HW developer, learning to do firmware for our HW, so I am kind of new to software development, so I am using HAL, please be nice
STM32L475 allows to configure a GPIO in different modes that must be (exclusively) selected through the corresponding GPIOx_MODER register:1
(Digital) Input mode
General purpose output mode
Alternate function mode
Analog mode
The alternate function applied in Alternate function mode must also be selected exclusively, through the corresponding GPIOx_AFRL or GPIOx_AFRH register, resp.2
The trigger for an interrupt or timer is an alternate function, and the output of a (analogue or digital) signal is a (different) alternate function, too.
Therefore, I think there is no solution to the given problem based on peripheral configuration.
1
Reference Manual, Rev 7:
See
Section 8.5.1 for GPIO mode selection
Figures 23/24 in Section 8.4 for explanation
2
ibid.:
See
Section 8.5.9 for GPIO alternate function selection
Section 8.4.2 for explanation
I'm working on one of Freesacle micro controller. This microcontroller has several reset sources (e.g. clock monitor reset, watchdog reset and ...).
Suppose that because of watchdog, my micro controller is reset. How can I save some data just before reset happens. I mean for example how can I understand that where had been the program counter just before watchdog reset. With this method I want to know where I have error (in another words long process) that causes watchdog reset.
Most Freescale MCUs work like this:
RAM is preserved after watchdog reset. But probably not after LVD reset and certainly not after power-on reset. This is in most cases completely undocumented.
The MCU will either have a status register where you can check the reset cause (for example HCS08, MPC5x, Kinetis), or it will have special reset vectors for different reset causes (for example HC11, HCS12, Coldfire).
There is no way to save anything upon reset. Reset happens and only afterwards can you find out what caused the reset.
It is however possible to reserve a chunk of RAM as a special segment. Upon power-on reset, you can initialize this segment by setting everything to zero. If you get a watchdog reset, you can assume that this RAM segment is still valid and intact. So you don't initialize it, but leave it as it is. This method enables you to save variable values across reset. Probably - this is not well documented for most MCU families. I have used this trick at least on HCS08, HCS12 and MPC56.
As for the program counter, you are out of luck. It is reset with no means to recover it. Meaning that the only way to find out where a watchdog reset occurred is the tedious old school way of moving a breakpoint bit by bit down your code, run the program and check if it reached the breakpoint.
Though in case of modern MCUs like MPC56 or Cortex M, you simply check the trace buffer and see what code that caused the reset. Not only do you get the PC, you get to see the C source code. But you might need a professional, Eclipse-free tool chain to do this.
Depending on your microcontroller you may get Reset Reason, but getting previous program counter (PC/IP) after reset is not possible.
Most of modern microcontrollers have provision for Watchdog Interrupt Instead of reset.
You can configure watchdog peripheral to enable interrupt , In that ISR you can check stored context on stack. ( You can take help from JTAG debugger to check call stack).
There are multiple debugging methods available if your micro-controller dosent support above method.
e.g
In simple while(1) based architecture you can use a HW timer and restart it after some section of code. In Timer ISR you will know which code section is consuming long enough than the timer.
Two things:
Write a log! And rotate that log to keep the last 30 min. or whatever reasonable amount of time you think you need to reproduce the error. Where the log stops, you can see what happened just before that. Even in production-level devices there is some level of logging.
(Less, practical) You can attach a debugger to nearly every micrcontroller and step through the code. Probably put a break-point that is hit just before you enter the critical section of code. Some IDEs/uCs allow having "data-breakpoints" that get triggered when certain variables contain certain values.
Disclaimer: I am not familiar with the exact microcontroller that you are using.
It is written in your manual.
I don't know that specific processor but in most microprocessors a watchdog reset is a soft reset, meaning that certain registers will keep information about the reset source and sometimes reason.
You need to post more specific information on your Freescale μC for this be answered properly.
Even if you could get the Program Counter before reset, it wouldn't be advisable to blindly set the program counter to another after reset --- as there would likely have been stack and heap information as well as the data itself may also have changed.
It depends on what you want to preserve after reset, certain behaviour or data? Volatile memory may or may not have been cleared after watchdog (see your uC datasheet) and you will be able to detect a reset after checking reset registers (again see your uC datasheet). By detecting a reset and checking volatile memory you may be able to prepare your uC to restart in a way that you'd prefer after the unlikely event of a reset occurring. You could create a global value and set it to a particular value in global scope, then if it resets, check the value against it when a reset event occurs -- if it is the same, you could assume other memory may also be the same. If volatile memory is not an option you'll need to have a look at the datasheet for non-volatile options, however it is also advisable not to continually write to non-volatile memory due to writing limitations.
The only reliable solution is to use a debugger with trace capability if your chip supports embedded instruction trace.
Some devices have an option to redirect the watchdog timeout to an interrupt rather then a reset. This would allow you to write the watchdog timeout handler much like an exception handler and dump or store the stack information including the return address which will indicate the location the interrupt occurred.
However in some cases, neither solution is a reliable method of achieving your aim. In a multi-tasking environment or system with interrupt handlers, the code running when the watchdog timeout occurs may not be the process that is causing the problem.
I'm implementing a Timer 1 (which is basically a comparator & capture timer ) in comparator mode with single-shot mode operation? There's an option for starting the timer in continuous mode too.
My question is when I start the timer in single shot mode , after it reaches a mentioned count & compares, it will generate an interrupt flag but then does it mean that the timer is also stopped?
or do I need to stop it explicitly in single -shot mode too? I think it makes sense only in continuous mode?
I'm currently checking only the generated interrupt flag & assuming the timer is stopped & clearing the interrupt flag for further operation & the n come out of my function.
however, there is a control bit in the control register of the timer which can be toggled to make it run or stop? Should I just check the bit after the interrupt flag has generated or do I need to reset this control bit too? Which means I should have an explicit function to stop the timer as well?
Additional Information -
I'm using NXP (Philips ) controller.
Thank you in advance,
Prateek
I just got to read in the NXP datasheet that yes, If any timer, started in single shot (one- shot) mode will stop automatically.
Btw, If any one of you have any explanation kindly, put it below.
Thank you.
To understand microcontroller timers, just have to first realize that there is generally just one single main timer running. When enabled, this timer counts up until it overflows and then starts over.
When you start a "hardware timer", you only set up a register with a timer value which holds the value main_timer + delay. The hardware compares this register with the main timer at every tick, and when they match, it triggers an interrupt, sets a port or whatever you have configured it to do. Typically, you'd have to set up your timer register anew after that.
More more specific answers you have to specify the MCU family and part number used. NXP has made everything from ancient 8051 to modern ARM Cortex, and the timer peripheral hardware will be different for every MCU family.
I'm looking for a way to determine whether an ARM processor is booting from a cold boot (i.e. initial power-on) versus a warm boot (i.e. reset assertion without actual power loss). Specifically I'm using an ARM968 core, will be making the determination using C or assembly, and I will use the determination so certain operations only run on the initial power-on and not on subsequent resets. In previous projects I've leveraged external circuitry (e.g. FPGA) to detect the different boot scenarios, but in this case I am limited to the ARM core.
Check the docs for you specific chip ("ARM968" is not specific enough). There should be a register that describes the cause of reset. E.g. here's what LPC23xx has:
Reset Source Identification Register (RSIR - 0xE01FC180)
This register contains one bit for each source of Reset. Writing a 1 to any of these bits
clears the corresponding read-side bit to 0. The interactions among the four sources are
described below.
Bit Symbol Description
0 POR Assertion of the POR signal sets this bit, and clears all of the other bits in
this register. But if another Reset signal (e.g., External Reset) remains
asserted after the POR signal is negated, then its bit is set. This bit is not
affected by any of the other sources of Reset.
1 EXTR Assertion of the RESET signal sets this bit. This bit is cleared by POR,
but is not affected by WDT or BOD reset.
2 WDTR This bit is set when the Watchdog Timer times out and the WDTRESET
bit in the Watchdog Mode Register is 1. It is cleared by any of the other
sources of Reset.
3 BODR This bit is set when the 3.3 V power reaches a level below 2.6 V.
If the VDD(DCDC)(3V3) voltage dips from 3.3 V to 2.5 V and backs up, the
BODR bit will be set to 1.
If the VDD(DCDC)(3V3) voltage dips from 3.3 V to 2.5 V and continues to
decline to the level at which POR is asserted (nominally 1 V), the BODR
bit is cleared.
if the VDD(DCDC)(3V3) voltage rises continuously from below 1 V to a level
above 2.6 V, the BODR will be set to 1.
This bit is not affected by External Reset nor Watchdog Reset.
Note: Only in case when a reset occurs and the POR = 0, the BODR bit
indicates if the VDD(DCDC)(3V3) voltage was below 2.6 V or not.
You can initialize a global variable in RAM to a value that is unlikely during cold boot, and check for that during boot.
For microcontrollers normally the reset logic of the specific chip provides a status register, which indicates the source of the reset. I don't know if that exists for this bigger core, and whether you could use that.
It is likely to be difficult, and maybe you dont really mean just the core itself. The core should have gotten a reset, but the memory outside (but perhaps still within the chip) did not. if the memory is dram based then it may still get wiped on boot. I dont know of a generic one size fits all answer. both you and starblue have it though, you have to find some register somewhere that is not cleared on a reset, set that to something that is "likely" not to happen randomly on a power up. read it then set it. thinks like the fpga or pld that manage the reset logic at the board level (if any) are the best because on a power on reset they are reset as well, and on a warm reset they are the one that caused it and keep their state.
dig through the TRM for your core or through the register spec for the chip, and see if there are any registers whose reset state is undefined, one that you normally dont use and wont hurt the chip if you set it to something, and see what it powers up as, that is where I would start looking.