HAL_GetTick() always returns 0 - stm32

I'm currently working on a project with an existing codebase where HAL_GetTick() works in some places, but when I try to call the function in other files it returns 0.
HAL_Delay() does work for some reason.
Am I missing something obvious?

It sounds to me that your codebase may have an override for that function. See this post about HAL_GetTick():
STM32 and HAL function GetTick()
As an alternative you can do the following. If you know the frequency of a timer you can use the following code snippet:
const uint32_t freq = 1000000; // Freq in Hz
uint32_t get_ticks()
{
uint32_t ticks = __HAL_TIM_GET_COUNTER(&htim2);
return ticks;
}
double ticks_to_seconds(uint32_t ticks)
{
double seconds = (double) ticks/freq;
return seconds;
}

The internal (global) tick counter variable used by the HAL is incremented in an ISR. If you happened to disable IRQs without, the counter won't be incremented any more. The same applies if you didn't enable interrupts at all since startup.
Note: You reported the (reproducible?) result value 0, which hints that the tick counter has never been incremented since power-up. This points us to the assumption that you forgot to
enable the underlying interrupt (SysTick unless you selected some TIM, e.g., in CubeMX)
enable interrupts globally
retain the CubeHAL SysTick/TIMx handler code after you replaced it by your own (<-- less realistic option...).

I forgot to mention that I also use LoRaWAN. Apparently LoRaWAN also has functions like HAL_InitTick() and HAL_Delay(). I've come to the conclusion that LoRaWAN somehow overrides the timer.
How I fixed this was by going into mlm32I0xx_hal_msp.c and redefine HAL_GetTick():
uint32_t HAL_GetTick(void){
return HW_RTC_Tick2ms(HW_RTC_GetTimerValue());
}
Hopefully I can help someone else with this solution.

Related

STM32 HAL Lib,Can not clear TIM SR register by use __HAL_TIM_CLEAR_FLAG?

The TIM SR register value always be 0x1F, And Can not use to clear the reg.
HAL Lib Always runs into time interrupt really fast, and Can not clear SR register.
How to fix the promble?
Cubemx set
NVIC
`
void TIM3_IRQHandler(void)
{
/* USER CODE BEGIN TIM3_IRQn 0 */
/* USER CODE END TIM3_IRQn 0 */
HAL_TIM_IRQHandler(&htim3);
/* USER CODE BEGIN TIM3_IRQn 1 */
/* USER CODE END TIM3_IRQn 1 */
}
`
`
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if ( htim == &htim3){
__HAL_TIM_CLEAR_FLAG(&htim3,TIM_FLAG_UPDATE) ;
HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_13) ;
}
}
`
I will base my explanation on STM32F746's TIM3. Timers across STM32 that share number are usually identical or very similar.
TIM3->SR has 0x1F? That's 5 flags set! TIM3 is a general purpose STM32 timer. These 5 flags mean you have counter interrupt and four capture/compare interrupt status flags set at the same time. Something weird is going on. Are you sure you're supposed to have those flags set? Well, if their interrupts are not enabled, it doesn't matter.
You can clear these flags in TIM3->SR by writing zero to the specific position you want to clear and 1 everywhere else. As per reference manual, this register ignores if you write 1. It doesn't set bits when you do that. It only resets when you write zero. So,
TIM3->SR = 0; //clear all interrupt flags
TIM3->SR = ~TIM_SR_UIF; //clear update interrupt flag only
This works because the bits in the reference manual are marked rc_w0 - read, clear by writing zero. If bits in your SR register work differently, you may have to clear them differently. For example, sometimes status register is read-only and you clear it via write to flag clear register. Check reference manual of your MCU.

STM32F411 DWT CYCCNT counter width

For some time I have been using the DWT cycle counter, CYCCNT in STM32F4 processors for timing operations. Everywhere I look, the assumption is that this is a 32 bit counter.
However, I am now using the STM32F411CE processor and it looks to me like there are only 31 bits.
I run this code:
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
DWT->CTRL |= 1;
uint32_t next = millis()+200;
DWT->CYCCNT = 0;
while(1){
while(next > millis()){
// do nothing
}
next += 200;
printf("%8lu %12lu\n",next,DWT->CYCCNT);
}
And observe the results on the terminal. The processor is running at 100MHz, so the counter increases by 20 million after 200ms. After a while the counter value wraps but it wraps at 2^31, not 2^32:
21435 2039916353
21635 2059916353
21835 2079916353
22035 2099916353
22235 2119916353
22435 2139916341
22635 12432705
22835 32432705
23035 52432705
23235 72432705
So, can anyone point me to any definitive information about the CYCCNT counter width on the STM32F411 processor? Or have I overlooked something embarrassingly simple?
UPDATE:
I ran the exact same code on a board containing an STM32F405 processor and got these results:
30419 4204732031
30619 4233532031
30819 4262332031
31019 4291132031
31219 24964735
31419 53764738
31619 82564738
31819 111364735
So it seems clear to me that the '405 processor CYCCNT register is 32 bit whereas the '411 processor is only 31 bit. Most odd!
UPDATE2:
A second board with the same processor type behaves perfectly as well. A friend also ran the code on his (different) '411 board with no problems. It now seems that the board itself is faulty or, possibly, the processor is broken. All the other processor functions appear correct. Looks like it is just time to swap out the processor.
The description of DWT_CYCCNT is in section C1.8.8 of the Arm V7m Architecture Reference manual which you can get from here
Section C1.8.3 says
CYCCNT is an optional free-running 32-bit cycle counter.
When implemented and enabled, CYCCNT increments on each cycle of the processor clock. When the counter
overflows it wraps to zero, transparently.
So this doesn't explain your findings.

Gstreamer 1.0 Pause signal

I need to detect when the current playing audio/video is paused. I cannot find anything for 1.0. My app is a bit complex but here is condensed code
/* This function is called when the pipeline changes states. We use it to
* keep track of the current state. */
static void state_changed_cb(GstBus *bus, GstMessage *msg, CustomData *data)
{
GstState old_state, new_state, pending_state;
gst_message_parse_state_changed(msg, &old_state, &new_state, &pending_state);
if(GST_MESSAGE_SRC(msg) == GST_OBJECT(data->playbin))
{
g_print("State set to %s\n", gst_element_state_get_name(new_state));
}
}
gst_init(&wxTheApp->argc, &argv);
m_playbin = gst_element_factory_make("playbin", "playbin");
if(!m_playbin)
{
g_printerr("Not all elements could be created.\n");
exit(1);
}
CustomData* data = new CustomData(xid, m_playbin);
GstBus *bus = gst_element_get_bus(m_playbin);
gst_bus_set_sync_handler(bus, (GstBusSyncHandler) create_window, data, NULL);//here I do video overly stuffs
g_signal_connect (G_OBJECT (bus), "message::state-changed", (GCallback)state_changed_cb, &data);
What do I do wrong? I cannot find working example on connecting such events on Gstreamer 1.0 and 0.x seems a bit different than 1.0 so the vast exaples there don't help
UPDATE
I have found a way to get signals. I run wxWidgets timer with 500ms time span and each time timer fires I call
GstMessage* msg = gst_bus_pop(m_bus);
if(msg!=NULL)
{
g_print ("New Message -- %s\n", gst_message_type_get_name(msg->type));
}
Now I get a lot of 'state-change' messages. Still I want to know if that message is for Pause or Stop or Play or End of Media (I mean way to differentiate which message is this) so that I can notify the UI.
So while I get signals now, the basic problem, to get specific signals, remains unsolved.
You have to call gst_bus_add_signal_watch() (like in 0.10) to enable emission of the signals. Without that you can only use the other ways to get notified about GstMessages on that bus.
Also just to be sure, you need a running GLib main loop on the default main context for this to work. Otherwise you need to do things a bit different.
For the updated question:
Check the documentation: gst_message_parse_state_changed() can be used to parse the old, new and pending state from the message. This is also still the same as in 0.10. From the application point of view, and conceptionally nothing much has changed really between 0.10 and 1.0
Also you shouldn't do this timeout-waiting as it will block your wxwidget main loop. Easiest solution would be to use a sync bus handler (which you already have) and dispatch all messages from there to some callback on the wxwidget main loop.

MSP430 clock problems after reset

I use the following routine to configure the clock of my MSP430 (msp430g2231) microcontroller:
void configure_clock(void) {
if (CALBC1_1MHZ == 0xFF || CALDCO_1MHZ == 0xFF) { // Checks the clock constants
while(TRUE); // If callibration constants are erased, TRAP!
}
BCSCTL1 |= CALBC1_1MHZ; // Sets DCO range
DCOCTL |= CALDCO_1MHZ; // Set DCO step and modulation
BCSCTL1 &= ~(XTS | XT2OFF); // Disables XT2 and sets low frequency mode
BCSCTL3 |= (LFXT1S_0 | XCAP_3); // Selects LFXT1 crystal with 12,5pF
do {
IFG1 &= ~OFIFG;
__delay_cycles(1000);
} while (IFG1 & OFIFG); // Waits until crystal stabilizes
BCSCTL2 |= (SELM_2 | SELS); // Selects SMCLK and MCLK from LFXT1CLK
}
The problem is that the first time the code runs (just after powering up the microcontroller) everything works as expected and I get 32768 kHz clock. But if I press the reset button on the board (MSP430 Launchpad) the clock does not seem to work correctly, the code executes much slowly (like 10 times or so). Any ideas on the clock configuration?
Thanks!
Pere
First you can look at the power supply voltage. In case there is some spike during the startup then DCO wont work. In that case try to use a delay right before the Alignment of the values to BCSCTL1.
__delay_cycles(10000);
BCSCTL1 = CALBC1_1MHZ; // Sets DCO range
This will ensure that the startup spike is suppressed.
The next suspect would be decoupling on your target board. I mean the Capacitor on the VCC as well as the one used in the Reset. TI recommends 1nF-2nF for the Reset line and a 0.1uF for the VCC. But in case you are using the LaunchPad as you platform then that should not be a problem.
Also for the calibration value assignments use assignment operators and not logical operators. As the other values being 0 is a default.
BCSCTL1 = CALBC1_1MHZ; // Set DCO
DCOCTL = CALDCO_1MHZ;
If you are planning to Run the XT2 it is not available in G2231. Its LFXT1 directly.
You dont need explicit initialization for the 32.768KHz crystal to work.
It just work when you power up. So the additional initialization step is not needed.
In order to find better help please have a look at slac463a for software examples related to clock setting.
The only things I can suggest with your code are below. Whether or not they fix your issue I don't know as it seems strange that the first run is OK but after a reset it is not. Do you access the clock configuration anywhere else? What code do you call on reset?
You always use bit manipulation to include or exclude values into the registers. You should start with a known value and then adjust bits from there otherwise you may be incorporating bits from a previous state. For example, instead of:
BCSCTL1 |= CALBC1_1MHZ;
BCSCTL1 &= ~(XTS | XT2OFF);
You can set it to a definitive value by doing something like this:
BCSCTL1 = XT2OFF | (CALBC1_1MHZ & 0x0F);
The other suggestion is that XT2OFF has to be set in order to turn off XT2. You are clearing the bit, so are leaving it on. This is in conflict with your comment so might be an error.

IPhone: different system timers?

I have been using mach_absolute_time() for all my timing functions so far. calculating how long between frames etc.
I now want to get the exact time touch input events happen using event.timestamp in the touch callbacks.
the problem is these two seem to use completely different timers. sure, you can get them both in seconds, but their origins are different and seemingly random...
is there any way to sync the two different timers?
or is there anyway to get access to the same timer that the touch input uses to generate that timestamp property? otherwise its next to useless.
Had some trouble with this myself. There isn't a lot of good documentation, so I went with experimentation. Here's what I was able to determine:
mach_absolute_time depends on the processor of the device. It returns ticks since the device was last rebooted (otherwise known as uptime). In order to get it in a human readable form, you have to modify it by the result from mach_timebase_info (a ratio), which will return billionth of seconds (or nanoseconds). To make this more usable I use a function like the one below:
#include <mach/mach_time.h>
int getUptimeInMilliseconds()
{
static const int64_t kOneMillion = 1000 * 1000;
static mach_timebase_info_data_t s_timebase_info;
if (s_timebase_info.denom == 0) {
(void) mach_timebase_info(&s_timebase_info);
}
// mach_absolute_time() returns billionth of seconds,
// so divide by one million to get milliseconds
return (int)((mach_absolute_time() * s_timebase_info.numer) / (kOneMillion * s_timebase_info.denom));
}
Get the initial difference between two i.e
what is returned by mach_absolute_time() initally when your application starts and also get the event.timestamp initially at the same time...
store the difference... it would remain same through out the time your application runs.. so you can use this time difference to convert one to another...
How about CFAbsoluteTimeGetCurrent?