8851是一款网络芯片,驱动如下:
/****************************************************************************** * 文 件 名 称:BspKsz8851.c * 文件功能概述: * 文 件 作 者: * 版 本:V1.0.0.0 * 修 订 记 录:2018-05-02创建 ******************************************************************************/ #include "BspKsz8851.h" #include "FreeRTOS.h" #include "semphr.h" /*8851的总线宽度由P1LED1上电时的状态决定 拉高P1LED1 然后复位 读取bus总线宽度 16位宽就继续执行,否则进行重复操作*/ /* * 8851接收缓冲区大小 */ static Ksz8851RxMsg stKsz8851RxFrameBuff[E_KSZ8851_Max][KSZ8851RxFrameCounterMax]; static uint16 stKsz8851RxFrameLen[E_KSZ8851_Max][KSZ8851RxFrameCounterMax]; /* * 用于记录8851环形缓冲区中有效数据的首位置 */ static uint8 stKsz8851RxFrameHead[E_KSZ8851_Max] = {0x00}; /* * 用于记录8851环形缓冲区中有效数据的尾位置 */ static uint8 stKsz8851RxFrameTail[E_KSZ8851_Max] = {0x00}; /* * 用于记录CAN环形缓冲区中的数据长度 */ static uint16 stKsz8851RxFrameCounter[E_KSZ8851_Max] = {0x00}; /* * 8851发送缓冲区大小 */ static Ksz8851TxMsg stKsz8851TxBuff[E_KSZ8851_Max][KSZ8851TxBuffSize]; /* * 用于记录8851环形缓冲区中有效数据的首位置 */ static uint8 stKsz8851TxBuffHead[E_KSZ8851_Max] = {0x00}; /* * 用于记录8851环形缓冲区中有效数据的尾位置 */ static uint8 stKsz8851TxBuffTail[E_KSZ8851_Max] = {0x00}; /* * 用于记录CAN环形缓冲区中的数据长度 */ static uint16 stKsz8851TxBuffLen[E_KSZ8851_Max] = {0x00}; uint16 cmd_Backup[E_KSZ8851_Max] = {0}; #define KSZ8895Delay(x) DelayUs(x) /* * 数据结构-KSZ8851 */ typedef struct KSZ8851CtrlStruc { S_GpioCtrl KSZ8851xRST; S_ExtiCtrl KSZ8851xINT; }S_KSZ8851Ctrl; S_KSZ8851_Struc stKsz8851Struc[E_KSZ8851_Max]= { {(uint16 *)0x68000000,(uint16 *)0x68000002}, {(uint16 *)0x64000000,(uint16 *)0x64000002} }; const uint8 cKsz8851MacAddr[E_KSZ8851_Max][6]= { {0x43,0x4A,0x4B,0x00,0x03,0x11}, {0x43,0x4A,0x4B,0x00,0x03,0x12} }; /* * 用于记录KSZ8851的端口信息 */ static S_KSZ8851Ctrl stKSZ8851Ctrl[E_KSZ8851_Max] = { { {RCC_AHB1Periph_GPIOG,GPIOG,GPIO_Pin_7}, { RCC_AHB1Periph_GPIOA, GPIOA, GPIO_Pin_11, EXTI_PortSourceGPIOA, EXTI_PinSource11, 0, EXTI15_10_IRQn, EXTI_Line11 } }, { {RCC_AHB1Periph_GPIOG,GPIOG,GPIO_Pin_7}, { RCC_AHB1Periph_GPIOA, GPIOA, GPIO_Pin_12, EXTI_PortSourceGPIOA, EXTI_PinSource12, 0, EXTI15_10_IRQn, EXTI_Line12 } } }; void KSZ8851Reset(E_KSZ8851 eKsz8851) { stKSZ8851Ctrl[eKsz8851].KSZ8851xRST.GPIOx->BSRRH = stKSZ8851Ctrl[eKsz8851].KSZ8851xRST.GPIOxPinx; KSZ8895Delay(200); stKSZ8851Ctrl[eKsz8851].KSZ8851xRST.GPIOx->BSRRL = stKSZ8851Ctrl[eKsz8851].KSZ8851xRST.GPIOxPinx; KSZ8895Delay(200); } static void KSZ8851_InitPort(E_KSZ8851 eKsz8851) { GPIO_InitTypeDef GPIO_InitStructure; RCC_AHB1PeriphClockCmd(stKSZ8851Ctrl[eKsz8851].KSZ8851xRST.GPIOxSource,ENABLE); GPIO_InitStructure.GPIO_Pin = stKSZ8851Ctrl[eKsz8851].KSZ8851xRST.GPIOxPinx; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_Init(stKSZ8851Ctrl[eKsz8851].KSZ8851xRST.GPIOx, &GPIO_InitStructure); GPIOxWriteBit(stKSZ8851Ctrl[eKsz8851].KSZ8851xRST.GPIOx, stKSZ8851Ctrl[eKsz8851].KSZ8851xRST.GPIOxPinx , 1); } static void KSZ8851_InitModule(E_KSZ8851 eKsz8851) { /* 初始化FMC */ } static void KSZ8851_SetPortIrq(E_KSZ8851 eKsz8851) { EXTI_InitTypeDef EXTI_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; /* Enable GPIOG clock */ RCC_AHB1PeriphClockCmd(stKSZ8851Ctrl[eKsz8851].KSZ8851xINT.GPIOxSource , ENABLE); /* Enable SYSCFG clock */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); /* Configure PG15 pin as input floating */ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_InitStructure.GPIO_Pin = stKSZ8851Ctrl[eKsz8851].KSZ8851xINT.GPIOxPinx; GPIO_Init(stKSZ8851Ctrl[eKsz8851].KSZ8851xINT.GPIOx, &GPIO_InitStructure); /* Connect EXTI Line9 to PG15 pin */ SYSCFG_EXTILineConfig(stKSZ8851Ctrl[eKsz8851].KSZ8851xINT.EXTIxPortSource, stKSZ8851Ctrl[eKsz8851].KSZ8851xINT.EXTIxPinSource); /* Configure EXTI Line15 */ EXTI_InitStructure.EXTI_Line = stKSZ8851Ctrl[eKsz8851].KSZ8851xINT.EXTIxLine; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure); /* Enable and set EXTI15_10 Interrupt to the lowest priority */ NVIC_InitStructure.NVIC_IRQChannel = (uint8_t)stKSZ8851Ctrl[eKsz8851].KSZ8851xINT.EXTIxIRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00U; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02U; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } static __inline void KSZ8851_WriteByte(E_KSZ8851 eKsz8851,uint16 u16_RegAddr, uint8 u8_RegValue) { uint16 u16_RegValue = 0; u16_RegAddr = u16_RegAddr | ((BE0)<<(u16_RegAddr&0x03)); u16_RegValue = u8_RegValue << ((u16_RegAddr&0x01)<<3); cmd_Backup[eKsz8851] = u16_RegAddr; Fmc_WriteHalfWord(u16_RegAddr,stKsz8851Struc[eKsz8851].phw_addr_cmd); Fmc_WriteHalfWord(u16_RegValue,stKsz8851Struc[eKsz8851].phw_addr_data); } static __inline uint8 KSZ8851_ReadByte(E_KSZ8851 eKsz8851,uint16 u16_RegAddr) { uint8 u8_RegValue = 0; u16_RegAddr = u16_RegAddr | ((BE0)<<(u16_RegAddr&0x03)); cmd_Backup[eKsz8851] = u16_RegAddr; Fmc_WriteHalfWord(u16_RegAddr,stKsz8851Struc[eKsz8851].phw_addr_cmd); u8_RegValue = (uint8)(Fmc_ReadHalfWord(stKsz8851Struc[eKsz8851].phw_addr_data)>>((u16_RegAddr&0x01)<<3)); return u8_RegValue; } /*由于KSZ8851在16bit总线时,低两位地址线固定为0,所以需要通过BE0-3确定读写的是哪一个字节*/ static __inline void KSZ8851_WriteHalfWord(E_KSZ8851 eKsz8851,uint16 u16_RegAddr, uint16 u16_RegValue) { u16_RegAddr = u16_RegAddr | ((BE1 | BE0)<<(u16_RegAddr&0x02)); cmd_Backup[eKsz8851] = u16_RegAddr; Fmc_WriteHalfWord(u16_RegAddr,stKsz8851Struc[eKsz8851].phw_addr_cmd); Fmc_WriteHalfWord(u16_RegValue,stKsz8851Struc[eKsz8851].phw_addr_data); } static __inline uint16 KSZ8851_ReadHalfWord(E_KSZ8851 eKsz8851,uint16 u16_RegAddr) { u16_RegAddr = u16_RegAddr | ((BE1 | BE0)<<(u16_RegAddr&0x02)); cmd_Backup[eKsz8851] = u16_RegAddr; Fmc_WriteHalfWord(u16_RegAddr,stKsz8851Struc[eKsz8851].phw_addr_cmd); return Fmc_ReadHalfWord(stKsz8851Struc[eKsz8851].phw_addr_data); } static void KSZ8851_SoftReset(E_KSZ8851 eKsz8851) { /* 关闭8851所有中断*/ KSZ8851_WriteHalfWord(eKsz8851,KSZ8851_IER,0x00000); /* 只复位QMU */ KSZ8851_WriteHalfWord(eKsz8851,KSZ8851_GRR,GRR_QMU); DelayMs(10); /* 清除复位 */ KSZ8851_WriteHalfWord(eKsz8851,KSZ8851_GRR,0); DelayMs(10); } static void KSZ8851_DisableRx(E_KSZ8851 eKsz8851) { uint16 u16_RegValue; /* * 停止QMU接收(RXCR1). */ u16_RegValue = KSZ8851_ReadHalfWord(eKsz8851, KSZ8851_RXCR1); u16_RegValue &= (uint16)(~RXCR1_RXE); KSZ8851_WriteHalfWord(eKsz8851, KSZ8851_RXCR1, u16_RegValue); } static void KSZ8851_DisableTx(E_KSZ8851 eKsz8851) { uint16 u16_RegValue = 0; u16_RegValue = KSZ8851_ReadHalfWord(eKsz8851, KSZ8851_TXCR); /* * 禁能QMU发送(TXCR). */ u16_RegValue &= (uint16)(~TXCR_TXE); KSZ8851_WriteHalfWord(eKsz8851, KSZ8851_TXCR, u16_RegValue); } static void KSZ8851_EnableRx(E_KSZ8851 eKsz8851) { uint16 u16_RegValue; /* * 使能QMU接收(RXCR1). */ u16_RegValue = KSZ8851_ReadHalfWord(eKsz8851, KSZ8851_RXCR1); u16_RegValue |= (uint16)(RXCR1_RXE); KSZ8851_WriteHalfWord(eKsz8851, KSZ8851_RXCR1, u16_RegValue); } static void KSZ8851_EnableTx(E_KSZ8851 eKsz8851) { uint16 u16_RegValue = 0; u16_RegValue = KSZ8851_ReadHalfWord(eKsz8851, KSZ8851_TXCR); /* * 使能QMU发送(TXCR). */ u16_RegValue |= (uint16)(TXCR_TXE | TXCR_TCGICMP | TXCR_TCGUDP | TXCR_TCGTCP | TXCR_TCGIP); KSZ8851_WriteHalfWord(eKsz8851, KSZ8851_TXCR, u16_RegValue); } static void KSZ8851_SetMacAddr(E_KSZ8851 eKsz8851) { uint16 u16_RegValue = 0; u16_RegValue = cKsz8851MacAddr[eKsz8851][0]; u16_RegValue = ((u16_RegValue<<8) | cKsz8851MacAddr[eKsz8851][1]); KSZ8851_WriteHalfWord(eKsz8851, KSZ8851_MARH, u16_RegValue); u16_RegValue = cKsz8851MacAddr[eKsz8851][2]; u16_RegValue = ((u16_RegValue<<8) | cKsz8851MacAddr[eKsz8851][3]); KSZ8851_WriteHalfWord(eKsz8851, KSZ8851_MARM, u16_RegValue); u16_RegValue = cKsz8851MacAddr[eKsz8851][4]; u16_RegValue = ((u16_RegValue<<8) | cKsz8851MacAddr[eKsz8851][5]); KSZ8851_WriteHalfWord(eKsz8851, KSZ8851_MARL, u16_RegValue); } static sint8 KSZ8851_Config16BitBus(E_KSZ8851 eKsz8851) { uint8 u8_RegValue = 0; sint8 s8_ret = -1; uint32 u32_NowTime = SystemClockGetTime(); do { u8_RegValue = KSZ8851_ReadByte(eKsz8851,KSZ8851_CCR); if(u8_RegValue&0x40) { /* 当前数据总线宽度已经是16bit */ s8_ret = 0; break; } else { /* do nothing */ } } while(CompareDelayTime(SystemClockGetTime(),u32_NowTime,1000)); return s8_ret; } static sint8 KSZ8851_SelfTest(E_KSZ8851 eKsz8851) { sint8 s8_ret = 0; uint16 u16_RegValue = 0; u16_RegValue = KSZ8851_ReadHalfWord(eKsz8851, KSZ8851_CIDER); u16_RegValue &= (uint16_t)(~CIDER_REV_MASK); /* simple check for a valid chip being connected to the bus */ /* if ((ks_rdreg16(ps_ks, KSZ8851_CIDER) & ~CIDER_REV_MASK) != CIDER_ID)*/ if (u16_RegValue != CIDER_ID) { s8_ret = -1; } else { } u16_RegValue = KSZ8851_ReadHalfWord(eKsz8851,KSZ8851_MBIR); if((u16_RegValue&(MBIR_TXMBF|MBIR_RXMBF)) ==(MBIR_TXMBF|MBIR_RXMBF)) { if ((u16_RegValue & MBIR_TXMBFA) != 0U) { s8_ret = -2; } else { /* */ } if ((u16_RegValue & MBIR_RXMBFA) != 0U) { s8_ret = -3; } else { /* */ } } else { s8_ret = -1; } return s8_ret; } static void KSZ8851_DisableQmu(E_KSZ8851 eKsz8851) { uint16 u16_RegValue = 0; u16_RegValue = KSZ8851_ReadHalfWord(eKsz8851, KSZ8851_TXCR); /* * 禁能QMU发送(TXCR). */ u16_RegValue &= (uint16)(~TXCR_TXE); KSZ8851_WriteHalfWord(eKsz8851, KSZ8851_TXCR, u16_RegValue); /* 禁能QMU接收(RXCR1). */ u16_RegValue = KSZ8851_ReadHalfWord(eKsz8851, KSZ8851_RXCR1); u16_RegValue &= (uint16)(~RXCR1_RXE); KSZ8851_WriteHalfWord(eKsz8851, KSZ8851_RXCR1, u16_RegValue); } static void KSZ8851_EnableQmu(E_KSZ8851 eKsz8851) { uint16 u16_RegValue = 0; u16_RegValue = KSZ8851_ReadHalfWord(eKsz8851, KSZ8851_TXCR); /* * 使能QMU发送(TXCR). */ u16_RegValue |= (uint16)(TXCR_TXE); KSZ8851_WriteHalfWord(eKsz8851, KSZ8851_TXCR, u16_RegValue); u16_RegValue = KSZ8851_ReadHalfWord(eKsz8851, KSZ8851_RXQCR); KSZ8851_WriteHalfWord(eKsz8851, KSZ8851_RXQCR, (uint16)(u16_RegValue | RXQCR_RXFCTE)); /* 使能QMU接收(RXCR1). */ u16_RegValue = KSZ8851_ReadHalfWord(eKsz8851, KSZ8851_RXCR1); // u16_RegValue &= ~((uint16)(RXCR1_RXINVF | RXCR1_RXPAFMA)); u16_RegValue |= (uint16)(RXCR1_RXE); KSZ8851_WriteHalfWord(eKsz8851, KSZ8851_RXCR1, u16_RegValue); } static void KSZ8851_CustomConfig(E_KSZ8851 eKsz8851) { uint16 u16_RegValue = 0; /* * * Configure QMU Transmit */ /* Setup Transmit Frame Data Pointer Auto-Increment (TXFDPR) */ KSZ8851_WriteHalfWord(eKsz8851, KSZ8851_TXFDPR, TXFDPR_TXFPAI); /* Setup Receive Frame Data Pointer Auto-Increment */ KSZ8851_WriteHalfWord(eKsz8851, KSZ8851_RXFDPR, RXFDPR_RXFPAI); /* Setup Receive Frame duration timer threshold */ KSZ8851_WriteHalfWord(eKsz8851, KSZ8851_RXDTTR, KS_RX_DURATION_THR); /* Setup Receive Frame Threshold - 1 frame (RXFCTFC) */ KSZ8851_WriteHalfWord(eKsz8851, KSZ8851_RXFCTR, (uint16_t)(KS_RX_FRM_CNT & RXFCTR_THRESHOLD_MASK)); /* Setup RxQ Command Control (RXQCR) */ u16_RegValue = RXQCR_CMD_CNTL; KSZ8851_WriteHalfWord(eKsz8851, KSZ8851_RXQCR, u16_RegValue); /* * * set the force mode to half duplex, default is full duplex * because if the auto-negotiation fails, most switch uses * half-duplex. */ u16_RegValue = KSZ8851_ReadHalfWord(eKsz8851, KSZ8851_P1MBCR); u16_RegValue &= (uint16)(~P1MBCR_FORCE_FDX); KSZ8851_WriteHalfWord(eKsz8851, KSZ8851_P1MBCR, u16_RegValue); u16_RegValue = TXCR_TXFCE | TXCR_TXPE | TXCR_TXCRC; /* u16_RegValue = TXCR_TXFCE | TXCR_TXFCE | TXCR_TXCRC | TXCR_TCGIP | TXCR_TCGTCP | TXCR_TCGICMP | TXCR_TCGUDP;*/ KSZ8851_WriteHalfWord(eKsz8851, KSZ8851_TXCR, u16_RegValue); // u16_RegValue = RXCR1_RXFCE | RXCR1_RXBE | RXCR1_RXUE | RXCR1_RXME; u16_RegValue = RXCR1_RXFCE | RXCR1_RXBE | RXCR1_RXUE | RXCR1_RXME; u16_RegValue |= RXCR1_RXPAFMA; KSZ8851_WriteHalfWord(eKsz8851, KSZ8851_RXCR1, u16_RegValue); } static void KSZ8851_SetSoftIrq(E_KSZ8851 eKsz8851,uint16 u16_IrqConfig, uint8 u8_Flag) { uint16 u16_RegValue = 0; u16_RegValue = KSZ8851_ReadHalfWord(eKsz8851, KSZ8851_IER); if(u8_Flag == 0) { u16_RegValue &= ~(u16_IrqConfig); KSZ8851_WriteHalfWord(eKsz8851, KSZ8851_IER, u16_IrqConfig); } else { u16_RegValue |= u16_IrqConfig; KSZ8851_WriteHalfWord(eKsz8851, KSZ8851_IER, u16_IrqConfig); } } static void KSZ8851_SetMixedMode(E_KSZ8851 eKsz8851,uint8 u8_Flag) { uint16 u16_RegValue = 0; // KSZ8851_DisableRx(eKsz8851); u16_RegValue = KSZ8851_ReadHalfWord(eKsz8851, KSZ8851_RXCR1); u16_RegValue &= ~RXCR1_FILTER_MASK; if(u8_Flag == 0) { u16_RegValue |= RXCR1_RXPAFMA; } else { u16_RegValue |= RXCR1_RXAE | RXCR1_RXINVF; } KSZ8851_WriteHalfWord(eKsz8851, KSZ8851_RXCR1, u16_RegValue); // KSZ8851_EnableRx(eKsz8851); } static void ks_set_powermode(E_KSZ8851 eKsz8851, uint16 pwrmode_u16) { uint16_t pmecr_u16; KSZ8851_ReadHalfWord(eKsz8851, KSZ8851_GRR); /* */ pmecr_u16 = KSZ8851_ReadHalfWord(eKsz8851, KSZ8851_PMECR); /* */ pmecr_u16 &= (uint16_t)(~PMECR_PM_MASK); pmecr_u16 |= pwrmode_u16; KSZ8851_WriteHalfWord(eKsz8851, KSZ8851_PMECR, pmecr_u16); /* */ } sint8 KSZ8851Init(E_KSZ8851 eKsz8851) { sint8 s8_ret = -1; KSZ8851_InitPort(eKsz8851); KSZ8851_SetPortIrq(eKsz8851); // KSZ8851_InitModule(eKsz8851); if (eKsz8851 == E_KSZ8851_1) { KSZ8851Reset(eKsz8851); } else { } KSZ8851_Config16BitBus(eKsz8851); KSZ8851_SelfTest(eKsz8851); KSZ8851_SoftReset(eKsz8851); KSZ8851_SetMacAddr(eKsz8851); KSZ8851_DisableQmu(eKsz8851); KSZ8851_CustomConfig(eKsz8851); KSZ8851_WriteHalfWord(eKsz8851, KSZ8851_ISR, 0xFFFF);//清除所有中断 KSZ8851_SetMixedMode(eKsz8851,1); ks_set_powermode(eKsz8851,PMECR_AUTO_WAKE_EN); DelayMs(2); KSZ8851_WriteHalfWord(eKsz8851, KSZ8851_ISR, 0xFFFF);//清除所有中断 KSZ8851_SetSoftIrq(eKsz8851,IRQ_LCI | IRQ_RXI | IRQ_RXOI| IRQ_RXPSI,1);//使能中断 KSZ8851_WriteHalfWord(eKsz8851, KSZ8851_ISR, IRQ_LCI | IRQ_TXI | IRQ_RXI | IRQ_RXOI| IRQ_RXPSI); /*shineng zhonduan*/ KSZ8851_EnableQmu(eKsz8851); s8_ret = 0; return s8_ret; } void KSZ8851GetMacAddr(E_KSZ8851 eKsz8851,uint8 *u8_p_data) { memcpy(u8_p_data,&cKsz8851MacAddr[eKsz8851][0],sizeof(cKsz8851MacAddr[eKsz8851])); } static uint16 KSZ8851GetTxFreeBuffer(E_KSZ8851 eKsz8851) { uint16 u16_Len = 0; u16_Len = KSZ8851_ReadHalfWord(eKsz8851, KSZ8851_TXMIR); return (uint16)(u16_Len & TXMIR_SIZE_MASK); } static sint8 KSZ8851_WriteQmu(E_KSZ8851 eKsz8851,uint16 *u16_p_data, uint16 u16_len) { uint16 u16_Length = 0; uint32 i = 0; vPortEnterCritical(); KSZ8851_WriteByte(eKsz8851,KSZ8851_RXQCR, RXQCR_CMD_CNTL|RXQCR_SDA); Fmc_WriteHalfWord(0x00,stKsz8851Struc[eKsz8851].phw_addr_data); Fmc_WriteHalfWord(u16_len,stKsz8851Struc[eKsz8851].phw_addr_data); u16_Length = ((u16_len+(3U))&(~(0x03U))); u16_Length = u16_Length>>1; for(i=0;i<u16_Length;i++) { Fmc_WriteHalfWord(*u16_p_data,stKsz8851Struc[eKsz8851].phw_addr_data); u16_p_data++; } KSZ8851_WriteByte(eKsz8851,KSZ8851_RXQCR, RXQCR_CMD_CNTL); KSZ8851_WriteHalfWord(eKsz8851,KSZ8851_TXQCR, TXQCR_METFE); vPortExitCritical(); while((KSZ8851_ReadHalfWord(eKsz8851,KSZ8851_TXQCR)&TXQCR_METFE)!=0) { if(i >= 0x1000) //约200us { return -1; } i ++; } return 0; } sint8 KSZ8851SendFrame(E_KSZ8851 eKsz8851,uint16 *u16_p_data, uint16 u16_len) { #define KSZ8851TX_GUARD_BLOCK_TIME ( 20 ) sint8 s8_ret = -1; uint16 u16_FreeLen = 0; u16_FreeLen = KSZ8851GetTxFreeBuffer(eKsz8851); if(u16_FreeLen>(u16_len+12U)) { s8_ret = KSZ8851_WriteQmu(eKsz8851,u16_p_data,u16_len); } else { /* do nothing */ } return s8_ret; } static void KSZ8851_ReadQmu(E_KSZ8851 eKsz8851,uint16 *u16_p_data, uint16 u16_len) { uint16 i=0; //set to DMA mode -read KSZ8851_WriteHalfWord(eKsz8851,KSZ8851_RXFDPR, RXFDPR_RXFPAI); KSZ8851_WriteByte(eKsz8851,KSZ8851_RXQCR, RXQCR_CMD_CNTL|RXQCR_SDA); Fmc_ReadHalfWord(stKsz8851Struc[eKsz8851].phw_addr_data); /* discard the first halfword - status register*/ Fmc_ReadHalfWord(stKsz8851Struc[eKsz8851].phw_addr_data); /* discard the second halfword - len register*/ Fmc_ReadHalfWord(stKsz8851Struc[eKsz8851].phw_addr_data); u16_len = (u16_len+1)>>1; for(i=0;i<u16_len;i++) { *u16_p_data = Fmc_ReadHalfWord(stKsz8851Struc[eKsz8851].phw_addr_data); u16_p_data ++; } KSZ8851_WriteByte(eKsz8851,KSZ8851_RXQCR, RXQCR_CMD_CNTL); } static sint8 KSZ8851_RecvNetMessage(E_KSZ8851 eKsz8851) { uint16 u16_Status = 0,u16_Length = 0; uint16 u16_NetFrameCount = 0,u16_NetFrameNormalCount = 0; uint16 i = 0; u16_NetFrameCount = ((KSZ8851_ReadHalfWord(eKsz8851, KSZ8851_RXFCTR))>>8)&0xFF; for(i=0;i<u16_NetFrameCount;i++) { u16_Status = KSZ8851_ReadHalfWord(eKsz8851,KSZ8851_RXFHSR); u16_Length = KSZ8851_ReadHalfWord(eKsz8851,KSZ8851_RXFHBCR); if( (u16_Status&RXFSHR_RXFV) && (u16_Length<=1500)) { KSZ8851_ReadQmu(eKsz8851,(uint16 *)&stKsz8851RxFrameBuff[eKsz8851][stKsz8851RxFrameTail[eKsz8851]],u16_Length); stKsz8851RxFrameLen[eKsz8851][stKsz8851RxFrameTail[eKsz8851]] = u16_Length; stKsz8851RxFrameTail[eKsz8851] ++; if(KSZ8851RxFrameCounterMax <= stKsz8851RxFrameTail[eKsz8851]) { stKsz8851RxFrameTail[eKsz8851] = 0; } else { /* do nothing */ } if(KSZ8851RxFrameCounterMax <= stKsz8851RxFrameCounter[eKsz8851]) { stKsz8851RxFrameHead[eKsz8851] = stKsz8851RxFrameTail[eKsz8851]; } else { stKsz8851RxFrameCounter[eKsz8851] ++; } u16_NetFrameNormalCount ++; } else { /* 丢弃错误帧 */ KSZ8851_WriteHalfWord(eKsz8851, KSZ8851_RXQCR, (uint16)(RXQCR_CMD_CNTL | RXQCR_RRXEF)); } } if(u16_NetFrameNormalCount == 0) { return -2; } else if(u16_NetFrameNormalCount < u16_NetFrameCount) { return -1; } else { return 0; } } uint16 KSZ8851GetRxFrameCounter(E_KSZ8851 eKsz8851) { uint16 u16_len = 0; DISABLE_INT(); u16_len = stKsz8851RxFrameCounter[eKsz8851]; ENABLE_INT(); return u16_len; } uint16 KSZ8851GetRxCurFrameLen(E_KSZ8851 eKsz8851) { uint16 u16_len = 0; if(eKsz8851 < E_KSZ8851_Max) { DISABLE_INT(); u16_len = stKsz8851RxFrameLen[eKsz8851][stKsz8851RxFrameHead[eKsz8851]] ; ENABLE_INT(); } else { } return u16_len; } uint16 KSZ8851ReadFrame(E_KSZ8851 eKsz8851,uint16 *u16_p_data) { uint16 u16_ReadLen = 0; uint16 u16_FrameCounter = 0,i = 0; uint16 *p_u16_data = NULL; DISABLE_INT(); u16_FrameCounter = stKsz8851RxFrameCounter[eKsz8851]; ENABLE_INT(); if(u16_FrameCounter > 0) { DISABLE_INT(); u16_ReadLen = stKsz8851RxFrameLen[eKsz8851][stKsz8851RxFrameHead[eKsz8851]]; p_u16_data = (uint16 *)&stKsz8851RxFrameBuff[eKsz8851][stKsz8851RxFrameHead[eKsz8851]]; ENABLE_INT(); if(u16_ReadLen < 1500) { for(i=0;i<u16_ReadLen;i++) { *u16_p_data++ = *p_u16_data++; } } else { u16_ReadLen = 0; } DISABLE_INT(); stKsz8851RxFrameCounter[eKsz8851] --; stKsz8851RxFrameLen[eKsz8851][stKsz8851RxFrameHead[eKsz8851]] = 0; stKsz8851RxFrameHead[eKsz8851] ++; if(KSZ8851RxFrameCounterMax <= stKsz8851RxFrameHead[eKsz8851]) { stKsz8851RxFrameHead[eKsz8851] = 0; } else { /* do nothing */ } ENABLE_INT(); } return u16_ReadLen; } void KSZ8851_ClearTxQueue(E_KSZ8851 eKsz8851) { uint16 reg_cnt_u16; KSZ8851_DisableTx(eKsz8851); reg_cnt_u16 = KSZ8851_ReadHalfWord(eKsz8851, KSZ8851_TXCR); KSZ8851_WriteHalfWord(eKsz8851, KSZ8851_TXCR, (uint16)(reg_cnt_u16 | TXCR_FTXQ)); KSZ8851_WriteHalfWord(eKsz8851, KSZ8851_TXCR, reg_cnt_u16); KSZ8851_EnableTx(eKsz8851); } static void KSZ8851_ClearRxQueue(E_KSZ8851 eKsz8851) { #define KSZ8851_WAIT_STOP (100U) uint16 reg_cnt_u16,int_status_u16; uint16 i=0; KSZ8851_DisableRx(eKsz8851); for (i= 0U; i < KSZ8851_WAIT_STOP; i++) { int_status_u16 = KSZ8851_ReadHalfWord(eKsz8851, KSZ8851_ISR); if ((int_status_u16 & IRQ_RXPSI) != 0U) { break; } else { /* */ } } reg_cnt_u16 = KSZ8851_ReadHalfWord(eKsz8851, KSZ8851_RXCR1); KSZ8851_WriteHalfWord(eKsz8851, KSZ8851_RXCR1, (uint16)(reg_cnt_u16 | RXCR1_FRXQ)); KSZ8851_WriteHalfWord(eKsz8851, KSZ8851_RXCR1, reg_cnt_u16); KSZ8851_WriteHalfWord(eKsz8851, KSZ8851_ISR, IRQ_RXI); KSZ8851_EnableRx(eKsz8851); KSZ8851_WriteHalfWord(eKsz8851, KSZ8851_ISR, IRQ_RXPSI); } sint8 KSZ8851ISR(E_KSZ8851 eKsz8851) { uint16 u16_RegValue = 0; uint16 u16_OtherValue = 0; sint8 s8_ret = -1; // DISABLE_INT(); u16_RegValue = KSZ8851_ReadHalfWord(eKsz8851, KSZ8851_ISR); if(u16_RegValue==0) { return s8_ret; } KSZ8851_WriteHalfWord(eKsz8851, KSZ8851_ISR, u16_RegValue); if((u16_RegValue&IRQ_LCI) != 0) { /* 处理链接状态变化 */ } else { /* do nothing */ } if((u16_RegValue&IRQ_RXI) != 0) { /* 处理接收 */ s8_ret = KSZ8851_RecvNetMessage(eKsz8851); } else { /* do nothing */ } if((u16_RegValue&IRQ_LDI) != 0) { u16_OtherValue = KSZ8851_ReadHalfWord(eKsz8851, KSZ8851_PMECR); u16_OtherValue &= ~((0xFU)<<2); u16_OtherValue |= ((0x02U)<<2); KSZ8851_WriteHalfWord(eKsz8851, KSZ8851_PMECR, u16_RegValue); } else { /* do nothing */ } if((u16_RegValue&IRQ_RXOI) != 0) { /* 处理接收溢出 */ KSZ8851_ClearRxQueue(eKsz8851); } else { /* do nothing */ } if((u16_RegValue&IRQ_RXPSI) != 0) { /* 处理接收异常停止 */ KSZ8851_ClearRxQueue(eKsz8851); } else { /* do nothing */ } if((u16_RegValue&IRQ_TXPSI) != 0) { /* 处理发送 异常停止*/ } else { /* do nothing */ } // ENABLE_INT(); return s8_ret; }头文件如下:
/****************************************************************************** * 文 件 名 称:BspKsz8851.h * 文件功能概述: * 文 件 作 者: * 版 本:V1.0.0.0 * 修 订 记 录:2018-05-02创建 ******************************************************************************/ #ifndef __BSP_KSZ8851_H__ #define __BSP_KSZ8851_H__ #include ".\BspInterface.h" /* * * 寄存器地址定义 */ #define KSZ8851_CCR ((uint16_t)0x08) /* * 配置寄存器 */ #define KSZ8851_MARL ((uint16_t)0x10) /* * MAC地址低字 */ #define KSZ8851_MARM ((uint16_t)0x12) /* * MAC地址中字 */ #define KSZ8851_MARH ((uint16_t)0x14) /* * MAC地址高字-6字节表示法中的前两字节 */ #define KSZ8851_OBCR ((uint16_t)0x20) /* * 芯片总线控制 */ #define KSZ8851_EEPCR ((uint16_t)0x22) /* * EEPROM控制 */ #define KSZ8851_MBIR ((uint16_t)0x24) /* * 芯片内存自测试状态 */ #define KSZ8851_GRR ((uint16_t)0x26) /* * 全局复位寄存器 */ #define KSZ8851_WFCR ((uint16_t)0x2A) /* * 唤醒帧控制 */ #define KSZ8851_WF0CRC0 ((uint16_t)0x30) /* * 唤醒帧0CRC0寄存器 */ #define KSZ8851_WF0CRC1 ((uint16_t)0x32) /* * 唤醒帧0CRC1寄存器 */ #define KSZ8851_WF0BM0 ((uint16_t)0x34) /* * 唤醒帧0字节掩码0寄存器 */ #define KSZ8851_WF0BM1 ((uint16_t)0x36) /* * 唤醒帧0字节掩码1寄存器 */ #define KSZ8851_WF0BM2 ((uint16_t)0x38) /* * 唤醒帧0字节掩码2寄存器 */ #define KSZ8851_WF0BM3 ((uint16_t)0x3A) /* * 唤醒帧0字节掩码3寄存器 */ #define KSZ8851_WF1CRC0 ((uint16_t)0x40) /* * 唤醒帧1CRC0寄存器 */ #define KSZ8851_WF1CRC1 ((uint16_t)0x42) /* * 唤醒帧1CRC1寄存器 */ #define KSZ8851_WF1BM0 ((uint16_t)0x44) /* * 唤醒帧1字节掩码0寄存器 */ #define KSZ8851_WF1BM1 ((uint16_t)0x46) /* * 唤醒帧1字节掩码1寄存器 */ #define KSZ8851_WF1BM2 ((uint16_t)0x48) /* * 唤醒帧1字节掩码2寄存器 */ #define KSZ8851_WF1BM3 ((uint16_t)0x4A) /* * 唤醒帧1字节掩码3寄存器 */ #define KSZ8851_WF2CRC0 ((uint16_t)0x50) /* * 唤醒帧2CRC0寄存器 */ #define KSZ8851_WF2CRC1 ((uint16_t)0x52) /* * 唤醒帧2CRC1寄存器 */ #define KSZ8851_WF2BM0 ((uint16_t)0x54) /* * 唤醒帧2字节掩码0寄存器 */ #define KSZ8851_WF2BM1 ((uint16_t)0x56) /* * 唤醒帧2字节掩码1寄存器 */ #define KSZ8851_WF2BM2 ((uint16_t)0x58) /* * 唤醒帧2字节掩码2寄存器 */ #define KSZ8851_WF2BM3 ((uint16_t)0x5A) /* * 唤醒帧2字节掩码3寄存器 */ #define KSZ8851_WF3CRC0 ((uint16_t)0x60) /* * 唤醒帧3CRC0寄存器 */ #define KSZ8851_WF3CRC1 ((uint16_t)0x62) /* * 唤醒帧3CRC1寄存器 */ #define KSZ8851_WF3BM0 ((uint16_t)0x64) /* * 唤醒帧3字节掩码0寄存器 */ #define KSZ8851_WF3BM1 ((uint16_t)0x66) /* * 唤醒帧3字节掩码1寄存器 */ #define KSZ8851_WF3BM2 ((uint16_t)0x68) /* * 唤醒帧3字节掩码2寄存器 */ #define KSZ8851_WF3BM3 ((uint16_t)0x6A) /* * 唤醒帧3字节掩码3寄存器 */ #define KSZ8851_TXCR ((uint16_t)0x70) /* * 发送控制寄存器 */ #define KSZ8851_TXSR ((uint16_t)0x72) /* * 发送状态寄存器 */ #define KSZ8851_RXCR1 ((uint16_t)0x74) /* * 接收状态寄存器1 */ #define KSZ8851_RXCR2 ((uint16_t)0x76) /* * 接收状态寄存器2 */ #define KSZ8851_TXMIR ((uint16_t)0x78) /* * TXQ存储区信息寄存器 */ #define KSZ8851_RXFHSR ((uint16_t)0x7C) /* * 接收帧头状态寄存器 */ #define KSZ8851_RXFHBCR ((uint16_t)0x7E) /* * 接收帧头字节数寄存器 */ #define KSZ8851_TXQCR ((uint16_t)0x80) /* * TXQ命令寄存器 */ #define KSZ8851_RXQCR ((uint16_t)0x82) /* * RXQ命令寄存器 */ #define KSZ8851_TXFDPR ((uint16_t)0x84) /* * 发送帧数据地址指针寄存器 */ #define KSZ8851_RXFDPR ((uint16_t)0x86) /* * 接收帧数据地址指针寄存器 */ #define KSZ8851_RXDTTR ((uint16_t)0x8C) /* * 接收数据持续时间阈值寄存器 */ #define KSZ8851_RXDBCTR ((uint16_t)0x8E) /* * 接收数据字节长度阈值寄存器 */ #define KSZ8851_IER ((uint16_t)0x90) /* * 中断使能寄存器 */ #define KSZ8851_ISR ((uint16_t)0x92) /* * 中断状态寄存器 */ #define KSZ8851_RXFCTR ((uint16_t)0x9C) /* * 接收帧计数及阈值寄存器 */ #define KSZ8851_TXNTFSR ((uint16_t)0x9E) /* * 待发送帧长度请求寄存器 */ #define KSZ8851_MAHTR0 ((uint16_t)0xA0) /* * 哈希过滤表寄存器0 */ #define KSZ8851_MAHTR1 ((uint16_t)0xA2) /* * 哈希过滤表寄存器1 */ #define KSZ8851_MAHTR2 ((uint16_t)0xA4) /* * 哈希过滤表寄存器2 */ #define KSZ8851_MAHTR3 ((uint16_t)0xA6) /* * 哈希过滤表寄存器3 */ #define KSZ8851_FCLWR ((uint16_t)0xB0) /* * 流控下限寄存器 */ #define KSZ8851_FCHWR ((uint16_t)0xB2) /* * 流控上限寄存器 */ #define KSZ8851_FCOWR ((uint16_t)0xB4) /* * 流控超限寄存器 */ #define KSZ8851_CIDER ((uint16_t)0xC0) /* * 芯片ID寄存器 */ #define KSZ8851_CGCR ((uint16_t)0xC6) /* * 芯片全局控制寄存器 */ #define KSZ8851_PMECR ((uint16_t)0xD4) /* * 电源管理事件控制寄存器 */ #define KSZ8851_P1MBCR ((uint16_t)0xE4) /* * MII寄存器基本控制寄存器 */ #define KSZ8851_P1MBSR ((uint16_t)0xE6) /* * MII寄存器基本状态寄存器 */ #define KSZ8851_P1SCLMD ((uint16_t)0xF4) /* * 端口1LinkMD控制/状态寄存器 */ #define KSZ8851_P1CR ((uint16_t)0xF6) /* * 端口1控制寄存器 */ #define KSZ8851_P1SR ((uint16_t)0xF8) /* * 端口1状态寄存器 */ /* * 配置寄存器 */ #define CCR_EEPROM ((uint16_t)(1U << 9)) /* * EEPROM配置位 */ #define CCR_SPI ((uint16_t)(1U << 8)) /* * SPI模式,手册中为保留 */ #define CCR_8BIT ((uint16_t)(1U << 7)) /* * 8位总线模式 */ #define CCR_16BIT ((uint16_t)(1U << 6)) /* * 16位总线模式 */ #define CCR_32BIT ((uint16_t)(1U << 5)) /* * 32位总线模式,手册中为保留 */ #define CCR_SHARED ((uint16_t)(1U << 4)) /* * 地址数据总线共享模式 */ #define CCR_48PIN ((uint16_t)(1U << 1)) /* * 48脚封装 */ #define CCR_32PIN ((uint16_t)(1U << 0)) /* * 32脚封装,手册中为保留 */ /* * 芯片总线控制 */ #define OBCR_ODS_16MA ((uint16_t)(1U << 6)) /* * 引脚驱动电流16mA */ #define OBCR_BCDS_1 ((uint16_t)(0U << 0)) /* * 1分频 */ #define OBCR_BCDS_2 ((uint16_t)(1U << 0)) /* * 2分频 */ #define OBCR_BCDS_3 ((uint16_t)(2U << 0)) /* * 3分频 */ #define OBCR_BCDS_MSK ((uint16_t)(3U << 0)) /* * 分频设置掩码 */ /* * EEPROM控制 */ #define EEPCR_EESA ((uint16_t)(1U << 4)) /* * 允许软件存取EEPROM */ #define EEPCR_EESB ((uint16_t)(1U << 3)) /* * EEPROM数据读出位,对应EED_IO */ #define EEPCR_EEDO ((uint16_t)(1U << 2)) /* * EEPROM数据写入位,对应EED_IO */ #define EEPCR_EESCK ((uint16_t)(1U << 1)) /* * EEPROM时钟,对应EESK */ #define EEPCR_EECS ((uint16_t)(1U << 0)) /* * EEPROM操作选择位,对应EECS */ /* * 芯片内存自测试状态 */ #define MBIR_TXMBF ((uint16_t)(1U << 12)) /* * 置位,发送区测试完成 */ #define MBIR_TXMBFA ((uint16_t)(1U << 11)) /* * 置位,发送区测试失败 */ #define MBIR_RXMBF ((uint16_t)(1U << 4)) /* * 置位,接收区测试完成 */ #define MBIR_RXMBFA ((uint16_t)(1U << 3)) /* * 置位,接收区测试失败 */ /* * 全局复位寄存器 */ #define GRR_QMU ((uint16_t)(1U << 1)) /* * 软件复位QMU */ #define GRR_GSR ((uint16_t)(1U << 0)) /* * 全局软件复位 */ /* * 唤醒帧控制寄存器 */ #define WFCR_MPRXE ((uint16_t)(1U << 7)) /* * 魔幻包唤醒使能 */ #define WFCR_WF3E ((uint16_t)(1U << 3)) /* * 唤醒帧3使能 */ #define WFCR_WF2E ((uint16_t)(1U << 2)) /* * 唤醒帧2使能 */ #define WFCR_WF1E ((uint16_t)(1U << 1)) /* * 唤醒帧1使能 */ #define WFCR_WF0E ((uint16_t)(1U << 0)) /* * 唤醒帧0使能 */ /* * 发送控制寄存器 */ #define TXCR_TCGICMP ((uint16_t)(1U << 8)) /* * 生成ICMP校验码 */ #define TXCR_TCGUDP ((uint16_t)(1U << 7)) /* * 生成UDP校验码,手册中为保留 */ #define TXCR_TCGTCP ((uint16_t)(1U << 6)) /* * 生成TCP校验码 */ #define TXCR_TCGIP ((uint16_t)(1U << 5)) /* * 生成IP校验码 */ #define TXCR_FTXQ ((uint16_t)(1U << 4)) /* * 清除发送队列缓冲区并复位发送指针 */ #define TXCR_TXFCE ((uint16_t)(1U << 3)) /* * 使能发送流控 */ #define TXCR_TXPE ((uint16_t)(1U << 2)) /* * 使能自动追加数据 */ #define TXCR_TXCRC ((uint16_t)(1U << 1)) /* * 使能发送帧校验和计算 */ #define TXCR_TXE ((uint16_t)(1U << 0)) /* * 使能发送 */ /* * 发送状态寄存器 */ #define TXSR_TXLC ((uint16_t)(1U << 13)) /* * 发送晚到冲突 */ #define TXSR_TXMC ((uint16_t)(1U << 12)) /* * 发送冲突达到最大值 */ #define TXSR_TXFID_MASK ((uint16_t)(0x3FU << 0)) /* * 帧ID掩码 */ #define TXSR_TXFID_SHIFT ((uint16_t)(0)) /* * 帧ID移位数 */ #define TXSR_TXFID_GET(_v) (((_v) >> 0U) & 0x3FU) /* * 接收控制寄存器1 */ #define RXCR1_FRXQ ((uint16_t)(1U << 15)) /* * 清除接收缓冲区并复位接收指针,须先禁能接收 */ #define RXCR1_RXUDPFCC ((uint16_t)(1U << 14)) /* * 使能UDP校验检查 */ #define RXCR1_RXTCPFCC ((uint16_t)(1U << 13)) /* * 使能TCP校验检查 */ #define RXCR1_RXIPFCC ((uint16_t)(1U << 12)) /* * 使能IP校验检查 */ #define RXCR1_RXPAFMA ((uint16_t)(1U << 11)) /* * 使能MAC地址过滤 */ #define RXCR1_RXFCE ((uint16_t)(1U << 10)) /* * 使能接收流控 */ #define RXCR1_RXEFE ((uint16_t)(1U << 9)) /* * 使能接收CRC错误帧 */ #define RXCR1_RXMAFMA ((uint16_t)(1U << 8)) /* * 使能组播MAC地址过滤 */ #define RXCR1_RXBE ((uint16_t)(1U << 7)) /* * 使能接收广播帧 */ #define RXCR1_RXME ((uint16_t)(1U << 6)) /* * 使能接收组播帧 */ #define RXCR1_RXUE ((uint16_t)(1U << 5)) /* * 使能接收单播帧 */ #define RXCR1_RXAE ((uint16_t)(1U << 4)) /* * 使能接收所有帧 */ #define RXCR1_RXINVF ((uint16_t)(1U << 1)) /* * 使能反转过滤 */ #define RXCR1_RXE ((uint16_t)(1U << 0)) /* * 使能接收 */ /* * 过滤掩码 */ #define RXCR1_FILTER_MASK (RXCR1_RXINVF | RXCR1_RXAE | RXCR1_RXMAFMA | RXCR1_RXPAFMA) /* * 接收控制寄存器2 */ #if 0 /* * 手册中无此定义 */ #define RXCR2_SRDBL_MASK (0x7U << 5) /* * */ #define RXCR2_SRDBL_SHIFT (5) /* * */ #define RXCR2_SRDBL_4B (0x0U << 5) #define RXCR2_SRDBL_8B (0x1U << 5) #define RXCR2_SRDBL_16B (0x2U << 5) #define RXCR2_SRDBL_32B (0x3U << 5) #define RXCR2_SRDBL_FRAME (0x4U << 5) #endif #define RXCR2_IUFFP ((uint16_t)(1U << 4)) /* * 使能IP分割帧校验接收 */ #define RXCR2_RXIUFCEZ ((uint16_t)(1U << 3)) /* * 使能IP校验检查 */ #define RXCR2_UDPLFE ((uint16_t)(1U << 2)) /* * 使能UDP校验检查 */ #define RXCR2_RXICMPFCC ((uint16_t)(1U << 1)) /* * 使能ICMP校验检查 */ #define RXCR2_RXSAF ((uint16_t)(1U << 0)) /* * 使能源地址过滤 */ #define TXMIR_SIZE_MASK ((uint16_t)0x1FFF) /* * 可用发送缓冲区大小,最大6kB */ /* * 接收帧头状态寄存器 */ #define RXFSHR_RXFV ((uint16_t)(1U << 15)) /* * 接收帧有效标志 */ #define RXFSHR_RXICMPFCS ((uint16_t)(1U << 13)) /* * 接收的ICMP帧校验错 */ #define RXFSHR_RXIPFCS ((uint16_t)(1U << 12)) /* * 接收的IP帧校验错 */ #define RXFSHR_RXTCPFCS ((uint16_t)(1U << 11)) /* * 接收的TCP帧校验错 */ #define RXFSHR_RXUDPFCS ((uint16_t)(1U << 10)) /* * 接收的UDP帧校验错 */ #define RXFSHR_RXBF ((uint16_t)(1U << 7)) /* * 接收到广播帧 */ #define RXFSHR_RXMF ((uint16_t)(1U << 6)) /* * 接收到组播帧 */ #define RXFSHR_RXUF ((uint16_t)(1U << 5)) /* * 接收到单播帧 */ #define RXFSHR_RXMR ((uint16_t)(1U << 4)) /* * 接收的帧存在MII标记错 */ #define RXFSHR_RXFT ((uint16_t)(1U << 3)) /* * 置位表示接收的是以太帧,清位表示是802.3帧 */ #define RXFSHR_RXFTL ((uint16_t)(1U << 2)) /* * 接收到超长帧 */ #define RXFSHR_RXRF ((uint16_t)(1U << 1)) /* * 接收到过小帧 */ #define RXFSHR_RXCE ((uint16_t)(1U << 0)) /* * 接收帧CRC错 */ /* * 接收错误标志码 */ #define RXFSHR_ERR (RXFSHR_RXCE | RXFSHR_RXRF | RXFSHR_RXFTL | RXFSHR_RXMR | \ RXFSHR_RXICMPFCS | RXFSHR_RXIPFCS | RXFSHR_RXTCPFCS) /* * 发送命令寄存器 */ #define TXQCR_AETFE ((uint16_t)(1U << 2)) /* * 置位启用发送自动队列 */ #define TXQCR_TXQMAM ((uint16_t)(1U << 1)) /* * 使能发送缓冲区可用监视 */ #define TXQCR_METFE ((uint16_t)(1U << 0)) /* * 使能手动队列 */ /* * 接收命令寄存器 */ #define RXQCR_RXDTTS ((uint16_t)(1U << 12)) /* * 接收持续定时器阈值状态 */ #define RXQCR_RXDBCTS ((uint16_t)(1U << 11)) /* * 接收字节数阈值状态 */ #define RXQCR_RXFCTS ((uint16_t)(1U << 10)) /* * 接收帧数阈值状态 */ #define RXQCR_RXIPHTOE ((uint16_t)(1U << 9)) /* * 使能IP报头两字节偏移功能 */ #define RXQCR_RXDTTE ((uint16_t)(1U << 7)) /* * 使能持续接收定时功能 */ #define RXQCR_RXDBCTE ((uint16_t)(1U << 6)) /* * 使能接收字节数阈值控制功能 */ #define RXQCR_RXFCTE ((uint16_t)(1U << 5)) /* * 使能接收帧数阈值控制功能 */ #define RXQCR_ADRFE ((uint16_t)(1U << 4)) /* * 使能接收报文自动出队列 */ #define RXQCR_SDA ((uint16_t)(1U << 3)) /* * 使能DMA操作 */ #define RXQCR_RRXEF ((uint16_t)(1U << 0)) /* * 释放错误帧 */ /* * 使用帧数控制和报文自动队((uint16_t)列 */ #define RXQCR_CMD_CNTL (RXQCR_RXFCTE | RXQCR_ADRFE | RXQCR_RXDTTE) /* #define RXQCR_CMD_CNTL (RXQCR_RXFCTE | RXQCR_ADRFE )*/ /* * 发送帧数据指针寄存器 */ #define TXFDPR_TXFPAI ((uint16_t)(1U << 14)) /* * 发送帧数据指针自动增加 */ #define TXFDPR_TXFP_MASK (0x7FFU << 0) /* * 发送帧数据指针值掩码 */ #define TXFDPR_TXFP_SHIFT (0) /* * 移位数 */ /* * 接收帧数据指针寄存器 */ #define RXFDPR_RXFPAI ((uint16_t)(1U << 14)) /* * 接收帧数据指针自动增加 */ #define RXFDPR_WST ((uint16_t)(1U << 12)) /* * 写采样时间,清位8~16ns,置位4ns */ #define RXFDPR_EMS ((uint16_t)(1U << 11)) /* * 端模式设置,清位;小端,置位:大端 */ #define RXFDPR_RXFP_MASK (0x7FFU << 0) /* * 接收帧数据指针值掩码 */ #define RXFDPR_RXFP_SHIFT (0) /* * 移位数 */ /* * 中断使能、状态寄存器 */ #define IRQ_LCI ((uint16_t)(1U << 15)) /* * 链接状态改变中断标志,使能或中断有效 */ #define IRQ_TXI ((uint16_t)(1U << 14)) /* * 发送中断 */ #define IRQ_RXI ((uint16_t)(1U << 13)) /* * 接收中断 */ #define IRQ_RXOI ((uint16_t)(1U << 11)) /* * 接收超载中断 */ #define IRQ_TXPSI ((uint16_t)(1U << 9)) /* * 发送停止中断 */ #define IRQ_RXPSI ((uint16_t)(1U << 8)) /* * 接收停止中断 */ #define IRQ_TXSAI ((uint16_t)(1U << 6)) /* * 发送空间有效中断 */ #define IRQ_RXWFDI ((uint16_t)(1U << 5)) /* * 接收检测到唤醒帧 */ #define IRQ_RXMPDI ((uint16_t)(1U << 4)) /* * 接收检测到麻木魔术包 */ #define IRQ_LDI ((uint16_t)(1U << 3)) /* * 建立链接中断 */ #define IRQ_EDI ((uint16_t)(1U << 2)) /* * 当前信道检测到能量中断 */ #define IRQ_SPIBEI ((uint16_t)(1U << 1)) /* * 手册中未定义 */ #define IRQ_DEDI ((uint16_t)(1U << 0)) /* * 延迟能量检测中断 */ /* * 接收帧计数及阈值寄存器 */ #define RXFCTR_THRESHOLD_MASK (0x0005U) /* * 帧计数阈值掩码 */ /* * 芯片ID寄存器 */ #define CIDER_ID (0x8870U) /* * 芯片ID */ #define CIDER_REV_MASK ((uint16_t)(0x7U << 1)) #define CIDER_REV_SHIFT (1) #define CIDER_REV_GET(_v) (((_v) >> 1) & 0x7) /* * 间接存取控制寄存器 */ #define IACR_RDEN ((uint16_t)(1U << 12)) /* * 读使能 */ #define IACR_TSEL_MASK ((uint16_t)(0x3U << 10)) /* * 数据表选择掩码 */ #define IACR_TSEL_SHIFT (10) /* * */ #define IACR_TSEL_MIB ((uint16_t)(0x3U << 10)) #define IACR_ADDR_MASK ((uint16_t)(0x1FU << 0)) /* * MIB地址 */ #define IACR_ADDR_SHIFT (0) /* * 电源管理控制寄存器 */ #define PMECR_PME_DELAY ((uint16_t)(1U << 14)) /* * PME引脚输出延时使能 */ #define PMECR_PME_POL ((uint16_t)(1U << 12)) /* * PME输出极性,置位:高有效 清位:低有效 */ #define PMECR_WOL_WAKEUP ((uint16_t)(1U << 11)) /* * 使能唤醒帧影响PME引脚 */ #define PMECR_WOL_MAGICPKT ((uint16_t)(1U << 10)) /* * 使能魔术帧影响PME引脚 */ #define PMECR_WOL_LINKUP ((uint16_t)(1U << 9)) /* * 使能链接建立状态影响PME引脚 */ #define PMECR_WOL_ENERGY ((uint16_t)(1U << 8)) /* * 使能信道能量检测影响PME引脚 */ #define PMECR_AUTO_WAKE_EN ((uint16_t)(1U << 7)) /* * 使能自动唤醒 */ #define PMECR_WAKEUP_NORMAL ((uint16_t)(1U << 6)) /* * 能量检测唤醒到正常模式 */ #define PMECR_WKEVT_MASK ((uint16_t)(0xFU << 2)) /* * 唤醒事件掩码 */ #define PMECR_WKEVT_SHIFT (2) /* * 移位数 */ #define PMECR_WKEVT_GET(_v) (((_v) >> 2U) & 0xFU) /* * 取唤醒事件 */ #define PMECR_WKEVT_ENERGY ((uint16_t)(0x1U << 2)) /* * 信道能量检测唤醒事件 */ #define PMECR_WKEVT_LINK ((uint16_t)(0x2U << 2)) /* * 链接建立唤醒事件 */ #define PMECR_WKEVT_MAGICPKT ((uint16_t)(0x4U << 2)) /* * 魔术包唤醒事件 */ #define PMECR_WKEVT_FRAME ((uint16_t)(0x8U << 2)) /* * 唤醒帧唤醒事件 */ #define PMECR_PM_MASK ((uint16_t)(0x3U << 0)) /* * 电源管理模式掩码 */ #define PMECR_PM_SHIFT (0) /* * 移位数 */ #define PMECR_PM_NORMAL ((uint16_t)(0x0U << 0)) /* * 正常模式 */ #define PMECR_PM_ENERGY ((uint16_t)(0x1U << 0)) /* * 能量检测模式 */ #define PMECR_PM_SOFTDOWN ((uint16_t)(0x2U << 0)) /* * 软件掉电模式 */ #define PMECR_PM_POWERSAVE ((uint16_t)(0x3U << 0)) /* * 节能模式 */ /* * PHY MII寄存器基础控制寄存器 */ #define P1MBCR_LLB ((uint16_t)(1U << 14)) /* * 本地loopback模式 */ #define P1MBCR_FORCE_100 ((uint16_t)(1U << 13)) /* * 禁止自动协商时,强制100/10Mbps,缺省100Mbps */ #define P1MBCR_AN ((uint16_t)(1U << 12)) /* * 使能自动协商 */ #define P1MBCR_RAN ((uint16_t)(1U << 9)) /* * 重启自动协商 */ #define P1MBCR_FORCE_FDX ((uint16_t)(1U << 8)) /* * 强制全双工 */ #define P1MBCR_HP_MDIX ((uint16_t)(1U << 5)) /* * 自动MDIX */ #define P1MBCR_FORCE_MDIX ((uint16_t)(1U << 4)) /* * 强制MDIX */ #define P1MBCR_DIS_HP_MDIX ((uint16_t)(1U << 3)) /* * 禁止自动MDIX */ #define P1MBCR_DIS_TX ((uint16_t)(1U << 1)) /* * 禁止发送 */ #define P1MBCR_DIS_LED ((uint16_t)(1U << 0)) /* * 禁止LED指示 */ /* * PHY MII基础状态寄存器 */ #define P1MBSR_AN_COMPLETE ((uint16_t)(1U << 5)) /* * */ #define P1MBSR_AN_CAPABLE ((uint16_t)(1U << 3)) #define P1MBSR_LINK_UP ((uint16_t)(1U << 2)) #define PHY_ID_LR (0x1430) #define PHY_ID_HI (0X0022) /* * 端口1控制寄存器 */ #define P1CR_DIS_LED ((uint16_t)(1U << 15)) /* * 禁止LED指示 */ #define P1CR_TXIDS ((uint16_t)(1U << 14)) /* * 禁止发送 */ #define P1CR_RAN ((uint16_t)(1U << 13)) /* * 重启自动协商 */ #define P1CR_DIS_MDIX ((uint16_t)(1U << 10)) /* * 禁止自动MDI/MDIX识别 */ #define P1CR_FORCE_MDIX ((uint16_t)(1U << 9)) /* * 强制MDIX */ #define P1CR_ANE ((uint16_t)(1U << 7)) /* * 使能自动协商 */ #define P1CR_FORCE_100BT ((uint16_t)(1U << 6)) /* * 强制100Mbps */ #define P1CR_FORCE_FDX ((uint16_t)(1U << 5)) /* * 强制全双工 */ #define P1CR_ADT_FLOW ((uint16_t)(1U << 4)) /* * 宣告具有流控能力 */ #define P1CR_ADT_100BT_FDX ((uint16_t)(1U << 3)) /* * 宣告具有100M全双工能力 */ #define P1CR_ADT_100BT_HDX ((uint16_t)(1U << 2)) /* * 宣告具有100M半双工能力 */ #define P1CR_ADT_10BT_FDX ((uint16_t)(1U << 1)) /* * 宣告具有10M全双工能力 */ #define P1CR_ADT_10BT_HDX ((uint16_t)(1U << 0)) /* * 宣告具有10M半双工能力 */ /* * 端口1状态寄存器 */ #define P1SR_HP_MDIX ((uint16_t)(1U << 15)) /* * HP自动MDIX模式 */ #define P1SR_REV_POL ((uint16_t)(1U << 13)) /* * 极性翻转 */ #define P1SR_OP_100M ((uint16_t)(1U << 10)) /* * 链接速度100Mbps */ #define P1SR_OP_FDX ((uint16_t)(1U << 9)) /* * 全双工模式 */ #define P1SR_OP_MDI ((uint16_t)(1U << 7)) /* * 工作在MDI模式 */ #define P1SR_AN_DONE ((uint16_t)(1U << 6)) /* * 自动协商完成 */ #define P1SR_LINK_GOOD ((uint16_t)(1U << 5)) /* * 链接状态正常 */ #define P1SR_PNTR_FLOW ((uint16_t)(1U << 4)) /* * 链接远端流控能力 */ #define P1SR_PNTR_100BT_FDX ((uint16_t)(1U << 3)) /* * 链接远端具备100M全双工能力 */ #define P1SR_PNTR_100BT_HDX ((uint16_t)(1U << 2)) /* * 链接远端具备100M半双工能力 */ #define P1SR_PNTR_10BT_FDX ((uint16_t)(1U << 1)) /* * 链接远端具备10M全双工能力 */ #define P1SR_PNTR_10BT_HDX ((uint16_t)(1U << 0)) /* * 链接远端具备10M半双工能力 */ #define BE3 0x8000U /* Byte Enable 3 */ #define BE2 0x4000U /* Byte Enable 2 */ #define BE1 0x2000U /* Byte Enable 1 */ #define BE0 0x1000U /* Byte Enable 0 */ #define KS_RX_DURATION_THR ((uint16_t)1000) /* * 持续接收时间阈值,单位:us */ #define KS_RX_FRM_CNT (1U) /* * 收到5帧再中断 */ typedef struct { uint16 __IO *phw_addr_data; /* * 芯片数据端口地址 */ uint16 __IO *phw_addr_cmd; /* * 芯片命令端口地址 */ }S_KSZ8851_Struc; typedef struct { uint8 u8_Data[1524+12]; //1524大小加上12字节预留 }Ksz8851RxMsg; typedef struct { uint8 u8_Data[1524+12]; //1524大小加上12字节预留 }Ksz8851TxMsg; typedef enum { E_KSZ8851_1=0x00, E_KSZ8851_2, E_KSZ8851_Max, E_KSZ8851_Invalid }E_KSZ8851; #define KSZ8851RxFrameCounterMax 5 //#define KSZ8851TxBuffSize 5 sint8 KSZ8851Init(E_KSZ8851 eKsz8851); void KSZ8851GetMacAddr(E_KSZ8851 eKsz8851,uint8 *u8_p_data); sint8 KSZ8851SendFrame(E_KSZ8851 eKsz8851,uint16 *u16_p_data, uint16 u16_len); uint16 KSZ8851ReadFrame(E_KSZ8851 eKsz8851,uint16 *u16_p_data); uint16 KSZ8851GetRxFrameCounter(E_KSZ8851 eKsz8851); uint16 KSZ8851GetRxCurFrameLen(E_KSZ8851 eKsz8851); void KSZ8851_ClearTxQueue(E_KSZ8851 eKsz8851); sint8 KSZ8851ISR(E_KSZ8851 eKsz8851); #endif