¿Cómo hacer que funcione un ENC28J60?

2

Para empezar: sí, sé que estoy a punto de reinventar la rueda con la siguiente tarea por delante.

Quiero crear mi propia biblioteca para el ENC28J60 para un AVR (ATMEGA1284P).

Así que he estado navegando por la red durante meses, ahora he progresado bastante bien, pero ahora estoy golpeando las paredes a menudo.

Este es mi diseño de red. Para el primer paso, solo intento comunicar uC1 con PC1 a través de Router1.

El paso final sería tener comunicación entre PC1 y uC2.

Tobby Jaffey en su respuesta aquí ha desglosado los pasos de cómo hacer que el chip funcione.

  

Ahora, con la ayuda de su lista, les mostraré dónde estoy a la derecha.   ahora.

     

Si estuviera emprendiendo este proyecto, lo desglosaría así:

     
  1. Escriba un programa para hacer parpadear un LED
  2.   
  3. Extiéndalo para enviar y recibir bytes en la UART (esto será invaluable para la depuración)
  4.   
  5. Extiéndalo para usar la interfaz SPI, verificando las formas de onda con un analizador de alcance / lógica
  6.   
  7. Conecte el ENC28J60 a la interfaz SPI, sin olvidar el chip   seleccione (dejaría la línea de interrupción desconectada por ahora)
  8.   
  9. Extienda el software para leer desde el registro de id / versión de chip y   verifica el resultado
  10.   
  11. Extienda el software para escribir en un registro y volver a leerlo
  12.   
  13. Enchufe un cable Ethernet, verifique que el estado del enlace Ethernet sea   cambio en los registros ENC28J60s
  14.   
  15. Conecte la línea de interrupción ENC28J60 a una entrada en mi   Microcontrolador y prueba (habilita interrupciones en cambios de estado de enlace).   parecería una buena prueba)
  16.   

Ahora, estoy seguro de que mi hardware funciona.

     
  1. Traiga las funciones del controlador de Ethernet (accesos a registros de 16 bits,   Acceso, etc) en mi proyecto y verifíquelos accediendo a   registros
  2.   
  3. Configure el ENC28J60 para el modo promiscuo y el volcado entrante   paquetes al UART, verifíquelos comparándolos con Wireshark / tcpdump
  4.   
  5. Mira cómo el autor original manejó el tiempo, en particular cómo   regularmente sondean la pila IP y el controlador de Ethernet. Implementar   un bucle principal para atender estas rutinas
  6.   
  7. Tire del resto de la pila de IP en la parte superior de la capa de mi controlador
  8.   
  9. Configurar la pila de IP para mi red (comenzando con una IP estática)
  10.   
  11. Ping it
  12.   
  13. Coloque el resto del código de la aplicación (servidor web / etc.) en mi   proyecto.
  14.   

Parpadeo de un LED no es un problema. Estoy usando la lógica XOR para ello. Funciona para mí.

La comunicación a través de UART es solo de una manera desde uC a PC. Estoy desplegando datos en HyperTerminal. Por cada nuevo fragmento / parte de código no probado, estoy enviando una línea de texto UART como a PC.

void ENC28J60_SRC(void)             // System Reset Command (Soft Reset) 
{
    ENC28J60_CS();                  // Enable
    SPIWR(0xFF);
    ENC28J60_DS();                  // Disable
    _delay_ms(50);

while(!(ENC28J60_RD(ESTAT) & CLKRDY))
{
    USART0_TX_String("waiting for CLKRDY");
}
USART0_TX_String("CLKRDY is Ready");
}

La comunicación SPI funciona, pero no se probó con un analizador de alcance o logis. He estado enviando y recibiendo datos desde el ENC28J60 sin ningún problema. Así que podemos verificar la parte de los registros de lectura y escritura, así como el chip / id de lectura que tiene el valor de 6, por lo que el chip es Rev.:B7

Después de configurar los registros PHY y enchufar el cable, los LED parpadean, pero aún no se aceptan datos. También he estado revisando el contador de paquetes. Siempre es 0.

La interrupción está habilitada solo para la recepción de paquetes. Nunca pasa al nivel lógico BAJO.

El hardware, como en el ENC28J60, es de la tienda, por lo que no es auto construido, los errores de conexión son menos probables. El panel de prueba ATMEGA1284P es de fabricación propia, conexiones probadas.

Mi inicialización ENC28J60 se ve así:

void ENC28J60_Init(void)
{
    USART0_TX_String("ENC28J60 Reset");
    USART0_TXD(13);
    USART0_TXD(10);
    ENC28J60_SRC();

    USART0_TX_String("RX Buffer Init");
    USART0_TXD(13);
    USART0_TXD(10);

    /*
    #define RXSTART         0x0000      0x0000      0   0       0   
    #define RXEND           4095        0x0FFF      15 255      4095
    #define TXSTART         (RXEND+1)   0x1000      16  0       4096
    #define TXEND           0x1FFF      0x1FFF      31 255      8191
    */

    // Init TX/RX Buffer    Datasheet Section 6.1
    ENC28J60_BANK_SEL(BANK0);
    ENC28J60_CS();
    SPIWR(WCR|ERDPTL);          //  
    SPIWR(RXSTART&0xFF);        //  ERDPTL      Buffer Read Pointer Low
    SPIWR(RXSTART>>8);          //  ERDPTH      Buffer Read Pointer High
    SPIWR(TXSTART&0xFF);        //  EWRPTL      Buffer Write Pointer Low
    SPIWR(TXSTART>>8);          //  EWRPTH      Buffer Write Pointer High
    SPIWR(TXSTART&0xFF);        //  ETXSTL      Transmit Buffer Start Low
    SPIWR(TXSTART>>8);          //  ETXSTH      Transmit Buffer Start High
    SPIWR(TXEND&0xFF);          //  ETXNDL      Transmit Buffer End Low
    SPIWR(TXEND>>8);            //  ETXNDH      Transmit Buffer High
    SPIWR(RXSTART&0xFF);        //  ERXSTL      Recive Buffer Start Low
    SPIWR(RXSTART>>8);          //  ERXSTH      Recive Buffer Start High
    SPIWR(RXEND&0xFF);          //  ERXNDL      Recive Buffer End Low
    SPIWR(RXEND>>8);            //  ERXNDH      Recive Buffer End High
    SPIWR(RXSTART&0xFF);        //  ERXRDPTL    Recive Buffer Read Pointer Low
    SPIWR(RXSTART>>8);          //  ERXRDPTH    Recive Buffer Read Pointer High
    SPIWR(RXSTART&0xFF);        //  ERXWRPTL    Recive Buffer Write Pointer Low
    SPIWR(RXSTART>>8);          //  ERXWRPTH    Recive Buffer Write Pointer High
    SPIWR(0x00);                //  EDMASTL     DMA Start Low
    SPIWR(0x00);                //  EDMASTH     DMA Start High
    SPIWR(0x00);                //  EDMANDL     DMA End Low
    SPIWR(0x00);                //  EDMANDH     DMA End High
    SPIWR(0x00);                //  EDMADSTL    DMA Destination Low
    SPIWR(0x00);                //  EDMADSTH    DMA Destination High
    SPIWR(0x00);                //  EDMACSL     DMA Checksum Low
    SPIWR(0x00);                //  EDMACSH     DMA Checksum High
    ENC28J60_DS();

    USART0_TX_String("BANK1");
    USART0_TXD(13);
    USART0_TXD(10);

    /*
    USART0_TX_String("BANK1 EPMM Init");
    USART0_TXD(13);
    USART0_TXD(10);

    ENC28J60_BANK_SEL(BANK1);
    ENC28J60_CS();
    SPIWR(WCR|EPMM0);
    SPIWR(0x00);                    //  EPMM0
    SPIWR(0x00);                    //  
    SPIWR(0x00);                    //  
    SPIWR(0x00);                    //  
    SPIWR(0x00);                    //  
    SPIWR(0x00);                    //  
    SPIWR(0x00);                    //  
    SPIWR(0x00);                    //  EPMM7
    SPIWR(0x00);                    //  EPMCSL
    SPIWR(0x00);                    //  EPMCSH
    SPIWR(DUMMY);
    SPIWR(DUMMY);
    SPIWR(0x00);                    //  EPMOL
    SPIWR(0x00);                    //  EPMOH
    ENC28J60_DS();

    ENC28J60_BANK_SEL(BANK1);
    ENC28J60_CS();
    SPIWR(WCR|ERXFCON);
    SPIWR(0xA3);                    //  ERXFCON
    ENC28J60_DS();
    */

    USART0_TX_String("MAC Init");
    USART0_TXD(13);
    USART0_TXD(10);

    ENC28J60_BANK_SEL(BANK2);
    ENC28J60_CS();
    SPIWR(WCR|MACON1);
    SPIWR(MARXEN|TXPAUS|RXPAUS);            //  MACON1
    SPIWR(DUMMY);                           //  MACON2?
    SPIWR(PADCFG0|FRMLNEN|TXCRCEN|FULDPX);  //  MACON3
    SPIWR(DEFER);                           //  MACON4
    SPIWR(0x15);                            //  MABBIPG
    SPIWR(DUMMY);                           //  
    SPIWR(0x12);                            //  MAIPGL
    SPIWR(0x00);                            //  MAIPGH
    SPIWR(0x00);                            //  MACLCON1
    SPIWR(0x00);                            //  MACLCON2
    SPIWR(0xEE);                            //  MAMXFLL     MAC MaXimum Frame Length is set to 0x0500 or 1280byte (0x05EE 1518byte)
    SPIWR(0x05);                            //  MAMXFLH
    ENC28J60_DS();

    USART0_TX_String("BANK3");
    USART0_TXD(13);
    USART0_TXD(10);

    // MAC Init         Datasheet Section 6.5
    ENC28J60_BANK_SEL(BANK3);
    ENC28J60_CS();
    SPIWR(WCR|MAADR5);
    SPIWR(myMAC[4]);                        //  MAC address 5
    SPIWR(myMAC[5]);                        //  MAC address 6
    SPIWR(myMAC[2]);                        //  MAC address 3
    SPIWR(myMAC[3]);                        //  MAC address 4
    SPIWR(myMAC[0]);                        //  MAC address 1
    SPIWR(myMAC[1]);                        //  MAC address 2
    ENC28J60_DS();

    USART0_TX_String("PHY Init");
    USART0_TXD(13);
    USART0_TXD(10);

    //  PHY Init            Datasheet Section 6.6
    ENC28J60_PHYWR(PHCON1,PDPXMD,0);                //  PHY in Full-Duplex Mode
    ENC28J60_PHYWR(PHLCON,0b00000010,0b00010010);   //  LED Init

    USART0_TX_String("Int Init");
    USART0_TXD(13);
    USART0_TXD(10);
    ENC28J60_BANK_SEL(BANK0);
    ENC28J60_CS();
    SPIWR(BFS|EIE);                 //  
    SPIWR(INTIE|PKTIE);             //  EIE
    ENC28J60_DS();

    USART0_TX_String("ECON1.RXEN Enabled");
    ENC28J60_CS();
    SPIWR(BFS|ECON1);   
    SPIWR(RXEN);                    //  ECON1
    ENC28J60_DS();
}

Problemas de sofar:

No se pudo establecer el bit ECON1.RXEN. De alguna manera se lo arregló, no sé lo que hizo. No obteniendo ningún dato en el búfer recive. El LED parpadea en la actividad de RX.

¿Tal vez sea útil quitar el cheque CRC en el filtro?

Actualización: 2014.08.16 23:25

¡Sí! Bajar el cheque de CRC ayudó. Ahora puedo recibir paquetes.

    
pregunta Balázs Bagi

0 respuestas

Lea otras preguntas en las etiquetas