2017-05-11 11:48 PM
Hi,
I'm new at STM32. (I own DISCOVERY board STM32F411E-Disco) I have written few programs using Cube and HAL but now I need to use assembler.Can you share any sources where should I start to learn using assembler? Any 'Hello World' for assembler would be great. Or 'STM32 assembler for dummies'
As I mentioned I'm new in STM32 so please send me direct links, STM datasheets are something new for me and I don't know with one is correct. There is a lot of them for each micro Procesor. I used to use Atmel.I'm using AC6 with Toolchain SW4STM32 if this is the case.
Why assembler:
I need to very precisely turn on and off pin according to data in an array. Time of pulse can vary but the smallest one is 0,5 us +/- 150ns.(I need to control WS2811).The task is to convert 8bit values array to pulses.1->0.5us High, 2.0 us Low0->1.2us High, 1.3 us Lowat the end of data
50us LowTimer with interrupts (on HAL) was too slow in my tests.
Thanks in advance for any help.
Best Regards, Stefan2017-05-12 05:44 AM
You'd be better off driving GPIO via a pattern table in RAM, using DMA clocked with a TIM
For singular bits a TIM in PWM mode would suffice, again with the pulse train driven by a RAM based array loaded with DMA (TIM Update)
Assembler has been covered here before, best placed in startup.s file and called from regular code.
2017-05-12 06:10 AM
Look at the DMA Stream/Channel table and find out if one timer has its Channel covered.
If yes, instead of generating a PWN with a compare value and the overflow value of the timer, the compare value comes from a table which is scanned by DMA. This way, during the timer period, you can generate a burst of pulses with any timing you want, generated by HW. Convert your bits in compares in a RAM table, and use the DMA to update several times the compare timer register value before overflowing. SW prepare the table, launch the timer say in one pulse mode and there you go.
2017-05-12 07:55 AM
Can you tell me more about
driving GPIO via a pattern table in RAM. It sunds very interesting. Can you point me in some direction where should I look for some details about it?
Perhaps simple code...
2017-05-12 08:11 AM
Google for 'WS2811 stm32 dma'...
JW
2017-05-12 09:02 AM
Searching GPIO+DMA+TIM here might also yield some hits
2017-05-13 06:17 AM
Well. Using assembly code in C depends of the compiler used.
For GCC toolchain (AC6 looks GCC compatible) you can use ugly
assembler or separate source contains an assembler code onlyI prefer the second way:
- Create header file describes the assembly functions
- Create source for the assembly code with *.S extension (for example you can check the MCU startup code)
- Write your assembly functions using
http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042f/IHI0042F_aapcs.pdf
andhttps://sourceware.org/binutils/docs/as/
.- Enjoy
PS. Unfortunately the device header (ie. stm32xxxxxx.h) can't be used with assembly code. You should define all required constants and addresses by yourself.
PPS. Here is the examples of the small macro for the fast 32-bit rotation. It expands to the inline assembly and can be used in C source directly.
#define __ror(a, b) \
({ uint32_t __a = (a); uint32_t __b = (b); \ __asm__('ror %0, %1' : '+l'(__a) : 'l'(__b) : 'cc'); \ __a; })#define __rol(a, b) \({ uint32_t __a = (a); uint32_t __b = (b); \ __asm__ ('neg %1, %1 \n\t ror %0, %1' : '+l'(__a), '+l'(__b) : : 'cc'); \ __a; })2017-05-13 09:41 AM
Are we sure that C compilers don't have any macro or specific function to generate any assembly op-code?
2017-05-13 11:39 AM
AFAIK no native operators for bit rotation in C. It's a macro or static inline function uses bit shift.
Usually like '(op1 >> op2) | (op1 << (32U - op2))'
Sometimes compiler replaces it by ROR opcode.