quarta-feira, 16 de junho de 2010

Ethernet 8051 1º Passo

Neste blog, eu gostaria de compartilhar alguns conhecimentos com os amantes da prataforma 80C51. A idéia é conectar este micro com o controlador ethernet da microchip ENC28J60. Neste exemplo nós vamos abrir uma pagina web, gravada dentro do micro, e através desta página vamos ligar e desligar um led.

O ENC28J60 possui ótimas caracteristicas para quem quer aprender a conectar o 80C51 na Ethernet. Ele possui uma interface de comunicação muito conhecida, protocolo SPI. Ele trabalha com sistemas de 3.3V, mas pode ser facilmente adaptado para sistemas de niveis TTL, desde que as suas saídas tenham chips CMOS com nivel TTL, veja página 8 do data sheet.

Esquema no Proteus


Neste esquema, eu estou utilizando o AT89C51 com uma RAM 6264, neste projeto é necessário ter memória disponivel para trabalhar com a pilha TCP-IP, talves se você tiver um outro modelo de micro com memória EEPROM de 2K a RAM poderá ser descartada. Vamos discutir sobre este assunto.
Eu não gostaria de discutir neste blog sobre inicialização de LCD, protocolo SPI e escrita na memória RAM externa, vamos direto a inicialização do controlador ENC28J60. Qualquer sugestão por favor é só comentar e eu coloco aqui no blog.
A memória ram estática do ENC28J60 é dividida em três partes:
-Control Registers;
-Ethernet buffer;
-PHY registers;
O Control Registers é responsavel pela configuração e controle do ENC28J60.
Ethernet buffer contem os pacotes de transmissão e recebimento.
PHY registers é responsavel pela configuração e controle do módulo PHY do ENC.

Abaixo estão as definições de todos os registradores e operações ENC28J60. Vamos salvar este arquivo como ENC28J60.h.

#ifndef ENC28J60_H_
#define ENC28J60_H_


#define ADDR_MASK 0x1F //mascara de endereços
#define BANK_MASK 0x60 //mascara do Banco de registradores

// Estes são comuns nos bancos de registradores
#define EIE 0x1B
#define EIR 0x1C
#define ESTAT 0x1D
#define ECON2 0x1E
#define ECON1 0x1F

// Banco 0
#define ERDPTL (0x00|0x00)
#define ERDPTH (0x01|0x00)
#define EWRPTL (0x02|0x00)
#define EWRPTH (0x03|0x00)
#define ETXSTL (0x04|0x00)
#define ETXSTH (0x05|0x00)
#define ETXNDL (0x06|0x00)
#define ETXNDH (0x07|0x00)
#define ERXSTL (0x08|0x00)
#define ERXSTH (0x09|0x00)
#define ERXNDL (0x0A|0x00)
#define ERXNDH (0x0B|0x00)
#define ERXRDPTL (0x0C|0x00)
#define ERXRDPTH (0x0D|0x00)
#define ERXWRPTL (0x0E|0x00)
#define ERXWRPTH (0x0F|0x00)
#define EDMASTL (0x10|0x00)
#define EDMASTH (0x11|0x00)
#define EDMANDL (0x12|0x00)
#define EDMANDH (0x13|0x00)
#define EDMADSTL (0x14|0x00)
#define EDMADSTH (0x15|0x00)
#define EDMACSL (0x16|0x00)
#define EDMACSH (0x17|0x00)

// Banco 1
#define EHT0 (0x00|0x20)
#define EHT1 (0x01|0x20)
#define EHT2 (0x02|0x20)
#define EHT3 (0x03|0x20)
#define EHT4 (0x04|0x20)
#define EHT5 (0x05|0x20)
#define EHT6 (0x06|0x20)
#define EHT7 (0x07|0x20)
#define EPMM0 (0x08|0x20)
#define EPMM1 (0x09|0x20)
#define EPMM2 (0x0A|0x20)
#define EPMM3 (0x0B|0x20)
#define EPMM4 (0x0C|0x20)
#define EPMM5 (0x0D|0x20)
#define EPMM6 (0x0E|0x20)
#define EPMM7 (0x0F|0x20)
#define EPMCSL (0x10|0x20)
#define EPMCSH (0x11|0x20)
#define EPMOL (0x14|0x20)
#define EPMOH (0x15|0x20)
#define EWOLIE (0x16|0x20)
#define EWOLIR (0x17|0x20)
#define ERXFCON (0x18|0x20)
#define EPKTCNT (0x19|0x20)

// Banco 2
#define MACON1 (0x00|0x40|0x80)
#define MACON2 (0x01|0x40|0x80)
#define MACON3 (0x02|0x40|0x80)
#define MACON4 (0x03|0x40|0x80)
#define MABBIPG (0x04|0x40|0x80)
#define MAIPGL (0x06|0x40|0x80)
#define MAIPGH (0x07|0x40|0x80)
#define MACLCON1 (0x08|0x40|0x80)
#define MACLCON2 (0x09|0x40|0x80)
#define MAMXFLL (0x0A|0x40|0x80)
#define MAMXFLH (0x0B|0x40|0x80)
#define MAPHSUP (0x0D|0x40|0x80)
#define MICON (0x11|0x40|0x80)
#define MICMD (0x12|0x40|0x80)
#define MIREGADR (0x14|0x40|0x80)
#define MIWRL (0x16|0x40|0x80)
#define MIWRH (0x17|0x40|0x80)
#define MIRDL (0x18|0x40|0x80)
#define MIRDH (0x19|0x40|0x80)

// Banco 3
#define MAADR1 (0x00|0x60|0x80)
#define MAADR0 (0x01|0x60|0x80)
#define MAADR3 (0x02|0x60|0x80)
#define MAADR2 (0x03|0x60|0x80)
#define MAADR5 (0x04|0x60|0x80)
#define MAADR4 (0x05|0x60|0x80)
#define EBSTSD (0x06|0x60)
#define EBSTCON (0x07|0x60)
#define EBSTCSL (0x08|0x60)
#define EBSTCSH (0x09|0x60)
#define MISTAT (0x0A|0x60|0x80)
#define EREVID (0x12|0x60)
#define ECOCON (0x15|0x60)
#define EFLOCON (0x17|0x60)
#define EPAUSL (0x18|0x60)
#define EPAUSH (0x19|0x60)

// PHY registradores
#define PHCON1 0x00
#define PHSTAT1 0x01
#define PHHID1 0x02
#define PHHID2 0x03
#define PHCON2 0x10
#define PHSTAT2 0x11
#define PHIE 0x12
#define PHIR 0x13
#define PHLCON 0x14

// ENC28J60 ERXFCON definição de BIT
#define ERXFCON_UCEN 0x80
#define ERXFCON_ANDOR 0x40
#define ERXFCON_CRCEN 0x20
#define ERXFCON_PMEN 0x10
#define ERXFCON_MPEN 0x08
#define ERXFCON_HTEN 0x04
#define ERXFCON_MCEN 0x02
#define ERXFCON_BCEN 0x01

// ENC28J60 EIE definição de BIT
#define EIE_INTIE 0x80
#define EIE_PKTIE 0x40
#define EIE_DMAIE 0x20
#define EIE_LINKIE 0x10
#define EIE_TXIE 0x08
#define EIE_WOLIE 0x04
#define EIE_TXERIE 0x02
#define EIE_RXERIE 0x01

// ENC28J60 EIR definição de BIT
#define EIR_PKTIF 0x40
#define EIR_DMAIF 0x20
#define EIR_LINKIF 0x10
#define EIR_TXIF 0x08
#define EIR_WOLIF 0x04
#define EIR_TXERIF 0x02
#define EIR_RXERIF 0x01

// ENC28J60 ESTAT definição de BIT
#define ESTAT_INT 0x80
#define ESTAT_LATECOL 0x10
#define ESTAT_RXBUSY 0x04
#define ESTAT_TXABRT 0x02
#define ESTAT_CLKRDY 0x01

// ENC28J60 ECON2 definição de BIT
#define ECON2_AUTOINC 0x80
#define ECON2_PKTDEC 0x40
#define ECON2_PWRSV 0x20
#define ECON2_VRPS 0x08

// ENC28J60 ECON1 definição de BIT
#define ECON1_TXRST 0x80
#define ECON1_RXRST 0x40
#define ECON1_DMAST 0x20
#define ECON1_CSUMEN 0x10
#define ECON1_TXRTS 0x08
#define ECON1_RXEN 0x04
#define ECON1_BSEL1 0x02
#define ECON1_BSEL0 0x01

// ENC28J60 MACON1 definição de BIT
#define MACON1_LOOPBK 0x10
#define MACON1_TXPAUS 0x08
#define MACON1_RXPAUS 0x04
#define MACON1_PASSALL 0x02
#define MACON1_MARXEN 0x01

// ENC28J60 MACON2 definição de BIT
#define MACON2_MARST 0x80
#define MACON2_RNDRST 0x40
#define MACON2_MARXRST 0x08
#define MACON2_RFUNRST 0x04
#define MACON2_MATXRST 0x02
#define MACON2_TFUNRST 0x01

// ENC28J60 MACON3 definição de BIT
#define MACON3_PADCFG2 0x80
#define MACON3_PADCFG1 0x40
#define MACON3_PADCFG0 0x20
#define MACON3_TXCRCEN 0x10
#define MACON3_PHDRLEN 0x08
#define MACON3_HFRMLEN 0x04
#define MACON3_FRMLNEN 0x02
#define MACON3_FULDPX 0x01

// ENC28J60 MACON4 definição de BIT
#define MACON4_DEFER (1<<6)
#define MACON4_BPEN (1<<5)
#define MACON4_NOBKOFF (1<<4)

// ENC28J60 MICMD definição de BIT
#define MICMD_MIISCAN 0x02
#define MICMD_MIIRD 0x01

// ENC28J60 MISTAT definição de BIT
#define MISTAT_NVALID 0x04
#define MISTAT_SCAN 0x02
#define MISTAT_BUSY 0x01

// ENC28J60 PHY PHCON1 definição de BIT
#define PHCON1_PRST 0x8000
#define PHCON1_PLOOPBK 0x4000
#define PHCON1_PPWRSV 0x0800
#define PHCON1_PDPXMD 0x0100

// ENC28J60 PHY PHSTAT1 definição de BIT
#define PHSTAT1_PFDPX 0x1000
#define PHSTAT1_PHDPX 0x0800
#define PHSTAT1_LLSTAT 0x0004
#define PHSTAT1_JBSTAT 0x0002

// ENC28J60 PHY PHCON2 definição de BIT
#define PHCON2_FRCLINK 0x4000
#define PHCON2_TXDIS 0x2000
#define PHCON2_JABBER 0x0400
#define PHCON2_HDLDIS 0x0100

// ENC28J60 Packet Contro ldefinição de BIT
#define PKTCTRL_PHUGEEN 0x08
#define PKTCTRL_PPADEN 0x04
#define PKTCTRL_PCRCEN 0x02
#define PKTCTRL_POVERRIDE 0x01

// SPI operações
#define ENC28J60_READ_CTRL_REG 0x00
#define ENC28J60_READ_BUF_MEM 0x3A
#define ENC28J60_WRITE_CTRL_REG 0x40
#define ENC28J60_WRITE_BUF_MEM 0x7A
#define ENC28J60_BIT_FIELD_SET 0x80
#define ENC28J60_BIT_FIELD_CLR 0xA0
#define ENC28J60_SOFT_RESET 0xFF

#define RESET P1_1 //reset P1.1

#define MAX_TX_BUFFER 1500 //maximo TX buffer
#define MAX_RX_BUFFER 1500 //maximo RX buffer
#define RXSTART_INIT 0x0000
#define RXSTOP_INIT (8192-1500-1)
#define TXSTART_INIT (8192-1500)
#define TXSTOP_INIT 8192
#define MAX_FRAMELEN 1518 //cumprimento maximo do frame
static BYTE Enc28j60Bank;
static WORD next_packet_ptr;

extern BYTE enc28j60ReadOp(BYTE op, BYTE address);
extern void enc28j60WriteOp(BYTE op, BYTE address, BYTE dado);
extern void enc28j60SetBank(BYTE address);
extern BYTE enc28j60Read(BYTE address);
extern void enc28j60Write(BYTE address, BYTE dado);
extern WORD enc28j60_read_phyreg(BYTE address);
extern void enc28j60PhyWrite(BYTE address,WORD dado);
extern void enc28j60_init(void);
extern void enc28j60_packet_send (WORD length );
extern WORD enc28j60_packet_receive (WORD max_length );



#endif

Alguns defines não serão usados nas funções mesmo assim eu os coloquei.
Até a próxima postagem.

3 comentários:

  1. Muito boa Demiro, assim fica bem melhor para aprendermos.
    vlw pelo esforço.

    Weliton (SISAE)

    ResponderExcluir
  2. Boa tarde Deniro,

    Estava pesquisando no forum Asm51 e me interessei muito em aprender ethernet no 8051, vou apartir de agora acompanhar a evolução desse projeto e assim que possivel começar a fazer testes tbm para que eu possa trocar mais informaçoes com vc.

    Tenho uma duvida em relação a essa programação, essa biblioteca é algo padrao?

    Meu e-mail é: paulo.eduardojunior@hotmail.com

    Desde jah agradeço

    Paulo

    ResponderExcluir
  3. Olá Paulo,
    Você conhece a linguagem C?
    Qual o seu conhecimento em relação a este micro?

    ResponderExcluir