;***************************************************************************
; Application:  Led flasher
; Author:       Rue Mohr
; Date:         
; Assembler:    AVR Studio 4.07.
; Target:       Atmel ATtiny13.
;***************************************************************************

; pin 1: reset, tie high
; pin 2: ADC value, 0-5V in
; pin 3: not used
; pin 4: gnd
; pin 5: serial clock input
; pin 6: serial data out
; pin 7: not used
; pin 8: VCC +5V


;****************************************************************************

.device ATtiny13 

; ------------- Memory locations ---------------
;
;  .def bar =r01 ; one byte ram location
;
; ----------------------------------------------

; R 0 ->15 are gen. purp.

.def A          = r16    
.def B          = r17            ; and logic instructions
.def C          = r18
.def D          = r19

.def _P         = r20
.def _Q         = r21
.def _R         = r22
.def _S         = r23
.def _T         = r24
.def _U         = r25
.def _V         = r26
.def _W         = r27
.def _X         = r28
.def _Y         = r29
.def _Z         = r30


;cant use r25 -> r31

; ------------- Equates ------------------


.equ INPUT   = 0
.equ OUTPUT  = 1

; --- Port Directions ---
.equ PB0DIR  = INPUT
.equ PB1DIR  = OUTPUT
.equ PB2DIR  = INPUT
.equ PB3DIR  = INPUT
.equ PB4DIR  = INPUT
.equ PB5DIR  = INPUT

; --- Initial port state ---
.equ INPB0   = 0
.equ INPB1   = 1
.equ INPB2   = 0
.equ INPB3   = 0
.equ INPB4   = 0
.equ INPB5   = 1

; --- Port Names ---
.equ CLOCK    = 0  
.equ DATA     = 1  
;.equ     = 2  
;.equ     = 3  
;.equ     = 4  
;.equ     = 5  ; RESET

; --- amalgimate ---

.equ INITDIR   = ((PB5DIR<<DDB5)|(PB4DIR<<DDB4)|(PB3DIR<<DDB3)|(PB2DIR<<DDB2)|(PB1DIR<<DDB1)|(PB0DIR<<DDB0))
.equ INITSTATE = ((INPB5<<PORTB5)|(INPB4<<PORTB4)|(INPB3<<PORTB3)|(INPB2<<PORTB2)|(INPB1<<PORTB1)|(INPB0<<PORTB0))


;========================| SYSTEM VECTORS |===========================
;
.cseg                                   ;CODE segment
.org 0x0000
    rjmp    init   ; RESET 
    reti           ; EXT_INT0  
    reti           ; PCINT0   (pin change)
    reti           ; TIM0_OVF  
    reti           ; EE_RDY  
    reti           ; ANA_COMP  
    reti           ; TIM0_COMPA  
    reti           ; TIM0_COMPB  
    reti           ; WATCHDOG  
    reti           ; ADC  

;=============================| MAIN |================================
;


   .org 0x000A
   init:   
   ; Set up stack
   ldi     A,   low(RAMEND)        ; load low address of ram to R16...
   out     SPL, A               ; Set Stack Pointer to top of RAM

   ; Disable interrupts
   cli        

   ; Set up io ports
   ldi   A,    INITSTATE
   out   PORTB, A
   ldi   A,    INITDIR
   out   DDRB,  A

   ; adc init
   ; Activate ADC with Prescaler 
   ldi   A, ((1 << ADEN)|(1 << ADPS2)|(1 << ADPS1)|(1 << ADPS1)|(1 << ADPS0))
   out   ADCSRA, A   ; 6

   ; channel 3 
   ldi      A, ((1 << MUX0)|(1 << MUX1))
   out     ADMUX, A

   ; flag done with data high
   cbi   PORTB, DATA  


   MainLoup:

      ; wait for rising edge on clock line
      sbis   PINB, CLOCK  
      rjmp   MainLoup

      ; start conversion
      sbi   ADCSRA, ADSC

      ; wait for conversion to finish (while ADIF flag clear)
      waitConvert:
      sbis      ADCSRA, ADIF
      rjmp      waitConvert     
      ; clear flag
      sbi       ADCSRA, ADIF    
      ; catch value
      in        C, ADCL
      in        D, ADCH

      ; flag conversion done

      sbi       PORTB, DATA

      ; set up bit counter
      ldi   B, 0x0A
      bitLoup:           
         ; wait for clock bit to go low
         sbic     PINB, CLOCK 
         rjmp     bitLoup

         ;   put data bit on bus  
         sbrs    C, 0   
         rjmp    clearBit
         sbi     PORTB, DATA
         rjmp    bitDone
         clearBit:
         cbi     PORTB, DATA
         bitDone:

         ; shift word along.
         lsr     D
         ror     C   

         ; decrement loop counter           
         subi    B, 1   
         ; repeat
         brne    bitLoup

      waitDone:        
      ; wait for done (falling edge)
      sbic   PINB, CLOCK
      rjmp    waitDone;

      ; leave data low
      cbi     PORTB, DATA       

      rjmp    MainLoup                ; go back and do it all over again


;========================| SUBROUTINES |==============================
;

















