/**************************************************************
        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) / OSC1 [| 9     20|] VCAP/VDDCORE
               \ OSC2 [|10     19|] VSS
                      [|11     18|] 
                      [|12     17|] RB8 -> D2
                  VDD [|13     16|] RB7 -> D1
                      [|14     15|] 
                       +---------+
                    dsPIC33FJ128GP802
***************************************************************/
#include "p33fxxxx.h"
//definiujemy szybkość oscylatora dla funkcji __delay_
#define FCY 40000000UL 
//biblioteka z funkcjami __delay_us i __delay_ms
#include <libpic30.h>
/**************************************************************/
//Ustawienie bitów konfiguracyjnych
//FNOSC_PRIPLL	- zewnętrzny oscylator z PLL
_FOSCSEL(FNOSC_PRIPLL);

//FCKSM_CSECME	- włączona możliwość przełączania źródeł zegara, 
//				  włączony Fail-Safe Clock Monitor
//OSCIOFNC_OFF	- OSC2 jest wyjściem zegarowym
//POSCMD_XT		- oscylator XT
_FOSC(FCKSM_CSECME & OSCIOFNC_OFF & POSCMD_XT);

//FWDTEN_OFF	- watchdog może być wyłączony przez użytkownika w programie
_FWDT(FWDTEN_OFF);
/**************************************************************/

int main()
{
	int i;
////////////////////////////////////////////////////////////////////////////////
	//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;
	//2. PLLFBDbits.PLLDIV = M - 2
	PLLFBDbits.PLLDIV = 38;
	//3. CLKDIVbits.PLLPOST - (00 = 2)(01 = 4)(10 = zarezerwowane)(11 = 8)
	CLKDIVbits.PLLPOST = 0;
////////////////////////////////////////////////////////////////////////////////
	RCONbits.SWDTEN = 0;			//wyłączenie timera Watchdog

	//inicjalizacja ustawień oscylatora
	__builtin_write_OSCCONH(0x03);	//NOSC = 011 (Primary Oscillator with PLL (XTPLL, HSPLL, ECPLL))
	__builtin_write_OSCCONL(0x01);	//Start oscylatora wg ustawień NOSC
	while(OSCCONbits.COSC != 0x03);	//Zaczekaj na ustawienie bitów COSC

	while(OSCCONbits.LOCK!=1);		//zaczekaj na ustabilizowanie PLL
////////////////////////////////////////////////////////////////////////////////
// konfiguracja I/O
	AD1PCFGL = 0xFFFF;				//wszystkie linie cyfrowe               

	TRISBbits.TRISB7 = 0;			//linia RB7 wyjściowa
	LATBbits.LATB7 = 0;				//linia początkowo wyzerowana
	TRISBbits.TRISB8 = 0;			//linia RB8 wyjściowa
	LATBbits.LATB8 = 0;				//linia początkowo wyzerowana

////////////////////////////////////////////////////////////////////////////////
// nieskończona pętla
	for(;;)                            
	{
		//10 razy mrugniemy z oscylatorem zewnętrznym i PLL
		for(i=0; i<10; i++)
		{
			LATBbits.LATB7 ^= 1;		//przełącz stan na linii RB7
			__delay_ms(250);			//czekaj 1/4 s
		}

		//inicjalizacja ustawień oscylatora FRC
		__builtin_write_OSCCONH(0x00);	//NOSC = 000 (FRC)
		__builtin_write_OSCCONL(0x01);	//start oscylatora wg ustawień NOSC
		while(OSCCONbits.COSC != 0x00);	//zaczekaj na ustawienie bitów COSC

		//10 razy mrugniemy z oscylatorem FRC
		for(i=0; i<10; i++)
		{
			LATBbits.LATB8 ^= 1;		//przełącz stan na linii RB8
			__delay_ms(250);			//czekaj 1/4 s
		}

		//inicjalizacja ustawień oscylatora XT z PLL
		__builtin_write_OSCCONH(0x03);	//NOSC = 011 (Primary Oscillator with PLL (XTPLL, HSPLL, ECPLL))
		__builtin_write_OSCCONL(0x01);	//start oscylatora wg ustawień NOSC
		while(OSCCONbits.COSC != 0x03);	//zaczekaj na ustawienie bitów COSC
		while(OSCCONbits.LOCK!=1);		//zaczekaj na ustabilizowanie PLL
	}
}
