Farba Research XMEGA Native Language Example

;BEGIN initialization routine for the Atmel AtXMega64A1U
;NOTE: This is jumped-to directly from the MCU's Reset interrupt vector
;Written by  E. Nicholas Cupery  07 October 2009
RESET:  ldi     XL, LOW(SRAM_STARTADR)  ;lo-order starting address of SRAM
        ldi     XH,HIGH(SRAM_STARTADR)  ;hi-order starting address of SRAM
        ldi     rByteLo, LOW(SRAM_BYTESIZE) ;lo-order number of bytes of SRAM
        ldi     rByteHi,HIGH(SRAM_BYTESIZE) ;hi-order number of bytes of SRAM
        clr     rTemp                   ;get a zero in a register

SRAM0:  st      X+,rTemp                ;clear this one SRAM byte location
        sbiw    rByteLo,1               ;cleared all of SRAM yet?
        brne    SRAM0                   ;br if no (loop)

        lds     rTemp,RST_STATUS        ;read the Reset Status Register
        sts     sResetType,rTemp        ;save the reset-type bits
        ldi     rTemp,$3F               ;all reset-type bits
        sts     RST_STATUS,rTemp        ;explicitly clear the reset-type flags

        ldi     XL, LOW(sStack)         ;lo-order bottom address of stack
        ldi     XH,HIGH(sStack)         ;hi-order bottom address of stack
        ldi     rCount,STACK_SIZE       ;number of bytes of stack
        ser     rTemp                   ;get a -1 in a register

STACKI: st      X+,rTemp                ;initialize stack area to -1 flag value
        dec     rCount                  ;initialized 'em all yet?
        brne    STACKI                  ;br if no (loop)

        ldi     rTemp, LOW(sStackTop)   ;lo-order starting address of stack
        out     SPL,rTemp               ;load up the lo-order stack-pointer
        ldi     rTemp,HIGH(sStackTop)   ;hi-order starting address of stack
        out     SPH,rTemp               ;load up the hi-order stack-pointer

        ;will now set the port initial values
        ldi     rTemp,INITIAL_PORTA     ;initial value for PORTA
        sts     PORTA_OUT,rTemp         ;load it
        ldi     rTemp,INITIAL_PORTB     ;initial value for PORTB
        sts     PORTB_OUT,rTemp         ;load it
        ldi     rTemp,INITIAL_PORTC     ;initial value for PORTC
        sts     PORTC_OUT,rTemp         ;load it
        ldi     rTemp,INITIAL_PORTD     ;initial value for PORTD
        sts     PORTD_OUT,rTemp         ;load it
        ldi     rTemp,INITIAL_PORTE     ;initial value for PORTE
        sts     PORTE_OUT,rTemp         ;load it
        ldi     rTemp,INITIAL_PORTF     ;initial value for PORTF
        sts     PORTF_OUT,rTemp         ;load it
        ldi     rTemp,INITIAL_PORTH     ;initial value for PORTH
        sts     PORTH_OUT,rTemp         ;load it
        ldi     rTemp,INITIAL_PORTJ     ;initial value for PORTJ
        sts     PORTJ_OUT,rTemp         ;load it
        ldi     rTemp,INITIAL_PORTK     ;initial value for PORTK
        sts     PORTK_OUT,rTemp         ;load it
        ldi     rTemp,INITIAL_PORTQ     ;initial value for PORTQ
        sts     PORTQ_OUT,rTemp         ;load it

        ;will now set the port directions
        ldi     rTemp,DIRECTION_PORTA   ;Port A bit-directions
        sts     PORTA_DIR,rTemp         ;set all PortA bit directions
        ldi     rTemp,DIRECTION_PORTB   ;Port B bit-directions
        sts     PORTB_DIR,rTemp         ;set all PortB bit directions
        ldi     rTemp,DIRECTION_PORTC   ;Port C bit-directions
        sts     PORTC_DIR,rTemp         ;set all PortC bit directions
        ldi     rTemp,DIRECTION_PORTD   ;Port D bit-directions
        sts     PORTD_DIR,rTemp         ;set all PortD bit directions
        ldi     rTemp,DIRECTION_PORTE   ;Port E bit-directions
        sts     PORTE_DIR,rTemp         ;set all PortE bit directions
        ldi     rTemp,DIRECTION_PORTF   ;Port F bit-directions
        sts     PORTF_DIR,rTemp         ;set all PortF bit directions
        ldi     rTemp,DIRECTION_PORTH   ;Port H bit-directions
        sts     PORTH_DIR,rTemp         ;set all PortH bit directions
        ldi     rTemp,DIRECTION_PORTJ   ;Port J bit-directions
        sts     PORTJ_DIR,rTemp         ;set all PortJ bit directions
        ldi     rTemp,DIRECTION_PORTK   ;Port K bit-directions
        sts     PORTK_DIR,rTemp         ;set all PortK bit directions
        ldi     rTemp,DIRECTION_PORTQ   ;Port Q bit-directions
        sts     PORTQ_DIR,rTemp         ;set all PortQ bit directions

        ;will now set pullups on all input pins
        ldi     rTemp,PORT_OPC_PULLUP_gc;"totem-pole with pullup"
        sts     PORTC_PIN2CTRL,rTemp    ;set pullup on "Rxd" input from HMI
        sts     PORTC_PIN6CTRL,rTemp    ;set pullup on "Rxd" input from Logport
        sts     PORTD_PIN0CTRL,rTemp    ;set pullup on TCoil input
        sts     PORTD_PIN6CTRL,rTemp    ;set pullup on "Rxd" input from IRR
        sts     PORTF_PIN7CTRL,rTemp    ;set pullup on S5VIO spare 5v I/O
        sts     PORTA_PIN1CTRL,rTemp    ;set pullup on "Ack" pushbutton input
        sts     PORTA_PIN4CTRL,rTemp    ;set pullup on "Event" pushbutton input

        ;will now check for Diagnostic-Mode ("Ack" button held down at reset)
        clr     rTemp                   ;get a zero in a register
        lds     rChar,MANUAL_ACK_PORT   ;read the Manual-Ack port
        andi    rChar,MANUAL_ACK_BITP   ;clear all but the "Manual Ack" bit
        brne    SETDIAG                 ;skip if "Ack" not pressed
        ser     rTemp                   ;change to non-zero value
SETDIAG:sts     sDiagFlag,rTemp         ;store the operating mode

        ;will now preload all timer countdown counters
        ldi     rTemp,TICKS_PER_MS      ;# of fast-ticks per mS
        sts     sCountdown_mS,rTemp     ;preload the mS timedown
        ldi     rTemp,10                ;full-count of ten
        sts     sCountdown_cS,rTemp     ;preload the cS countdown counter
        sts     sCountdown_dS,rTemp     ;preload the dS countdown counter
        sts     sCountdown_1S,rTemp     ;preload the 1S countdown counter

        ;load up the timing parameters for Error-Number (yellow) LED flashing
        ldi     rTemp,FLASH_ON_TIME_10thS    ;LED ON time (S/10)
        sts     sFlashOnTime,rTemp           ;store it in SRAM
        ldi     rTemp,FLASH_OFF_TIME_10thS   ;LED OFF time (S/10)
        sts     sFlashOffTime,rTemp          ;store it in SRAM
        ldi     rTemp,FLASH_DELAY_TIME_10thS ;delay between flash cycles (S/10)
        sts     sFlashDelayTime,rTemp        ;store it in SRAM

        ;setup Heartbeat (green) LED timing
        ldi     rTemp,BLINK_NORMAL_10thS;assume Normal operating mode
        lds     rTemp2,sDiagFlag        ;fetch the Diagnostic-Mode flag
        tst     rTemp2                  ;startup in Diagnostic-Mode?
        breq    NORMAL                  ;br if no
        ldi     rTemp,BLINK_WARNING_10thS ;warn about Diagnostic operating mode
NORMAL: sts     sBlinkSTime_dS,rTemp    ;load # of dS between LED blink toggles
        sts     sBlinkSTDown_dS,rTemp   ;preload for the very first blink toggle

        ;initialize the HMI UART
        ldi     rTemp,LOW (BSEL_HMI)    ;lo-order baud-selector
        sts     USARTC0_BAUDCTRLA,rTemp ;load it
        ldi     rTemp,HIGH(BSEL_HMI)    ;hi-order baud-selector
        sts     USARTC0_BAUDCTRLB,rTemp ;load it
        ldi     rTemp,3                 ;8-bit character size
        sts     USARTC0_CTRLC,rTemp     ;load it
        ldi     rTemp,USART_RXEN_bm     ;receiver-enable bit
        ori     rTemp,USART_TXEN_bm     ;transmitter-enable bit
        ori     rTemp,USART_CLK2X_bm    ;double-speed enable bit
        sts     USARTC0_CTRLB,rTemp     ;start up the HMI UART
        ldi     rTemp,$10               ;LOW-level Receiver interrupts ONLY
        sts     USARTC0_CTRLA,rTemp     ;set the interrupt level

        ;initialize the InfraRed Receiver UART
        ldi     rTemp,LOW (BSEL_IRR)    ;lo-order baud-selector
        sts     USARTD1_BAUDCTRLA,rTemp ;load it
        ldi     rTemp,HIGH(BSEL_IRR)    ;hi-order baud-selector
        sts     USARTD1_BAUDCTRLB,rTemp ;load it
        ldi     rTemp,7                 ;9-bit character size
        sts     USARTD1_CTRLC,rTemp     ;load it
        ldi     rTemp,USART_RXEN_bm     ;receiver-enable bit
        ori     rTemp,USART_CLK2X_bm    ;double-speed enable bit
        sts     USARTD1_CTRLB,rTemp     ;start up the IRR UART
        ldi     rTemp,$30               ;HIGH-level Receiver interrupts ONLY
        sts     USARTD1_CTRLA,rTemp     ;set the interrupt level

        ;initialize the Logging UART
        ldi     rTemp,LOW (BSEL_LOG)    ;lo-order baud-selector
        sts     USARTC1_BAUDCTRLA,rTemp ;load it
        ldi     rTemp,HIGH(BSEL_LOG)    ;hi-order baud-selector
        sts     USARTC1_BAUDCTRLB,rTemp ;load it
        ldi     rTemp,3                 ;8-bit character size
        sts     USARTC1_CTRLC,rTemp     ;load it
        ldi     rTemp,USART_RXEN_bm     ;receiver-enable bit
        ori     rTemp,USART_TXEN_bm     ;transmitter-enable bit
        ori     rTemp,USART_CLK2X_bm    ;double-speed enable bit
        sts     USARTC1_CTRLB,rTemp     ;start up the Logging UART

        ;will now switch from internal 2MHz oscillator to external crystal
        ldi     rTemp,HEARTBEAT_BITP            ;heartbeat LED bit pattern
        sts     HB_OUTCLR_PORT,rTemp            ;temporarily turn ON the green LED

        ldi     rTemp,OSC_FRQRANGE_2TO9_gc      ;frequency range 2 - 9 MHz
        ori     rTemp,OSC_XOSCSEL_XTAL_16KCLK_gc;normal quartz crystal
        sts     OSC_XOSCCTRL,rTemp              ;load the XOSC Control Register

        ldi     rTemp,OSC_XOSCEN_bm             ;"external OSC Enable"
        sts     OSC_CTRL,rTemp                  ;enable the external OSC (crystal)

OSCWAIT:lds     rTemp,OSC_STATUS                ;read the XOSC Status Register
        andi    rTemp,OSC_XOSCRDY_bm            ;clear all but "External Osc Ready"
        breq    OSCWAIT                         ;br if XOSC not ready yet

        ldi     rTemp,OSC_PLLSRC_XOSC_gc        ;"PLL source is XOSC"
        ori     rTemp,8                         ;and multiply by 8
        sts     OSC_PLLCTRL,rTemp               ;select XOSC as 8x PLL source

        ldi     rTemp,OSC_PLLEN_bm              ;"PLL Enable"
        ori     rTemp,OSC_XOSCEN_bm             ;keep "XOSC Enable"
        sts     OSC_CTRL,rTemp                  ;enable the PLL

PLLWAIT:lds     rTemp,OSC_STATUS                ;read the XOSC Status Register
        andi    rTemp,OSC_PLLRDY_bm             ;clear all but "PLL Ready"
        breq    PLLWAIT                         ;br if PLL not ready yet

        ldi     rTemp,0xD8                      ;change-protection signature
        sts     CPU_CCP,rTemp                   ;allow changes within 4 clocks
        ldi     rTemp,CLK_SCLKSEL_PLL_gc        ;"select External Clock"
        sts     CLK_CTRL,rTemp                  ;select the crystal

        ldi     rTemp,HEARTBEAT_BITP            ;heartbeat LED bit pattern
        sts     HB_OUTSET_PORT,rTemp            ;turn OFF the green LED

        ;flag the reboot with flashing of the yellow LED
        ldi     rTemp,FLASH_REBOOT      ;flash-count for this condition
        call    FLASHNUM                ;flash this code, if is the highest yet

        ;will now set the Timer0 interrupt level
        ldi     rTemp,TC_OVFINTLVL_MED_gc ;MEDIUM interrupt level for Timer0
        sts     TCC0_INTCTRLA,rTemp       ;set the interrupt level

        ;will now set up the Timer0 timer period
        ldi     rByteLo,LOW (Timer0_Count) ;lo-order timer period
        ldi     rByteHi,HIGH(Timer0_Count) ;hi-order timer period
        sts     TCC0_PER+0,rByteLo      ;load lo-order timer period register
        sts     TCC0_PER+1,rByteHi      ;load hi-order timer period register

        ;will now start Timer0 by telling it it's clock source
        ldi     rTemp,TIMER0_PRESCALE   ;system clock divided by 64
        sts     TCC0_CTRLA,rTemp        ;start Timer0

        ;will now enable the interrupt system
        ldi     rTemp,PMIC_HILVLEN_bm   ;"enable high-level interrupts"
        ori     rTemp,PMIC_MEDLVLEN_bm  ;"enable medium-level interrupts"
        ori     rTemp,PMIC_LOLVLEN_bm   ;"enable low-level interrupts"
        sts     PMIC_CTRL,rTemp         ;enable interrupt levels

        ;will now check out the external SRAM
        call    XSRAMCHK                ;run XSRAM diagnostic

        ;will now load any general register that is DEDICATED
        ;NOTE: System Reset does NOT clear general registers
        clr     rPendingState                   ;no breaker Pending-State yet

        ;will now enable the Watchdog-Timer
        ldi     rTemp,$D8                       ;protection signature for I/O registers
        out     CPU_CCP,rTemp                   ;disable protection for 4 CPU cycles
        ldi     rTemp,$1F                       ;Watchdog-Enable + timer period (64 mS)
        sts     WDT_CTRL,rTemp                  ;enable the watchdog timer

        sei                                     ;globally enable interrupts

        rjmp    MAINLOOP                        ;now enter main program loop
;END initialization example code for an Atmel AtXMega64A1U

Farba Products WORK