;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;        Schemat podłączeń programowanego układu
;                       +----v----+
;                 MCLR [| 1     28|] AVDD
;                      [| 2     27|] AVSS
;                      [| 3     26|] 
;                      [| 4     25|] 
;                      [| 5     24|] 
;                      [| 6     23|] 
;                      [| 7     22|] 
;                  VSS [| 8     21|] 
;       (8 MHz) / OSCI [| 9     20|] VCAP/VDDCORE
;               \ OSCO [|10     19|] VSS
;                      [|11     18|] 
;                      [|12     17|] 
;                  VDD [|13     16|] RB7 -> D1
;                      [|14     15|] 
;                       +---------+
;                    dsPIC33FJ128GP802
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	.include "p33fxxxx.inc"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ustawienia bitów konfiguracyjnych
; FNOSC_PRIPLL	- zewnętrzny oscylator z PLL
	config	_FOSCSEL,	FNOSC_PRIPLL

; FCKSM_CSDCMD	- wyłączona możliwość przełączania źródeł zegara
; OSCIOFNC_OFF	- OSC2 jest wyjściem zegarowym
; POSCMD_XT	- oscylator XT
	config	_FOSC,	FCKSM_CSDCMD & OSCIOFNC_OFF & POSCMD_XT

; FWDTEN_OFF	- watchdog może być wyłączony przez użytkownika w programie
	config	_FWDT,	FWDTEN_OFF
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; definicje stałych
	.equ	procesorek, (40000/4)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; deklaracje symboli globalnych
	.global __reset			;etykieta pierwszej linii kodu
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; początek kodu
__reset:
	mov	#__SP_init, W15			;inicjalizacja wskaźnika stosu (adres początku stosu)
	mov	#__SPLIM_init, W0		;inicjalizacja SPLIM (adres graniczny stosu)
	mov	W0, SPLIM				;W0 -> SPLIM
	nop                        	;konieczna instrukcja nop
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	;Ustawienia PLL: Fosc = (((Fin/PLLPRE)*PLLDIV)/PLLPOST)
	;przy spełnionych warunkach:
	;1.  0,8 MHz >= (Fin/PLLPRE)                    <= 8,0 MHz
	;2.  100 MHz >= ((Fin/PLLPRE)*PLLDIV)           <= 200 MHz
	;3. 12,5 MHz >= (((Fin/PLLPRE)*PLLDIV)/PLLPOST) <= 80,0 MHz
  
	;nasza konfiguracja
	;1. 8,00 MHz/2 = 4,00 MHz		(N1 = 2)
	;2. 4,00 MHz*40 = 160,00 MHz	(M = 40)
	;3. 160,00 MHz/2 = 80,00 MHz	(N2 = 2)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	;1. CLKDIVbits.PLLPRE = N1 - 2
	;   CLKDIVbits.PLLPRE = 0;
	mov	#0xFFE0, W0				;załaduj do W0 maskę
	mov	#CLKDIV, W1				;załaduj do W1 adres CLKDIV
	and	W0, [W1], [W1]			;czyść bity PLLPRE
	;2. PLLFBDbits.PLLDIV = M - 2
	;   PLLFBDbits.PLLDIV = 38;
	mov	#0xFE00, W0				;załaduj do W0 maskę
	mov	#PLLFBD, W1				;załaduj do W1 adres PLLFBD
	and	W0, [W1], [W1]			;czyść bity PLLDIV
	mov	#38, W0					;W0 <- 38
	ior	W0, [W1], [W1]			;PLLDIV <- 38
	;3. CLKDIVbits.PLLPOST - (00 = 2)(01 = 4)(10 = zarezerwowane)(11 = 8)
	;   CLKDIVbits.PLLPOST = 0;
	mov	#0xFF3F, W0				;załaduj do W0 maskę
	mov	#CLKDIV, W1				;załaduj do W1 adres CLKDIV
	and	W0, [W1], [W1]			;czyść bity PLLPOST
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	;RCONbits.SWDTEN = 0;			//wyłączenie timera Watchdog
	bclr	RCON, #SWDTEN

	;while(OSCCONbits.COSC != 0x03);		//zaczekaj na ustawienie bitów COSC
	mov	#0x7000, W0				;załaduj do W0 maskę
	mov	#0x3000, W2				;załaduj do W2 oczekiwaną postać COSC
petla_COSC:
	mov	OSCCON, W1				;załaduj do W1 zawartość OSCCON
	and	W0, W1, W1				;pozostaw w W1 bity COSC
	cpseq	W1, W2				;porównaj odczytane bity z oczekiwaną wartością COSC
								;pomiń nast. instrukcję, jeśli są równe
	goto	petla_COSC			;powrót do pętli
		
	;while(OSCCONbits.LOCK != 1);		//zaczekaj na ustabilizowanie PLL
petla_LOCK:
	btss	OSCCON, #LOCK		;pomiń nast. instrukcję, jeśli LOCK wyzerowany
	goto	petla_LOCK			;wróć do pętli
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	; konfiguracja I/O
	; AD1PCFGL = 0xFFFF;		//wszystkie linie cyfrowe
	setm	AD1PCFGL			;ustaw bity rejestru AD1PCFGL

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; konfiguracja linii portu B
	bclr	TRISB, #7			;linia RB7 wyjściowa

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; nieskończona pętla
petla:

	bset	LATB, #7			;RB7 = 1
	mov	#250, W1				;W1 <- 250
	rcall	Czekaj_ms			;czekaj 250 ms

	bclr	LATB, #7			;RB7 = 0
	mov	#250, W1				;W1 <- 250
	rcall	Czekaj_ms			;czekaj 250 ms

	bra	petla					;skok bezwarunkowy do etykiety pętla
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Czekaj_ms:
	mov	#procesorek, W2			;W2 <- FCPU/4
Czekaj_ms_petla:
	nop							;nic nie rób (nawet nie odpoczywaj)
	dec	W2, W2					;zmniejsz W2 o 1
	bra	NZ, Czekaj_ms_petla		;wróć do pętli, jeśli nie było zera
	dec	W1, W1					;W1--
	bra	NZ, Czekaj_ms			;wróć do pętli, jeśli nie było 0
	return						;powrót z podprogramu
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.end							;koniec programu
