User Tools

Site Tools


avr_assembler

Renesis from Darker Technologies contributes his AVR assembly code example for controlling ShiftBrites using an Atmega164:

shiftbrite_example_20090726.asm

;//_ shiftbrite_example_20090726.asm
;
; avr assembly macros for driving shiftbrites.
;
; this example swaps the colors purple and green between two 
; shiftbrites a few times a second at 8MHz core speed. 
;
; the number of shiftbrites and the io pins used by the code are 
; defined in the file "sb_config.inc". 8bit and 10bit color data 
; modes can also be selected in this file.
;
; The color data is stored in sram and shifted out by the
; macro "sb_send_all". The cache size is dependent on the number
; of shiftbrites and 8b or 10b mode selection. Data can be created
; in, stored to, or loaded from the cache using the macros "sb_sti",
; "sb_st", and "sb_ld".
;
; detailed descriptions of these macros can be found in the file
; "sb_frontend.inc".
;
; developed on avrstudio4 using conditional preprocessor directives.
 
 
;//_ part definition (change this to match your avr)
 
.include "m164pdef.inc"
 
 
;//_ shiftbrite related include files
 
.include "sb_config.inc"
.include "sb_backend.inc"
.include "sb_frontend.inc"
 
 
;//_ register definitions
 
.def temp   = r16
.def temp2  = r17
.def temp3  = r18
.def temp4  = r19
.def temp5  = r20
.def temp6  = r21
 
 
;//_ initialization
 
.org 0
 
    ; setup stack pointer
 
    ldi temp,high(ramend)
    out sph,temp
    ldi temp,low(ramend)
    out spl,temp
 
    ; setup shiftbrite output pins
 
    sb_pin_init
 
    ; setup shiftbrite red/green/blue color data
 
    sb_sti 1,$ff,$00,$ff
    sb_sti 2,$00,$ff,$00
 
 
;//_ program mainloop
 
deathloop: 
 
    ; shift color data out 
 
    sb_send_all
 
    ; primitive delay routine
 
    ldi r16,100
delay0:
    ldi r17,100
delay1:
    ldi r18,100
delay2:
    dec r18
    brne delay2
    dec r17
    brne delay1
    dec r16
    brne delay0 
 
    ; swap shiftbrite color data
 
    sb_ld 1,r1,r2,r3
    sb_ld 2,r4,r5,r6
 
    sb_st 1,r4,r5,r6
    sb_st 2,r1,r2,r3
 
    ; restart mainloop
 
    jmp deathloop

sb_config.inc

;//_ shiftbright constants
 
    ; number of shiftbrite devices
.set sb_count = 2 ; do not use (n - 1) values 
 
    ; color data mode 
#define SB8_MODE 1 ; 0 = 10 bit, 1 = 8 bit
 
 
;//_ shiftbrite control pin definitions
 
    ; data pin    
.set sb_d_port   = porta
.set sb_d_ddr    = ddra
.set sb_d_pin    = pa0
 
    ; latch pin
.set sb_l_port   = porta
.set sb_l_ddr    = ddra
.set sb_l_pin    = pa1
 
    ; enable pin
.set sb_e_port   = porta
.set sb_e_ddr    = ddra
.set sb_e_pin    = pa2
 
    ; clock pin
.set sb_c_port   = porta
.set sb_c_ddr    = ddra
.set sb_c_pin    = pa3

sb_backend.inc

;//_ shiftbrite backend macros 
    ;    ;
    ; access to a shiftbrite's color register is done thru an sram buffer
    ; using the macros in the file "sb_fontend.inc". 
    ;
    ;
    ; shiftbrite config register access is optimized for speed. dot
    ; correction and pwm clock settings are changed by editing the 
    ; sbi/cbi lines in the macro "sb_qconfig".
    ;
    ; color data sram buffer size is calculated and allocated in this file,
    ; based on constants set in the file "sb_config.inc".
    ;
    ; sb_clock      - pulses shiftbrite clock pin
    ; sb_latch      - pulses shiftbrite latch pin
    ; sb_enable     - enables shiftbrite led drivers
    ; sb_disable    - disables shiftbrite led drivers
    ; sb_qconfig    - shifts out hard coded shiftbrite config data
    ; sb_bit        - outputs a color data bit 
    ; sb_color      - shifts out one shiftbrite's 10b color data
    ; sb8_color     - shifts out one shiftbrite's 8b color data
    ;
    ; file dependancies:
    ;
    ; sb_config.inc
 
 
.dseg
    ; sram allocation
    ;
    ; // shiftbrite color data array order
    ;
    ; 1st shiftbrite data block (LSA, shifted out first)
    ; 2nd shiftbrite data block 
    ; 3rd...
    ; 4th...
 
    ; // shiftbrite data block (6 bytes)
    ;
    ; blue msb (LSA)
    ; blue lsb 
    ; red msb
    ; red lsb
    ; green lsb
    ; green lsb (MSA)
 
 
 
#if (SB8_MODE)
#message "*** color word mode: 8 bits"
    sb_sram:    .byte (3 * sb_count)
#else
#message "*** color word mode: 10 bits"
    sb_sram:    .byte (6 * sb_count)
#endif
 
.cseg
 
 
 
.macro sb_clock
    sbi sb_c_port,sb_c_pin
    cbi sb_c_port,sb_c_pin
.endmacro
 
 
 
.macro sb_latch
    sbi sb_l_port,sb_l_pin
    cbi sb_l_port,sb_l_pin
.endmacro
 
 
 
.macro sb_enable
    cbi sb_e_port,sb_e_pin
.endmacro
 
 
 
.macro sb_disable
    sbi sb_e_port,sb_e_pin
.endmacro
 
 
 
.macro sb_qconfig ; shift out config word (fast, no input)
 
    cbi sb_d_port,sb_d_pin ; d31 dont care
    sb_clock
    sbi sb_d_port,sb_d_pin ; d30 config register select (set 1)
    sb_clock
    cbi sb_d_port,sb_d_pin ; d29 allegro test bit (set 0)
    sb_clock
    cbi sb_d_port,sb_d_pin ; d28 allegro test bit (set 0)
    sb_clock
    cbi sb_d_port,sb_d_pin ; d27 dot correction blue
    sb_clock
    cbi sb_d_port,sb_d_pin ; d25 ...
    sb_clock
    cbi sb_d_port,sb_d_pin ; d25 ...
    sb_clock
    cbi sb_d_port,sb_d_pin ; d24 ...
    sb_clock
    cbi sb_d_port,sb_d_pin ; d23 ...
    sb_clock
    cbi sb_d_port,sb_d_pin ; d22 ...
    sb_clock
    cbi sb_d_port,sb_d_pin ; d21 ...
    sb_clock
    cbi sb_d_port,sb_d_pin ; d20 ...
    sb_clock
    cbi sb_d_port,sb_d_pin ; d19 dont care
    sb_clock
    cbi sb_d_port,sb_d_pin ; d18 dont care
    sb_clock
    cbi sb_d_port,sb_d_pin ; d17 dont care
    sb_clock
    cbi sb_d_port,sb_d_pin ; d16 dot correction red...
    sb_clock
    cbi sb_d_port,sb_d_pin ; d15 ...
    sb_clock
    cbi sb_d_port,sb_d_pin ; d14 ...
    sb_clock
    cbi sb_d_port,sb_d_pin ; d13 ...
    sb_clock
    cbi sb_d_port,sb_d_pin ; d12 ...
    sb_clock
    cbi sb_d_port,sb_d_pin ; d11 ...
    sb_clock
    cbi sb_d_port,sb_d_pin ; d10 ...
    sb_clock
    cbi sb_d_port,sb_d_pin ; d9 dont care
    sb_clock
    cbi sb_d_port,sb_d_pin ; d8 clock mode (0 for 800KHz pwm clock)
    sb_clock
    cbi sb_d_port,sb_d_pin ; d7 clock mode (0 for 800KHz pwm clock)
    sb_clock
    cbi sb_d_port,sb_d_pin ; d6 dot correction green...
    sb_clock
    cbi sb_d_port,sb_d_pin ; d5 ...
    sb_clock
    cbi sb_d_port,sb_d_pin ; d4 ...
    sb_clock
    cbi sb_d_port,sb_d_pin ; d3 ...
    sb_clock
    cbi sb_d_port,sb_d_pin ; d2 ...
    sb_clock
    cbi sb_d_port,sb_d_pin ; d1 ...
    sb_clock
    cbi sb_d_port,sb_d_pin ; d0 ...
    sb_clock
 
.endmacro    
 
 
 
.macro sb_bit
 
    sbrs temp,@0
    rjmp bit_clear
    sbi sb_d_port,sb_d_pin
    rjmp bit_set
bit_clear: 
    cbi sb_d_port,sb_d_pin
bit_set:
 
.endmacro
 
 
 
.macro sb_color 
 
    cbi sb_d_port,sb_d_pin ; d31 dont care
    sb_clock
    cbi sb_d_port,sb_d_pin ; d30 color register select (set 0)
    sb_clock
 
    ld temp,z+
 
    sb_bit 1
    sb_clock
    sb_bit 0
    sb_clock
 
    ld temp,z+
 
    sb_bit 7
    sb_clock
    sb_bit 6
    sb_clock
    sb_bit 5
    sb_clock
    sb_bit 4
    sb_clock
    sb_bit 3
    sb_clock
    sb_bit 2
    sb_clock
    sb_bit 1
    sb_clock
    sb_bit 0
    sb_clock
 
    ld temp,z+
 
    sb_bit 1
    sb_clock
    sb_bit 0
    sb_clock
 
    ld temp,z+
 
    sb_bit 7
    sb_clock
    sb_bit 6
    sb_clock
    sb_bit 5
    sb_clock
    sb_bit 4
    sb_clock
    sb_bit 3
    sb_clock
    sb_bit 2
    sb_clock
    sb_bit 1
    sb_clock
    sb_bit 0
    sb_clock
 
    ld temp,z+
 
    sb_bit 1
    sb_clock
    sb_bit 0
    sb_clock
 
    ld temp,z+
 
    sb_bit 7
    sb_clock
    sb_bit 6
    sb_clock
    sb_bit 5
    sb_clock
    sb_bit 4
    sb_clock
    sb_bit 3
    sb_clock
    sb_bit 2
    sb_clock
    sb_bit 1
    sb_clock
    sb_bit 0
    sb_clock
 
.endmacro
 
 
 
.macro sb8_color 
 
    cbi sb_d_port,sb_d_pin ; d31 dont care
    sb_clock
    cbi sb_d_port,sb_d_pin ; d30 color register select (set 0)
    sb_clock
 
    ld temp,z+
 
    sb_bit 7
    sb_clock
    sb_bit 6
    sb_clock
    sb_bit 5
    sb_clock
    sb_bit 4
    sb_clock
    sb_bit 3
    sb_clock
    sb_bit 2
    sb_clock
    sb_bit 1
    sb_clock
    sb_bit 0
    sb_clock
    cbi sb_d_port,sb_d_pin
    sb_clock
    cbi sb_d_port,sb_d_pin
    sb_clock
 
    ld temp,z+
 
    sb_bit 7
    sb_clock
    sb_bit 6
    sb_clock
    sb_bit 5
    sb_clock
    sb_bit 4
    sb_clock
    sb_bit 3
    sb_clock
    sb_bit 2
    sb_clock
    sb_bit 1
    sb_clock
    sb_bit 0
    sb_clock
    cbi sb_d_port,sb_d_pin
    sb_clock
    cbi sb_d_port,sb_d_pin
    sb_clock
 
    ld temp,z+
 
    sb_bit 7
    sb_clock
    sb_bit 6
    sb_clock
    sb_bit 5
    sb_clock
    sb_bit 4
    sb_clock
    sb_bit 3
    sb_clock
    sb_bit 2
    sb_clock
    sb_bit 1
    sb_clock
    sb_bit 0
    sb_clock
    cbi sb_d_port,sb_d_pin
    sb_clock
    cbi sb_d_port,sb_d_pin
    sb_clock
 
.endmacro

sb_frontend.inc

;//_ shiftbrite frontend macros
    ;
    ;
    ; sb_sti        - store immediate to shiftbrite sram
    ; sb_st         - store to shiftbrite sram from registers
    ; sb_ld         - load from shiftbrite sram to registers   
    ; sb_pin_init   - initializes shiftbrite interface pins 
    ; sb_send_all   - shift color data cache out to shiftbrites
    ;
    ;
    ; these macros are used to access a shiftbrite's color data
    ; buffer in sram and shift the data out to the shiftbrites.
    ;
    ; variables in "sb_config.inc" control the number of shiftbrite
    ; devices and select between 8bit and 10bit color data. both will
    ; affect the size of the shiftbrite color data sram buffer. 
    ;
    ; everytime "sb_send_all" is called:
    ;
    ; 1) configuration data is shifted out to all shiftbrites and latched. 
    ; with high update rates, this can help your shiftbrites win battles 
    ; with tesla coils.
    ; 
    ; 2) color data buffer is shifted out to all shiftbrites.
    ;
    ; 3) shiftbrite leds drivers are disabled, the new color data is latched
    ; in, and the led drivers are re-enabled after a delay. this reduces 
    ; flicker causing voltage rail dropouts.
    ;
    ; file dependancies:
    ;
    ; sb_config.inc
    ; sb_backend.inc
 
 
 
.macro sb_sti 
 
    ; stores immediate values to a shiftbrite's color data sram
    ;
    ; 10b parameters:   shiftbrite id, 10b red imed, 10b grn imed, 10b blu imed
    ; 8b parameters:    shiftbrite id, 8b red imed, 8b grn imed, 8b blu imed
    ;
    ; 10b example:  sb_sti 1,$3ff,$3ff,$3ff 
    ; 8b example:   sb_sti 1,$ff,$ff,$ff
 
#if (SB8_MODE)
    ldi zh,high(sb_sram + ((@0 - 1) * 3))
    ldi zl,low(sb_sram + ((@0 - 1) * 3))
    ldi temp,@3
    st z+,temp
    ldi temp,@1
    st z+,temp
    ldi temp,@2
    st z,temp
#else       
    ldi zh,high(sb_sram + ((@0 - 1) * 6))
    ldi zl,low(sb_sram + ((@0 - 1) * 6))
    ldi temp,high(@3)
    st z+,temp
    ldi temp,low(@3)
    st z+,temp
    ldi temp,high(@1)
    st z+,temp
    ldi temp,low(@1)
    st z+,temp
    ldi temp,high(@2)
    st z+,temp
    ldi temp,low(@2)
    st z,temp
#endif
 
.endmacro
 
 
 
.macro sb_st 
 
    ; stores a shiftbrite's color data from registers to sram
    ;
    ; 10b parameters:   shiftbrite id, red lreg, red hreg, grn lreg, grn hreg, blu lreg, blu hreg
    ; 8b parameters:    shiftbrite id, red reg, grn reg, blu reg
    ;
    ; 10b example:  sb_st 1,r16,r17,r18,r19,r20,r21
    ; 8b example:   sb_st 1,r16,r18,r20
 
#if (SB8_MODE)
    ldi zh,high(sb_sram + ((@0 - 1) * 3))
    ldi zl,low(sb_sram + ((@0 - 1) * 3))    
    st z+,@3
    st z+,@1
    st z,@2
#else
    ldi zh,high(sb_sram + ((@0 - 1) * 6))
    ldi zl,low(sb_sram + ((@0 - 1) * 6))    
    st z+,@6
    st z+,@5
    st z+,@2
    st z+,@1
    st z+,@4
    st z,@3
#endif
 
.endmacro
 
 
 
.macro sb_ld 
 
    ; loads a shiftbrite's color data from sram to registers
    ;
    ; 10b parameters:   shiftbrite id, red lreg, red hreg, grn lreg, grn hreg, blu lreg, blu hreg
    ; 8b parameters:    shiftbrite id, red reg, grn reg, blu reg 
    ;
    ; 10b example:  sb_ld 1,r16,r17,r18,r19,r20,r21
    ; 8b example:   sb_ld 1,r16,r18,r20
 
#if (SB8_MODE)
    ldi zh,high(sb_sram + ((@0 - 1) * 3))
    ldi zl,low(sb_sram + ((@0 - 1) * 3))
    ld @3,z+
    ld @1,z+
    ld @2,z
#else
    ldi zh,high(sb_sram + ((@0 - 1) * 6))
    ldi zl,low(sb_sram + ((@0 - 1) * 6))
    ld @6,z+
    ld @5,z+
    ld @2,z+
    ld @1,z+
    ld @4,z+
    ld @3,z
#endif
 
.endmacro
 
 
 
.macro sb_pin_init
 
    ; initializes shiftbrite pins. shiftbrite led drivers are left disabled.
    ;
    ; 10b parameters:   none
    ; 8b parameters:    none 
    ;
    ; 10b example:  sb_pin_init
    ; 8b example:   sb_pin_init
 
    cbi sb_d_port,sb_d_pin
    cbi sb_l_port,sb_l_pin
    sbi sb_e_port,sb_e_pin
    cbi sb_c_port,sb_c_pin
    sbi sb_d_ddr,sb_d_pin
    sbi sb_l_ddr,sb_l_pin
    sbi sb_e_ddr,sb_e_pin
    sbi sb_c_ddr,sb_c_pin
 
.endmacro
 
 
 
.macro sb_send_all 
 
    ; shifts color data cache in sram out to shiftbrites
    ;
    ; 10b parameters:   none
    ; 8b parameters:    none
    ;
    ; 10b example:  sb_send_all
    ; 8b example:   sb_send_all
 
    push temp
    push temp2
    push zl
    push zh
 
    ldi temp2,sb_count
loop_sb_qconfig:
    rcall call_sb_qconfig
    dec temp2
    brne loop_sb_qconfig
    rjmp exit_sb_qconfig
call_sb_qconfig: 
    sb_qconfig
    ret
exit_sb_qconfig:
 
    sb_latch
 
    ldi zh,high(sb_sram)
    ldi zl,low(sb_sram) 
    ldi temp2,sb_count
loop_sb_color:
    rcall call_sb_color
    dec temp2
    brne loop_sb_color
    rjmp exit_sb_color
call_sb_color:
#if (SB8_MODE)
    sb8_color
#else
    sb_color
#endif
    ret
exit_sb_color:
 
    sb_disable
    sb_latch
 
    ldi temp,20
this_loops:    
    dec temp
    brne this_loops
 
    sb_enable
 
    pop zh
    pop zl
    pop temp2
    pop temp
 
.endmacro
/home/macetec/public_html/docs/data/pages/avr_assembler.txt · Last modified: 2009/07/27 06:32 by macegr