cancel
Showing results for 
Search instead for 
Did you mean: 

How to start with asembler on Cortex M4

Stefan Wozniak
Associate III
Posted on May 12, 2017 at 08:48

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 Low

0->1.2us High, 1.3 us Low

at the end of data

50us Low

Timer with interrupts (on HAL) was too slow in my tests.

Thanks in advance for any help.

Best Regards,

Stefan
8 REPLIES 8
Posted on May 12, 2017 at 14:44

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.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
S.Ma
Principal
Posted on May 12, 2017 at 15:10

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.

Posted on May 12, 2017 at 14:55

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...

Posted on May 12, 2017 at 15:11

Google for 'WS2811 stm32 dma'...

JW

Posted on May 12, 2017 at 16:02

Searching GPIO+DMA+TIM here might also yield some hits

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
dmitrystu
Associate II
Posted on May 13, 2017 at 15:17

Well. Using assembly code in C depends of the compiler used.

For GCC toolchain (AC6 looks GCC compatible) you can use ugly

https://gcc.gnu.org/onlinedocs/gcc/Using-Assembly-Language-with-C.html#Using-Assembly-Language-with-C

assembler or separate source contains an assembler code only

I 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

and

https://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; })
Posted on May 13, 2017 at 16:41

Are we sure that C compilers don't have any macro or specific function to generate any assembly op-code?

Posted on May 13, 2017 at 18:39

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.