/**************************************************************
        Schemat podłączeń programowanego układu
                       +----v----+
                 MCLR [| 1     28|] VDD
                      [| 2     27|] VSS
                      [| 3     26|] RP15 -> SCK1OUT
            S1 -> RB0 [| 4     25|] RP14 -> SDO1
            S2 -> RB1 [| 5     24|] 
            S3 -> RB2 [| 6     23|] 
            S4 -> RB3 [| 7     22|] 
                  VSS [| 8     21|] 
       (8 MHz) / OSCI [| 9     20|] VCAP/VDDCORE
               \ OSCO [|10     19|] DISVREG
                      [|11     18|] RB9 -> D3
                      [|12     17|] RB8 -> D2
                  VDD [|13     16|] RB7 -> D1 
                      [|14     15|] 
                       +---------+
                     PIC24FJ64GB002
***************************************************************/
#include <p24Fxxxx.h>

//ustawienia bitów konfiguracyjnych
//1. 
//FWDTEN_OFF - Watchdog wyłączony
//JTAGEN_OFF - JTAG wyłączony
_CONFIG1(FWDTEN_OFF & JTAGEN_OFF)
//2.
//FNOSC_PRIPLL - układ taktowany zewnętrznym oscylatorem z pętlą PLL
//POSCMOD_XT - częstotliwość taktowania oscylatora 8 MHz
//PLLDIV_DIV2 - konieczność podzielenia przez 2 dla modułu USB PLL
_CONFIG2(FNOSC_PRIPLL & POSCMOD_XT & PLLDIV_DIV2)

//funkcja tworząca opóźnienie o wielokrotność mikrosekund
//dla taktowania 32 MHz
void Czekaj_us(unsigned long int ile)
{
	//jednokrotne wykonanie pętli zajmuje 16 cykli (1 us)
	while(ile>0) 
	{
		ile--;
		asm("nop");		
		asm("nop");		
		asm("nop");		
		asm("nop");		
		asm("nop");	
		asm("nop");
	}
}

void StartSPI()
{
	//1. konfiguracja SPI1CON1 i SPI1CON2
	SPI1CON1bits.MSTEN = 1;		//tryb Master
	SPI1CON1bits.MODE16 = 0;	//dane 8-bitowe
	//2. ustawienie bitu SPIEN (włączenie modułu SPI1)
	SPI1STATbits.SPIEN = 1;	
}

unsigned char TransferSPI1(unsigned char dane)
{
    SPI1BUF = dane;				//załaduj dane do bufora
    while(!SPI1STATbits.SPIRBF);//zaczekaj na zakończenie operacji
    return SPI1BUF;    			//odczytaj dane
}


int main()
{
	AD1PCFG = 0xFFFF;			//wszystkie linie cyfrowe
	//konfiguracja linii portu B
	TRISBbits.TRISB0 = 1;		//linia RB0 wejściowa (S1)
	TRISBbits.TRISB1 = 1;		//linia RB1 wejściowa (S2)
	TRISBbits.TRISB2 = 1;		//linia RB2 wejściowa (S3)
	TRISBbits.TRISB3 = 1;		//linia RB3 wejściowa (S4)

	TRISBbits.TRISB7 = 0;		//linia RB7 wyjściowa (D1)
	TRISBbits.TRISB8 = 0;		//linia RB8 wyjściowa (D2)
	TRISBbits.TRISB9 = 0;		//linia RB9 wyjściowa (D3)

	//remapowanie linii portów dla interfejsu SPI
	//1. RP14 -> SDO1 (nr 7)
	RPOR7bits.RP14R = 7;
	//2. RP15 -> SCK1OUT (nr 8)
	RPOR7bits.RP15R = 8;
	
	StartSPI();					//uruchomienie modułu SPI

	for(;;)						//nieskończona pętla
	{
		//sprawdź przyciski
		if(PORTBbits.RB0 == 0)
		{
			LATBbits.LATB8 = 0;
			LATBbits.LATB9 = 0;
			TransferSPI1(1);
		}
		if(PORTBbits.RB1 == 0)
		{
			LATBbits.LATB8 = 1;
			LATBbits.LATB9 = 0;
			TransferSPI1(2);
		}
		if(PORTBbits.RB2 == 0)
		{
			LATBbits.LATB8 = 0;
			LATBbits.LATB9 = 1;
			TransferSPI1(3);
		}
		if(PORTBbits.RB3 == 0)
		{
			LATBbits.LATB8 = 1;
			LATBbits.LATB9 = 1;
			TransferSPI1(4);
		}
		//oczekiwanie 125 ms
		Czekaj_us(125000);
		//mruganie diody kontrolnej D1
		LATBbits.LATB7 ^= 1;
	}
}
