Problem with shifting and masking bits with ATMEGA256RFR2

Go To Last Post
27 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello,

I am having a very strange problem with masking bits.

1 uint8_t lsb, msb;

2 uint16_t zac;

3 zac = (uint16_t)(lsb|(msb<<8));

4 // if((zac & 0x0001) == 0) TODO

5 // return false;

6 zac = zac >> 0x0001UL;

I put a break point at line 6 and I see the original zac which is 18827, but then I step over one line (so that line 6 is executed) and I get

a wrong result: 9246.

In binary:

18827: 0100100110001011

9246 :  0010010000011110

The result I would expect is:  0010010011000101 = 9413.

I tried changing 0x0001UL with 0x01, 1... Does not help.

Also lines 4 and 5 don't execute properly. The code is suppose to check the lsb bit, and return false if it is zero. But it returns false for zac = 18827.

I am using Atmel ATMEGA256RFR2 Xplained pro board in Atmel Studio 7.8.

Thank you for your help.

Last Edited: Tue. Aug 8, 2017 - 03:21 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

So where are you "masking" bits, all I see is shifting bits?

 

Jim

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Optimisation ... ?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Jim,

Maybe I choose the wrong title. But there is bit masking in line 4.

 

Awneil,

I have turned off optimisations in order to be able to use the debugger.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

jure12 wrote:
there is bit masking in line 4.

but that line is commented-out and forms no part of the question!

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Awneil,

forgive me for being so unclear.

When I ran the code with the lines uncommented. I get the following result:

"The code is suppose to check the lsb bit, and return false if it is zero. But it returns false for zac = 18827.".

But when that didn't work I tried commenting the code and working on the other part of the code.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

jure12 wrote:
3 zac = (uint16_t)(lsb|(msb<<8));

You might want to check the generated code.  Do C promotion rules make the msb operation 16-bits, signed?  Or does it shift everything off the end and you end up with 0?

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

As you are using stdint.h types just build this for PC and use printf() there to see what is going on. Much easier than fiddling about with AVRs

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

theusch,

zac = zac >> 0x0001UL;

000009BA  STD Y+3,R24 Store indirect with displacement 

000009BB  LDD R24,Y+3 Load indirect with displacement 

000009BC  LDD R25,Y+4 Load indirect with displacement 

000009BD  LSR R25 Logical shift right 

000009BE  ROR R24 Rotate right through carry 

000009BF  STD Y+4,R25 Store indirect with displacement 

this is the dissassembly code for the line. I am not to familiar with the comands,

and register of AVR. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Put some breakpoints on the opcodes there - specifically on line 9BF then look at the raw value in registers 25 and 24. Ignore "watch windows" and other debugger stuff - that can sometimes be wrong. Do the actual AVR registers hold the value you hope to see?

 

In fact follow it all the way from where msb/lsb come in.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Clawson, I went line by line:

9BA: R24 = 0x5A R25 = 0x49
9BB: R24 = 0x5A R25 = 0x49
9BC: R24 = 0x5A R25 = 0x49
9BD: R24 = 0x5A R25 = 0x49
9BE: R24 = 0x5A R25 = 0x24
9BF: R24 = 0xAD R25 = 0x24

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

theusch wrote:
jure12 wrote:
3 zac = (uint16_t)(lsb|(msb<<8));

You might want to check the generated code.  Do C promotion rules make the msb operation 16-bits, signed?  Or does it shift everything off the end and you end up with 0?

C doesn't do integer arithmetic with anything smaller than an int.

Also, given a 16-bit int, neither  1<<16 nor 1<<15 is allowed. 1U<<15 is allowed, but not 1U<<16 .

 

OP shows no value for lsb or msb.

Don't know why he would expect anything in particular.

Methinks 'tis time for complete code.

International Theophysical Year seems to have been forgotten..
Anyone remember the song Jukebox Band?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

skeeve,

here is the full code:

 

uint8_t MAX_readTemp(double * temperatura)

{

  uint8_t lsb, msb;

uint16_t zac;

while(readPin(MAX_DRDY_PORT, MAX_DRDY));

 

SPI_start(MAX_SS_PORT, MAX_SS);

SPI_write(REG_RTDLSB_READ_ADD);

lsb=SPI_read();

SPI_end(MAX_SS_PORT, MAX_SS);

 

SPI_start(MAX_SS_PORT, MAX_SS);

SPI_write(REG_RTDMSB_READ_ADD);

msb=SPI_read();

SPI_end(MAX_SS_PORT, MAX_SS);

zac = (uint16_t)(lsb|(msb<<8));

// if((zac & 0x0001) == 0) TODO

// return false;

zac = zac >> 0x0001UL;

zac = (zac*MAX_REFERENTIAL_RESISTANCE)/(2^15); 

*temperatura = (zac - MAX_REFERENTIAL_RESISTANCE) / (PT1000_M222_ALPHA_COEF);

return 1;

}

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

jure12 wrote:
I see the original zac which is 18827
The calculator in Windows tells me that is 0x498B which rather raise the question of how that comes to be:

jure12 wrote:
9BA: R24 = 0x5A R25 = 0x49
So it's 0x495A not 0x498B. So I would suggest that at the very start of this lsb=0x5A=90 and msb=0x49=73. If you go back up a little is that what you see at the point of entry to this? Where do msb and lsb come from and what registers are they held in at the entry to this code?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
zac = (zac*MAX_REFERENTIAL_RESISTANCE)/(2^15); 

zac*MAX_REFERENTIAL_RESISTANCE has a high overflow potential (depends on what MAX_REFERENTIAL_RESISTANCE actually is).

And I doubt that 2 XOR 15 is what you really want.

Stefan Ernst

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson, here is the whole dissassembly:

00000986  RET Subroutine return 

00000987  PUSH R28 Push register on stack 

00000988  PUSH R29 Push register on stack 

00000989  RCALL PC+0x0001 Relative call subroutine 

0000098A  RCALL PC+0x0001 Relative call subroutine 

0000098B  IN R28,0x3D In from I/O location 

0000098C  IN R29,0x3E In from I/O location 

0000098D  STD Y+6,R25 Store indirect with displacement 

0000098E  STD Y+5,R24 Store indirect with displacement 

while(readPin(MAX_DRDY_PORT, MAX_DRDY));

0000098F  NOP No operation 

--- No source file -------------------------------------------------------------

00000990  LDI R22,0x02 Load immediate 

00000991  LDI R24,0x04 Load immediate 

00000992  RCALL PC-0x045D Relative call subroutine 

00000993  OR R24,R25 Logical OR 

00000994  BRNE PC-0x04 Branch if not equal 

00000995  LDI R22,0x00 Load immediate 

00000996  LDI R24,0x06 Load immediate 

00000997  CALL 0x00001471 Call subroutine 

00000999  LDI R24,0x02 Load immediate 

0000099A  RCALL PC+0x069B Relative call subroutine 

0000099B  CALL 0x00001260 Call subroutine 

0000099D  STD Y+1,R24 Store indirect with displacement 

0000099E  LDI R22,0x00 Load immediate 

0000099F  LDI R24,0x06 Load immediate 

000009A0  CALL 0x00001572 Call subroutine 

000009A2  LDI R22,0x00 Load immediate 

000009A3  LDI R24,0x06 Load immediate 

SPI_write(REG_RTDMSB_READ_ADD);

000009A4  CALL 0x00001471 Call subroutine 

000009A6  LDI R24,0x01 Load immediate 

msb=SPI_read();

000009A7  RCALL PC+0x068E Relative call subroutine 

000009A8  CALL 0x00001260 Call subroutine 

SPI_end(MAX_SS_PORT, MAX_SS);

000009AA  STD Y+2,R24 Store indirect with displacement 

000009AB  LDI R22,0x00 Load immediate 

000009AC  LDI R24,0x06 Load immediate 

000009AD  CALL 0x00001572 Call subroutine 

000009AF  LDD R24,Y+1 Load indirect with displacement 

000009B0  MOV R18,R24 Copy register 

000009B1  LDI R19,0x00 Load immediate 

000009B2  LDD R24,Y+2 Load indirect with displacement 

000009B3  MOV R24,R24 Copy register 

000009B4  LDI R25,0x00 Load immediate 

000009B5  MOV R25,R24 Copy register 

000009B6  CLR R24 Clear Register 

000009B7  OR R24,R18 Logical OR 

000009B8  OR R25,R19 Logical OR 

000009B9  STD Y+4,R25 Store indirect with displacement 

zac = zac >> 0x0001UL;

000009BA  STD Y+3,R24 Store indirect with displacement 

000009BB  LDD R24,Y+3 Load indirect with displacement 

000009BC  LDD R25,Y+4 Load indirect with displacement 

000009BD  LSR R25 Logical shift right 

000009BE  ROR R24 Rotate right through carry 

000009BF  STD Y+4,R25 Store indirect with displacement 

zac = (zac*MAX_REFERENTIAL_RESISTANCE)/(2^15); 

000009C0  STD Y+3,R24 Store indirect with displacement 

000009C1  LDD R18,Y+3 Load indirect with displacement 

000009C2  LDD R19,Y+4 Load indirect with displacement 

000009C3  LDI R24,0x3C Load immediate 

000009C4  LDI R25,0x0F Load immediate 

000009C5  MUL R18,R24 Multiply unsigned 

000009C6  MOVW R20,R0 Copy register pair 

000009C7  MUL R18,R25 Multiply unsigned 

000009C8  ADD R21,R0 Add without carry 

000009C9  MUL R19,R24 Multiply unsigned 

000009CA  ADD R21,R0 Add without carry 

000009CB  CLR R1 Clear Register 

--- C:\Users\xpero\OneDrive - Univerza v Mariboru\Diplomska naloga\Program\Verzija_5\Diplomska4\Diplomska2\Debug/.././MAX31865.c 

000009CC  MOVW R18,R20 Copy register pair 

000009CD  LDI R26,0xC5 Load immediate 

000009CE  LDI R27,0x4E Load immediate 

000009CF  CALL 0x00001995 Call subroutine 

000009D1  LSR R25 Logical shift right 

000009D2  ROR R24 Rotate right through carry 

000009D3  LSR R25 Logical shift right 

000009D4  ROR R24 Rotate right through carry 

000009D5  STD Y+4,R25 Store indirect with displacement 

*temperatura = (zac - MAX_REFERENTIAL_RESISTANCE) / (PT1000_M222_ALPHA_COEF);

000009D6  STD Y+3,R24 Store indirect with displacement 

000009D7  LDD R24,Y+3 Load indirect with displacement 

000009D8  LDD R25,Y+4 Load indirect with displacement 

000009D9  SUBI R24,0x3C Subtract immediate 

000009DA  SBCI R25,0x0F Subtract immediate with carry 

000009DB  MOVW R24,R24 Copy register pair 

000009DC  LDI R26,0x00 Load immediate 

000009DD  LDI R27,0x00 Load immediate 

000009DE  MOVW R22,R24 Copy register pair 

--- C:\Users\xpero\OneDrive - Univerza v Mariboru\Diplomska naloga\Program\Verzija_5\Diplomska4\Diplomska2\Debug/.././MAX31865.c 

000009DF  MOVW R24,R26 Copy register pair 

000009E0  CALL 0x00001874 Call subroutine 

000009E2  MOVW R26,R24 Copy register pair 

000009E3  MOVW R24,R22 Copy register pair 

000009E4  LDI R18,0x66 Load immediate 

000009E5  LDI R19,0x66 Load immediate 

000009E6  LDI R20,0x76 Load immediate 

000009E7  LDI R21,0x40 Load immediate 

000009E8  MOVW R22,R24 Copy register pair 

000009E9  MOVW R24,R26 Copy register pair 

000009EA  CALL 0x000017E0 Call subroutine 

000009EC  MOVW R26,R24 Copy register pair 

000009ED  MOVW R24,R22 Copy register pair 

000009EE  LDD R18,Y+5 Load indirect with displacement 

000009EF  LDD R19,Y+6 Load indirect with displacement 

000009F0  MOVW R30,R18 Copy register pair 

000009F1  STD Z+0,R24 Store indirect with displacement 

000009F2  STD Z+1,R25 Store indirect with displacement 

--- C:\Users\xpero\OneDrive - Univerza v Mariboru\Diplomska naloga\Program\Verzija_5\Diplomska4\Diplomska2\Debug/.././MAX31865.c 

000009F3  STD Z+2,R26 Store indirect with displacement 

return 1;

000009F4  STD Z+3,R27 Store indirect with displacement 

}

 

sternst, MAX_REFERENTIAL_RESISTANCE is equal to 3900.  I am quite sure that part is correct (in logic), but you are I think correct about the overflow issue. I should make zac to uint32_t.

EDIT:

sternst, I see what you were trying to say now. I ment 2 to the power of 15. I will use the math library.

Last Edited: Tue. Aug 8, 2017 - 05:03 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OP has not coded for clarity.
'Twould be nice to know the types and values of
MAX_REFERENTIAL_RESISTANCE and PT1000_M222_ALPHA_COEF.
I suspect an integer type and double.
If MAX_REFERENTIAL_RESISTANCE is an int,
zac*MAX_REFERENTIAL_RESISTANCE is likely to overflow.
zac = zac >> 0x0001UL could be replaced by
zac = zac >> 1 ,
In recent C, the type of the shift has no effect on the type of the result.
As noted 2^15 is not 0x80000.
it is 2 .
avr-gcc and most avr-C's have 16-bit ints, therefore:
0x80000 is an unsigned int.
1<<15 is invalid
pow(2, 15) is allowed, though not necessarily wise.
1U<<15 and 1L<<15 are both allowed.

For testing purposes, lsb, msb and zac
should get their values from assignments from explicit values.

International Theophysical Year seems to have been forgotten..
Anyone remember the song Jukebox Band?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Can you show the LSS not the totally hopeless asm from the debugger? Between 990 and 9A3 it seems to have given up on source annotation! I am trying to work out what the actually call to spi_read() is - I think it must be

 

0000099B  CALL 0x00001260 Call subroutine 

0000099D  STD Y+1,R24 Store indirect with displacement

 

and later one sees:

 

msb=SPI_read();

000009A7  RCALL PC+0x068E Relative call subroutine 

000009A8  CALL 0x00001260 Call subroutine 

SPI_end(MAX_SS_PORT, MAX_SS);

000009AA  STD Y+2,R24 Store indirect with displacement 

 

the forget the RCALL, the call to 1260 appears to be the read and this seems to suggest that Y+1 is "lsb" and Y+2 is "msb". I would like to know what is in R24 at the point at which each STD is executed. I'm guessing it is 0x5A and 0x49 ?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson,

I am not sure what LSS is or how to get it. 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Sorry but I thought from your disassembly that you were using Studio 7. By default it creates a file called <project name>.lss in the build directory (either ./Debug or ./Release). That is an Asm disassembly with C annotation that is MUCh easier to read than the disassembly shown in the debugger.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This is the code from the .lss

0000130e <MAX_readTemp>:

 

uint8_t MAX_readTemp(double * temperatura)

{

    130e: cf 93       push r28

    1310: df 93       push r29

    1312: 00 d0       rcall .+0       ; 0x1314 <MAX_readTemp+0x6>

    1314: 00 d0       rcall .+0       ; 0x1316 <MAX_readTemp+0x8>

    1316: cd b7       in r28, 0x3d ; 61

    1318: de b7       in r29, 0x3e ; 62

    131a: 9e 83       std Y+6, r25 ; 0x06

    131c: 8d 83       std Y+5, r24 ; 0x05

  uint8_t lsb, msb;

uint16_t zac;

while(readPin(MAX_DRDY_PORT, MAX_DRDY));

    131e: 00 00       nop

    1320: 62 e0       ldi r22, 0x02 ; 2

    1322: 84 e0       ldi r24, 0x04 ; 4

    1324: a2 db       rcall .-2236   ; 0xa6a <readPin>

    1326: 89 2b       or r24, r25

    1328: d9 f7       brne .-10     ; 0x1320 <MAX_readTemp+0x12>

 

SPI_start(MAX_SS_PORT, MAX_SS);

    132a: 60 e0       ldi r22, 0x00 ; 0

    132c: 86 e0       ldi r24, 0x06 ; 6

    132e: 0e 94 81 14 call 0x2902 ; 0x2902 <SPI_start>

SPI_write(REG_RTDLSB_READ_ADD);

    1332: 82 e0       ldi r24, 0x02 ; 2

lsb=SPI_read();

    1334: aa d6       rcall .+3412   ; 0x208a <SPI_write>

    1336: 0e 94 70 12 call 0x24e0 ; 0x24e0 <SPI_read>

SPI_end(MAX_SS_PORT, MAX_SS);

    133a: 89 83       std Y+1, r24 ; 0x01

    133c: 60 e0       ldi r22, 0x00 ; 0

    133e: 86 e0       ldi r24, 0x06 ; 6

    1340: 0e 94 82 15 call 0x2b04 ; 0x2b04 <SPI_end>

 

SPI_start(MAX_SS_PORT, MAX_SS);

    1344: 60 e0       ldi r22, 0x00 ; 0

    1346: 86 e0       ldi r24, 0x06 ; 6

SPI_write(REG_RTDMSB_READ_ADD);

    1348: 0e 94 81 14 call 0x2902 ; 0x2902 <SPI_start>

    134c: 81 e0       ldi r24, 0x01 ; 1

msb=SPI_read();

    134e: 9d d6       rcall .+3386   ; 0x208a <SPI_write>

    1350: 0e 94 70 12 call 0x24e0 ; 0x24e0 <SPI_read>

SPI_end(MAX_SS_PORT, MAX_SS);

    1354: 8a 83       std Y+2, r24 ; 0x02

    1356: 60 e0       ldi r22, 0x00 ; 0

    1358: 86 e0       ldi r24, 0x06 ; 6

    135a: 0e 94 82 15 call 0x2b04 ; 0x2b04 <SPI_end>

zac = (uint16_t)(lsb|(msb<<8));

    135e: 89 81       ldd r24, Y+1 ; 0x01

    1360: 28 2f       mov r18, r24

    1362: 30 e0       ldi r19, 0x00 ; 0

    1364: 8a 81       ldd r24, Y+2 ; 0x02

    1366: 88 2f       mov r24, r24

    1368: 90 e0       ldi r25, 0x00 ; 0

    136a: 98 2f       mov r25, r24

    136c: 88 27       eor r24, r24

    136e: 82 2b       or r24, r18

    1370: 93 2b       or r25, r19

    1372: 9c 83       std Y+4, r25 ; 0x04

// if((zac & 0x0001) == 0) TODO

// return false;

zac = zac >> 0x0001UL;

    1374: 8b 83       std Y+3, r24 ; 0x03

    1376: 8b 81       ldd r24, Y+3 ; 0x03

    1378: 9c 81       ldd r25, Y+4 ; 0x04

    137a: 96 95       lsr r25

    137c: 87 95       ror r24

    137e: 9c 83       std Y+4, r25 ; 0x04

zac = (zac*MAX_REFERENTIAL_RESISTANCE)/pow(2,15); 

    1380: 8b 83       std Y+3, r24 ; 0x03

    1382: 4b 81       ldd r20, Y+3 ; 0x03

    1384: 5c 81       ldd r21, Y+4 ; 0x04

    1386: 2c e3       ldi r18, 0x3C ; 60

    1388: 3f e0       ldi r19, 0x0F ; 15

    138a: 42 9f       mul r20, r18

    138c: c0 01       movw r24, r0

    138e: 43 9f       mul r20, r19

    1390: 90 0d       add r25, r0

    1392: 52 9f       mul r21, r18

    1394: 90 0d       add r25, r0

    1396: 11 24       eor r1, r1

    1398: cc 01       movw r24, r24

    139a: a0 e0       ldi r26, 0x00 ; 0

    139c: b0 e0       ldi r27, 0x00 ; 0

    139e: bc 01       movw r22, r24

    13a0: cd 01       movw r24, r26

    13a2: 0e 94 84 18 call 0x3108 ; 0x3108 <__floatunsisf>

    13a6: dc 01       movw r26, r24

    13a8: cb 01       movw r24, r22

    13aa: 20 e0       ldi r18, 0x00 ; 0

    13ac: 30 e0       ldi r19, 0x00 ; 0

    13ae: 40 e0       ldi r20, 0x00 ; 0

    13b0: 57 e4       ldi r21, 0x47 ; 71

    13b2: bc 01       movw r22, r24

    13b4: cd 01       movw r24, r26

    13b6: 0e 94 f0 17 call 0x2fe0 ; 0x2fe0 <__divsf3>

    13ba: dc 01       movw r26, r24

    13bc: cb 01       movw r24, r22

    13be: bc 01       movw r22, r24

    13c0: cd 01       movw r24, r26

    13c2: 0e 94 58 18 call 0x30b0 ; 0x30b0 <__fixunssfsi>

    13c6: dc 01       movw r26, r24

    13c8: cb 01       movw r24, r22

    13ca: 9c 83       std Y+4, r25 ; 0x04

*temperatura = (zac - MAX_REFERENTIAL_RESISTANCE) / (PT1000_M222_ALPHA_COEF);

    13cc: 8b 83       std Y+3, r24 ; 0x03

    13ce: 8b 81       ldd r24, Y+3 ; 0x03

    13d0: 9c 81       ldd r25, Y+4 ; 0x04

    13d2: 8c 53       subi r24, 0x3C ; 60

    13d4: 9f 40       sbci r25, 0x0F ; 15

    13d6: cc 01       movw r24, r24

    13d8: a0 e0       ldi r26, 0x00 ; 0

    13da: b0 e0       ldi r27, 0x00 ; 0

    13dc: bc 01       movw r22, r24

    13de: cd 01       movw r24, r26

    13e0: 0e 94 84 18 call 0x3108 ; 0x3108 <__floatunsisf>

    13e4: dc 01       movw r26, r24

    13e6: cb 01       movw r24, r22

    13e8: 26 e6       ldi r18, 0x66 ; 102

    13ea: 36 e6       ldi r19, 0x66 ; 102

    13ec: 46 e7       ldi r20, 0x76 ; 118

    13ee: 50 e4       ldi r21, 0x40 ; 64

    13f0: bc 01       movw r22, r24

    13f2: cd 01       movw r24, r26

    13f4: 0e 94 f0 17 call 0x2fe0 ; 0x2fe0 <__divsf3>

    13f8: dc 01       movw r26, r24

    13fa: cb 01       movw r24, r22

    13fc: 2d 81       ldd r18, Y+5 ; 0x05

    13fe: 3e 81       ldd r19, Y+6 ; 0x06

    1400: f9 01       movw r30, r18

    1402: 80 83       st Z, r24

    1404: 91 83       std Z+1, r25 ; 0x01

    1406: a2 83       std Z+2, r26 ; 0x02

return 1;

    1408: b3 83       std Z+3, r27 ; 0x03

    140a: 81 e0       ldi r24, 0x01 ; 1

    140c: 26 96       adiw r28, 0x06 ; 6

    140e: 0f b6       in r0, 0x3f ; 63

    1410: f8 94       cli

    1412: de bf       out 0x3e, r29 ; 62

    1414: 0f be       out 0x3f, r0 ; 63

    1416: cd bf       out 0x3d, r28 ; 61

    1418: df 91       pop r29

    141a: cf 91       pop r28

    141c: 08 95       ret

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

In which case breakpoint at :

 

  133a: 89 83       std Y+1, r24 ; 0x01

 

and

 

  1354: 8a 83       std Y+2, r24 ; 0x02

 

At each break what is in R24 ?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

For command  133a: 89 83       std Y+1, r24 ; 0x01:

 

R24 before execution was 0xA8, after execution still 0xA8

 

For command 1354: 8a 83       std Y+2, r24 ; 0x02:

 

R24 before execution was 0x48, after execution it is still 0x48

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OK so those are the values of lsb and msb. So the input value is 0x48A8 (18,600) after >>1 I expect that to then be 0x2454 (9,300)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok, so this is a little embarrassing.

I've changed 

uint8_t lsb, msb;

uint16_t zac;

to

uint16_t lsb, msb;

uint32_t zac;

 

And now it works.

I thought the uint16_t cast in line

zac = (uint16_t)(lsb|(msb<<8));

would do the trick, but that cast casts the variables after the shifting operation.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

so apply the cast to the variable to be shifted - rather than the result of the shift!

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Anyway this does not really explain the original issue anyway. The need for the casting (because of sign extension) would surely only come into play if the most significant bit (bit 7) of "msb" were set. But in the test data suggested it never was anyway.