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.
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í:
- Escriba un programa para hacer parpadear un LED
- Extiéndalo para enviar y recibir bytes en la UART (esto será invaluable para la depuración)
- Extiéndalo para usar la interfaz SPI, verificando las formas de onda con un analizador de alcance / lógica
- Conecte el ENC28J60 a la interfaz SPI, sin olvidar el chip seleccione (dejaría la línea de interrupción desconectada por ahora)
- Extienda el software para leer desde el registro de id / versión de chip y verifica el resultado
- Extienda el software para escribir en un registro y volver a leerlo
- Enchufe un cable Ethernet, verifique que el estado del enlace Ethernet sea cambio en los registros ENC28J60s
- 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)
Ahora, estoy seguro de que mi hardware funciona.
- Traiga las funciones del controlador de Ethernet (accesos a registros de 16 bits, Acceso, etc) en mi proyecto y verifíquelos accediendo a registros
- Configure el ENC28J60 para el modo promiscuo y el volcado entrante paquetes al UART, verifíquelos comparándolos con Wireshark / tcpdump
- 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
- Tire del resto de la pila de IP en la parte superior de la capa de mi controlador
- Configurar la pila de IP para mi red (comenzando con una IP estática)
- Ping it
- Coloque el resto del código de la aplicación (servidor web / etc.) en mi proyecto.
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.