Why does the sequence of init calls matter in STM32CubeIDE? - stm32cubeide

Writing a simple UART program using CubeIDE 1.7.0 for a Nucleo-H723ZG board using DMA. A UART DMA receive call is issued waiting for input from a serial port app on the Mac OSX host (CoolTerm). A callback echoes the data received.
When a text message is sent to the board nothing but zeros is echoed back.
I noted that CubeMX had generated the DMΑ initialisation call (MX_DMA_Init()) AFTER the UART initialisation call (MX_USARTx_UART_Init()).
By Reversing the sequence of these two calls the code worked perfectly!
Is this my error, has something been missed in the setup, or is it an MX error?

This issue only affects CubeIDE 1.7.0 users on MacOSX Big Sur. Under Windows there is no problem and the code generator correctly positions the DMA initialisation call before that of the USART.
When using the MX configurator the peripheral initialisation calls are generated in the sequence in which they are entered. When setting up a USART to use DMA to perform the data transfer, two peripherals' initialisations need to be generated: the USART and the DMA device. As the USART was the first of the two peripherals selected the USART init call is generated before the DMA init call.
However, unknown to me at the time, the USART needs to set up a DMA register which must have its clock enabled. The DMA init must therefore be done BEFORE the USART init. Hence my problem.
Knowing this, in the MX Project Manager tab, the Advanced Settings tab provides the option to rearrange the sequence of these init calls and all is well!
So this is a bug. However, using a Nucleo-H743ZI2 with USART DMA there is no problem with out-of-sequence initialisation. Thus far the bug is limited to the Nucleo-H723ZG!

The firmware generated by CubeMX6.3.0 for Nucleo-G474RE does the same initialization inversion (UART before DMA) and leads to unresponsive code.

Related

STM32H7 SPI frozen during break?

In order to freeze a timer during a break in debug mode on a STM32H7, one has to set a bit in the DBGMCU. But I didn't find such a bit for SPI. Does it mean that the SPI is always frozen ? Or on the contrary never frozen ?
Short answer:
There is no such option for the SPI. SPI is always enabled, if used and proper configured.
Long answer:
There is no such option for SPI because this interface must be either actively served by the microcontroller. In this case the SPI transaction is automaticly stoped if your device is halted e.g in break mode. Any ongoing transaction of a word/fifo will be executed anyway.
Or the dma controler is configured to server the SPI. In this case data transmission is controlled by the dma controller. The dma controller itself has different trigger sources. As long this trigger source is not a timer depended one there is no way to implicitly halt the transfer.
See also: https://stackoverflow.com/a/43225545/5388805

Watchpoint on STM32 GPIO register

using Keil µVision on a STM32F4 I am trying to add a watchpoint to a GPIO data register, which just does not trigger.
I want the watchpoint to be triggered as soon as output data gets writting into this register.
Setting the watchpoint to the os timer work fine.
Peripheral registers are memory mapped in STM32 F4, as far as I know.
Any (simple) explanation that I am missing here?
Any hint is very much appreciated.
While the ARM core can access the peripheral I/O registers in the same flat 32-bit address space as SRAM or flash, peripheral I/O registers are located in separate buses on the MCU, and not accessed by the same bus as the SRAM. For example, on the STM32F, there are the ABH bus which are usually further divided into the APB1 and APB2 buses, depending on the device. In any case, the debug controller unit defined by ARM ("CoreSight"), provides data watchpoint capability, and it only works on "real" data access.
Would be great if it did though ;-)
No source, or personal experience, but I can think of a few reasons why this wouldn't work.
Often value isn't "there" like in RAM, but is created when you access a peripheral register.
You could say periodic access could then solve this, but that wouldn't work for registers where reading has side effects (usually clearing some status flag).
I think you'll have to create an interrupt handler for GPIO, and a breakpoint for that.
there is a workaround if 12 cycles latency is a problem. Use Pin as a trigger which triggers memory to memory DMA transfer. Set the watchpoint on the destination (or source) RAM address.

SH72867 with I2C

I am using ‘SH72867(Renesas)’ connect with ‘EEPROM(24LC04B)’ . In the customer’s document at ‘address 0xF0 of EEPROM have data 0x5555’, But when I reading from this address always return ‘0xFFFF’ and same with other address.
I can’t write to EEPROM too.
I used I2C sample of Renesas but not run.
Do you have any suggestion about setting up I2C?
Sorry for my bad English and no clear explanation.
Any help apprciated,
Thanks
Verify the common issues:
Data and clock are connected properly.
Pull up resistor on clock and data connected to VCC.
Loop the I2C read request, connect scope and verify that I2C signals are OK. In addition check the ACK bit.
Verify clock is lower then 400kHz.
When using code examples, they usually fit to specific board. Verify that the code example configuration is the same as your board.
Some MCU may have more then one I2C pinout options. The code example might use I2C module that connected to diffrent pins.

How do I write a simple bare-metal program?

Hypothetical here: Let's say you have a processor attached to some form of USB-storage and a motor. How would I write a simple bare-metal program to tell the motor to move for 10 seconds? I want to learn how to bare metal program, and having a program to look at and analyze would be wonderful. (Any language would be great)
1) you have to understand how the processor in question boots. there is the core processor itself then the non-volatile storage. for example a raspberry pi is a little unique in that there is something in logic (or an on chip rom?) that reads the sd card, boots up the gpu, then the gpu copies the arm program to ram and releases the arm into that ram. most microcontrollers have on board flash and ram and the flash is mapped into the address space that the processor boots from and/or there is a vendor supplied bootloader that boots the processor then calls your code.
2) you have to learn how to enable and initialize the peripherals you care to use. a timer perhaps if you want to count to 10 seconds.
3) write the application.
debugging is the trick, you can sometimes use a hardware debugger via jtag or sometimes use a rom monitor via gdb or some other program on some interface like uart. or one that almost always is available either a blinking led or a uart to send text or numbers out to see what is going on. and of course an oscilloscope, you can wiggle gpios or do other things and see them on the scope.
driving a motor is too generic you need to specifically know what kind of motor and how to drive it, likely zero chance you are driving it directly from the microcontroller, you might have something outside a transistor h bridge or something that isolates the microcontroller or you have a specific type of motor driver chip/circuit that you speak to either through discrete signals, or i2c or spi, or other to tell it to drive the motor, and then maybe some analog to deal with the high power or maybe that chip is a hybrid. so you have to know all that or at least you have to know the programming side of all that, what interface and/or what signals have to have state changes in what way to cause the motor to do something. it could be as simple as a pwm that you create that is amplified between you and the motor. pwm may involve first learning how to mess with one of the timers then either another peripheral or a subset of the timer to make a pwm signal out of it. a scope is really helpful here too or a logic analyzer, or if you have another microcontroller you can sample a gpio in faster than the signal being generated you can turn it into a logic analyzer.
start with finding a board, blink an led, figure out how to run a timer, accurately blink an led. figure out the clock rates you are really running at instead of guessing, figure out how to configure the uart, send some characters out that, now you have a debug interface a knowledge of what your timer reference clock speeds are and can now try to count to 10 seconds, and then get into the signals needed for the motor. expect to blow up a few boards, buy some spares.

Power save mode STM32F205RG

I am using STM32F205RGT6 Cortex-M3 microcontroller and coding with IAR Embedded Workbench.
I plan to keep the microcontroller in a power saving mode most of the time except when an external component tries to either communicate via SPI (the STM32 microcontroller is meant to be a SP slave) or via USB.
One external compinent is connected via SPI (PB12-15) and PC is connected via USB (PA11-12).
The communication works fine - I have tested both the SPI as well as USB.
I figured that once I am done setting up SPI and USB I will call a power saving function and add the same function call at the end of interrupt service routines. I have found PWR_EnterSTANDBYMode and PWR_EnterSTOPMode (in stm32f2xx_pwr.h) both of which I tried using.
However with such arrangement I cannot establish any communication (SPI or USB) with the microcontroller.
Is there something extra that needs to be configured (for example which pins should wake the microcontroller up)?
Am I using wrong function? Or wrong header file?
Can you point me to an example resembling such case (I could not find anything similar on ST's website)?
Any constructive feedback would be welcome.
In the mean time I found the application note AN3430 (http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/APPLICATION_NOTE/DM00033348.pdf) which is somehow more digestible (only 38 pages) which gives an excellent overview on power saving in the microcontroller.
Since I don't have access to PA0-WKUP (the wake-up pin) I had to discard using stand-by. Seems that just a simple sleep mode in main loop - by calling __WMI(); - should lower current consumption enough in my case. I might consider stop mode if sleep mode isn't enough but I will have read fragments of datasheet on configuration of EXTI registers that the application notepoints to.