Load R16 with Status Reg??

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

What is the correct way to load the status register into R16?

 

LDS R16, 0x005F      LDS R16, 0x00DF   don't seem to work on the Studio 7 simulator.  I can see the Status Register in Memory 4 Data Registers Window at 0x005F.

 

 

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

You need IN not LDS

	in	save_sreg,SREG		;Save Status register
;Do something here		
	out	SREG,save_sreg		;Restore Status register

 

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

if you use in it's 0x3f

it you use ld(s) it's 0x5f, and it should work in the simulator!

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

 

All's well that ends well, but I'm still puzzled.  

 

Studio 7 simulator appears to store the S-Register value in r16 as 21, but in the I/O Window and in the Data Mapped I/O window it is 0xA1.

 

However, when r16 is read back into S-Register the correct value returns!

 

Attached is a screen shot of the IDE

 

What am I missing?

;
; Status Reg Save.asm
;
; Created: 4/1/2017 7:05:49 AM
; Author : John
;Part simulated is ATtiny1634



main:
	sei						;
	ldi r18, 0xFF			;
Loop:
	inc r18					;Measurement Counter
	cpi r18, 0xFE			;
	nop						;
	in r16, SREG			; ***NOT Working*** 
	sbrc r16, 1				;
	jmp Loop				;
	clc						;To change S-Reg
	out SREG, r16			;
	nop						;

 

Attachment(s): 

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

John3 wrote:
Studio 7 simulator appears to store the S-Register value in r16 as 21, but in the I/O Window and in the Data Mapped I/O window it is 0xA1.
The difference is the I-flag. The debugger is tampering with it (e.g. the flag is masked during single stepping by default), so I would not be surprised to see it cleared here and set there.

Stefan Ernst

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

Thanks for the info Stefan.  

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

if you use in it's 0x3f

it you use ld(s) it's 0x5f,

Of course one shouldn't use either in order not to encourage MNS (magic number syndrome) but use SREG instead which happens to be defined as 

.equ	SREG	= 0x3f

in the .inc files. wink

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

I ended up using IN r16, SREG  (where I started).  I was single stepping through my code (finding lots of errors I could eventually fix) but I was bothered that I read 0x21 in r16 when the memory address read A1 (which was also what was displayed in the I/O window).

 

Then, I really got off in the weeds with the LDS (16-bit) – Load Direct from Data Space description:

 

" A 7-bit address must be supplied. The address given in the instruction is coded to a data space address
as follows:

ADDR[7:0] = (INST[8], INST[8], INST[10], INST[9], INST[3], INST[2], INST[1], INST[0])

Memory access is limited to the address range 0x40...0xbf."

 

So I tried turning 0x5F into 0xDF.

 

I'm really thankful everyone on this board is so helpful.  

 

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

By the way you can use any register to save SREG without the need to use more valuable registers R16-R31, I reserve R15 for SREG use in ISRs.

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

What for an advice?

if you use SREG together with LD instructions it wont work! 

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

if you use SREG together with LD instructions it wont work! 

Which is why I said to use IN.  And why would you want to use a longer instruction than necessary? cheeky

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

because ld and ldd works (correct LDS don't make sense).

 

Often you want to write general code that can be reused!

 

My info in #3 is correct , and written because your info in #2 is wrong.

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

Oh dear! I hope my 1,000s of boards in the filed don't find out I have been doing the sreg thing wrong all these years, they may decide to stop working. surprise

 

And somebody tell Atmel to stop publishing wrong things like:

Do_spm:
; check for previous SPM complete
Wait_spm:
    in temp1, SPMCR
    sbrc temp1, SPMEN
    rjmp Wait_spm

; input: spmcrval determines SPM action
; disable interrupts if enabled, store status

    in temp2, SREG      //############################
    cli

; check that no EEPROM write access is present
Wait_ee:
    sbic EECR, EEWE
    rjmp Wait_ee

; SPM timed sequence
    out SPMCR, spmcrval
    spm

; restore SREG (to enable interrupts if originally enabled)
    out SREG, temp2     //############################
    ret

so I have been doing things like the above in #2

ISR_INT1:
	in	save_sreg,SREG		;Save Status register
;Code here
	out	SREG,save_sreg		;Restore Status register
	reti

and lately with Xmegas

 

; 500us ticks
 IVEC_TCD5_CCA_vect:
	push	temp
	in	save_sreg,CPU_SREG	; Save Status register #######################
	ldi	temp, (1<<PIN1_bp)	; 1KHz output
	STORE	PORTC_OUTTGL, temp	;
	out	CPU_SREG,save_sreg	; Restore Status register ####################
	pop	temp
	reti

 

 

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

Last Edited: Sun. Apr 2, 2017 - 10:09 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You'd better send out a recall notice John!wink

David

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

I guess that is the way the devil read the bible

in #2 you wrote :

You need IN not LDS

and that is wrong!

Both LDS and IN works fine, and how to use them I showed in #3!

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

Both LDS and IN works fine,

True but isn't t that going against the spirit of using assembler where you want the fastest/smallest code?

 

IN 1 word/1 cycle (preferred by Atmel as all .inc files have SREG at 0x3f)

 

LDS 2 words/2 cycles

 

LD or LDD 1 word/1 cycle but you also need to load X, Y or Z so longer/slower still.

 

Even if you used GCC the code optimises at using IN and OUT

0f b6      in	r0, 0x3f    ; 63
0f be      out	0x3f, r0    ; 63

and Codevision

b7ef      IN   R30,SREG
bfef      OUT  SREG,R30

and Imagecraft (timer demo C code for Xmega I wrote)

 

_TCD5_CCA_interrupt:
    00195 938A      ST	-Y,R24
    00196 B78F      IN	R24,0x3F    @@@@@@@@@@@@@
    00197 938A      ST	-Y,R24
    00198 E082      LDI	R24,2
    00199 9380 0647 STS	0x647,R24
(0107) }
(0108)
(0109) // 500us ticks, 1KHz output
(0110) void TCD5_CCA_interrupt (void)
(0111) {
(0112) 	PORTC_OUTTGL = (1<<PIN1_bp);
    0019B 9189      LD	R24,Y+
    0019C BF8F      OUT	0x3F,R24   @@@@@@@@@@@@@
    0019D 9189      LD	R24,Y+
    0019E 9518      RETI
(0113) }

so why confuse the OP?

 

and by the way religious quotations are not allowed, signed the devil

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

Last Edited: Mon. Apr 3, 2017 - 06:00 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This go in circles I answered it in #12 

 

I guess I'm out.