📄 cs8900_enet_if_driver.c
字号:
{
// Convert to half words
enet_vals [j / 2] = (eaddr [j + 1] << 8) + eaddr [j];
// Save new local copy
enetaddr [j ] = eaddr [j];
enetaddr [j + 1] = eaddr [j + 1];
}
// Write the ethernet address to the controller
enet_set_pp_addr (&enet_pp_data->filter_regs.enet_address, 1);
enet_write_data (enet_vals [0]);
enet_write_data (enet_vals [1]);
enet_write_data (enet_vals [2]);
}
/**********************************************************************
*
* Function: enet_get_address
*
* Purpose: Returns the ethernet address.
*
* Processing:
* The ethernet address is read from the ethernet controller and
* converted to an array of 6 bytes. The address is copied into the
* array provided by the caller.
*
* Parameters:
* eaddr: Pointer to where to put the ethernet address
*
* Outputs: None
*
* Returns: Nothing
*
* Notes: None
*
**********************************************************************/
void enet_get_address (UNS_8 *eaddr)
{
UNS_16 enet_vals [3];
INT_32 j;
// Read the ethernet address from the controller
enet_set_pp_addr (&enet_pp_data->filter_regs.enet_address, 1);
enet_vals [0] = enet_read_data ();
enet_vals [1] = enet_read_data ();
enet_vals [2] = enet_read_data ();
// Convert ethernet address to 6 bytes
for (j = 0 ; j < 6; j = j + 2)
{
eaddr [j ] = enet_vals [j / 2] & 0xFF;
eaddr [j + 1] = (enet_vals [j / 2] & 0xFF00) >> 8;
}
}
/**********************************************************************
*
* Function: enet_get_chipid
*
* Purpose: Returns the chip identification.
*
* Processing: Reads the high and low chip identification values and
* concatenates them into a single word.
*
* Parameters: None
*
* Outputs: None
*
* Returns: The chip identifier of the ethernet controller.
*
* Notes: None
*
**********************************************************************/
UNS_32 enet_get_chipid (void)
{
enet_set_pp_addr (&enet_pp_data->bus_regs.chip_id_h, 1);
return (enet_read_data () << 16) + enet_read_data ();
}
/**********************************************************************
*
* Function: enet_write_port
*
* Purpose: Writes a data value to an ethernet controller I/O port.
*
* Processing:
* This function simply writes a data value to one of the ethernet
* controller ports.
*
* Parameters:
* port_id: enumerated read port id
* data: Data to write to the port
*
* Outputs: None
*
* Returns: Nothing
*
* Notes: This routine will compile inline with routines that use it to
* minimize impact to system performance.
*
**********************************************************************/
void enet_write_port (tx_port_t port_id, UNS_16 data)
{
*enet_port_addr[port_id] = data;
}
/**********************************************************************
*
* Function: enet_read_port
*
* Purpose: Reads a data value from an ethernet controller I/O port.
*
* Processing:
* This function simply reads a data value from one of the ethernet
* controller ports.
*
* Parameters:
* port_id: enumerated read port id
*
* Outputs: None
*
* Returns: The data value read from the port.
*
* Notes: None
*
**********************************************************************/
UNS_16 enet_read_port (rx_port_t port_id)
{
if (dummy_write_en)
dummy_write();
return (*enet_port_addr[port_id]);
}
/**********************************************************************
*
* Function: enet_set_pp_addr
*
* Purpose: Sets the PacketPage (PP) pointer register.
*
* Processing:
* This function will set the PP pointer register and enable the
* autoincrement function if autoinc is set. This function should
* be used to set the PP pointer address to read or write before
* using the enet_read_data and enet_write_data functions. When
* using the block functions, this function does not need to be
* used.
*
* Parameters:
* ppptr: PacketPage pointer
* autoinc: Flag used to set autoincrement flag in PP pointer
*
* Outputs: None
*
* Returns: Nothing
*
* Notes: None
*
**********************************************************************/
void enet_set_pp_addr (void *address, INT_32 autoinc)
{
UNS_16 addr = (UNS_16) ((INT_32) address);
if (autoinc != 0)
{
// Set autoincrement bit in PacketPage pointer value
addr = addr | 0x8000;
}
#ifdef DEBUG
printf("Setting ppptr address to %04x (%d)\n",
(int)addr,
autoinc);
#endif
*enet_port_addr[ppptr] = addr;
}
/**********************************************************************
*
* Function: enet_read_data
*
* Purpose: Read data from the current PP register address.
*
* Processing:
* This function will read data from PacketPage port 0 using the
* current address in the PacketPage pointer register.
*
* Parameters: None
*
* Outputs: None
*
* Returns: Data read from the PacketPage port 0 register.
*
* Notes: None
*
**********************************************************************/
UNS_16 enet_read_data (void)
{
#ifdef DEBUG
UNS_16 data;
#endif
if (dummy_write_en)
dummy_write();
#ifdef DEBUG
{
data = *enet_port_addr[pd0];
printf("Data read from port = %04x\n", (int)data);
return data;
}
#else
return (*enet_port_addr[pd0]);
#endif
}
/**********************************************************************
*
* Function: enet_write_data
*
* Purpose:
* Write data to the current PP register address.
*
* Processing:
* This function will write data to PacketPage port 0 using the
* current address in the PacketPage pointer register.
*
* Parameters:
* data: Data to write to the PacketPage port 0.
*
* Outputs: None
*
* Returns: Nothing
*
* Notes: None
*
**********************************************************************/
void enet_write_data (UNS_16 data)
{
*enet_port_addr[pd0] = data;
#ifdef DEBUG
printf("Data written to port = %04x\n", (int)data);
#endif
}
/**********************************************************************
*
* Function: enet_write_block
*
* Purpose:
* Write a block of data to the PP area at the current PP pointer.
*
* Processing:
* This function will write a block of 16-bit half words to the
* controller via PP port 0 at the current PP pointer address;
*
* Parameters:
* data: Pointer to a block of data to transfer to controller.
* len: Length of the block in 16-bit half words.
*
* Outputs: None
*
* Returns: Nothing
*
* Notes: None
*
**********************************************************************/
void enet_write_block (UNS_16 *data, INT_32 len)
{
INT_32 J;
for (J = 0; J < len; ++J)
{
*enet_port_addr[pd0] = data [J];
}
}
/**********************************************************************
*
* Function: enet_read_block
*
* Purpose:
* Read a block of data from the PP area at the current PP pointer.
*
* Processing:
* This function will read a block of 16-bit half words from the
* controller via PP port 0 at the current PP pointer address;
*
* Parameters:
* data: Pointer to a block area to update from the controller.
* len: Number of 16-bit half words to read.
*
* Outputs: None
*
* Returns: Nothing
*
* Notes: None
*
**********************************************************************/
void enet_read_block (UNS_16 *data, INT_32 len)
{
INT_32 J;
for (J = 0; J < len; ++J)
{
if (dummy_write_en)
dummy_write();
data [J] = *enet_port_addr[pd0];
}
}
/**********************************************************************
*
* Function: enet_write_block_auto_increament
*
* Purpose:
* Initialize PP address and write a block of data to the PP area.
*
* Processing:
* This function will initialize the PP pointer and write a block
* of 16-bit half words to the controller via PP port 0.
*
* Parameters:
* address: PacketPage pointer address for start of block.
* data: Pointer to a block of data to transfer to controller.
* len: Length of the block in 16-bit half words.
*
* Outputs: None
*
* Returns: Nothing
*
* Notes: None
*
**********************************************************************/
void enet_write_block_auto_increament (UNS_16 address,
UNS_16 *data,
INT_32 len)
{
// Update PP address with autoincrementing on
*enet_port_addr[ppptr] = (address | 0x8000);
enet_write_block(data, len);
}
/**********************************************************************
*
* Function: enet_read_block_auto_increament
*
* Purpose:
* Read a block of data from the PP area at the current PP pointer.
*
* Processing:
* This function will initialize the PP pointer and read a block
* of 16-bit half words from the controller via PP port 0.
*
* Parameters:
* address: PacketPage pointer address for start of block.
* data: Pointer to a block area to update from the controller.
* len: Number of 16-bit half words to read.
*
* Outputs: None
*
* Returns: Nothing
*
* Notes: None
*
**********************************************************************/
void enet_read_block_auto_increament (UNS_16 address,
UNS_16 *data,
INT_32 len)
{
// Update PP address with autoincrementing on
*enet_port_addr[ppptr] = (address | 0x8000);
enet_read_block(data, len);
}
/**********************************************************************
*
* Function: enet_set_irq_number
*
* Purpose: Set which IRQ line the CS8900 will drive.
*
* Processing: Configure PacketPage register for Bus Registers
*
* Parameters: IRQ number to set
*
* Outputs: None
*
* Returns: Nothing
*
* Notes: Updates the EEPROM memory structure as well.
*
**********************************************************************/
void enet_set_irq_number(enet_int_t irq_num)
{
enet_set_pp_addr(&enet_pp_data->bus_regs.int_num, 0);
enet_write_data((UNS_16) irq_num);
enet_8900e2_set_irq(irq_num);
}
/**********************************************************************
*
* Function: enet_set_dma_chan
*
* Purpose: Set which DMA channel the CS8900 will use.
*
* Processing: Configure PacketPage register for Bus Registers
*
* Parameters: DMA channel number to set.
*
* Outputs: None
*
* Returns: Nothing
*
* Notes: Updates the EEPROM memory structure as well.
*
**********************************************************************/
void enet_set_dma_chan(enet_dma_t dma_num)
{
enet_set_pp_addr(&enet_pp_data->bus_regs.dma_channel, 0);
enet_write_data((UNS_16) dma_num);
enet_8900e2_set_dma(dma_num);
}
/**********************************************************************
*
* Function: dummy_write
*
* Purpose: Performs a dummy write to the ethernet controller.
*
* Processing:
* This function performs a dummy write to the ethernet controller.
* Dummy writes are needed between consecutive reads of data from
* an I/O port on the ethernet controller for SoC's that do not
* generate the nIOR strobe on consecutive data reads. This
* mechanism is used to force these chips to perform the strobe by
* forcing a write before every read. The actual write does not
* matter - for the purpose of this driver, data is being written
* to a 'read-only' area so the driver will not corrupt anything as
* it is running.
*
* Parameters: None
*
* Outputs: None
*
* Returns: Nothing
*
* Notes: This routine will compile inline with routines that use it to
* minimize impact to system performance. There must be a global
* variable named dummy_write_en that is non-zero for this to be used.
*
**********************************************************************/
void __inline dummy_write(void)
{
*enet_port_addr[unused_t1] = 0x0;
}
/**********************************************************************
*
* Function: enet_reset
*
* Purpose: Execute a software reset the CS8900 chip.
*
* Processing:
*
* Parameters:
*
* Outputs: None
*
* Returns: Nothing
*
* Notes: WARNING!!!
* This function requires a maximum of 10mSec to complete. To
* avoid tying this driver to a specific platform, the user must
* accomidate this delay in the calling function!!!
*
**********************************************************************/
void enet_reset(void)
{
enet_set_pp_addr(&enet_pp_data->stco_regs.reg15_selfctl, 0);
enet_write_data((UNS_16) RESET);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -