Go Down

Topic: Book (Read 699 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