#include "platform.h" #include "eth.h" #include "enc28j60.h" #include "ap.h" #include "arp.h" #include "icmp.h" #include "ip.h" #include "udp.h" #include "stdlib.h" #include "globals.h" #include "tcp.h" #include "http.h" void posunminutu(void); void nastavvetve(void); void setresto(void); void cpu_init (void); /* enc28j60.c je asi blbe void delay (unsigned int us) { ???? vi mikro sec ???? MAC adresa je ASI v enc28j60.h na konci, pokud se to jeste nekde neprepisuje A pak je to jeste cely tady dal const unsigned char mymac[6]={0x0,0xBC,0x6F,0x55,0x1C,0xC4}; const unsigned char myip[4]={192,168,1,223}; netusim, ktera plati, jestli ta tady, nebo ta v tom enc... */ //nastavení pojistek // Register FOSC (0xf80000) po smazani 00C71F // _FOSC(0xC1E1); tohle je pro Martina 1100 0001 1110 0001 // 11xx x001 xxx0 0001 // FCKSM FOS FPR no a nechapu, pro jsou xxx na hodnote 1 // tohle je prvni slovo v "prima editace pojistek" // tohle je HS - primary oscilator, source on POR - primary oscilator // no a FOSFPR je prej BLBE // mam vnejsi oscilator - krystal 8MHz - ma byt XT - takze to ma byt takhle // FOS<2:0> FPR<4:0> // 011 00100 // a dale viz kap. 17.2.7 datasheet Microchip FCKSM 1x = FAil safe disabled, jinak ale tam nic dalsiho neni // 0100 0011 0000 0100 zkusime tohle 4304 // _FOSC(0xC1E1); // _FOSC(0x0304); TOHLE JE MOJE NOVA HODNOTA // _FOSC(0xC3E4); tohle fungyje, vnejsi krystal, // HS, alternate oscilator, fal safe disabled, clock switch disabled _FOSC(0xC3E4); // finalni hodnota, navic je fail safe disabled a clock switch disabled // ale musis to dale osetrit pri eventualni poruse // 1100 0011 1110 0100 // FOS 110 tahle hodnota neni vtipne v datasheetu // FPR 00100 XT primary ale ta 0 uplne na zacatku nevim // Register 7-3: FOSC: Oscillator Configuration Register for Oscillator System VERSION 3 // v priruccel /dbf S07_Oscilator // 00xx x011 xxx0 0100 // FOS DFPR - a vychazi nam to stejne jako nahore 1NE 0304 // bud 0304 nebo 0704 bori se bud MPLAB nebo PRESTO // _FOSC(CSW_FSCM_OFF & FRC_PLL4); //& FRC_PLL4- fázový závěs zatím nepoužijeme - při DEBUG módu dělá problémy // _FOSC(CSW_FSCM_OFF ); //& FRC_PLL4- fázový závěs zatím nepoužijeme - při DEBUG módu dělá problémy // 7.37 ma FRC oscilator ????? *4 je 29.52 MHz // a citac je taktez nastaven na kmitocet 7.37 MHz // a potom v cpu_init se nastavi deleni dvema ???? - bity POSC registru OSCCON // Register FWDT (0xf80002) po smazani 00803F //_FWDT(WDT_OFF); //zákaz WDT // ON - na 15. bitu je 1 tkye 803F je nelpomalejsi WDT _FWDT(0x00803F); // WDT zapnut, nejvetsi mozny cas // FBORPOR (0xf80004) po smazani 0087B3 //_FBORPOR(PBOR_ON & PWRT_64 & BORV27 & MCLR_DIS); //BOREN při 2,7 V, PWRT 64 ms, RA5 // vypli jsme FBOR POR _FBORPOR(0x00733); // _FBS Register RESERVED1 (0xf80006) po smazani 00310F _RESERVED1(0x00310F) // _FSS tohle v PICKITu je v Ccku RESERVED2 f80008 po smazani 00330F _RESERVED2(0x00330F ) // Register FGS (0xf8000a) po smazani 000007 // _FGS(CODE_PROT_OFF); //ochrana dat zakázána _FGS(0x00007); // _FICD se v Ccku jmenije ICD Register ICD (0xf8000c) po smazani 00C003 _ICD(0x00C003) // No, a potom ma ASIX PRESTO jeste adresu F8000E, a na ni jsou same 0 , je otazka , zad to k necemu je char status; char data_OK; unsigned long int sekundy=1; /* =1 proto, aby prvni munutu blikala LED 1:1 - viz preruseni od TMR1 if( !(sekundy % 60) ){ */ unsigned long int posl_data=0; unsigned int radek=0; unsigned int pocet_radku=0; char rem_mac[6]; char rem_ip[4]; unsigned char zv[10]; unsigned char vet[10]; unsigned int dt[10]; char tcp_stat; unsigned char mamIPprotejsku; /*globální proměnné - ip a mac adresa (maksa??? - pouze pokud budeme chtít samovolně vysílat - ARP protokol pro překlad cílové IP na MAC) no ale tady jsem z toho dost na vetvi, MAC adresa se take zadava v v enc28j60.h na konci - dal jsem to stejne */ const unsigned char mymac[6]={0x0,0xBC,0x6F,0x55,0x1C,0xC4}; const unsigned char myip[4]={192,168,1,222}; unsigned int nastPR1; unsigned int maskaT2; unsigned int pocitmin; unsigned char pocitT2; unsigned char casjespravne; unsigned char cosestalo[MAXCOSESTALO+1]; unsigned char stavvetve[MAXPOLMOD+1]; unsigned short int mindoak[MAXPOLMOD+1]; /* pole pro zaznam udalosti - reset a podobne MAXCOSESTALO je index posledni bunky - definovano v globals.h nyni je to 11 - posledi 2 byte jsou hodnota TMR1 bunka 0 - vyplni se po RESETu atd, indikuje to, co se stalo ? - stav vetvi; to musim jeste poresit, netusim, co delaji inicializacni procedury "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ne, stav vetvi neni v cosestalo! to se pridava az do celeho paketu 1 - 4 adresa havarie pri interruptu a podobne 6 - 9 cas sekundy - okopirovano sekundy little endian !!! a v paketu je to o 2 posunuto cosestalo[0] 129 - address error trap 130 stack error trap 1 power Up Reset 2 BOR - pokles napajeni 3 SOFTE reset 4 WDT reset 5 nevim od ceho RESET 6 hodiny normalne bezi, v cosestalo je posledni cas sekundy 7 reset jako reakce na RESET_REQ - je to ale pak udelano pomoci WDT 8 reset, protoze za 24 hodin neprisel zadny paket od pocitace v udp.c se nastavuje port - nejak zmenit ! nyní vyplníme udp hlavičku udp->UDP_destPort = 15150; udp->UDP_sourcePort = 15151; Predelej proceduru - proste VZDY prida COSESTALO , a je to. udp_send(buffer,DATA_REQ,1); - takze len bude nanic v procedure to fakt udelao len++ i kdyz je to formalni parametr - podivne podivej se, co to vlastne posila alternate startup module (crt1.o) is linked when the -Wl, --no-data-init option is specified. It performs the same operations, except for step (3), which is omitted. The alternate startup module is smaller than the primary module, and can be selected to conserve program memory if data initialization is not required. je to uplne jendoduche Project - -Build options - project cvaknout na MPLAB LINK C30 use alternate settings a do radku pridat --no-data-init radek poak vypada -o"$(BINDIR_)$(TARGETBASE).$(TARGETSUFFIX)" -Map="$(BINDIR_)$(TARGETBASE).map" --report-mem --no-data-init a FAKT TO DATA NENULUJE !!!!!!!! */ // void uart_init(void); void T1init(); void T2init(); void eth_init(); //hlavní program ****************************************************************** void main (void) { int iii; // pocitatko pro cokoli pocitT2 = 16; /* s Vx se hybe opravdu jenom v main.c a testuji se v udp.c ** blok s pomchar pomchar = 0; if(!V0) pomchar = pomchar | 0x01; ..... if(!V3) pomchar = pomchar | 0x10; větve naprosto silene v enc28j60.h //větve - predelano pro Juranka #define V0 PORTBbits.RB1 #define V1 PORTBbits.RB2 #define V2 PORTBbits.RB3 #define V3 PORTBbits.RB4 #define V4 PORTBbits.RB5 // // #define LED PORTCbits.RC5 */ // po RESETu jsou vsechny INTERRUPTy disable - neni se tedy ceho bat cpu_init(); // inicializace procesoru pocitmin = MINUTODEN; if( (RCON & 0x0003) == 0x0003 ) { /* tohle je POR - Power Up Reset */ cosestalo[0] = 1; V0=0; V1=0; V2=0; V3=0; V4=0; // jedine tady vypinam vetve Vx !!!! data_OK=0; status=0xff; mamIPprotejsku = 0; // v polich rem_ip a rem_mac je platna adresa protejsku - prosel UDP paket maskaT2 = 0xff00; nastPR1 = DEFPR1; } // RCON 0001 1101 0010 0000 4.3V a WDT bezi ! -* bit 5 tedy 0x1D20 // RCON maska 101 0011 if(cosestalo[0] == 6) cosestalo[0] = 0; // pokud jsme normalne bezeli, byla tam 6 - TMR1 bezi v poradku if( !cosestalo[0]) { // po zapsani do vysilaci fronty bunku cosestalo[0] nuluji ! switch (RCON & 0x0053) { case 0x0001: cosestalo[0] = 2; // BOR reset break; case 0x0040: cosestalo[0] = 3; // SOFT reset break; case 0x0010: cosestalo[0] = 4; // WDT reset break; default: cosestalo[0] = 5; // neco jineho break; } } RCON = 0x1D20; //RCON = RCON & (~0x0503 ); for(iii = 0; iii<=MAXPOLMOD;iii++) { mindoak[iii] = 0xffff; stavvetve[iii] = 0x00; } T1init(); T2init(); eth_init(); // inicializace ethernetu enc28_phyreg_wr(PHLCON, 0x0880); // delay(100000); tak to mozna melo cekat 0,1 sec, ale fakt to neceka ! // je to truncated na 35636 mikro sec simulator rika 52ms // simulator 208ms pri 7.38MHz // pockej(9212); // 5 mili sec nesmi to prelezt 16582 - 14 bitu for(iii = 0; iii < 20; iii++ ) pockej(9212); // celkem 100 mili sec enc28_phyreg_wr(PHLCON, 0x0470); pocitT2 = 16; status=0xff; tcp_stat = 0; casjespravne = 0; OSCTUN = 1 ; /* 0d 1 do 7 se to postupne zrychluje az na +12 procent od -1, tedy 0x000f, do minus moc - 0x008 se to zpomaluje !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! POZOR !!!!!!!!!!! zavisle na kusu soucastky */ data_OK = 0; asm("CLRWDT"); //hlavní smyčka WDT ma periodu 16sec while(1) { asm("CLRWDT"); if(!pocitmin) { // 24 hodin neprislo nic od pocitace cosestalo[0] = 8; maskaT2 = 0x5550; while(1) ; // kousnu to a cekam na WDT reset } eth_proc(); /* zasadni procedura" odpovida na ARP dotazy, v procedure ip_in prijima data v promenne status zanecha informaci o tom, co se deje - je to v eth.c buffer unsigned char definovan v eth.c jeho delka #define BUFFER_SIZE 1248 je v eth.h - ??? neni to trochu moc ???? konstanty DATA_REQ a podobne jsou v ap.h udp_send zajisti kompletni vyslani paketu, doda tam pole cosestalo , v cosestalo je i cas prvni byte je druha polozka udp_send, dale stav vetvi a souhlas s casem, od buffer[2] je cosestalo */ switch(status){ case DATA_REQ: udp_send(buffer,DATA_REQ,1); status=0xff; break; case DATA_ACK: udp_send(buffer,DATA_ACK,1); status=0xff; break; case CLK_ACK: udp_send(buffer,CLK_ACK,1); status=0xff; break; // odpoved na CLK_SYNC case CLK_REQ: udp_send(buffer,CLK_SEND,1); status=0xff; break; case POSILAMDEFPR1: udp_send(buffer,POSILAMDEFPR1,1); status=0xff; break; case POSILAMPR1: udp_send(buffer,POSILAMPR1,1); status=0xff; break; case ACK_SET_RP1: udp_send(buffer,ACK_SET_RP1,1); status=0xff; break; default: status = 0xff; } /* od switch */ // if(tcp_stat){ if(0){ unsigned char tcp_len = 0; unsigned char ip_len = 0; unsigned int http_len = 0; struct TCP_header *tcp; tcp_stat=0; tcp = (struct TCP_header *)&buffer[34]; switch (buffer[TCP_FLAGS]) { // tcp flags... case TF_SYN: // SYN tcp_send(0, buffer, 0x12,0,0); break; case (TF_ACK | TF_PSH): // PSH+ACK tcp_len = ((buffer[TCP_HEDLEN]) >> 4) * 4; ip_len = (buffer[IP_HEDLEN] & 0x0F) * 4; http_len = (((unsigned int)buffer[IP_TOTLEN_H] << 8) + buffer[IP_TOTLEN_L]) - tcp_len - ip_len; http ((tcp_len + ip_len + 14), http_len, buffer); break; case TF_ACK: // ACK ack_received(0x10); break; case TF_RST: // RST tcp_res(); break; case (TF_FIN | TF_ACK): // FIN+ACK ack_received(0x11); break; case (TF_FIN | TF_PSH | TF_ACK): // FIN + PSH + ACK tcp_res(); break; } } } /* od while (1) */ } /* od main */ void T1init() { /* vola se v cpu_init */ nastPR1 = DEFPR1; PR1=DEFPR1; /* !!!!!! pokud tohle zmenis, musis zmenit take ip.c ip_in case CLK_SYNC: */ asm("clr TMR1"); T1CON=0x8020; /* 1000 0000 0010 0000 - 10 na bitech 54 - delime 64 8MHz /4 = 2MHz 31250 to musime delit */ INTCON1bits.NSTDIS=1; IEC0bits.T1IE=1; } void T2init() { /* vola se v cpu_init delime 256 8000000 /4 /256 /16 a perioda bliku bude 2 sec */ // PR2=977; dame to trochu rychleji PR2 = 960; T2CON=0x8030; asm("clr TMR2"); INTCON1bits.NSTDIS=1; IEC0bits.T2IE=1; } /* inicializace procesoru */ void cpu_init (void) { // asm("MOV #OSCCONL,w1"); // asm("MOV #0x46,w2"); // asm("MOV #0x57,w3"); // asm("MOV.b w2,[w1]"); // asm("MOV.b w3,[w1]"); // asm("BSET.b [w1],#6"); // bity POSC - postscaller v konfig. registu ???? kolik ato deli // tad yto yapinalo nejakou delicku - vyhazuji PMD1 = 0xe7ff; // 1110 0111 1111 1111 zapinam jen TMR1 a TMR2 PMD2 = 0xffff; // zapinaji se v odpovidajicim podprobrami _init ADPCFG= 0xffff; //převodník vypnout TRISB = 0xfc41; // 27.5.2014 po kontrole deskz upraveno TRISC = 0xdfff; TRISD = 0xffff; TRISF = 0xfff; // init programy se volaji az tady !!!! } //přerušení od TMR2 void __attribute__((interrupt, shadow, auto_psv)) _T2Interrupt(void) { IFS0bits.T2IF=0; //nulování požadavkového bitu přerušení pocitT2--; LEDCERV = (maskaT2>>pocitT2) & 0x01; // LEDka je RC13 if( !pocitT2 ){ pocitT2 = 16; T2CONbits.TON = 0; /* a na konci cyklu vypinam */ } } // od void interrupt //přerušení od TMR1 void __attribute__((interrupt, shadow, auto_psv)) _T1Interrupt(void) { if( ! T2CONbits.TON ) { TMR2 = 0; T2CONbits.TON = 1; /* kdyz TMR2 stoji, tak poustim TMR2 aby bliknuto LED souhlasilo s casem TMR1 */ } IFS0bits.T1IF=0; //nulování požadavkového bitu přerušení sekundy++; //sekundy se inkrementují PR1 = nastPR1; if((cosestalo[0] == 0) ||(cosestalo[0] == 6 )) { cosestalo[6] = sekundy & 0xff; // je to little endian cosestalo[7] = (sekundy >> 8) & 0xff ; cosestalo[8] = (sekundy >> 16) & 0xff ; cosestalo[9] = (sekundy >> 24) & 0xff ; cosestalo[0] = 6; } if( !(sekundy % 60) ){ maskaT2 = 0xc000; posunminutu(); nastavvetve(); // setresto(); nastavvetve uz obsahuje setresto pocitmin--; } } // od void interrupt TMR1 void posunminutu(void){ int i; for(i=0; i<= MAXPOLMOD; i++) { if(mindoak[i]== 0xffff ) break; mindoak[i]--; } } void nastavvetve(void){ unsigned char stav; unsigned char cislov; int i; maskaT2 = 0x55ff; // tady se da nastavit, co odpovida 1 na 7. bitu stavvetve // predelano pro Juranka - 1 = DEN, topit while(!mindoak[0] ) { stav = 0; if(stavvetve[0] & 0x80) stav = 1; cislov = stavvetve[0] & 0x0f; switch ( cislov) { case 0: V0 = stav; break; case 1: V1 = stav; break; case 2: V2 = stav; break; case 3: V3 = stav; break; case 4: V4 = stav; break; default: if ( ! cosestalo[0]) cosestalo[0] = 9 ; /* spatne cislo vetve */ } /* od SWITCH */ for(i=0;i