📄 ethernet_c8051f120.c
字号:
void UART1_Init (void)
{
char SFRPAGE_SAVE = SFRPAGE; // Save Current SFR page
SFRPAGE = UART1_PAGE;
SCON1 = 0x10; // SCON1: mode 0, 8-bit UART, enable RX
SFRPAGE = TIMER01_PAGE;
TMOD &= ~0xF0;
TMOD |= 0x20; // TMOD: timer 1, mode 2, 8-bit reload
if (SYSCLK/BAUDRATE/2/256 < 1) {
TH1 = -(SYSCLK/BAUDRATE/2);
CKCON |= 0x10; // T1M = 1; SCA1:0 = xx
} else if (SYSCLK/BAUDRATE/2/256 < 4) {
TH1 = -(SYSCLK/BAUDRATE/2/4);
CKCON &= ~0x13; // Clear all T1 related bits
CKCON |= 0x01; // T1M = 0; SCA1:0 = 01
} else if (SYSCLK/BAUDRATE/2/256 < 12) {
TH1 = -(SYSCLK/BAUDRATE/2/12);
CKCON &= ~0x13; // T1M = 0; SCA1:0 = 00
} else {
TH1 = -(SYSCLK/BAUDRATE/2/48);
CKCON &= ~0x13; // Clear all T1 related bits
CKCON |= 0x02; // T1M = 0; SCA1:0 = 10
}
TL1 = TH1; // initialize Timer1
TR1 = 1; // start Timer1
SFRPAGE = UART1_PAGE;
TI1 = 1; // Indicate TX1 ready
SFRPAGE = SFRPAGE_SAVE; // Restore SFR page
}
//-----------------------------------------------------------------------------
// CS8900A_Reset
//-----------------------------------------------------------------------------
//
// This procedure resets the CS8900A using its reset pin (P4.5).
//
void CS8900A_Reset(void)
{
char SFRPAGE_SAVE = SFRPAGE; // Save Current SFR page
SFRPAGE = TMR3_PAGE;
TMR3CN = 0x00; // Disable Timer3
TMR3CF &= ~0x18; // Count System Clocks/12
TMR3 = -(SYSCLK / 2500000); // Load Timer3 with 400ns
// reset pin (active high) is on P4.5
ETH_RESET = 1; // Assert the Reset signal
TR3 = 1; // Start Timer3
while(!TF3); // wait for the Timer3 overflow flag.
ETH_RESET = 0; // Take the CS8900A out of reset
// wait at least 20ms for device to be ready
TMR3CN = 0x00; // Disable Timer3, use system clock/12
TMR3 = -(SYSCLK / 12 / 50); // Load Timer3 with 20ms
TR3 = 1; // Start Timer3
while(!TF3); // wait for the Timer3 overflow flag.
// check to see if the device is ready
while( !(PACKETPAGE_Read(IPPREG_SelfST) & INITD) );
SFRPAGE = SFRPAGE_SAVE; // Restore SFR page
}
//-----------------------------------------------------------------------------
// CS8900A_Init
//-----------------------------------------------------------------------------
//
// This function configures the CS8900A for transmitting and receiving. It
// also assigns the CS8900A the MAC address it should respond to.
//
void CS8900A_Init(void)
{
// set which frames will be accepted by the CS8900A
// the RxOKA bit must be set for the device to operate properly
PACKETPAGE_Write(IPPREG_RxCTL, RxOKA + PromiscuousA);
// assign the Ethernet MAC address
PACKETPAGE_Write(IPPREG_IA, MYMAC.Int[0]);
PACKETPAGE_Write(IPPREG_IA + 2, MYMAC.Int[1]);
PACKETPAGE_Write(IPPREG_IA + 4, MYMAC.Int[2]);
// enable transmit and receive
PACKETPAGE_Write(IPPREG_LineCTL,SerTxON | SerRxON);
}
//-----------------------------------------------------------------------------
// Function Definitions
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// PACKETPAGE_Read
//-----------------------------------------------------------------------------
//
// This function returns the contents of a PacketPage Register
//
// Note: Read high byte first and Write low byte first when communicating with
// the CS8900A.
//
unsigned int PACKETPAGE_Read (unsigned int IPPREG_address)
{
UINT register_address;
UINT retval;
register_address.Int = IPPREG_address;
// specify register address and set autoincrement off
PACKETPAGE_POINTERL = register_address.Char[1];
PACKETPAGE_POINTERH = (register_address.Char[0] & 0x7F);
// read lower 16-bits most significant byte first
retval.Char[0] = PACKETPAGE_DATA0H;
retval.Char[1] = PACKETPAGE_DATA0L;
// return the data register contents
return retval.Int;
}
//-----------------------------------------------------------------------------
// PACKETPAGE_Write
//-----------------------------------------------------------------------------
//
// This function writes a 16-bit value to a PacketPage Register.
//
// Note: Read high byte first and write low byte first when communicating with
// the CS8900A
//
void PACKETPAGE_Write(unsigned int IPPREG_address, unsigned int output_data)
{
UINT register_address;
UINT dat;
register_address.Int = IPPREG_address;
dat.Int = output_data;
// specify register address and set autoincrement off
PACKETPAGE_POINTERL = register_address.Char[1];
PACKETPAGE_POINTERH = (register_address.Char[0] & 0x7F);
//write the data to the data ports
PACKETPAGE_DATA0L = dat.Char[1];
PACKETPAGE_DATA0H = dat.Char[0];
}
//-----------------------------------------------------------------------------
// PACKETPAGE_ReadID
//-----------------------------------------------------------------------------
//
// This function returns the contents of the Product Identification Code
// register. This is a 32-bit register at location 0 in the PacketPage memory.
//
// This register identifies the device as a CS8900A and does not change.
//
unsigned long PACKETPAGE_ReadID ()
{
ULONG retval;
retval.Int[0] = PACKETPAGE_Read(0x0000);
retval.Int[1] = PACKETPAGE_Read(0x0002);
return retval.Long;
}
//-----------------------------------------------------------------------------
// CS8900A_RxPoll
//-----------------------------------------------------------------------------
//
// This function polls the CS8900A for the Receive OK event.
//
void CS8900A_RxPoll(void)
{
unsigned int event;
event = PACKETPAGE_Read(IPPREG_RxEvent);
if(event & RxOK){
Receive_Frame();
return;
}
}
//-----------------------------------------------------------------------------
// RECEIVE_FRAME
//-----------------------------------------------------------------------------
//
// This function Receives a frame from the CS8900A Data Ports and displays it
// on a Hyperterminal window.
//
void Receive_Frame(void)
{
UINT status;
UINT length;
UINT dat;
int i;
status.Char[0] = DATA0H;
status.Char[1] = DATA0L;
length.Char[0] = DATA0H;
length.Char[1] = DATA0L;
SFRPAGE = UART1_PAGE;
printf("\n\n New Packet: %d bytes", length.Int);
printf("\n Destination: ");
for ( i = 0; i < 3; i++) {
dat.Char[0] = DATA0L;
dat.Char[1] = DATA0H;
printf("%04X", dat.Int);
length.Int -= 2;
}
printf("\n Source: ");
for ( i = 0; i < 3; i++) {
dat.Char[0] = DATA0L;
dat.Char[1] = DATA0H;
printf("%04X", dat.Int);
length.Int -= 2;
}
printf("\n Data: ");
while( ((int) length.Int) > 0 ){
dat.Char[0] = DATA0L;
dat.Char[1] = DATA0H;
printf("%04X", dat.Int);
length.Int -= 2;
}
}
//-----------------------------------------------------------------------------
// Send_Frame
//-----------------------------------------------------------------------------
//
// This function sends an IEEE 802.3 frame to the CS8900A. Upon entry, there
// should be valid data in array <buffer>.
//
// 48-bit 48-bit 16-bit 0-1500 bytes
// -------------------------------------------------------------------------
// | Preamble | SFD | Dest | Source | Length of | Data Field | Pad | FCS |
// | | | Addr | Addr | data field | | | (CRC) |
// -------------------------------------------------------------------------
// supplied by | supplied by the host (TxLength) | supplied by
// CS8900A | | CS8900A
void Send_Frame(char* buffer, int length, MACADDR* dest_address_ptr)
{
UINT len;
int status;
int i;
// issue a transmit command
TxCMDL = TRANSMIT_CMDL;
TxCMDH = TRANSMIT_CMDH;
// bid for buffer space
// data field length + dest field (6) + source field (6) + length field (2)
len.Int = length + 14;
TxLENGTHL = len.Char[1];
TxLENGTHH = len.Char[0];
// error check
if (PACKETPAGE_Read(IPPREG_BusST) & TxBidErr) while (1);
// wait for CS8900A Tx ready
do {
status = PACKETPAGE_Read(IPPREG_BusST);
} while (!(status & Rdy4TxNow));
// write the destination address field
for (i = 0; i < 6; i+=2 ){
DATA0L = dest_address_ptr->Char[i];
DATA0H = dest_address_ptr->Char[i+1];
}
// write the source address field
for (i = 0; i < 6; i+=2 ){
DATA0L = MYMAC.Char[i];
DATA0H = MYMAC.Char[i+1];
}
// write the data length field
len.Int = length;
DATA0L = len.Char[0];
DATA0H = len.Char[1];
// write the data field
// The CS8900A automatically transmits after the last byte is written
i = 0;
while (i < length){
DATA0L = buffer[i];
i++;
if (i < length){
DATA0H = buffer[i];
i++;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -