Go Down

Topic: Arduino Due blink example in assembly (Read 10998 times) previous topic - next topic

blackcoursar

Nov 27, 2013, 08:20 pm Last Edit: Nov 27, 2013, 08:26 pm by blackcoursar Reason: 1
Good evening everyone I'm trying to understand the arm processor by using the Arduino Due and it could be a real help if someone could give me the blink example in assembly for the Arduino Due.I've searched the web but there isn't much on the subject.Thank you.

Gericom


Good evening everyone I'm trying to understand the arm processor by using the Arduino Due and it could be a real help if someone could give me the blink example in assembly for the Arduino Due.I've searched the web but there isn't much on the subject.Thank you.

Sadly the arduino ide doesn't support .s files. But you can use inline assembly.
Subscribe my youtube channel: http://www.youtube.com/user/MKDS3

graynomad

Quote
I've searched the web but there isn't much on the subject.

I'm not surprised, no-one in their right mind would use assembly these days unless there is a VERY good reason.

To start from scratch with no C would be a nightmare, but to use inline ASM in your C sketch would be ok so search for examples of inline assembly, get the SAM instruction set docs and start experimenting using some other code as a base.

Good luck, is there a particular reason you want to know the ARM at this level? Very few people need that knowledge.

______
Rob
Rob Gray aka the GRAYnomad www.robgray.com

Gericom


Quote
I've searched the web but there isn't much on the subject.

I'm not surprised, no-one in their right mind would use assembly these days unless there is a VERY good reason.

To start from scratch with no C would be a nightmare, but to use inline ASM in your C sketch would be ok so search for examples of inline assembly, get the SAM instruction set docs and start experimenting using some other code as a base.

Good luck, is there a particular reason you want to know the ARM at this level? Very few people need that knowledge.

______
Rob

ARM is not very complex. But it would be much easier if you could use real .s files instead of inline assembly.
Subscribe my youtube channel: http://www.youtube.com/user/MKDS3

graynomad

Quote
it would be much easier if you could use real .s files instead of inline assembly.

Reckon, inline ASM is a nightmare.

______
Rob
Rob Gray aka the GRAYnomad www.robgray.com

blackcoursar


Quote
I've searched the web but there isn't much on the subject.

I'm not surprised, no-one in their right mind would use assembly these days unless there is a VERY good reason.

To start from scratch with no C would be a nightmare, but to use inline ASM in your C sketch would be ok so search for examples of inline assembly, get the SAM instruction set docs and start experimenting using some other code as a base.

Good luck, is there a particular reason you want to know the ARM at this level? Very few people need that knowledge.

______
Rob

Yes , sadly i need it for a project in the university, i understand that it's a difficult subject because the arduino's purpose is exactly that, to not get involved with assembly but at the time I really need some help with the subject.
Thank you for the response.

blackcoursar



ARM is not very complex. But it would be much easier if you could use real .s files instead of inline assembly.

Yes, I know, I already have a basic assembly knowledge and it would be great if I could upload the code directly to arduino due with the various addresses and registers but  there isn't much of a documentation out there.
Thanks for the response.

blackcoursar

I've found this example but as i found out it's for arduino uno I've managed to find the addresses for the Due but it still doesn't work. Any help would be much appreciated .


Code: [Select]
void setup() {
  asm volatile (
    "sbi %0, %1 \n\t"           //pinMode(13, OUTPUT);
    :: "I" (_SFR_IO_ADDR(DDRB)), "I" (DDB5)
  );
}

void loop() {
  asm volatile (
     "sbi %0, %1 \n\t"          //LED on
     "call OneSecondDelay \n\t" //delay
     "cbi %0, %1 \n\t"          //LED off
     "call OneSecondDelay \n\t" //delay
     "rjmp 4f \n\t"             //exit

  "OneSecondDelay: \n\t"
     "ldi r18, 0 \n\t"          //delay 1 second
     "ldi r20, 0 \n\t"
     "ldi r21, 0 \n\t"

  "1: ldi r24, lo8(400) \n\t"
     "ldi r25, hi8(400) \n\t"
  "2: sbiw r24, 1 \n\t"         //10x around this loop = 1ms
     "brne 2b \n\t"
     "inc r18 \n\t"
     "cpi r18, 10 \n\t"
     "brne 1b \n\t"

     "subi r20, 0xff \n\t"      //1000 x 1ms = 1 second
     "sbci r21, 0xff \n\t"
     "ldi r24, hi8(1000) \n\t"
     "cpi r20, lo8(1000) \n\t"
     "cpc r21, r24 \n\t"
     "breq 3f \n\t"

     "ldi r18, 0 \n\t"
     "rjmp 1b \n\t"

  "3: \n\t"
     "ret \n\t"

  "4: \n\t"                     //exit

     :: "I" (_SFR_IO_ADDR(PORTB)), "I" (PORTB5)
     : "r18", "r20", "r21", "r24", "r25"
  );
}

MarkT


Quote
I've searched the web but there isn't much on the subject.

I'm not surprised, no-one in their right mind would use assembly these days unless there is a VERY good reason.



I think you misunderstand the difference between a general purpose computer and
a microcontroller, the latter has to deal with hard timing constraints and often you
need to know cycle counts and take the processor to its limit without jumping
through hoops to get persuade a compiler to do just what you want.

Certainly assembly is much less productive in programmer time, but sometimes you
need that real-time performance.  So yes embedded programming can involve snippets
of assembly language without any departure from sanity being involved. 

All engineering decisions are a trade off.
[ I will NOT respond to personal messages, I WILL delete them, use the forum please ]

Gericom


I've found this example but as i found out it's for arduino uno I've managed to find the addresses for the Due but it still doesn't work. Any help would be much appreciated .


Code: [Select]
void setup() {
  asm volatile (
    "sbi %0, %1 \n\t"           //pinMode(13, OUTPUT);
    :: "I" (_SFR_IO_ADDR(DDRB)), "I" (DDB5)
  );
}

void loop() {
  asm volatile (
     "sbi %0, %1 \n\t"          //LED on
     "call OneSecondDelay \n\t" //delay
     "cbi %0, %1 \n\t"          //LED off
     "call OneSecondDelay \n\t" //delay
     "rjmp 4f \n\t"             //exit

  "OneSecondDelay: \n\t"
     "ldi r18, 0 \n\t"          //delay 1 second
     "ldi r20, 0 \n\t"
     "ldi r21, 0 \n\t"

  "1: ldi r24, lo8(400) \n\t"
     "ldi r25, hi8(400) \n\t"
  "2: sbiw r24, 1 \n\t"         //10x around this loop = 1ms
     "brne 2b \n\t"
     "inc r18 \n\t"
     "cpi r18, 10 \n\t"
     "brne 1b \n\t"

     "subi r20, 0xff \n\t"      //1000 x 1ms = 1 second
     "sbci r21, 0xff \n\t"
     "ldi r24, hi8(1000) \n\t"
     "cpi r20, lo8(1000) \n\t"
     "cpc r21, r24 \n\t"
     "breq 3f \n\t"

     "ldi r18, 0 \n\t"
     "rjmp 1b \n\t"

  "3: \n\t"
     "ret \n\t"

  "4: \n\t"                     //exit

     :: "I" (_SFR_IO_ADDR(PORTB)), "I" (PORTB5)
     : "r18", "r20", "r21", "r24", "r25"
  );
}


This is avr assembly. You need arm assembly. As for the registers, yes, it's irritating that it lacks a lot of documentation.
Subscribe my youtube channel: http://www.youtube.com/user/MKDS3

graynomad

When I first got into LPC processors I tried some assembly just for the heck of it. Quite simple and with the LPCXpresso IDE you can use .S files.

If you just want to learn the ARM then that might be a better option, after all the chip vendor just adds peripherals and that have almost nothing to do with the ARM core.

______
Rob
Rob Gray aka the GRAYnomad www.robgray.com

blackcoursar

I found this in another part of the forum, the only thing that isn't really clear is the masking process do I really need to do that
or using an inline assembly code would be the same?



Code: [Select]


/*
    Raw blink sketch for DUE revealing SAM3X8E registers used
    Turns on an LED on for one second, then off for one second, repeatedly.
*/

// Pin 13 mask
uint32_t led = (1u << 27);

void setup()
{                 
  // Output Enable Register
  REG_PIOB_OER = led;
}

// the loop routine runs over and over again forever:
void loop()
{
    REG_PIOB_SODR = led; // Set Output Data Register, turns LED on
    delay(1000);         // wait for a second   
    REG_PIOB_CODR = led; // Clear Output Data Register, turns LED off
    delay(1000);         // wait for a second   
}

graynomad

Quote
the masking process do I really need to do that

You mean the (1u << 27), of course as that selects the bit in the port the action affects. You could I suppose just a constant of 0xFFFFFFFF and toggle all the bits on that port.

Quote
using an inline assembly code would be the same?

What do you mean here? Obviously the code would look nothing like this any more than the example you found back in reply #7 looks like normal Arduino C code. The REG_PIOB_xxx constants may be the same, that's about all.

______
Rob
Rob Gray aka the GRAYnomad www.robgray.com

blackcoursar

Quote
What do you mean here? Obviously the code would look nothing like this any more than the example you found back in reply #7 looks like normal Arduino C code. The REG_PIOB_xxx constants may be the same, that's about all.

Yes of course, you are right.Thank you.

Gericom


I found this in another part of the forum, the only thing that isn't really clear is the masking process do I really need to do that
or using an inline assembly code would be the same?



Code: [Select]


/*
    Raw blink sketch for DUE revealing SAM3X8E registers used
    Turns on an LED on for one second, then off for one second, repeatedly.
*/

// Pin 13 mask
uint32_t led = (1u << 27);

void setup()
{                 
  // Output Enable Register
  REG_PIOB_OER = led;
}

// the loop routine runs over and over again forever:
void loop()
{
    REG_PIOB_SODR = led; // Set Output Data Register, turns LED on
    delay(1000);         // wait for a second   
    REG_PIOB_CODR = led; // Clear Output Data Register, turns LED off
    delay(1000);         // wait for a second   
}


Something like this:
Code: [Select]

void setup()
{
    asm volatile("mov r0, %[val]"::[val] "r" (&REG_PIOB_OER));
    asm volatile("mov r1, #1, lsl #27");
    asm volatile("str r1, [r0]");
}

void loop()
{
    asm volatile("mov r0, %[val]"::[val] "r" (&REG_PIOB_SODR));
    asm volatile("mov r1, #1, lsl #27");
    asm volatile("str r1, [r0]");
    asm volatile("ldr r0,=1000");
    asm volatile("bl delay");
    asm volatile("mov r0, %[val]"::[val] "r" (&REG_PIOB_CODR));
    asm volatile("mov r1, #1, lsl #27");
    asm volatile("str r1, [r0]");
    asm volatile("ldr r0,=1000");
    asm volatile("bl delay");
}
Subscribe my youtube channel: http://www.youtube.com/user/MKDS3

Go Up