📄 smsc911x_platform.c
字号:
SMSC911X_PLATFORM_DATA * platformData=NULL;
SMSC_ASSERT((interfaceIndex>=0)&&(interfaceIndex<SMSC911X_INTERFACE_COUNT));
platformData=&(Smsc911xPlatformData[interfaceIndex]);
memset(platformData,0,sizeof(*platformData));
ASSIGN_SIGNATURE(platformData,SMSC911X_PLATFORM_DATA_SIGNATURE);
switch(interfaceIndex) {
case 0:
SMSC_ERROR(("NOT IMPLEMENTED"));
/* fill in appropriate resources here */
platformData->io_address=0;
platformData->irq_number=0;
/* initialize additional resources as necessary */
break;
/*case 1:*/
/*Add other interfaces as necessary */
default:
SMSC_ERROR(("Smsc911xPlatform_Initialize: Unexpected Interface Index = %d",interfaceIndex));
return 0;
}
return 1;
}
mem_ptr_t Smsc911xPlatform_GetIOAddress(int interfaceIndex)
{
/* Return the io address for the interface from
SMSC911X_PLATFORM_DATA structure.*/
SMSC_ASSERT((interfaceIndex>=0)&&(interfaceIndex<SMSC911X_INTERFACE_COUNT));
CHECK_SIGNATURE((&(Smsc911xPlatformData[interfaceIndex])),SMSC911X_PLATFORM_DATA_SIGNATURE);
return Smsc911xPlatformData[interfaceIndex].io_address;
}
static void Smsc911xPlatform_IsrWrapper(void * argument)
{
SMSC911X_PLATFORM_DATA * platformData=(SMSC911X_PLATFORM_DATA *)argument;
SMSC_ASSERT(platformData!=NULL);
CHECK_SIGNATURE(platformData,SMSC911X_PLATFORM_DATA_SIGNATURE);
SMSC_ASSERT(platformData->isr!=NULL);
/* ISR wrapper:
NOTE: not all platforms will require an ISR wrapper.
This wrapper is used because some platforms does not use a
return value for ISRs where as the driver is written as if there
was a return value. This wrapper can be used to safely ignore
the return value.
*/
platformData->isr(platformData->isr_argument);
}
int Smsc911xPlatform_InstallIsr(int interfaceIndex,SMSC911X_ISR isr,void * isrArgument)
{
SMSC911X_PLATFORM_DATA * platformData=NULL;
SMSC_ASSERT((interfaceIndex>=0)&&(interfaceIndex<SMSC911X_INTERFACE_COUNT));
SMSC_ASSERT(isr!=NULL);
platformData=&(Smsc911xPlatformData[interfaceIndex]);
CHECK_SIGNATURE(platformData,SMSC911X_PLATFORM_DATA_SIGNATURE);
platformData->isr=isr;
platformData->isr_argument=isrArgument;
/* This function should do interrupt request and install
interrupt handler.
*/
/*This function requires attention and must be implemented
according to the specific platform */
SMSC_ERROR(("NOT IMPLEMENTED"));
return 0;
}
void Smsc911xPlatform_GetMacAddress(int interfaceIndex, unsigned char macAddress[6])
{
int i;
/* Generate random mac address */
SMSC_ASSERT(macAddress!=NULL);
for(i=0;i<6;i++) {
macAddress[i]=(u8_t)rand();
}
macAddress[0]&=~(0x01);/* not a multicast address */
macAddress[0]|=(0x02);/* locally assigned address */
}
/* Writes a buffer to the TX_DATA_FIFO */
static void Smsc911xPlatform_TxWriteFifo(mem_ptr_t ioAddress, u32_t *buf, u16_t wordCount)
{
#define TX_DATA_FIFO 0x20
/* NOTE: These larger loops with repeated writes
have greately improved speed over the small
loop with single write */
while(wordCount>=16) {
SMSC911X_PLATFORM_WRITE_REGISTER(ioAddress,TX_DATA_FIFO,*(buf++));/*word 0*/
SMSC911X_PLATFORM_WRITE_REGISTER(ioAddress,TX_DATA_FIFO,*(buf++));/*word 1*/
SMSC911X_PLATFORM_WRITE_REGISTER(ioAddress,TX_DATA_FIFO,*(buf++));/*word 2*/
SMSC911X_PLATFORM_WRITE_REGISTER(ioAddress,TX_DATA_FIFO,*(buf++));/*word 3*/
SMSC911X_PLATFORM_WRITE_REGISTER(ioAddress,TX_DATA_FIFO,*(buf++));/*word 4*/
SMSC911X_PLATFORM_WRITE_REGISTER(ioAddress,TX_DATA_FIFO,*(buf++));/*word 5*/
SMSC911X_PLATFORM_WRITE_REGISTER(ioAddress,TX_DATA_FIFO,*(buf++));/*word 6*/
SMSC911X_PLATFORM_WRITE_REGISTER(ioAddress,TX_DATA_FIFO,*(buf++));/*word 7*/
SMSC911X_PLATFORM_WRITE_REGISTER(ioAddress,TX_DATA_FIFO,*(buf++));/*word 8*/
SMSC911X_PLATFORM_WRITE_REGISTER(ioAddress,TX_DATA_FIFO,*(buf++));/*word 9*/
SMSC911X_PLATFORM_WRITE_REGISTER(ioAddress,TX_DATA_FIFO,*(buf++));/*word 10*/
SMSC911X_PLATFORM_WRITE_REGISTER(ioAddress,TX_DATA_FIFO,*(buf++));/*word 11*/
SMSC911X_PLATFORM_WRITE_REGISTER(ioAddress,TX_DATA_FIFO,*(buf++));/*word 12*/
SMSC911X_PLATFORM_WRITE_REGISTER(ioAddress,TX_DATA_FIFO,*(buf++));/*word 13*/
SMSC911X_PLATFORM_WRITE_REGISTER(ioAddress,TX_DATA_FIFO,*(buf++));/*word 14*/
SMSC911X_PLATFORM_WRITE_REGISTER(ioAddress,TX_DATA_FIFO,*(buf++));/*word 15*/
wordCount-=16;
}
while(wordCount>=4) {
SMSC911X_PLATFORM_WRITE_REGISTER(ioAddress,TX_DATA_FIFO,*(buf++));/*word 0*/
SMSC911X_PLATFORM_WRITE_REGISTER(ioAddress,TX_DATA_FIFO,*(buf++));/*word 1*/
SMSC911X_PLATFORM_WRITE_REGISTER(ioAddress,TX_DATA_FIFO,*(buf++));/*word 2*/
SMSC911X_PLATFORM_WRITE_REGISTER(ioAddress,TX_DATA_FIFO,*(buf++));/*word 3*/
wordCount-=4;
}
while (wordCount) {
SMSC911X_PLATFORM_WRITE_REGISTER(ioAddress,TX_DATA_FIFO,*(buf++));
wordCount--;
}
}
#define TX_CMD_A_ON_COMP_ 0x80000000
#define TX_CMD_A_BUF_END_ALGN_ 0x03000000
#define TX_CMD_A_4_BYTE_ALGN_ 0x00000000
#define TX_CMD_A_16_BYTE_ALGN_ 0x01000000
#define TX_CMD_A_32_BYTE_ALGN_ 0x02000000
#define TX_CMD_A_DATA_OFFSET_ 0x001F0000
#define TX_CMD_A_FIRST_SEG_ 0x00002000
#define TX_CMD_A_LAST_SEG_ 0x00001000
#define TX_CMD_A_BUF_SIZE_ 0x000007FF
#define TX_CMD_B_PKT_TAG_ 0xFFFF0000
#define TX_CMD_B_ADD_CRC_DISABLE_ 0x00002000
#define TX_CMD_B_DISABLE_PADDING_ 0x00001000
#define TX_CMD_B_PKT_BYTE_LENGTH_ 0x000007FF
void Smsc911xPlatform_BeginWriting(
int interfaceIndex, u8_t * buffer, u16_t byteCount, u16_t tag)
{
mem_ptr_t ioAddress=Smsc911xPlatformData[interfaceIndex].io_address;
u32_t tx_cmd_a;
u32_t tx_cmd_b;
mem_ptr_t startAddress=((mem_ptr_t)buffer);
u16_t offset=(u16_t)(startAddress&0x03);
u16_t whole_dwords=(byteCount+3+offset)>>2;
tx_cmd_a =
/*TX_CMD_A_ON_COMP_ |*/ /* This flag is only needed if we use DMA */
TX_CMD_A_FIRST_SEG_|TX_CMD_A_LAST_SEG_|/* this is the first and last segment of the frame */
(((u32_t)offset)<<16)|/* set the starting offset */
byteCount;/* set the buffer length */
tx_cmd_b = ((u32_t)tag)<<16;
tx_cmd_b |= (u32_t)byteCount;
SMSC911X_PLATFORM_WRITE_REGISTER(ioAddress,TX_DATA_FIFO,tx_cmd_a);
SMSC911X_PLATFORM_WRITE_REGISTER(ioAddress,TX_DATA_FIFO,tx_cmd_b);
Smsc911xPlatform_TxWriteFifo(ioAddress,
(void *)(startAddress&(~((mem_ptr_t)(0x03)))),
whole_dwords);
}
static void Smsc911xPlatform_RxReadFifo(mem_ptr_t ioAddress, u32_t * buf, u16_t wordCount)
{
#define RX_DATA_FIFO 0x00
/* NOTE: These larger loops with repeated reads
have greately improved speed over the small
loop with single read */
while(wordCount>=16) {
*(buf++)=SMSC911X_PLATFORM_READ_REGISTER(ioAddress,RX_DATA_FIFO);/*word 0*/
*(buf++)=SMSC911X_PLATFORM_READ_REGISTER(ioAddress,RX_DATA_FIFO);/*word 1*/
*(buf++)=SMSC911X_PLATFORM_READ_REGISTER(ioAddress,RX_DATA_FIFO);/*word 2*/
*(buf++)=SMSC911X_PLATFORM_READ_REGISTER(ioAddress,RX_DATA_FIFO);/*word 3*/
*(buf++)=SMSC911X_PLATFORM_READ_REGISTER(ioAddress,RX_DATA_FIFO);/*word 4*/
*(buf++)=SMSC911X_PLATFORM_READ_REGISTER(ioAddress,RX_DATA_FIFO);/*word 5*/
*(buf++)=SMSC911X_PLATFORM_READ_REGISTER(ioAddress,RX_DATA_FIFO);/*word 6*/
*(buf++)=SMSC911X_PLATFORM_READ_REGISTER(ioAddress,RX_DATA_FIFO);/*word 7*/
*(buf++)=SMSC911X_PLATFORM_READ_REGISTER(ioAddress,RX_DATA_FIFO);/*word 8*/
*(buf++)=SMSC911X_PLATFORM_READ_REGISTER(ioAddress,RX_DATA_FIFO);/*word 9*/
*(buf++)=SMSC911X_PLATFORM_READ_REGISTER(ioAddress,RX_DATA_FIFO);/*word 10*/
*(buf++)=SMSC911X_PLATFORM_READ_REGISTER(ioAddress,RX_DATA_FIFO);/*word 11*/
*(buf++)=SMSC911X_PLATFORM_READ_REGISTER(ioAddress,RX_DATA_FIFO);/*word 12*/
*(buf++)=SMSC911X_PLATFORM_READ_REGISTER(ioAddress,RX_DATA_FIFO);/*word 13*/
*(buf++)=SMSC911X_PLATFORM_READ_REGISTER(ioAddress,RX_DATA_FIFO);/*word 14*/
*(buf++)=SMSC911X_PLATFORM_READ_REGISTER(ioAddress,RX_DATA_FIFO);/*word 15*/
wordCount-=16;
}
while(wordCount>=4) {
*(buf++)=SMSC911X_PLATFORM_READ_REGISTER(ioAddress,RX_DATA_FIFO);/*word 0*/
*(buf++)=SMSC911X_PLATFORM_READ_REGISTER(ioAddress,RX_DATA_FIFO);/*word 1*/
*(buf++)=SMSC911X_PLATFORM_READ_REGISTER(ioAddress,RX_DATA_FIFO);/*word 2*/
*(buf++)=SMSC911X_PLATFORM_READ_REGISTER(ioAddress,RX_DATA_FIFO);/*word 3*/
wordCount-=4;
}
while(wordCount) {
*(buf++)=SMSC911X_PLATFORM_READ_REGISTER(ioAddress,RX_DATA_FIFO);
wordCount--;
}
}
#define RX_CFG 0x6C
void Smsc911xPlatform_BeginReading(
int interfaceIndex, u8_t * buffer, u16_t byteCount)
{
/* Since this platform uses PIO this function is simply a wrapper around
the PIO function */
mem_ptr_t ioAddress=Smsc911xPlatformData[interfaceIndex].io_address;
u32_t * wordAlignedBuffer=(u32_t *)(((mem_ptr_t)buffer)&(~(0x03)));
u16_t wordCount=(byteCount+((u16_t)(((mem_ptr_t)buffer)&0x03))+3)>>2;
SMSC911X_PLATFORM_WRITE_REGISTER(ioAddress,RX_CFG,0x00000200UL);/*4 byte end alignment*/
Smsc911xPlatform_RxReadFifo(ioAddress,wordAlignedBuffer,wordCount);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -