Go Down

Topic: Book (Read 791 times) previous topic - next topic

DuaneB

Hi,
   Does anyone have any feedback on this book or can suggest an alternative resource for learning AVR Assembler. I have very limited experience in assembler so need to basics as well as the AVR Specifics, this book seems to cover both.

http://www.amazon.com/Some-Assembly-Required-Programming-Microcontroller/dp/1439820643/ref=sr_1_sc_1?s=books&ie=UTF8&qid=1335087290&sr=1-1-spell

Duane B

rcarduino.blogspot.com
Read this
http://rcarduino.blogspot.com/2012/04/servo-problems-with-arduino-part-1.html
then watch this
http://rcarduino.blogspot.com/2012/04/servo-problems-part-2-demonstration.html

Rcarduino.blogspot.com

robtillaart


- http://www.avr-asm-tutorial.net/ - seen this one ?
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

DuaneB

Hi,
   It looks good, I have downloaded the PDF and will have plenty of time to read through it next week when I am stuck on a plane again.

Thanks

Duane B

rcarduino.blogspot.com
Read this
http://rcarduino.blogspot.com/2012/04/servo-problems-with-arduino-part-1.html
then watch this
http://rcarduino.blogspot.com/2012/04/servo-problems-part-2-demonstration.html

Rcarduino.blogspot.com

DuaneB

Hi,
   I have just used the suggestions in this thread to look at the disassembled code for a sketch, its very interesting to see just how much goes on some functions, digitalRead is doing an awful lot to protect the user from themselves, I will be avoiding it in ISRs from now on.

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1193790150

I know this isn't news to many members, and a lot of the code is branching so only a fraction of it will be executed, but its still a bit of a wow for me to see just how much is going on in digital read -

Code: [Select]

int digitalRead(uint8_t pin)
{
uint8_t timer = digitalPinToTimer(pin);
    10f2: 68 2f        mov r22, r24
    10f4: 70 e0        ldi r23, 0x00 ; 0
    10f6: cb 01        movw r24, r22
    10f8: 82 55        subi r24, 0x52 ; 82
    10fa: 9f 4f        sbci r25, 0xFF ; 255
    10fc: fc 01        movw r30, r24
    10fe: 24 91        lpm r18, Z+
uint8_t bit = digitalPinToBitMask(pin);
    1100: cb 01        movw r24, r22
    1102: 86 56        subi r24, 0x66 ; 102
    1104: 9f 4f        sbci r25, 0xFF ; 255
    1106: fc 01        movw r30, r24
    1108: 44 91        lpm r20, Z+
uint8_t port = digitalPinToPort(pin);
    110a: 6a 57        subi r22, 0x7A ; 122
    110c: 7f 4f        sbci r23, 0xFF ; 255
    110e: fb 01        movw r30, r22
    1110: 94 91        lpm r25, Z+

if (port == NOT_A_PIN) return LOW;
    1112: 99 23        and r25, r25
    1114: 19 f4        brne .+6      ; 0x111c <digitalRead+0x2a>
    1116: 20 e0        ldi r18, 0x00 ; 0
    1118: 30 e0        ldi r19, 0x00 ; 0
    111a: 3c c0        rjmp .+120    ; 0x1194 <digitalRead+0xa2>

// If the pin that support PWM output, we need to turn it off
// before getting a digital reading.
if (timer != NOT_ON_TIMER) turnOffPWM(timer);
    111c: 22 23        and r18, r18
    111e: 51 f1        breq .+84      ; 0x1174 <digitalRead+0x82>
//
//static inline void turnOffPWM(uint8_t timer) __attribute__ ((always_inline));
//static inline void turnOffPWM(uint8_t timer)
static void turnOffPWM(uint8_t timer)
{
switch (timer)
    1120: 23 30        cpi r18, 0x03 ; 3
    1122: 71 f0        breq .+28      ; 0x1140 <digitalRead+0x4e>
    1124: 24 30        cpi r18, 0x04 ; 4
    1126: 28 f4        brcc .+10      ; 0x1132 <digitalRead+0x40>
    1128: 21 30        cpi r18, 0x01 ; 1
    112a: a1 f0        breq .+40      ; 0x1154 <digitalRead+0x62>
    112c: 22 30        cpi r18, 0x02 ; 2
    112e: 11 f5        brne .+68      ; 0x1174 <digitalRead+0x82>
    1130: 14 c0        rjmp .+40      ; 0x115a <digitalRead+0x68>
    1132: 26 30        cpi r18, 0x06 ; 6
    1134: b1 f0        breq .+44      ; 0x1162 <digitalRead+0x70>
    1136: 27 30        cpi r18, 0x07 ; 7
    1138: c1 f0        breq .+48      ; 0x116a <digitalRead+0x78>
    113a: 24 30        cpi r18, 0x04 ; 4
    113c: d9 f4        brne .+54      ; 0x1174 <digitalRead+0x82>
    113e: 04 c0        rjmp .+8      ; 0x1148 <digitalRead+0x56>
{
#if defined(TCCR1A) && defined(COM1A1)
case TIMER1A:   cbi(TCCR1A, COM1A1);    break;
    1140: 80 91 80 00 lds r24, 0x0080
    1144: 8f 77        andi r24, 0x7F ; 127
    1146: 03 c0        rjmp .+6      ; 0x114e <digitalRead+0x5c>
#endif
#if defined(TCCR1A) && defined(COM1B1)
case TIMER1B:   cbi(TCCR1A, COM1B1);    break;
    1148: 80 91 80 00 lds r24, 0x0080
    114c: 8f 7d        andi r24, 0xDF ; 223
    114e: 80 93 80 00 sts 0x0080, r24
    1152: 10 c0        rjmp .+32      ; 0x1174 <digitalRead+0x82>
#if defined(TCCR2) && defined(COM21)
case  TIMER2:   cbi(TCCR2, COM21);      break;
#endif

#if defined(TCCR0A) && defined(COM0A1)
case  TIMER0A:  cbi(TCCR0A, COM0A1);    break;
    1154: 84 b5        in r24, 0x24 ; 36
    1156: 8f 77        andi r24, 0x7F ; 127
    1158: 02 c0        rjmp .+4      ; 0x115e <digitalRead+0x6c>
#endif

#if defined(TIMER0B) && defined(COM0B1)
case  TIMER0B:  cbi(TCCR0A, COM0B1);    break;
    115a: 84 b5        in r24, 0x24 ; 36
    115c: 8f 7d        andi r24, 0xDF ; 223
    115e: 84 bd        out 0x24, r24 ; 36
    1160: 09 c0        rjmp .+18      ; 0x1174 <digitalRead+0x82>
#endif
#if defined(TCCR2A) && defined(COM2A1)
case  TIMER2A:  cbi(TCCR2A, COM2A1);    break;
    1162: 80 91 b0 00 lds r24, 0x00B0
    1166: 8f 77        andi r24, 0x7F ; 127
    1168: 03 c0        rjmp .+6      ; 0x1170 <digitalRead+0x7e>
#endif
#if defined(TCCR2A) && defined(COM2B1)
case  TIMER2B:  cbi(TCCR2A, COM2B1);    break;
    116a: 80 91 b0 00 lds r24, 0x00B0
    116e: 8f 7d        andi r24, 0xDF ; 223
    1170: 80 93 b0 00 sts 0x00B0, r24

// If the pin that support PWM output, we need to turn it off
// before getting a digital reading.
if (timer != NOT_ON_TIMER) turnOffPWM(timer);

if (*portInputRegister(port) & bit) return HIGH;
    1174: 89 2f        mov r24, r25
    1176: 90 e0        ldi r25, 0x00 ; 0
    1178: 88 0f        add r24, r24
    117a: 99 1f        adc r25, r25
    117c: 84 58        subi r24, 0x84 ; 132
    117e: 9f 4f        sbci r25, 0xFF ; 255
    1180: fc 01        movw r30, r24
    1182: a5 91        lpm r26, Z+
    1184: b4 91        lpm r27, Z+
    1186: 8c 91        ld r24, X
    1188: 20 e0        ldi r18, 0x00 ; 0
    118a: 30 e0        ldi r19, 0x00 ; 0
    118c: 84 23        and r24, r20
    118e: 11 f0        breq .+4      ; 0x1194 <digitalRead+0xa2>
    1190: 21 e0        ldi r18, 0x01 ; 1
    1192: 30 e0        ldi r19, 0x00 ; 0
return LOW;
}
    1194: c9 01        movw r24, r18
    1196: 08 95        ret


Duane B

rcarduino.blogspot.co
Read this
http://rcarduino.blogspot.com/2012/04/servo-problems-with-arduino-part-1.html
then watch this
http://rcarduino.blogspot.com/2012/04/servo-problems-part-2-demonstration.html

Rcarduino.blogspot.com

It's true.  Although you don't need assembler to determine that  :smiley-mr-green:  It's all right there in the C code.

DuaneB

Hi,
   Thats true, but its still interesting to look at the assembler, I assumed that some functions would be inlined but they are not, its also interesting to see how many cycles anything involving a volatile long takes - read four bytes from memory to register, do something to four bytes, write four bytes back to memory.

  I am interested because the RC Channel signals I am dealing with are 500us from neutral to full throttle, I will often have a situation with several pending interrupts, the lowest priority interrupt can be forced to wait 8us or more which shows up as a 2% error in the desired output signal.

I have half a dozen strategies to reduce this and will be working on them over the coming few days.

Duane B

rcarduino.blogspot.com

Read this
http://rcarduino.blogspot.com/2012/04/servo-problems-with-arduino-part-1.html
then watch this
http://rcarduino.blogspot.com/2012/04/servo-problems-part-2-demonstration.html

Rcarduino.blogspot.com

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy