Skip to content

Instantly share code, notes, and snippets.

@bigjosh
Created Jan 8, 2016
Embed
What would you like to do?
Test different wasy of setting the I bit in SREG on AVR
; Test if instruction after I bit in SREG is set is always run
; More info at http://wp.josh.com/2016/01/05/different-ways-to-set-i-bit-in-avr-sreg-besides-sei/
jmp start // Reset vector
.org INT0addr
INT0_handler:
loop1:
//sbi PORTB,5 // LED on . Uncommend this to verifiy that the ISR even gets called.
rjmp loop1 // Infinite loop
// INT0 is the only vector used, so mind as well start code here...
start:
#if 0 // Use this to try an find where the lost byte gets pushed when SP points to mem mapped IO registers
; Fill all of memory with the pattern 0x55 so I can see where the push is ending up
; (It turns out that it ended up nowheres)
.equ memstrt = 0x100 ; First address of RAM to be filled
.equ memend = 0x4FF ; Last address of RAM to be filled
.equ fillchr = 0x55 ; Fill pattern
;---------------------------------------------------------------------------
; Fills RAM with 0x55
fillmem:
ldi XL,low(SRAM_START); Load the X pointer with start address
ldi XH,high(SRAM_START) ;
ldi r16,0x55 ; Load fill pattern to r16
fill_lp:
st X+,r16 ; Store a fill pattern, advance X pointer
cpi XL,low(RAMEND+1) ; Repeat until XL = low(memend+1)
brne fill_lp ;
cpi XH,high(RAMEND+1) ; Repeat until XH = high(memend+1)
brne fill_lp ; (executed only on every 256th loop cycle)
;---------------------------------------------------------------------------
#endif
sbi DDRB,5 // LED pin to output mode
sbi DDRD,2 // INT0 to output mode
sbi PORTD,2 // INT0 high
sbi EIMSK, INT0 // Enable INT0 interrupt on low
cbi PORTD, 2 // Trigger INT0 interrupt
// Ok, gun is loaded - just sei to fire an interrupt!
// Test bed: Put some code here that turns on the I bit
// SEI (base case)
#if 1
sei
#endif
// ST
#if 0
clr r29 // Clear Y pointer high byte
ldi r28,0x5f // Set Y low byte to point to SREG (0x3f+0x20)
ld r16, Y // Get SREG
ori r16,128 // Set I bit
st Y,r16 // Put SREG in the Doug Henning way
#endif
// Point stack to SREG
#if 0
clr r28 // ZERO
out 0x3e, r28 // Stack high
ldi r28,0x5f // pointer to memory mapped SREG
out 0x3d, r28 // Stack now points to SREG!
ldi r16,0x80
push r16
#endif
// Point stack to GPIO1
#if 0
clr r28 // ZERO
out 0x3e, r28 // Stack high
ldi r28, 0x4a // pointer to memory mapped GPIOR1
out 0x3d, r28 // Stack now points to SREG!
ldi r16,0x80
push r16
#endif
// XCH
#if 0
clr r31 // Clear Z pointer high byte
ldi r20,0x5f // Set Z low byte to point to SREG (0x3f+0x20)
ld r16, Z // Get SREG
ori r16,128 // Set I bit
xch Z,r16 // Put SREG in the Doug Henning way
#endif
// nop // Uncomment this to test the negative case. The nop will consume the preveledged instruction so we shoudl never rea the next one.
sbi PORTB,5 // LED on
loop:
jmp loop // Infinate loop
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment