STM32L476RG HAL_UARTEx_RxEventCallback never call - stm32

I'm curently working on a projet with a STM32F334 and a STM32L476RG and I have a problem to making them talking with eachother. I'm using a DMA global interrupt like explained here.
I noticed a difference into the 'main.c' of my both projects:
With the F334: MX_DMA_Init() is done before MX_USART2_UART_Init()
With the L476RG: It's the opposite.
I tryed to inverse them and it works but only once... (at start)
So how could I tell the code generator to initialize the DMA before my USART2?
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t size) {
if (huart->Instance == USART2) {
rs485_send_data(huart, g_rs485Input, size);
HAL_UARTEx_ReceiveToIdle_DMA(&huart2, g_rs485Input, RS485_INPUT_LENGTH);
__HAL_DMA_DISABLE_IT(&hdma_usart2_rx, DMA_IT_HT);
}
}

I has experimented same issue.
I build the same example for NUCLEO-L073RZ but at first, the function HAL_UARTEx_RxEventCallback was never called.
Then I read your question, and I set the order as You say
MX_DMA_Init() before MX_USART2_UART_Init()
(like in the controllerstech example). I reset the uart transmisor and debug again NUCLEO board.Then I had one breakpoint in HAL_UARTEx_RxEventCallback, so the program entered into the function an was stoped in the breakpoint. AS you say, the program enter in the breakpoint once in ever start.
So, I tried deleting this breakpoint in order to do not stop the program in debugging. After that, I watch in Live Expressions MainBuf, RxBuf, isOK, oldPos, newPos and it seems that is working perfectly.
Has you tried without breakpoints? Another way, you can try not debugging, running the program in normal mode and verify turning on one led or writing in other uart port.
Is not the first time that I have experienced irregular running of the program in debug mode.

I had a setup where I was using Lab View to communicate with the Nucleo-STM32F401RE over UART, I was having the same issue as you described.
The solution in my case was to make sure the parity bit was set to none, for some reason if it's set to something else it caused the behavior you're describing.

I have come across the same issue. It took me a while to realise, but in debug mode the HAL_UARTEx_RxEventCallback is never called. Couldn't find a way to fix this, unfortunately. However, my code did run fine when running normally.

Related

Is there a process to remap/switch CANTX/CANRX pins STM32H7 FDCAN module?

Testing out an STM32 with an FDCAN module (updated from the older BxCAN peripheral). CAN Classic at 500kbps.
I am running into an issue that when using the default pair of pins (D0/D1 in my case) I get expected behavior, but when switching the pins to the secondary option (B8/B9) using GPIO remapping, I get strange output on the bus.
I tried baud settings and options like protocol exception. Nothing seems to explain where this scope output is coming from.
I'm using the HAL to get this working, so I'm certain I'm not missing any registers on remapping. I've DeInit and ReInit the FDCAN module, started/stopped, etc. There seems to be no documented "process" for remapping pins. The entire FDCAN section of the reference module doesn't have the letters GPIO.
Picture: Yellow is the CANTX 0-3V signal (low is dominant). Purple is the CAN+ signal that idles at 2.5V and pulls past ~3.5V on a dominant. There is nothing else on this line, so I'm not concerned about the sawtoothing. The large initial CAN "SOF" pulse is wrong for timing. The long recessives are nonsense. Then the small value 1 bits are of the correct 2uS pulses for 500kbps. Changing the data put into the FDCAN FIFO makes no difference, the output is always the same.
Solved.
After sending this message, the INIT bits were set in the FDCAN->CCCR register. There were values in the error counters. Indicates an internal error. I was using the HAL as a time saver, but it was over-writting my desired GPIO settings.
I would set the pins B8/B9 to AF mode for FDCAN. Then call FDCAN_DeInit/Init, which via an MSP_INIT callback also calls GPIO Init, but for the original D0/D1 pins. Meaning the B8/B9 I set, and the D0/D1 pins were enabled at the same time.
This is an obvious problem. The HAL is fine for prototyping, but careful because it will try and "help". Undefined behavior at best and I normally wouldn't even post such a dumb mistake.
However... Maybe someone else finds it interesting that whatever the FDCAN state machine is doing here, makes this unique output seen in the scope picture. I initially didn't double check my pin setup, because it looked right, I was getting output on the scope, just the wrong output. I spent much more time going over peripheral settings and data I was feeding to it.

Erasing STM32 Flash Sector is hanging program

I am using FreeRtos and in one of the tasks I Erase a sector of the flash using the following code
HAL_FLASH_Unlock();
// Fill EraseInit structure
static FLASH_EraseInitTypeDef EraseInitStruct;
EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;
EraseInitStruct.VoltageRange = FLASH_VOLTAGE_RANGE_3;
EraseInitStruct.Sector = sector;
EraseInitStruct.NbSectors = numOfSectorsToErase;
HAL_FLASHEx_Erase_IT(&EraseInitStruct);
HAL_FLASH_Lock();
I thought this was a non-blocking invocation to erase the sector however when this is called, all other threads seem to be Preempted for 100 ms (as seen on oscilloscope) until the erase is completed. I must be doing something wrong because I am using the interrupt version of the erase. It shouldn't hang everything like this correct?
(I am sure that I am erasing the sector where the program code does not reside. Sector 6)
Documentation is clear:
Always read the documentation, not internet forums.
So it would seem that #Hs2 is Correct. Among further research, erasing a sector on the flash will Block execution as stated here https://community.st.com/s/question/0D50X00009XkXwuSAF/how-to-save-a-variable-in-nonvolatile-memory
saying "flashing blocks code execution" .
Now this brings up even more questions though like why in the world would the engineers at stm include a interrupt version of a sector erase when either way the invocation is going to be blocking anyways. Its very misleading. There seems to be no use case for this.

How to debug a timer

Im having problem setting up the TIM1 in "External Source Mode 1". Im writing to CH1 programmatically but nothing comes out of the timer no matter what settings I try. Is there a way to debug a timer, meaning checking the values at every stage, for example values of TI2FP1, IC1, and then IC1PS. I cant find them while debugging
Edit: If you're familiar these are not the names of the ordinary config registers. Those I know how to find.
The IC1F and IC1PS configuration bits you refer to are found within the TIM1 CCMR1 register. In Truestudio - in the debug perspective, in the SFRs tab - expand TIM1 and then CCMR1_Input. See picture. (That screenshot is for an STM32F302RC, but I believe the TIM1 registers are very similar - if not almost identical - for the STM32F411RE).
TI2FP1, on the other hand, is a signal - not a configuration bit stored in the microcontroller's memory.
If you are using global variables inside the timer ISRs, don't forget to declare them volatile. Otherwise they may not be updating as you expect (at least once you enable optimization).

stm32f4 HardFault_Handler - need debugging advice

I'm working on a project based on the stm32f4discovery board using IAR Embedded Workbench (though I'm very close to the 32kb limit on the free version so I'll have to find something else soon). This is a learning project for me and so far I've been able to solve most of my issues with a few google searches and a lot of trial and error. But this is the first time I've encountered a run-time error that doesn't appear to be caused by a problem with my logic and I'm pretty stuck. Any general debugging strategy advice is welcome.
So here's what happens. I have an interrupt on a button; each time the button is pressed, the callback function runs my void cal_acc(uint16_t* data) function defined in stm32f4xx_it.c. This function gathers some data, and on the 6th press, it calls my void gn(float32_t* data, float32_t* beta) function. Eventually, two functions are called, gn_resids and gn_jacobian. The functions are very similar in structure. Both take in 3 pointers to 3 arrays of floats and then modify the values of the first array based on the second two. Unfortunately, when the second function gn_jacobian exits, I get the HardFault.
Please look at the link (code structure) for a picture showing how the program runs up to the fault.
Thank you very much! I appreciate any advice or guidance you can give me,
-Ben
Extra info that might be helpful below:
Running in debug mode, I can step into the function and run through all the lines click by click and it's OK. But as soon as I run the last line and it should exit and move on to the next line in the function where it was called, it crashes. I have also tried rearranging the order of the calls around this function and it is always this one that crashes.
I had been getting a similar crash on the first function gn_resids when one of the input pointers pointed to an array that was not defined as "static". But now all the arrays are static and I'm quite confused - especially since I can't tell what is different between the gn_resids function that works and the gn_jacobian function that does not work.
acc1beta is declared as a float array at the beginning of main.c and then also as extern float32_t acc1beta[6] at the top of stm32f4xx_it.c. I want it as a global variable; there is probably a better way to do this, but it's been working so far with many other variables defined in the same way.
Here's a screenshot of what I see when it crashes during debug (after I pause the session) IAR view at crash
EDIT: I changed the code of gn_step to look like this for a test so that it just runs gn_resids twice and it crashes as soon as it gets to the second call - I can't even step into it. gn_jacobian is not the problem.
void gn_step(float32_t* data, float32_t* beta) {
static float32_t resids[120];
gn_resids(resids, data, beta);
arm_matrix_instance_f32 R;
arm_mat_init_f32(&R, 120, 1, resids);
// static float32_t J_f32[720];
// gn_jacobian(J_f32, data, beta);
static float32_t J_f32[120];
gn_resids(J_f32, data, beta);
arm_matrix_instance_f32 J;
arm_mat_init_f32(&J, 120, 1, J_f32);
Hardfaults on Cortex M devices can be generated by various error conditions, for example:
Access of data outside valid memory
Invalid instructions
Division by zero
It is possible to gather information about the source of the hardfault by looking into some processor registers. IAR provides a debugger macro that helps to automate that process. It can be found in the IAR installation directory arm\config\debugger\ARM\vector_catch.mac. Please refer to this IAR Technical Note on Debugging Hardfaults for details on using this macro.
Depending on the type of the hardfault that occurs in your program you should try to narrow down the root cause within the debugger.

FreeRTOS Sleep Mode hazards while using MSP430f5438

I wrote an an idle hook shown here
void vApplicationIdleHook( void )
{
asm("nop");
P1OUT &= ~0x01;//go to sleep lights off!
LPM3;// LPM Mode - remove to make debug a little easier...
asm("nop");
}
That should cause the LED to turn off, and MSP430 to go to sleep when there is nothing to do. I turn the LED on during some tasks.
I also made sure to modify the sleep mode bit in the SR upon exit of any interrupt that could possibly wake the MCU (with the exception of the scheduler tick isr in portext.s43. The macro in iar is
__bic_SR_register_on_exit(LPM3_bits); // Exit Interrupt as active CPU
However, it seems as though putting the MCU to sleep causes some irregular behavior. The led stays on always, although when i scope it, it will turn off for a couple instructions cycles when ever i wake the mcu via one of the interrupts (UART), and then turn back on.
If I comment out the LPM3 instruction, things go as planned. The led stays off for most of the time and only comes on when a task is running.
I am using a MSP4f305438
Any ideas?
Perhaps the problem is the call __bic_SR_register_on_exit(LPM3_bits). This macro changes the LPM bits in the stacked SR, so it must know where to find the saved SR on the stack. I believe that __bic_SR_register_on_exit() is designed for the standard interrupt stack frame generated by the compiler when you use the __interrupt directive. However, a preemptive RTOS, like FreeRTOS, uses its own stack frame typically bigger than the stack frame generated by the compiler, because an RTOS must store the complete context. In this case __bic_SR_register_on_exit() called from an ISR might not find the SR on the stack. Worse, it probably corrupts some other saved register value on the stack.
For a preemptive kernel I would not call __bic_SR_register_on_exit() from the ISRs. The consequence is that the idle callback is called only once and never again, because every time the RTOS performs a context switch back to the idle task the side effect is restoring the SR with the LPM bits turned on. This causes a sleep mode (which is what you want), but your LED won't get toggled.
Miro Samek
state-machine.com