📄 cp2200.c
字号:
/*==========================================================
//CP220X芯片底层驱动,使用avr m16芯片,数据地址总线复用
//http://www.embed.org.cn hanembed@126.com
==========================================================*/
#include "board.h"
#include "reg.h"
#include "ne2000.h"
union NetNode myNode;
union netcard rxdnetbuf;
union netcard txdnetbuf;
void DelayIni(void)
{
TCCR0 = 0x00; //stop
TCNT0 = 0xE1; //set count
}
void delay_ms(unsigned char ms)
{
TCCR0 = 0x04; //start timer
while(ms--)
{
while((TIFR & (1<<TOV0)) != (1<<TOV0));
TIFR |= (1<<TOV0);
TCNT0 = 0xE1;
}
TCCR0 = 0x00; //stop
}
void portIni(void)
{
PORTB = MSK_CP; //high
DDRB = MSK_CP; //port out
PORTB = MSK_CP; //high
DDRD = ALE_CP; //ale out
PORTD |= INT_CP; //pull-up
DelayIni();
}
/*==========================================================
// function: write data to add
// Parameter: reg address
// data send data
// return: void
// date: 2006/11/9
// note: datasheet page 98
// write: han
==========================================================*/
void WriteReg(unsigned char add,unsigned char data)
{
DataPort = 0xFF;
DataOut = add;
PORTB &= ~CS_CP;
PORTD &= ~ALE_CP; //address send
PORTB &=~WR_CP;
DataOut = data;
PORTB |= WR_CP; //data send
PORTD |= ALE_CP;
PORTB |= CS_CP;
}
/*==========================================================
// function: write data to add
// Parameter: reg address
// data send data
// return: void
// date: 2006/11/9
// note: datasheet page 98
// write: han
==========================================================*/
unsigned char ReadReg(unsigned char reg)
{
unsigned char tmp;
DataPort = 0xFF;
DataOut = reg;
PORTB &= ~CS_CP;
PORTD &= ~ALE_CP; //address send
DataPort = 0x00; //ready to read
PORTB &= ~RD_CP;
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
tmp = DataIn; //data read
PORTB |= RD_CP;
PORTD |= ALE_CP;
PORTB |= CS_CP;
return tmp;
}
/*==========================================================
// function: Initializes the PHY using Autonegotiation
// Parameter: none
// return: unsigned char 0 on success, or the following error code
// date: 2006/11/9
// note: cp220x_core.c, datasheet page 88
// write: han
==========================================================*/
unsigned char PHY_Init(void)
{
unsigned char temp_char;
unsigned char i;
unsigned char retval = 0;
// Step 1: Disable the PHY
WriteReg(PHYCN,0x00);
// Step 2: Enable the PHY with link integrity test and auto-negotiation
// turned off
// A. Disable the Transmitter Power Save Option and Configure Options
WriteReg(TXPWR,0x80);
WriteReg(PHYCF,( SMSQ | JABBER | ADPAUSE | AUTOPOL ));
// B. Enable the Physical Layer
WriteReg(PHYCN,PHYEN);
// C. Wait for the physical layer to power up
delay_ms(10);
// D. Enable the Transmitter and Receiver
WriteReg(PHYCN,( PHYEN | PHYTXEN | PHYRXEN ));
// Step 3: Poll the Wake-on-Lan Interrupt
// A. Clear Interrupt Flags
temp_char = ReadReg(regINT1);
// B. Start a new timeout for 1.5 seconds
// C. Check for a signal wake
for(i = 0; i < 150; i++)
{
delay_ms(10);
temp_char = ReadReg(INT1RD);
if(temp_char & WAKEINT)
{
delay_ms(250);
break;
}
}
//--------------------------------------------------------------------------
// Physical Layer Initialization (Section 15.7 of CP220x Datasheet)
//--------------------------------------------------------------------------
// Step 1: Synchronization procedure implemented above
// Step 2: Disable the physical layer
WriteReg(PHYCN,0x00);
// Step 3: Configure the desired physical layer options including
// auto-negotiation and link integrity
WriteReg(PHYCF,( SMSQ | LINKINTG | JABBER | AUTONEG | ADPAUSE | AUTOPOL ));
// Step 4: Enable the physcial layer
// A. Enable the Physical Layer
WriteReg(PHYCN,PHYEN);
// B. Wait for the physical layer to power up
delay_ms(10);
// C. Enable the Transmitter and Receiver
// Auto-negotiation begins now
WriteReg(PHYCN,( PHYEN | PHYTXEN | PHYRXEN ));
// Step 5: Wait for auto-negotiation to complete
// Clear INT1 Interrupt Flags
temp_char = ReadReg(regINT1);
// Start a six second timeout
// Check for autonegotiation fail or complete flag
for(i = 0; i < 60; i++)
{
delay_ms(100);
temp_char = ReadReg(INT1RD);
// If Auto-Negotiation Completes/Fails, break
if(temp_char & (ANCINT | ANFINT))
{
break;
}
}
// Mask out all bits except for auto negotiation bits
temp_char = ReadReg(INT1RD);
temp_char &= (ANCINT | ANFINT);
// Check if Auto-Negotiation has FAILED
if(temp_char & ANFINT)
{
// Auto-Negotiation has failed
retval = LINK_ERROR;
}
else
// Check if Auto-Negotiation has PASSED
if(temp_char == ANCINT)
{
// Auto-Negotiation has passed
retval = 0;
// Enable Link LED and Activity LED
WriteReg(IOPWR,0x0C);
}
else
// Timeout Occured.
{
// Timeout
retval = LINK_ERROR;
}
return retval;
}
/*==========================================================
// function: Writes the value <mac_reg_data> to the indirect MAC register located at
// <mac_reg_offset>.
// Parameter: mac_reg_offset indirect register address
// mac_reg_data the data to write to mac_reg_offset
// return: void
// date: 2006/11/9
// note: cp220x_core.c, datasheet page 88
// write: han
==========================================================*/
void MAC_Write(unsigned char mac_reg_offset, unsigned int mac_reg_data)
{
// Step 1: Write the address of the indirect register to MACADDR.
WriteReg(MACADDR,mac_reg_offset);
// Step 2: Copy the contents of <mac_reg_data> to MACDATAH:MACDATAL
WriteReg(MACDATAH,(mac_reg_data >> 8)); // Copy High Byte
WriteReg(MACDATAL,(mac_reg_data & 0xFF)); // Copy Low Byte
// Step 3: Perform a write on MACRW to transfer the contents of MACDATAH:MACDATAL
// to the indirect MAC register.
WriteReg(MACRW,0);
return;
}
/*==========================================================
// function: Sets the current MAC address to the MAC address pointed to by <pMAC>.
// Parameter: pMAC pointer to a netnode
// return: void
// date: 2006/11/9
// note: cp220x_core.c, datasheet page 80
// write: han
==========================================================*/
void MAC_SetAddress(union NetNode *pMAC)
{
MAC_Write(MACAD0, pMAC->nodebytes.macwords[2]);
MAC_Write(MACAD1, pMAC->nodebytes.macwords[1]);
MAC_Write(MACAD2, pMAC->nodebytes.macwords[0]);
return;
}
/*==========================================================
// function: Initializes the MAC and programs the MAC address using the MAC address
// stored at address 0x1FFA in CP220x Flash.
// Parameter: none
// return: void
// date: 2006/11/9
// note: cp220x_core.c, datasheet page 78
// write: han
==========================================================*/
void MAC_Init(void)
{
unsigned char tmp;
// Check the duplex mode and perform duplex-mode specific initializations
tmp = ReadReg(PHYCN);
if(tmp & 0x10)
{
// The device is in full-duplex mode, configure MAC registers
// Padding is turned on.
MAC_Write(MACCF, 0x40B3);
MAC_Write(IPGT, 0x0015);
} else {
// The device is in half-duplex mode, configure MAC registers
// Padding is turned off.
MAC_Write(MACCF, 0x4012);
MAC_Write(IPGT, 0x0012);
}
// Configure the IPGR register
MAC_Write(IPGR, 0x0C12);
// Configure the MAXLEN register to 1518 bytes
MAC_Write(MAXLEN, 0x05EE);
// Copy MAC Address Stored in Flash to MYMAC
WriteReg(FLASHADDRH,0x1F);
WriteReg(FLASHADDRL,0xFA);
myNode.node.mac[0] = ReadReg(FLASHAUTORD);
myNode.node.mac[1] = ReadReg(FLASHAUTORD);
myNode.node.mac[2] = ReadReg(FLASHAUTORD);
myNode.node.mac[3] = ReadReg(FLASHAUTORD);
myNode.node.mac[4] = ReadReg(FLASHAUTORD);
myNode.node.mac[5] = ReadReg(FLASHAUTORD);
// Program the MAC address
MAC_SetAddress(&myNode);
// Enable Reception and configure Loopback mode
MAC_Write(MACCN, 0x0001); // Enable Reception without loopback
}
/*==========================================================
// function: read 8k flash data
// Parameter: hAdd high address, max 0x1F
// lAdd low address
// return: unsigned char read data
// date: 2006/11/9
// note: cp220x_core.c, datasheet page 75
// write: han
==========================================================*/
unsigned char ReadFlash(unsigned char hAdd,unsigned char lAdd)
{
unsigned char tmp;
if(hAdd > 0x1F)
return 0;
WriteReg(FLASHADDRH,hAdd);
WriteReg(FLASHADDRL,lAdd);
tmp = ReadReg(FLASHAUTORD);
return tmp;
}
/*==========================================================
// function: sends an IEEE 802.3 Ethernet packet using the CP220x.
// Parameter: pDestAddr pointer to a destination mac
// txdnet send packet buffer
// buffer_length length of buffer
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -