;===========================================================================

; Lab_2_1_student.s - Template for DAT Lab 2_1
;
; Description   : A more complete template for Lab 2_1

; Reference(s)  : ARM IAR Assembler Reference Guide

; Course        : Datorteknik (DAT) DT4009
;
; Authors       : Süleyman Savas
;
;
;===========================================================================

        NAME    main
        PUBLIC  main
        SECTION .text : CODE (2)
        THUMB
        
;===========================================================================

; TODO: Find and add the correct addresses, 
; Check sam3x datasheet - chapter 30 to find the addresses.
PIOA_WPMR EQU  0x400E0EE4       ; Write Protect Mode Register

PIOA_PER  EQU  0x400E0E00      ; PIO Enable Register
PIOA_ODR  EQU  0x400E0E14      ; Output Disable Register
PIOA_IDR  EQU  0x400E0E44      ; Interrupt Disable Register
PIOA_IER  EQU  0x400E0E40      ; Interrupt Enable Register
PIOA_ISR  EQU  0x400E0E4C      ; Interrupt Statuc Register
PIOA_IMR  EQU  0x400E0E48      ; Interrupt Mask Register
PIOA_PUER EQU  0x400E0E64      ; Pull Up Enable Register
PIOA_PDSR EQU  0x400E0E3C      ; Pin Data Status Register

; C port - (leds)
PIOC_WPMR EQU  0x400E12E4       ; Write Protect Mode Register

PIOC_PER  EQU   0x400E1200     ; PIO Enable Register - Arduino Due
PIOC_OER  EQU   0x400E1210     ; Output Enable Register
PIOC_SODR EQU   0x400E1230     ; Set Output Data Register
PIOC_PUDR EQU   0x400E1260     ; Pull Up Disable Register
PIOC_CODR EQU   0x400E1234     ; Clear Output Data Register
PIOC_PDSR EQU   0x400E123C     ; Pin Data Status Register
; NVIC
NVIC_ISER0 EQU  0xE000E100      ; Interrupt Set-enable Registers
NVIC_ICER0 EQU  0xE000E180      ; Interrupt Clear-enable Registers
NVIC_ISPR0 EQU  0xE000E200      ; Interrupt Set-pending Registers
NVIC_IABR0 EQU  0xE000E300      ; Interrupt Active-bit Registers
; PMC
PMC_WPMR  EQU   0x400E06E4      ; PMC Write Protect Mode Register
PMC_PCER  EQU   0x400E0610      ; Peripheral Clock Enable Register 0
PMC_PCDR  EQU   0x400E0614      ; Peripheral Clock Disable Register 0
PMC_PCSR  EQU   0x400E0618      ; Peripheral Clock Status Register 0
;===========================================================================
;SySTick

SYSTICK_CTRL    EQU     0xE000E010      ; SysTick control and status register
SYSTICK_LOAD    EQU     0xE000E014      ; SysTick reload value register
SYSTICK_VAL     EQU     0xE000E018      ; Current value register
SYSTICK_CALIB   EQU     0xE000E01C      ; Calibration value register

;===========================================================================
; Initialization of Peripheral Clock
main      LDR   R0,=PMC_PCER
          LDR   R1,=(5 << 11)  ; Peripheral Identifier: bit11=PIOA, bit13=PIOC 
          STR   R1,[R0]
          MOV   R3,#1
          MOV   R4,#0
  ;===========================================================================
; Initialization InPort  
; TODO: Write your code here

          LDR R0,=PIOA_PER
          MOV R1,#0xFFFFFFFF
          STR R1,[R0]
          
          LDR R0,=PIOA_ODR
          MOV R1,#0xFFFFFFFF
          STR R1,[R0]
          
          LDR R0,=PIOA_IDR
          MOV R1,#0xFFFFFFFF
          STR R1,[R0]
          
          LDR R0,=PIOA_PUER
          MOV R1,#0xFFFFFFFF
          STR R1,[R0]
          
          LDR R0,=PIOA_IER
          MOV R1,#0xFFFFFFFF
          STR R1,[R0]
          
          LDR R0,=0x400E0EB0            ;AIMER
          MOV R1,#0xFFFFFFFF
          STR R1,[R0]
         
          LDR R0,=0x400E0EC4            ;ESR
          MOV R1,#0xFFFFFFFF
          STR R1,[R0]
          
          LDR R0,=0x400E0EC0            ; LSR
          MOV R1,#0
          STR R1,[R0]
                 
;===========================================================================

; Initialization OutPort
; TODO: Write your code here

          LDR R0,=PIOC_PER
          MOV R1,#0xFFFFFFFF
          STR R1,[R0]
          
          LDR R0,=PIOC_OER
          MOV R1,#0xFFFFFFFF
          STR R1,[R0]
          
          LDR R0,=PIOC_PUDR
          MOV R1,#0xFFFFFFFF
          STR R1,[R0]
;===========================================================================      
;NVIC INIT
          LDR R0,=NVIC_ICER0
          MOV R1,#0x800
          STR R1,[R0]
          
          LDR R0,=NVIC_ISPR0
          MOV R1,#0x800
          STR R1,[R0]
          
          LDR R0,=NVIC_ISER0
          MOV R1,#0x800
          STR R1,[R0]
   
;===========================================================================    
INIT
        LDR R0, =SYSTICK_CTRL
        MOV R1, #0
        STR R1,[R0]
        
        LDR R0, =SYSTICK_VAL
        STR R1,[R0]
        
        LDR R0,=SYSTICK_LOAD
        LDR R1,=0xB71AFF                                ;12milleminusett
        STR R1,[R0]
        
        LDR R0,=SYSTICK_CTRL
        MOV R1,#0x07
        STR R1,[R0]
     
;===========================================================================
MASTER 
        MOV R3,#0
        LDR R0,=PIOA_PDSR
        LDR R1,[R0]
        ANDS R1,R1,#0x8000
        BEQ COUNTER
        ;BL Delay_ms
        B MASTER

;===========================================================================
COUNTER
        ADD R4,R4,#1
        CMP R4,#4
        BEQ RESETDONE
        B RESET
RESETDONE
        MOV R4,#0
RESET
        MOV R1,#0x6
        LDR R2, =PIOC_CODR
        STR R1, [R2]
        BL Delay_ms
        MOV R1, R4         
        LSL R1,R1,#1
        LDR R2, =PIOC_SODR     
        STR R1, [R2]
        
        B MASTER
;===========================================================================
        PUBLIC SysTick_Handler
SysTick_Handler
        ; what does this do?
        LDR R0,=PIOC_PDSR
        LDR R1,[R0]
        ANDS R1,R1,#8
        BEQ ON
        B OFF
ON
        MOV R2, #0x8                      ; Turn left light on
        LDR R3, =PIOC_SODR
        STR R2, [R3]
        B DONE
OFF     
        LDR R0, =PIOC_CODR                 ;turn both off
        MOV R1, #0x8
        STR R1, [R0]
DONE
        BX      LR
;===========================================================================

        PUBLIC PIOA_Handler
PIOA_Handler
      LDR R0,=PIOA_ISR
      LDR R1,=0x1
      LDR R1,[R0]
      
      LDR R0,=PIOA_PDSR
      LDR R1,[R0]
      ANDS R1,R1,#0x8000
      BEQ PRESSED
      B NOT_PRESSED
NOT_PRESSED
      LDR R0,=PIOC_PDSR
      LDR R1,[R0]
      CMP R1,#0x0
      BEQ SLOW
      CMP R1,#0x2
      BEQ FIRST
      CMP R1,#0x4
      BEQ SECOND
      CMP R1,#0x6
      BEQ THIRD
      B END_HANDLER
FIRST
      LDR R0,=SYSTICK_LOAD
      LDR R1,=0x5B8D7F                                ;12milleminusett
      STR R1,[R0]
      B END_HANDLER
SECOND
      LDR R0,=SYSTICK_LOAD
      LDR R1,=0x2DC6BF                                ;12milleminusett
      STR R1,[R0]
      B END_HANDLER
THIRD
      LDR R0,=SYSTICK_LOAD
      LDR R1,=0x16E35F                                ;12milleminusett
      STR R1,[R0]
      B END_HANDLER
PRESSED
      LDR R0,=PIOC_CODR
      LDR R1,=0x6
      STR R1,[R0]
SLOW   
      LDR R0,=SYSTICK_LOAD
      LDR R1,=0xB71AFF                                ;12milleminusett
      STR R1,[R0]
END_HANDLER
      
      BX      LR
;===========================================================================
;===========================================================================
DELAY_CALIB EQU 1200 ; utprovat värde (baserat på master clock – 12Mhz)         
Delay_ms                                                                        
          STMFD  SP!,{R0,R1,LR}                                                    
          MOV    R0,#200
do_delay_ms 
          LDR    R1,=DELAY_CALIB                                                
loop_ms                                                                         
          SUBS   R1,R1,#1
          BNE    loop_ms
          SUBS   R0,R0,#1
          BNE    do_delay_ms        
          LDMFD  SP!,{R0,R1, PC}
          BX            LR
;===========================================================================
;===========================================================================
        END
