FITkit
Fakulta informačních technologií

enc28j60_spi.c

Zobrazit dokumentaci tohoto souboru.
00001 /*******************************************************************************
00002    enc28j60_spi.c: Knihovna funkcí pro komunikaci s ENC28J60
00003    Copyright (C) 2010 Brno University of Technology,
00004                       Faculty of Information Technology
00005    Author(s): Martin Musil <xmusil34 AT fit.vutbr.cz>
00006 
00007    LICENSE TERMS
00008 
00009    Redistribution and use in source and binary forms, with or without
00010    modification, are permitted provided that the following conditions
00011    are met:
00012    1. Redistributions of source code must retain the above copyright
00013       notice, this list of conditions and the following disclaimer.
00014    2. Redistributions in binary form must reproduce the above copyright
00015       notice, this list of conditions and the following disclaimer in
00016       the documentation and/or other materials provided with the
00017       distribution.
00018    3. All advertising materials mentioning features or use of this software
00019       or firmware must display the following acknowledgement:
00020 
00021         This product includes software developed by the University of
00022         Technology, Faculty of Information Technology, Brno and its
00023         contributors.
00024 
00025    4. Neither the name of the Company nor the names of its contributors
00026       may be used to endorse or promote products derived from this
00027       software without specific prior written permission.
00028 
00029    This software or firmware is provided ``as is'', and any express or implied
00030    warranties, including, but not limited to, the implied warranties of
00031    merchantability and fitness for a particular purpose are disclaimed.
00032    In no event shall the company or contributors be liable for any
00033    direct, indirect, incidental, special, exemplary, or consequential
00034    damages (including, but not limited to, procurement of substitute
00035    goods or services; loss of use, data, or profits; or business
00036    interruption) however caused and on any theory of liability, whether
00037    in contract, strict liability, or tort (including negligence or
00038    otherwise) arising in any way out of the use of this software, even
00039    if advised of the possibility of such damage.
00040 
00041    $Id$
00042 
00043 *******************************************************************************/ 
00044 
00045 #include "enc28j60_spi.h"
00046 #include "enc28j60_arp.h"
00047 #include "fspi.h"
00048 
00049 
00050 unsigned char current_bank = 0;
00051 extern unsigned char local_mac[MAC_LEN];
00052 extern unsigned int rx_next_pkt;
00053 char enc_initialized = 0;
00057 char ENC28J60_init(){
00058 
00059         FSPI_Init(1); //14MHz SPI
00060         delay_ms(10);   
00061         control_reg_write(0x01); //EN = 1, RST=0
00062         delay_ms(10);
00063         control_reg_write(0x03); //EN = 1, RST=1
00064         delay_ms(10);
00065 
00066         enc_reset();
00067         delay_ms(10);
00068         
00069         bf_clear(ECON1, ECON1_RXEN);
00070                 
00071         select_bank(0);
00072         write_reg16(ERXST,RX_START);            //zacatek RX bufferu
00073         write_reg16(ERXND,RX_END);                      //konec RX bufferu
00074         write_reg16(ERXRDPT,RX_END);            //ptr pro cteni z bufferu
00075         write_reg16(ERDPT,RX_START);            //ptr pro zapis do bufferu
00076 
00077         arp_table_clear();
00078         rx_next_pkt = RX_START;
00079 
00080         bf_set(ECON2, ECON2_AUTOINC);           //autoinkrementace buffer-pointeru a 
00081         bf_clear(ECON2,ECON2_PWRSV);            //probuzeni
00082         delay_ms(10);                                           //cekani na ustaleni oscilatoru
00083 
00084 
00085         select_bank(1);
00086         write_reg8(ERXFCON, 0xA1);                      //vstupni filter - uni/broadcast
00087 
00088         select_bank(2);                                         //banka 2
00089         //inicializace MAC
00090         write_reg8(MACON2,0);
00091         write_reg8(MACON1,MACON1_MARXEN | MACON1_TXPAUS | MACON1_RXPAUS);       //nastaveni TXPAUS, RXPAUS, MARXEN
00092         write_reg8(MACON3,MACON3_PADCFG0 | MACON3_TXCRCEN | MACON3_FULDPX);     //nastaveni PADCFG, TXCRCEN, FULDPX
00093         write_reg8(MACON4,MACON4_DEFER);                //nastaveni DEFER
00094         
00095         write_reg16(MAMXFL,0x05EE);                     //max. velikost ramce 1518B
00096         write_reg8(MABBIPG,0x15);                                       //Back-to-Back Inter-Packet Gap - pro full duplex
00097         write_reg8(MAIPGL, 0x12);
00098         
00099         write_phy_reg16(PHCON1,PHCON1_PDPXMD);  //pro full duplex
00100                 
00101         write_phy_reg16(PHIE, PHIE_PLNKIE | PHIE_PGEIE);
00102         read_phy_reg16(PHIR);
00103 
00104         select_bank(3);                                         //banka 3
00105         write_reg8(MAADR1, local_mac[0]);       //nastaveni MAC adresy
00106         write_reg8(MAADR2, local_mac[1]);
00107         write_reg8(MAADR3, local_mac[2]);
00108         write_reg8(MAADR4, local_mac[3]);
00109         write_reg8(MAADR5, local_mac[4]);
00110         write_reg8(MAADR6, local_mac[5]);
00111 
00112         write_reg8(EIE,0);                                      //zakazani preruseni
00113         bf_set(ECON1, ECON1_RXEN);                      //povoleni vstupu
00114 
00115         enc_initialized = 1;
00116 
00117 return 0;
00118 }
00119 
00120 
00121 
00125 inline unsigned char read_reg8(unsigned char addr, unsigned char read_dummy){
00126         
00127         unsigned char data;
00128 
00129         FSPI_set_CS(0); //CS -> 0
00130         FSPI_write_wait(ENC_RCR | addr);
00131 
00132         if (read_dummy)
00133                 FSPI_write_wait(DUMMY);
00134         
00135         data = FSPI_write_wait_read(DUMMY);
00136         FSPI_set_CS(1); //CS -> 1
00137 
00138    return data;
00139 }
00140 
00144 inline unsigned int read_reg16(unsigned char addr, unsigned char read_dummy){
00145 
00146 return read_reg8(addr,read_dummy) | (read_reg8(addr+1,read_dummy) << 8);
00147 }
00148 
00152 inline void write_reg8(unsigned char addr, unsigned char data){
00153         FSPI_set_CS(0); //CS -> 0
00154         FSPI_write_wait(ENC_WCR | addr);
00155         FSPI_write_wait(data);
00156         FSPI_set_CS(1); //CS -> 1
00157 return;
00158 }
00159 
00163 inline void write_reg16(unsigned char addr, unsigned int data){
00164                 
00165         write_reg8(addr,(char)data);
00166         write_reg8(addr+1,(char)(data>>8));
00167         
00168 }
00169 
00173 inline int read_phy_reg16(unsigned char addr){
00174 
00175         select_bank(2); 
00176         write_reg8(MIREGADR, addr);
00177         write_reg8(MICMD, MICMD_MIIRD);
00178         
00179         while(read_reg8(MISTAT,DUMMY) & MISTAT_BUSY);
00180         write_reg8(MICMD, 0);
00181         
00182 return read_reg16(MIRD,DUMMY);                  
00183 }
00184 
00188 inline void write_phy_reg16(unsigned char addr, unsigned int data){
00189         
00190         select_bank(2);
00191         write_reg8(MIREGADR, addr);
00192         write_reg16(MIWR, data);
00193 
00194 return;
00195 }
00196 
00200 inline void bf_set(unsigned char addr, unsigned char mask){
00201    FSPI_set_CS(0); //CS -> 0
00202    FSPI_write_wait(ENC_BFS | addr);
00203    FSPI_write_wait(mask);
00204    FSPI_set_CS(1); //CS -> 1
00205 }
00206 
00210 inline void bf_clear(unsigned char addr, unsigned char mask){
00211    FSPI_set_CS(0); //CS -> 0
00212    FSPI_write_wait(ENC_BFC | addr);
00213    FSPI_write_wait(mask);
00214    FSPI_set_CS(1); //CS -> 1
00215 }
00216 
00220 inline void enc_reset(){
00221    FSPI_set_CS(0); //CS -> 0
00222    FSPI_write_wait(ENC_RST);
00223    FSPI_set_CS(1); //CS -> 1
00224    enc_initialized = 0;
00225 }
00226 
00230 inline void select_bank(unsigned char bank){
00231         
00232         if(bank < 4 && current_bank != bank){
00233                 current_bank = bank;
00234                 bf_clear(ECON1, 0x03);
00235                 bf_set(ECON1, bank);
00236         }
00237 return;
00238 }
00239 
00240 
00241 //******************************************
00242 //fce cteni/zapis do bufferu
00243 //******************************************
00244 
00248 unsigned char spi_getc(){
00249         
00250         unsigned char data;
00251 
00252         FSPI_set_CS(0); //CS -> 0
00253         FSPI_write_wait(ENC_RBM);
00254         data = FSPI_write_wait_read(DUMMY);
00255         FSPI_set_CS(1); //CS -> 1
00256 
00257    return data;
00258 }
00259 
00263 unsigned int spi_read(void* ptr, unsigned int length){
00264 
00265         if(ptr != NULL){                                                //cteni do pole
00266                 unsigned char* ptr_temp = ptr;
00267         
00268                 FSPI_set_CS(0); //CS -> 0
00269                 FSPI_write_wait(ENC_RBM);
00270         
00271                 while(length--)
00272                         *ptr_temp++ = FSPI_write_wait_read(DUMMY);
00273         
00274                 FSPI_set_CS(1); //CS -> 1
00275         }
00276         else{                                                                   //zahazovani
00277                 FSPI_set_CS(0); //CS -> 0
00278                 FSPI_write_wait(ENC_RBM);
00279         
00280                 while(length--)
00281                         FSPI_write_wait_read(DUMMY);
00282         
00283                 FSPI_set_CS(1); //CS -> 1
00284         }
00285 return length;
00286 }
00287 
00292 unsigned int spi_getline(void* ptr, unsigned int max_length){
00293 
00294         unsigned char c;
00295         unsigned int countdown = max_length;
00296 
00297         if(ptr != NULL){                                                //cteni do pole
00298                 unsigned char* ptr_temp = ptr;
00299         
00300                 FSPI_set_CS(0); //CS -> 0
00301                 FSPI_write_wait(ENC_RBM);
00302         
00303         
00304                 while(countdown != 0){
00305                         c = FSPI_write_wait_read(DUMMY);
00306                         *ptr_temp++ = c;
00307                         countdown--;
00308                         
00309                         if(c == 10)                                             // 10 - Line Feed
00310                                 break;
00311                 }
00312                 FSPI_set_CS(1); //CS -> 1
00313         }
00314         else{                                                                   //zahazovani
00315                 FSPI_set_CS(0); //CS -> 0
00316                 FSPI_write_wait(ENC_RBM);
00317         
00318                 while(countdown != 0){
00319                         c = FSPI_write_wait_read(DUMMY);
00320                         countdown--;
00321                         
00322                         if(c == 10)                                             // 10 - Line Feed
00323                                 break;
00324                 }
00325                 FSPI_set_CS(1); //CS -> 1
00326         }
00327         
00328 return max_length - countdown;
00329 }
00330 
00334 void spi_putc(unsigned char c){
00335 
00336         FSPI_set_CS(0); //CS -> 0
00337         FSPI_write_wait(ENC_WBM);
00338         FSPI_write_wait(c);
00339 
00340         FSPI_set_CS(1); //CS -> 1
00341 
00342 }
00343 
00347 void spi_write(void* ptr, unsigned int length){
00348         
00349         unsigned char* ptr_temp = ptr;
00350         
00351         FSPI_set_CS(0); //CS -> 0
00352         FSPI_write_wait(ENC_WBM);
00353         
00354         while(length--)
00355                 FSPI_write_wait(*ptr_temp++);
00356         
00357         FSPI_set_CS(1); //CS -> 1
00358 
00359 }
00360 
00364 void spi_fill(unsigned char value, unsigned int length){
00365         
00366         FSPI_set_CS(0); //CS -> 0
00367         FSPI_write_wait(ENC_WBM);
00368         
00369         while(length--)
00370                 FSPI_write_wait(value);
00371         
00372         FSPI_set_CS(1); //CS -> 1       
00373 }
00374 
00378 inline unsigned char link_change(){
00379         
00380         if((read_reg8(EIR,NO_DUMMY) & EIR_LINKIF) > 0){
00381                 read_phy_reg16(PHIR);
00382                 return 1;
00383         }
00384 
00385 return 0;       
00386 }
00387 
00391 inline unsigned char link_up(){
00392         
00393         //read_phy_reg16(PHIR);                 //smazani priznaku zmeny linky
00394         
00395         if((read_phy_reg16(PHSTAT2) & PHSTAT2_LSTAT) == 0 ){            //kabel odpojen
00396                 return 0;
00397         }
00398         
00399 return 1;
00400 }
00401