;******************Mega3D project by YS*******************
;*              	YS (c) 2008-2009                 *
;*              Device: ATmega48  XTAL: 8MHz             *
;*********************************************************
.include "M48DEF.INC"

.def t=R16
.def LEDS=R17
.def ARRIDX=R18
.def BUFNUM=R19
.def BUFMAX=R20
.def BUFPOS=R21
.def t1=R22

.dseg

buffer: .byte 180

.cseg
.org 0

rjmp RESET      ; Reset Handler
rjmp EXT_INT0   ; IRQ0 Handler
rjmp EXT_INT1   ; IRQ1 Handler
rjmp _PCINT0     ; PCINT0 Handler
rjmp _PCINT1     ; PCINT1 Handler
rjmp _PCINT2     ; PCINT2 Handler
rjmp WDT        ; Watchdog Timer Handler
rjmp TIM2_COMPA ; Timer2 Compare A Handler
rjmp TIM2_COMPB ; Timer2 Compare B Handler
rjmp TIM2_OVF   ; Timer2 Overflow Handler
rjmp TIM1_CAPT  ; Timer1 Capture Handler
rjmp TIM1_COMPA ; Timer1 Compare A Handler
rjmp TIM1_COMPB ; Timer1 Compare B Handler
rjmp TIM1_OVF   ; Timer1 Overflow Handler
rjmp TIM0_COMPA ; Timer0 Compare A Handler
rjmp TIM0_COMPB ; Timer0 Compare B Handler
rjmp TIM0_OVF   ; Timer0 Overflow Handler
rjmp SPI_STC    ; SPI Transfer Complete Handler
rjmp USART_RXC  ; USART, RX Complete Handler
rjmp USART_UDRE ; USART, UDR Empty Handler
rjmp USART_TXC  ; USART, TX Complete Handler
rjmp ADC_CCPL   ; ADC Conversion Complete Handler
rjmp EE_RDY     ; EEPROM Ready Handler
rjmp ANA_COMP   ; Analog Comparator Handler
rjmp TWI        ; 2-wire Serial Interface Handler
rjmp SPM_RDY    ; Store Program Memory Ready Handler
 
EXT_INT1  :
_PCINT0   :
_PCINT1   :
_PCINT2   :
WDT       :
TIM2_COMPA:
TIM2_COMPB:
TIM2_OVF  :
TIM1_CAPT :
TIM1_COMPB:
TIM1_OVF  :
TIM0_COMPA:
TIM0_COMPB:
TIM0_OVF  :
SPI_STC   :
USART_UDRE:
USART_TXC :
ADC_CCPL  :
EE_RDY    :
ANA_COMP  :
TWI       :
SPM_RDY   :

reti

RESET:

;================================General settings============================

  ldi t,HIGH(RamEnd)    ;stack initialization
  out SPH,t
  ldi t,LOW(RamEnd)
  out SPL,t

;PortB settings

  ldi t,0xFF           ;configure portB for output
  out DDRB,t

  ldi t,0              ;initializing portB
  out portB,t

;Timer 1 settings

  ldi t,0x00           ;Fintr=2KHz
  sts OCR1AH,t
  ldi t,0x3E
  sts OCR1AL,t

  ldi t,0b00000010     ;interrupt on compareA match
  sts TIMSK1,t

  ldi t,0              ;initializing timer
  sts TCNT1H,t
  sts TCNT1L,t

;Configure external interrupt 0

  ldi t,0b00000011     ;interrupt on rising edge on INT0 pin
  sts EICRA,t

  ldi t,0b00000001
  out EIMSK,t          ;enable INT0

;Configure UART

  ldi t,0b10010000
  sts UCSR0B,t         ;interrupt on RX complete enable,RX enable
  
  ldi t,0b00000110
  sts UCSR0C,t         ;8-bit character

  ldi t,0
  sts UBRR0H,t
  ldi t,34
  sts UBRR0L,t         ;14400bps
   

;Registers initialization

  ldi t,0
  ldi BUFMAX,180
  
  ldi ARRIDX,0
  ldi BUFPOS,0

  ldi YH,HIGH(buffer)
  ldi YL,LOW(buffer)


  ldi XH,HIGH(buffer)
  ldi XL,LOW(buffer)
  
;Enable interrupts

sei

;================================Main loop============================

LOOP:                  ; бесконечный цикл

rjmp LOOP

;============================Interupt handlers========================

;----------------------External interrupt 0 handler-------------------

EXT_INT0:

  cli

  ldi t,0              ;re-initializing timer
  sts TCNT1H,t
  sts TCNT1L,t
  
  ldi t,0b00000011     ;Starting timer (timer clock=Fclk/64)
  sts TCCR1B,t

  sei

reti

;-------------------Timer 1 Compare A match interrupt handler---------

TIM1_COMPA:

  cli                  ; запрещаем прерывания

  ldi t,0              ;ре-инициализация таймера	
  sts TCNT1H,t
  sts TCNT1L,t

  rcall ReadArray      ; вызов подпрограммы чтения массива

  out portB,t          ; вывод в порт B содержимое t 

  inc ARRIDX           ; увеличиваем ARRIDX на 1

  cp ARRIDX,BUFMAX     ; сравниваем 
  breq RESIDX          ; если 180 переходим на  RESIDX
  brne EXITCOMPA       ; если нет то на выход

RESIDX:

  ldi ARRIDX,0         ; обнуляем ARRIDX

  ldi t,0              ; останавливаем таймер
  sts TCCR1B,t

  out portB,t          ; вывод в порт B содержимое t

EXITCOMPA:

  sei                  ; разрешаем прерывания

reti

;-------------------------UART RX complete handler--------------------

USART_RXC:

  cli                  ; запрещаем прерывания

  lds t,UCSR0A         ; загружаем флаг ошибки
  sbrc t,FE0           ; если ошибка 
  rjmp FRAMING_ERROR   ; переходим на метку
                       ; если нет
  lds t,UDR0           ; загружаем содержимое в t

  rcall WriteArray     ; вызываем подпрограмму записи массива
  
  rjmp CHECK_BUF       ; переходим на проверку буфера

FRAMING_ERROR:

  ldi t,1              ; грузим в t - 1

  rcall WriteArray     ; вызываем подпрограмму записи массива

CHECK_BUF:

  inc BUFPOS           ; увеличиваем регистр на 1
  
  cp BUFPOS,BUFMAX     ; сравниваем регистры
  breq SBUF            ; если равны переходим на метку SBUF
  brne RX_END          ; если не равны то в конец

SBUF:  

  ldi BUFPOS,0         ; обнуляем BUFPOS 

RX_END:                ; конец

  sei                  ;разрешаем прерывания

reti

;==============================Other routines=========================

ReadArray:

  ldi t,0              ; обнуляем t

  ldi YH,HIGH(buffer)  ; загружаем в Y старший байт буфера
  ldi YL,LOW(buffer)   ; загружаем в Y младший байт буфера
  
  add YL,ARRIDX        ; сумируем младший байт Y с ARRIDX
  adc YH,t             ; сумируем старший байт Y с 0

  ld t,Y               ; загружаем Y в t

ret

WriteArray:

  ldi t1,0

  ldi XH,HIGH(buffer) ; загружаем в X старший байт буфера
  ldi XL,LOW(buffer)  ; загружаем в X младший байт буфера
  
  add XL,BUFPOS       ; сумируем младший байт X с BUFPOS
  adc XH,t1           ; сумируем старший байт X с 0
  
  st X,t              ; загружаем t в X

ret
;=====================================================================
