/*
 * RDA5807M.asm
 *
 *  Created: 28.01.2015 23:22:44
 *   Author: ??????
 */ 
 ; Atmega8A .Кварц внутренний от от 2мГц до 8мГц

.def temp = r16					; Используемые регистры
.def temp1 = r17
.def temp2 = r18
.def temp3 = r19

.equ key_pin = pinb		; порт для кнопок
.equ key_plus = 4		; бит порта для кнопки увиличения
.equ key_minus = 5		; бит порта для кнопки уменьшения


 .cseg
 .org 0

 RESET: 
		ldi r16,high(RAMEND)	; Определяем стек
		out SPH,r16			
		ldi r16,low(RAMEND)
		out SPL,r16
		ldi temp,0b11111100
		out DDRC,temp
		ldi temp,0b11111111
		out DDRD,temp
		ldi temp,0b11001111
		out DDRB,temp
		ldi temp,0b00010000	;Запись диапазона работы приемника бит3:2 и шага сканирования бит 1:0
		sts bait_03l,temp
		ldi temp,0b10001000
		sts sound,temp
		ldi temp,0x04	; начальная частота 107.9 = 0х0437
		sts FM,temp
		ldi temp,0x37
		sts FM+1,temp
		rcall speed_clk			; настройка скорости
start:	
		rcall pausa_05
		rcall formula			;Вычисление частоты.
		rcall	write_rda5807m	; запись частоты
key:		
		rcall read_rda5807m	
		sbis	key_pin,key_minus
		rjmp	minus_fm		;sound_minus
		sbis	key_pin,key_plus 
		rjmp	plus_fm			;sound_plus;
		rjmp key

;УВИЛИЧЕНИЕ ЧАСТОТЫ FM
plus_fm:
		lds yl,FM+1
		lds yh,FM
		cpi yl,0x38
		breq plus_fm1
		rjmp plus_fm3
plus_fm1:	
		cpi yh,0x04
		breq plus_fm2
plus_fm3:
		adiw yl,1
		sts FM,yh
		sts FM+1,yl
plus_fm2: 	
		rjmp start	

;УМЕНЬШЕНИЕ ЧАСТОТЫ FM
minus_fm:
		lds yl,FM+1
		lds yh,FM
		cpi yl,0x66
		breq minus_fm1
		rjmp minus_fm2
minus_fm1:
		cpi yh,0x03
		breq minus_fm3
minus_fm2:
		sbiw yl,1
		sts FM,yh
		sts FM+1,yl
minus_fm3:
		rjmp start

;УВИЛИЧЕНИЕ ЗВУКА
sound_plus:
		lds temp,sound
		cpi temp,143
		breq sound_plus1
		inc temp
		sts sound,temp
sound_plus1:
		rjmp start
;УМЕНЬШЕНИЕ ЗВУКА
sound_minus:
		lds temp,sound
		cpi temp,128
		breq sound_minus1
		dec temp
		sts sound,temp
sound_minus1:
		rjmp start
;################################
;###### Вычисление частоты ######
;################################ 
 Formula:
		ldi zl,0x66
		ldi zh,0x03
		lds yl,FM+1
		lds yh,FM
		clc
		sub yl,zl
		sbc yh,zh
;		lds temp,bait_03l	; Для шага сканировани 50кГц
;		sbrc temp,1
;		rjmp scan50kgz
Formula1:
		ldi temp,0
		lsr yh
		ror yl
		ror temp
		lsr yh
		ror yl
		ror temp
		sts fm_st,yl
		sts fm_ml,temp
		ret
;scan50kgz:
;		ldi temp,2		; Для шага сканировани 50кГц
;		mul yl,temp
;		mov yh,r1
;		mov yl,r0
;		rjmp Formula1

;ЧТЕНИЕ ДАННЫХ ИЗ RDA5807M
read_rda5807m:
		rcall IIC_Start			; Старт
		ldi temp,0b00100001
		rcall IIC_Send			; Отправка байта
		rcall IIC_Recieve		; Принимаем первый бай
		sts rds_poisk,temp
		rcall IIC_Recieve		; Принимаем второй байт
		sts chanel_fm,temp
		out portd,temp
		rcall IIC_Recieve		; Принимаем третий байт
		sts uroven,temp
		rcall IIC_Recieve_lst	; Аналогично с последним байтом
		sts rds_data,temp
		rcall IIC_Stop			; Стоп
		lds temp,uroven
		out portd,temp
		ret

;############################
;##### Пишем FM модуль ######
;############################
write_rda5807m:
		rcall IIC_Start		; Старт
		ldi temp,0b00100000 ;Отправляем адрес FM модуля с битом записи
		rcall IIC_Send		
		ldi temp,0b11010010 ;02H байт
		rcall IIC_Send
		ldi temp,0b00000101 ;02L байт
		rcall IIC_Send
		lds temp,fm_st		;02H байт
		rcall IIC_Send
		lds temp,bait_03l	;03L байт
		lds temp1,fm_ml
		or temp,temp1
		rcall IIC_Send
		ldi temp,0b00000010 ;04H байт
		rcall IIC_Send
		ldi temp,0b00000000 ;04L байт
		rcall IIC_Send
		ldi temp,0b10001000 ;05H байт
		rcall IIC_Send
		lds temp,sound		;05L байт включение антенного входа и регулировка громкости
		rcall IIC_Send
		ldi temp,0b00000000 ;06H байт
		rcall IIC_Send
		ldi temp,0b00001000 ;06L байт
		rcall IIC_Send
		ldi temp,0b01000010 ;07H байт
		rcall IIC_Send
		ldi temp,0b00000010 ;07L байт
		rcall IIC_Send
		ldi temp,0b00000000 ;08H байт
		rcall IIC_Send
		ldi temp,0b00000000;08L байт
		rcall IIC_Send
		rcall IIC_Stop		; Стоп
		ret

 ;#########################################
 ;#### Настройка скорости работы I2C ######
 ;#########################################
speed_clk:
		ldi temp,2						; ;TWBR = ((2000000/100000) - 16)/(2*4^0) = 2
		OUT TWBR,temp					; Настройка скорости работы I2C
		ldi temp, (0<<TWPS1)|(0<<TWPS0) ; частота работы 400кГц при частоте кварца 8 мГц
		OUT TWSR,temp
		ret

; Продцедуры для работы с I2C.
; Автор - Lpa
; http://radioelektr.ru/

;#########################################
;###### Отправка стартовой посылки #######
;#########################################
IIC_Start:

		ldi temp,(1<<TWINT)|(1<<TWSTA)|(1<<TWEN); Отправляем стартовую посылку
		OUT TWCR,temp
		rcall iic_wait							; Ожидаем, пока передатчик выполнит ЭКШН
		ret

;###################################
;#### Отправка стоповой посылки ####
;###################################
IIC_Stop:
; Отправка стоповой посылки	
	ldi temp,(1<<TWINT)|(1<<TWEN)|(1<<TWSTO)	; Отправляем стоповую посылку
	OUT TWCR,temp
	ret

;#########################
;###### Приём байта ######
;#########################
iic_recieve: 
											; Принятый байт помещается в temp
	ldi temp,(1<<TWINT)|(1<<TWEN)|(1<<TWEA)	; Настраиваем передатчик
	OUT TWCR,temp	
	rcall iic_wait							; Ожидаем, пока передатчик выполнит
	in temp,TWDR							; Считываем байт
	ret

;###########################################
;#### Приём последнего байта (без ACK) #####
;###########################################
iic_recieve_lst:
; Принятый байт помещается в temp
	ldi temp,(1<<TWINT)|(1<<TWEN)	; Настраиваем передатчик
	OUT TWCR,temp	
	rcall iic_wait					; Ожидаем, пока передатчик выполнит ЭКШН
	in temp,TWDR					; Считываем байт
	ret

;#########################################
;############ Отправка байта #############
;#########################################
iic_send: 
; Передаваемый байт помещается в temp

	out TWDR,temp					; Отправляем байт
	ldi temp,(1<<TWINT)|(1<<TWEN)	; Настраиваем передатчик
	OUT TWCR,temp	
	rcall iic_wait					; Ожидаем, пока передатчик выполнит ЭКШН
	ret

;#########################################
;#### Ожидание готовности передатчика ####
;#########################################
IIC_Wait:
	in temp,TWCR					; Берём значение из TWCR и помещаем в temp
	sbrs temp,TWINT					; Пока флаг прерывания в 1 - идёт передача
	rjmp IIC_Wait					; Как только обнулился, выходим из подпрограммы							
	ret

pausa_05:
		ldi temp1,10
paus1:		
		ldi temp2,60
paus2:
		ldi temp3,255
paus3:
		dec temp3
		brne paus3
		dec temp2
		brne paus2
		dec temp1
		brne paus1
		ret						

; RAM =====================================================
.DSEG			; Сегмент ОЗУ
FM_ST:		.byte 1	;байты для хранения расчитанной частоты радиоприемника.
FM_ML:		.byte 1	;байты для хранения расчитанной частоты радиоприемника.
bait_03l:	.byte 1 ;хранение шага сканирования диапазона частот. бит 4 включает точную настройку
FM:			.byte 2
sound:		.byte 1	; Громкось звука
rds_data:	.byte 1	; Данные RDS
rds_poisk:	.byte 1	; Поиск RDS
uroven:		.byte 1 ; Уровень принимаемого сигнала 
chanel_fm:	.byte 1 ; номер выбранного канала

