Assembly LED code

07 Mar 2013

null

13 Feb 2012

You'll find the addresses in the LPC headers. Create a project,click on imported mbed library and open it on right side

07 Mar 2013

null

16 Feb 2012

Did you see the example at http://mbed.org/cookbook/Assembly-Language

07 Mar 2013

null

16 Feb 2012

There are several ways to write to port pins from assembler:

You can create a mask for the selected pin and use the 'set' and 'reset' registers

or

You can write some binary value directly to the output register.

Note all port registers are in principle 32 bits but you can address them 8, 16 and 32 bits at a time creating very flexible ways of driving the port pins (and very fast too if needed) It will take some studying, not only to understand the IO system but also how all addressing modes of the ARM CPU work. If you do not need the absolute maximum speed I would stick to C, in one of my own projects I deliberately used some assembler to get the 'promised' 120 nsec response to an interrupt and to keep my interrupt routine under 1 usec in total. It takes a lot of tweaking to get assembler routines right and for the rest of the code I used standard C and mbed libraries.

If you want to learn more about the inner stuff of the mbed's CPU get a copy of the UM10360 LPC17xx manual and also take a peek at:

http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0337e/index.html

Prepare for some heavy reading though :)

16 Feb 2012

Here is some example on how to write a value directly to the port pins:

save this part as asmtest.s

    AREA asm_func, CODE, READONLY
    
; Export my asm function location so that C compiler can find it and link
    EXPORT speed_check
    
    ALIGN


speed_check

    ; setup a pointer to the base address of port 1
    LDR     R1,=0x2009c020      ; pointer to base of port1 

loop
    LDR     R3,=0x00000000      ; set LED 1 off (all bits 'zero')
    STR     R3,[R1,#0x14]       ; set outputs directly (base+0x14)
 
    LDR     R3,=0x00040000      ; set LED 1 on (bit 18 aka P1.18 is 'one')
    STR     R3,[R1,#0x14]       ; set outputs directly (base+0x14)
           
    B       loop                ; branch to loop (endless loop!)
    
    ALIGN
    END

and the calling C code (main.c):

#include "mbed.h"

DigitalOut myled(LED1);
extern "C" void speed_check();

int main() {
    
    speed_check();  // execute assembler routine

    // this part is never reached
    while(1) {
    }
}

The result of this little program is that LED1 is switched on and off as fast as possible resulting in multi MHZ blinking speed. The effect is that you will see the LED light up at half brightness.

Note, this code resets all bits on port1 to zero regardless of the internal function. Normally you would use the special set and clear registers with a mask to not disturb the other port pins.

07 Mar 2013

null

07 Mar 2013

null

19 Feb 2012

The C line:

DigitalOut myled(LED1);

initializes the port pins. In your code the port pin is not initialized as output.

Add a line like this before the loop and after the LDR R1

my_asm

    ; setup a pointer to the base address of port 1
    LDR     R1,=0x2009c020      ; pointer to base of port1 

    LDR     R3,=0x00040000      ; set LED 1 port pin to output
    STR     R3,[R1,#0x00]       ; set direction bits (base+0x00)

loop
    LDR     R3,=0x00000000      ; set LED 1 off (all bits 'zero')
    STR     R3,[R1,#0x14]       ; set outputs directly (base+0x14)
 
    LDR     R3,=0x00040000      ; set LED 1 on (bit 18 aka P1.18 is 'one')
    STR     R3,[R1,#0x14]       ; set outputs directly (base+0x14)
           
    B       loop                ; branch to loop (endless loop!)
    
    ALIGN
    END

07 Mar 2013

null