;
; hello.step.44.asm
;
; read and send step response
;
; Neil Gershenfeld
; CBA MIT 10/24/09
;
; (c) Massachusetts Institute of Technology 2009
; Permission granted for experimental and personal use;
; license for commercial sale available from MIT.

.include "tn44def.inc"
;
; definitions Sensor 1
;
.equ tx_pin = PB2 ; transmit pin
.equ charge_pin = PA0 ; charging pin
;
; registers
;
.def bit_count = R16 ; bit counter
.def temp = R17 ; temporary storage
.def temp1 = R18 ; temporary storage
.def txbyte = R19 ; data byte
.def delay_count = R20 ; delay counter
.def uplo = R21 ; up low byte
.def uphi = R22 ; up hi byte
;
; code segment
;
.cseg
.org 0
rjmp reset ; jump to reset routine
;
; bit delay
; serial bit delay
;
;.equ b = 13 ; 9600 baud (clock /8)
.equ b = 130 ; 9600 baud (clock /1)
;.equ b = 8 ; 115200 baud (clock /1)
bit_delay:
   ldi temp, b
   bitloop:
      dec temp
      brne bitloop
   ret
;
; putchar
; assumes no line driver (doesn't invert bits)
;
.equ sb = 1; number of stop bits
putchar:
   ldi bit_count, 9+sb; 1+8+sb
   com txbyte; invert everything
   sec; set start bit
   putchar0:
      brcc putchar1; if carry set
      cbi PORTB, tx_pin; send a '0'
      rjmp putchar2; else	
   putchar1:
       sbi PORTB, tx_pin	; send a '1'
       nop ; even out timing
   putchar2:
       rcall bit_delay; one bit delay
       rcall bit_delay
       lsr txbyte; get next bit
       dec bit_count; if not all bits sent
       brne putchar0; send next bit
   ret;
;
; char_delay
; delay between characters
;
char_delay:
ldi temp, 255
char_delay_loop:
   ldi temp1, 10
   char_delay_loop1:
      dec temp1
      brne char_delay_loop1
   dec temp
   brne char_delay_loop
   ret
;
; settle
; delay for charge to settle
;
.equ delay = 255
settle:
   ldi temp, delay
   settleloop:
      dec temp
      brne settleloop
   ret
;
; main program
;
reset:
   ;
   ; set clock divider to /1
   ;
   ldi temp, (1 << CLKPCE)
   ldi temp1, (0 << CLKPS3) | (0 << CLKPS2) | (0 << CLKPS1) | (0 << CLKPS0)
   out CLKPR, temp
   out CLKPR, temp1
   ;
   ; set stack pointer to top of RAM
   ;
   ldi temp, high(RAMEND)
   out SPH, temp
   ldi temp, low(RAMEND)
   out SPL, temp
   ;
   ; init comm and charge pins for output
   ;
   sbi PORTB, tx_pin
   sbi DDRB, tx_pin
   sbi PORTA, charge_pin
   sbi DDRA, charge_pin
   ;
   ; init A/D
   ;
   cbi ADMUX, REFS1 ; use VCC as reference
   cbi ADMUX, REFS0 ; "
   cbi ADMUX, ADLAR ; right-adjust result
   cbi ADMUX, MUX5 ; set MUX5:0 to ADC1 (PA1) -> ADMUX config 000001
   cbi ADMUX, MUX4 ; "
   cbi ADMUX, MUX3 ; "
   cbi ADMUX, MUX2 ; "
   cbi ADMUX, MUX1 ; "
   sbi ADMUX, MUX0 ; "
   sbi ADCSRA, ADEN ; enable A/D
   cbi ADCSRA, ADPS2 ; set prescaler to /2
   cbi ADCSRA, ADPS1 ; "
   cbi ADCSRA, ADPS0 ; "
   ;
   ; start main loop
   ;
   loop:
      ;
      ; loop over delays
      ;
      ldi delay_count, 254
      delayloop:
         ;
         ; settle sample and start upward step response
         ;
         cbi PORTA, charge_pin
         rcall settle
         mov temp, delay_count
         sbi PORTA, charge_pin
         ;
         ; wait for delay
         ;
         addelayup:
            dec temp
            brne addelayup
         ;
         ; read response
         ;
         sbi ADCSRA, ADSC ; start conversion
         adloopup:
            sbic ADCSRA, ADSC ; loop until complete
            rjmp adloopup
         ;
         ; save conversion
         ;
         in uplo, ADCL ; get low byte
         in uphi, ADCH ; get high byte
         ;
         ; settle sample and start downward step response
         ;
         rcall settle
         mov temp, delay_count
         cbi PORTA, charge_pin
         ;
         ; wait for delay
         ;
         addelaydown:
            dec temp
            brne addelaydown
         ;
         ; read response
         ;
         sbi ADCSRA, ADSC ; start conversion
         adloopdown:
            sbic ADCSRA, ADSC ; loop until complete
            rjmp adloopdown
         ;
         ; send conversions
         ;
         in txbyte, ADCL ; low down byte
         rcall putchar
         in txbyte, ADCH ; hi down byte
         rcall putchar
         mov txbyte, uplo ; low up byte
         rcall putchar
         mov txbyte, uphi ; hi up byte
         rcall putchar
         rcall char_delay
         ;
         ; decrement and return
         ;
	      dec delay_count
	      dec delay_count
	      brne delayloop
      ;
      ; send 1 2 3 4 for framing
      ;
      ldi txbyte, 1
      rcall putchar
      ldi txbyte, 2
      rcall putchar
      ldi txbyte, 3
      rcall putchar
      ldi txbyte, 4
      rcall putchar
      rcall char_delay
      rjmp loop
