
.include "m8def.inc"   ; Используем ATMega16a

.equ ISP=PORTB
.equ SCK=5
.equ MISO=4
.equ MOSI=3
.equ CSN=2
.equ CE=1
.equ ReadReg=0x00
.equ WriteReg=0x20
.equ Read_RX=0x61
.equ Write_TX=0xA0
.equ Flush_RX=0xE2
.equ Flush_TX=0xE1
.equ Reuse_TX=0xE3
.equ Activate=0x50
.equ Read_RX_Wid=0x60
.equ Write_Ack_PL=0xA8
.equ Write_TX_No_Ack=0xB0
.equ No_OP=0xFF



; RAM ========================================================
		.DSEG


; FLASH ======================================================

 .CSEG
         .ORG $000        	; (RESET) 
         RJMP   Reset
         .ORG $001
         RJMP   INTO        ; (INT0) External Interrupt Request 0
         .ORG $002
         RETI             	; (INT1) External Interrupt Request 1
         .ORG $003
         RETI		      	; (TIMER2 COMP) Timer/Counter2 Compare Match
         .ORG $004
         RETI             	; (TIMER2 OVF) Timer/Counter2 Overflow
         .ORG $005
         RETI		      	; (TIMER1 CAPT) Timer/Counter1 Capture Event
         .ORG $006 
         RETI			  	; (TIMER1 COMPA) Timer/Counter1 Compare Match A
         .ORG $007
         RETI				; (TIMER1 COMPB) Timer/Counter1 Compare Match B
         .ORG $008
         RETI			  	; (TIMER1 OVF) Timer/Counter1 Overflow
         .ORG $009
         RETI			 	; (TIMER0 OVF) Timer/Counter0 Overflow
         .ORG $00A
         RETI             	; (SPI,STC) Serial Transfer Complete
         .ORG $00B
         RETI	  	        ; (USART,RXC) USART, Rx Complete
         .ORG $00C
         RETI	      		; (USART,UDRE) USART Data Register Empty
         .ORG $00D
         RETI           	; (USART,TXC) USART, Tx Complete
         .ORG $00E
         RETI       	    ; (ADC) ADC Conversion Complete
         .ORG $00F
         RETI             	; (EE_RDY) EEPROM Ready
         .ORG $010
         RETI             	; (ANA_COMP) Analog Comparator
         .ORG $011
         RETI             	; (TWI) 2-wire Serial Interface
         .ORG $012
         RETI             	; (SPM_RDY) Store Program Memory Ready



 
;Internal Hardware Init ===========================================



; ======== Delay ========

Delay:		ldi r21,70
Loop:		dec r21
			brne Loop

			ret



;  ======== Transmit SPI =======

Transmit_SPI:   out SPDR,R16
Wait_transmit:  sbis SPSR,SPIF
				rjmp Wait_transmit
				in R17,SPDR
				
				ret

; ====== Write register ======

WrReg:			cbi ISP,CSN
				rcall Transmit_SPI
				mov r16,R19
				rcall Transmit_SPI
				sbi ISP,CSN
				ret


; ====== Write 1 byte register ======

Write_reg:		clr R18
				cbi ISP,CSN
				rcall Transmit_SPI

send:			cp R18,R20
				breq ext
				lpm R16,z+
				rcall Transmit_SPI
				inc R18
				rjmp send

ext: 			sbi ISP,CSN
				ret


; ====== Write 11 byte register ======

;Write_reg11:	clr r18
				;cbi ISP,CSN
				;rcall Transmit_SPI

;send11:			cpi r18,11
				;breq ext11
				;lpm r16,z+
				;rcall Transmit_SPI
				;inc r18
				;jmp send11

;ext11: 		sbi ISP,CSN
				;ret


; ======== Switch to RX mode ========

Switch_RX:		cbi ISP,CSN
				ldi R16,ReadReg|0x00
				rcall Transmit_SPI
				ldi R16,0x00
				rcall Transmit_SPI
				mov R19,R17
				sbi ISP,CSN
				ori R19,0b00000001
				cbi ISP,CSN
				ldi R16,WriteReg|0x00
				rcall Transmit_SPI
				mov R16,R19
				rcall Transmit_SPI
				sbi ISP,CSN
				ret


; ======== Switch to TX mode ========

Switch_TX:		cbi ISP,CSN
				ldi R16,ReadReg|0x00
				rcall Transmit_SPI
				ldi R16,0x00
				rcall Transmit_SPI
				mov R19,R17
				sbi ISP,CSN
				andi R19,0b11111110
				cbi ISP,CSN
				ldi R16,WriteReg|0x00
				rcall Transmit_SPI
				mov R16,R19
				rcall Transmit_SPI
				sbi ISP,CSN
				ret


; ======== Power UP ========

Power_UP:		cbi ISP,CSN
				ldi R16,ReadReg|0x00
				rcall Transmit_SPI
				ldi R16,0x00
				rcall Transmit_SPI
				mov R19,R17
				sbi ISP,CSN
				ori R19,0b00000010
				cbi ISP,CSN
				ldi R16,WriteReg|0x00
				rcall Transmit_SPI
				mov R16,R19
				rcall Transmit_SPI
				sbi ISP,CSN
				ret


; ======== Power Down ========

Power_DN:		cbi ISP,CSN
				ldi R16,ReadReg|0x00
				rcall Transmit_SPI
				ldi R16,0x00
				rcall Transmit_SPI
				mov R19,R17
				sbi ISP,CSN
				andi R19,0b11111101
				cbi ISP,CSN
				ldi R16,WriteReg|0x00
				rcall Transmit_SPI
				mov R16,R19
				rcall Transmit_SPI
				sbi ISP,CSN
				ret



; ======== Disable IRQ for RX complete ========

DS_RX_DR:		cbi ISP,CSN
				ldi R16,ReadReg|0x00
				rcall Transmit_SPI
				ldi R16,0x00
				rcall Transmit_SPI
				mov R19,R17
				sbi ISP,CSN
				ori R19,0b01000000
				cbi ISP,CSN
				ldi R16,WriteReg|0x00
				rcall Transmit_SPI
				mov R16,R19
				rcall Transmit_SPI
				sbi ISP,CSN
				ret


; ======== Enable IRQ for RX complete ========

EN_RX_DR:			cbi ISP,CSN
				ldi R16,ReadReg|0x00
				rcall Transmit_SPI
				ldi R16,0x00
				rcall Transmit_SPI
				mov R19,R17
				sbi ISP,CSN
				andi R19,0b10111111
				cbi ISP,CSN
				ldi R16,WriteReg|0x00
				rcall Transmit_SPI
				mov R16,R19
				rcall Transmit_SPI
				sbi ISP,CSN
				ret


; ======== Disable IRQ for TX complete ========

DS_TX_DS:		cbi ISP,CSN
				ldi R16,ReadReg|0x00
				rcall Transmit_SPI
				ldi R16,0x00
				rcall Transmit_SPI
				mov R19,R17
				sbi ISP,CSN
				ori R19,0b00100000
				cbi ISP,CSN
				ldi R16,WriteReg|0x00
				rcall Transmit_SPI
				mov R16,R19
				rcall Transmit_SPI
				sbi ISP,CSN
				ret


; ======== Enable IRQ for TX complete ========

EN_TX_DS:		cbi ISP,CSN
				ldi R16,ReadReg|0x00
				rcall Transmit_SPI
				ldi R16,0x00
				rcall Transmit_SPI
				mov R19,R17
				sbi ISP,CSN
				andi R19,0b11011111
				cbi ISP,CSN
				ldi R16,WriteReg|0x00
				rcall Transmit_SPI
				mov R16,R19
				rcall Transmit_SPI
				sbi ISP,CSN
				ret


; ======== Disable IRQ for Max_RT ========

DS_MAX_RT:		cbi ISP,CSN
				ldi R16,ReadReg|0x00
				rcall Transmit_SPI
				ldi R16,0x00
				rcall Transmit_SPI
				mov R19,R17
				sbi ISP,CSN
				ori R19,0b00010000
				cbi ISP,CSN
				ldi R16,WriteReg|0x00
				rcall Transmit_SPI
				mov R16,R19
				rcall Transmit_SPI
				sbi ISP,CSN
				ret


; ======== Enable IRQ for Max_RT ========

EN_MAX_RT:		cbi ISP,CSN
				ldi R16,ReadReg|0x00
				rcall Transmit_SPI
				ldi R16,0x00
				rcall Transmit_SPI
				mov R19,R17
				sbi ISP,CSN
				andi R19,0b11101111
				cbi ISP,CSN
				ldi R16,WriteReg|0x00
				rcall Transmit_SPI
				mov R16,R19
				rcall Transmit_SPI
				sbi ISP,CSN
				ret


; ======== Enable CRC ========

EN_CRC:		 	cbi ISP,CSN
				ldi R16,ReadReg|0x00
				rcall Transmit_SPI
				ldi R16,0x00
				rcall Transmit_SPI
				mov R19,R17
				sbi ISP,CSN
				ori R19,0b00001000
				cbi ISP,CSN
				ldi R16,WriteReg|0x00
				rcall Transmit_SPI
				mov R16,R19
				rcall Transmit_SPI
				sbi ISP,CSN
				ret


; ======== Disable CRC ========

DS_CRC:			cbi ISP,CSN
				ldi R16,ReadReg|0x00
				rcall Transmit_SPI
				ldi R16,0x00
				rcall Transmit_SPI
				mov R19,R17
				sbi ISP,CSN
				andi R19,0b11110111
				cbi ISP,CSN
				ldi R16,WriteReg|0x00
				rcall Transmit_SPI
				mov R16,R19
				rcall Transmit_SPI
				sbi ISP,CSN
				ret



; ======== CRC Coding 2 Byte ========

CRC_2B:			cbi ISP,CSN
				ldi R16,ReadReg|0x00
				rcall Transmit_SPI
				ldi R16,0x00
				rcall Transmit_SPI
				mov R19,R17
				sbi ISP,CSN
				ori R19,0b00000100
				cbi ISP,CSN
				ldi R16,WriteReg|0x00
				rcall Transmit_SPI
				mov R16,R19
				rcall Transmit_SPI
				sbi ISP,CSN
				ret


; ======== CRC Coding 1 Byte ========

CRC_1B:			cbi ISP,CSN
				ldi R16,ReadReg|0x00
				rcall Transmit_SPI
				ldi R16,0x00
				rcall Transmit_SPI
				mov R19,R17
				sbi ISP,CSN
				andi R19,0b11111011
				cbi ISP,CSN
				ldi R16,WriteReg|0x00
				rcall Transmit_SPI
				mov R16,R19
				rcall Transmit_SPI
				sbi ISP,CSN
				ret


; ======== Switch to Bank0 Register =======

Switch_Bank0:	rcall Power_UP
				rcall Delay
				cbi ISP,CSN
				ldi R16,0xFF ;ldi R16,NOP
				rcall Transmit_SPI
				sbi ISP,CSN
				sbrs R17,7
				ret
				cbi ISP,CE
				rcall Delay
				cbi ISP,CSN
				ldi R16,0x50
				rcall Transmit_SPI
				ldi R16,0x53
				rcall Transmit_SPI
				sbi ISP,CSN
				sbi ISP,CE
				rcall Delay
				ret

;  ======== Switch to Bank1 Register =======

Switch_Bank1:	rcall Power_UP
				rcall Delay
				cbi ISP,CSN
				ldi R16,0xFF ;ldi R16,NOP
				rcall Transmit_SPI
				sbi ISP,CSN
				sbrc R17,7
				ret
				cbi ISP,CE
				rcall Delay
				cbi ISP,CSN
				ldi R16,0x50
				rcall Transmit_SPI
				ldi R16,0x53
				rcall Transmit_SPI
				sbi ISP,CSN
				sbi ISP,CE
				rcall Delay
				ret

; ======= Write register in bank1 =======

Init_Bank1:		rcall Switch_Bank1

				ldi ZL, low(Reg100*2)
				ldi ZH, high(Reg100*2)
				ldi R16,WriteReg|0x00
				ldi R20,4
				rcall Write_reg


				ldi ZL, low(Reg101*2)
				ldi ZH, high(Reg101*2)
				ldi R16,WriteReg|0x01
				ldi R20,4
				rcall Write_reg


				ldi ZL, low(Reg102*2)
				ldi ZH, high(Reg102*2)
				ldi R16,WriteReg|0x02
				ldi R20,4
				rcall Write_reg


				ldi ZL, low(Reg103*2)
				ldi ZH, high(Reg103*2)
				ldi R16,WriteReg|0x03
				ldi R20,4
				rcall Write_reg

				ldi ZL, low(Reg104*2)
				ldi ZH, high(Reg104*2)
				ldi R16,WriteReg|0x04
				ldi R20,4
				rcall Write_reg


				ldi ZL, low(Reg105*2)
				ldi ZH, high(Reg105*2)
				ldi R16,WriteReg|0x05
				ldi R20,4
				rcall Write_reg

				ldi ZL, low(Reg10C*2)
				ldi ZH, high(Reg10C*2)
				ldi R16,WriteReg|0x0C
				ldi R20,4
				rcall Write_reg


				ldi ZL, low(Reg10D*2)
				ldi ZH, high(Reg10D*2)
				ldi R16,WriteReg|0x0D
				ldi R20,4
				rcall Write_reg


				ldi ZL, low(Reg10E*2)
				ldi ZH, high(Reg10E*2)
				ldi R16,WriteReg|0x0E
				ldi R20,11
				rcall Write_reg

				ret


; ======= Write register in bank0 =======

Init_Bank0:		rcall Switch_Bank0
				rcall DS_RX_DR
				rcall EN_TX_DS
				rcall DS_MAX_RT
				rcall DS_CRC
				rcall Power_UP
				rcall Switch_TX

				ldi R16,WriteReg|0x01		;disable Auto Ack
				ldi R19,0x00
				rcall WrReg

				ldi R16,WriteReg|0x02		;enable data pipe 0
				ldi R19,0x01
				rcall WrReg

				ldi R16,WriteReg|0x03		;ldi R19,AddrWidth5
				ldi R19,0x03		        
				rcall WrReg

				ldi R16,WriteReg|0x04		;disable retransmission
				ldi R19,0x00				
				rcall WrReg

				ldi R16,WriteReg|0x05		;setup RF channel
				ldi R19,0x19
				rcall WrReg

				ldi R16,WriteReg|0x06		;setup RF: 1Mbps,5dBm,LNA High Gain
				ldi R19,0x01
				rcall WrReg

				ldi R16,WriteReg|0x09		;CD Disable
				ldi R19,0x00
				rcall WrReg

				ldi ZL, low(Reg00A*2)		;address RX pipe 0
				ldi ZH, high(Reg00A*2)
				ldi R16,WriteReg|0x0A
				ldi R20,5
				rcall Write_reg

				ldi ZL, low(Reg010*2)		;address TX
				ldi ZH, high(Reg010*2)
				ldi R16,WriteReg|0x10
				ldi R20,5
				rcall Write_reg

				ldi R16,WriteReg|0x11		;number of byte in data pipe 0 (1byte)
				ldi R19,0x01
				rcall WrReg

				ldi R16,WriteReg|0x1C		;disable dynamic pay load
				ldi R19,0x00
				rcall WrReg

				 

				ret

; ======= Register 0x00 Bank 1 ======= 
				
Reg100:			.db 0x40,0x4B,0x01,0xE2


; ======= Register 0x01 Bank 1 ======= 

Reg101:			.db 0xC0,0x4B,0x00,0x00


; ======= Register 0x02 Bank 1 ======= 

Reg102:			.db 0xD0,0xFC,0x8C,0x02


; ======= Register 0x03 Bank 1 ======= 

Reg103:			.db 0x99,0x00,0x39,0x41


; ======= Register 0x04 Bank 1 ======= 

Reg104:			.db 0xD9,0x9E,0x86,0x0B


; ======= Register 0x05 Bank 1 ======= 

Reg105:			.db 0x24,0x06,0x7F,0xA6


; ======= Register 0x0C Bank 1 ======= 

Reg10C:			.db 0x00,0x12,0x73,0x00


; ======= Register 0x0D Bank 1 ======= 

Reg10D:			.db 0x36,0xB4,0x80,0x00


; ======= Register 0x0E Bank 1 ======= 

Reg10E:			.db 0x41,0x20,0x08,0x04,0x81,0x20,0xCF,0xF7,0xFE,0xFF,0xFF




; ======= Register 0x10 Bank 0 ======= 

Reg010:			.db 0x0B,0x1C,0x2D,0x3E,0x4F		;TX address


; ======= Register 0x0A Bank 0 ======= 

Reg00A:			.db 0x0F,0x1E,0x2D,0x3C,0x4B		;RX address



; End Internal Hardware Init ===================================



; External Hardware Init  ======================================

; End Internal Hardware Init ===================================



; Run ==========================================================
Run:			sei
				
Opros:			ldi R16,Write_TX
				ldi R19,0b000010111
				rcall WrReg

				rjmp Opros


; End Run ======================================================



; Main =========================================================

Reset:			LDI 	R16,Low(RAMEND)						; Инициализация стека
		    	OUT 	SPL,R16								; Обязательно!!!
		 		LDI 	R16,High(RAMEND)
		 		OUT 	SPH,R16

															;Init SPI
				ldi R16,(1<<SPE)|(1<<MSTR)					;Enable SPI, Master, set clock rate fck/16
				out SPCR,R16

				ldi R16,0x40
				out GICR,R16
				ldi R16,0x00
				out MCUCR,r16

				ldi R16,0x80								;disable analog comparator
				out ACSR,r16
				
				ldi R16,(1<<SCK) + (1<<MOSI) + (1<<CSN) + (1<<CE) 
				out DDRB,R16	
				
				ldi R16,0b00000000
				out DDRC,R16
				
				ldi R16,0b11111111
				out PORTC,R16							

				cli

				sbi ISP,CSN

				cbi ISP,SCK

				cbi ISP,CE

				rcall Delay

				rcall Init_Bank1

				rcall Init_Bank0

				rcall Switch_TX	
				
				rcall Power_UP

				rcall Delay

				sbi ISP,CE

				rcall Delay		

				rjmp Run



	
	

; End Main =====================================================


; Procedure ====================================================

INTO: 			cbi ISP,CSN					;read RX payload
				ldi R16,Flush_TX
				rcall Transmit_SPI
				sbi ISP,CSN
				
				reti			

; End Procedure ================================================


; EEPROM =====================================================
			.ESEG				; Сегмент EEPROM
