1、背景介绍
ZYNQ通过裕太PHY 8521主要连接两种国产交换芯片,一种为盛科的CTC8096,另一种为32所的JEM5396。框图示意如下:
2、硬件状态确认
首先检查phy的模式,确认为SGMII_MAC-RGMII_PHY
可通过读出A001寄存器确认状态
读出来应该是0x8155
这样确保状态对
3、PHY软件配置
PHY软件需要配置为强制千兆
./phyreg.elf eth1 0x0 0x340
设置phy的tx_delay
一般设置a003寄存器为0xf8或者0xfa
Phyreg代码如下
/*============================================================================Name : main.cAuthor : 123Version :Copyright : Your copyright noticeDescription : Hello World in C============================================================================*/#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <linux/mii.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <linux/sockios.h>
#include <linux/types.h>
#include <netinet/in.h>#define reteck(ret) \if(ret < 0){ \printf("%m! \"%s\" : line: %d\n", __func__, __LINE__); \goto lab; \
}
#define help() \printf("mdio:\n"); \printf("read operation: mdio reg_addr\n"); \printf("write operation: mdio reg_addr value\n"); \printf("For example:\n"); \printf("mdio eth0 1\n"); \printf("mdio eth0 0 0x12\n\n"); \exit(0);int sockfd;int main(int argc, char *argv[]) {if (argc == 1 || !strcmp(argv[1], "-h")) {help();}struct mii_ioctl_data *mii = NULL;struct ifreq ifr;int ret;memset(&ifr, 0, sizeof(ifr));strncpy(ifr.ifr_name, argv[1], IFNAMSIZ - 1);sockfd = socket(PF_LOCAL, SOCK_DGRAM, 0);reteck(sockfd);
//get phy address in smi busret = ioctl(sockfd, SIOCGMIIPHY, &ifr);reteck(ret);mii = (struct mii_ioctl_data*) &ifr.ifr_data;if (argc == 3) {mii->reg_num = (uint16_t) strtoul(argv[2], NULL, 0);ret = ioctl(sockfd, SIOCGMIIREG, &ifr);reteck(ret);printf("read phy addr: 0x%x reg: 0x%x value : 0x%x\n", mii->phy_id,mii->reg_num, mii->val_out);} else if (argc == 4) {mii->reg_num = (uint16_t) strtoul(argv[2], NULL, 0);mii->val_in = (uint16_t) strtoul(argv[3], NULL, 0);ret = ioctl(sockfd, SIOCSMIIREG, &ifr);reteck(ret);printf("write phy addr: 0x%x reg: 0x%x value : 0x%x\n", mii->phy_id,mii->reg_num, mii->val_in);}lab: close(sockfd);return 0;
}
4、交换芯片端配置
交换芯片端与PHY相连的端口需要配置强制千兆模式
针对CTC8096(一般在SDK应用内配置)
ctc8096端将对应端口强制千兆
port 0x0007 auto-neg disableport 0x0007 property auto-neg-mode sgmii-slaver
针对JEM5396(一般在UBOOT阶段配置)
printf("Set Port 5 CONNECT TO ZYNQ SPEED 1000M\n");workBuf[0] = 0x8b;workBuf[1] = 0x0;writeBCM5396_2(&spi, 0, 0x65, workBuf); workBuf[0] = 0x40;workBuf[1] = 0x1; Status = writeBCM5396(&spi, 0x15, 0x0, workBuf );
JEM5396配置的详细代码如下:
// SPDX-License-Identifier: GPL-2.0+
/** (C) Copyright 2001-2015* Wolfgang Denk, DENX Software Engineering, wd@denx.de.* Joe Hershberger, National Instruments*/#include <common.h>
#include <dm.h>
#include <environment.h>
#include <net.h>
#include <dm/device-internal.h>
#include <dm/uclass-internal.h>#define XGpioPs_ReadReg(BaseAddr, RegOffset) \(*(volatile u32 * )((BaseAddr) + (RegOffset)))#define XGpioPs_WriteReg(BaseAddr, RegOffset, Data) \*(volatile u32 *) ((BaseAddr) + RegOffset) = Data#define AD9520READ (0x80)
#define AD9520WRITE (0x00)/*-----------------------国产ZYNQ GPIO 通用代码--------------------------------------------*/
#define XGPIOPS_DATA_LSW_OFFSET 0x00000000U /* Mask and Data Register LSW, WO */
#define XGPIOPS_DATA_MSW_OFFSET 0x00000004U /* Mask and Data Register MSW, WO */
#define XGPIOPS_DATA_OFFSET 0x00000040U /* Data Register, RW */
#define XGPIOPS_DATA_RO_OFFSET 0x00000060U /* Data Register - Input, RO */
#define XGPIOPS_DIRM_OFFSET 0x00000004U //0x00000204U /* Direction Mode Register, RW */
#define XGPIOPS_OUTEN_OFFSET 0x00000208U /* Output Enable Register, RW */
#define XGPIOPS_INTMASK_OFFSET 0x0000020CU /* Interrupt Mask Register, RO */
#define XGPIOPS_INTEN_OFFSET 0x00000210U /* Interrupt Enable Register, WO */
#define XGPIOPS_INTDIS_OFFSET 0x00000214U /* Interrupt Disable Register, WO*/
#define XGPIOPS_INTSTS_OFFSET 0x00000218U /* Interrupt Status Register, RO */
#define XGPIOPS_INTTYPE_OFFSET 0x0000021CU /* Interrupt Type Register, RW */
#define XGPIOPS_INTPOL_OFFSET 0x00000220U /* Interrupt Polarity Register, RW */
#define XGPIOPS_INTANY_OFFSET 0x00000224U /* Interrupt On Any Register, RW */#define XGPIOPS_DATA_MASK_OFFSET 0x00000008U /* Data/Mask Registers offset */
#define XGPIOPS_DATA_BANK_OFFSET 0x00000004U /* Data Registers offset */
#define XGPIOPS_REG_MASK_OFFSET 0x00000100U /* Registers offset */ //0x00000040U /* For backwards compatibility */
#define XGPIOPS_BYPM_MASK_OFFSET (u32)0x40#define XGPIOPS_INTTYPE_BANK0_RESET 0xFFFFFFFFU
#define XGPIOPS_INTTYPE_BANK1_RESET 0x3FFFFFFFU
#define XGPIOPS_INTTYPE_BANK2_RESET 0xFFFFFFFFU
#define XGPIOPS_INTTYPE_BANK3_RESET 0xFFFFFFFFU#define XGPIOPS_IRQ_TYPE_EDGE_RISING 0x00U /**< Interrupt on Rising edge */
#define XGPIOPS_IRQ_TYPE_EDGE_FALLING 0x01U /**< Interrupt Falling edge */
#define XGPIOPS_IRQ_TYPE_EDGE_BOTH 0x02U /**< Interrupt on both edges */
#define XGPIOPS_IRQ_TYPE_LEVEL_HIGH 0x03U /**< Interrupt on high level */
#define XGPIOPS_IRQ_TYPE_LEVEL_LOW 0x04U /**< Interrupt on low level */
/*@}*/#define XGPIOPS_BANK0 0x00U /**< GPIO Bank 0 */
#define XGPIOPS_BANK1 0x01U /**< GPIO Bank 1 */
#define XGPIOPS_BANK2 0x02U /**< GPIO Bank 2 */
#define XGPIOPS_BANK3 0x03U /**< GPIO Bank 3 */#define XGPIOPS_MAX_BANKS 0x04U /**< Max banks in a GPIO device */
#define XGPIOPS_BANK_MAX_PINS (u32)32 /**< Max pins in a GPIO bank */#define XGPIOPS_DEVICE_MAX_PIN_NUM (u32)118 /*< Max pins in the GPIO device*/#define LED_DELAY 10000000
#define FLASH_RESET_GPIO 0x41220000
#define FLASH_RST_PERIOD 600000#define FIFO_CFG_GPIO 0x41210000
#define FIFO_DONE_GPIO 0x41220000#define UBOOT_CFG_GPIO 0x41250000#define GGF_REST_GPIO 0x41260000
#define DBFGKJ_REST_GPIO 0x412A0000
#define FIRST_V_GPIO 0x41260000
#define SECOND_V_GPIO 0x41270000
#define THIRD_V_GPIO 0x41280000
#define FORTH_V_GPIO 0x41290000typedef void (*XGpioPs_Handler) (void *CallBackRef, u32 Bank, u32 Status);typedef struct {u16 DeviceId; /**< Unique ID of device */u32 BaseAddr; /**< Register base address */
} XGpioPs_Config;typedef struct {XGpioPs_Config GpioConfig; /**< Device configuration */u32 IsReady; /**< Device is initialized and ready */XGpioPs_Handler Handler; /**< Status handlers for all banks */void *CallBackRef; /**< Callback ref for bank handlers */
} XGpioPs;XGpioPs_Config XGpioPs_ConfigTable[] =
{{0,0xE0003000}
};XGpioPs_Config *g_GpioConfig;void XGpioPs_GetBankPin(u8 PinNumber, u8 *BankNumber, u8 *PinNumberInBank)
{/** This structure defines the mapping of the pin numbers to the banks when* the driver APIs are used for working on the individual pins.*/u32 XGpioPsPinTable[] = {(u32)31, /* 0 - 31, Bank 0 */(u32)63, /* 32 - 53, Bank 1 */(u32)95, /* 54 - 85, Bank 2 */(u32)127 /* 86 - 117 Bank 3 */};*BankNumber = 0U;while (*BankNumber < 4U) {if (PinNumber <= XGpioPsPinTable[*BankNumber]) {break;}(*BankNumber)++;}if (*BankNumber == (u8)0) {*PinNumberInBank = PinNumber;} else {*PinNumberInBank = (u8)((u32)PinNumber %(XGpioPsPinTable[*BankNumber - (u8)1] + (u32)1));}
}void XGpioPs_SetDirectionPin(XGpioPs *InstancePtr, u32 Pin, u32 Direction)
{u8 Bank;u8 PinNumber;u32 DirModeReg;/** Get the Bank number and Pin number within the bank.*/XGpioPs_GetBankPin((u8)Pin, &Bank, &PinNumber);DirModeReg = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr,((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +XGPIOPS_DIRM_OFFSET);// DirModeReg = XGpioPs_ReadReg(0xE000A244,0);if (Direction!=(u32)0) { /* input Direction */DirModeReg |= ((u32)1 << (u32)PinNumber);} else { /* output Direction */DirModeReg &= ~ ((u32)1 << (u32)PinNumber);}XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr,((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +XGPIOPS_DIRM_OFFSET, DirModeReg);// XGpioPs_WriteReg(0xE000A244, 0,DirModeReg);
}void XGpioPs_SetOutputEnablePin(XGpioPs *InstancePtr, u32 Pin, u32 OpEnable)
{u8 Bank;u8 PinNumber;u32 OpEnableReg;/** Get the Bank number and Pin number within the bank.*/XGpioPs_GetBankPin((u8)Pin, &Bank, &PinNumber);OpEnableReg = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr,((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +XGPIOPS_OUTEN_OFFSET);// OpEnableReg = XGpioPs_ReadReg(0xE000A248,0);if (OpEnable != (u32)0) { /* Enable Output Enable */OpEnableReg |= ((u32)1 << (u32)PinNumber);} else { /* Disable Output Enable */OpEnableReg &= ~ ((u32)1 << (u32)PinNumber);}XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr,((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +XGPIOPS_OUTEN_OFFSET, OpEnableReg);
// XGpioPs_WriteReg(0xE000A248,0, OpEnableReg);
}void XGpioPs_WritePin(XGpioPs *InstancePtr, u32 Pin, u32 Data)
{u32 Value;u8 Bank;u8 PinNumber;u32 DataVar = Data;/** Get the Bank number and Pin number within the bank.*/XGpioPs_GetBankPin((u8)Pin, &Bank, &PinNumber);
//
// if (PinNumber > 15U) {/** There are only 16 data bits in bit maskable register.*/
// PinNumber -= (u8)16;
// RegOffset = XGPIOPS_DATA_MSW_OFFSET;
// } else {
// RegOffset = XGPIOPS_DATA_LSW_OFFSET;
// }/** Get the 32 bit value to be written to the Mask/Data register where* the upper 16 bits is the mask and lower 16 bits is the data.*/DataVar &= (u32)0x01;Value = ((DataVar << PinNumber) | 0x00000000U);XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr,((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +XGPIOPS_DATA_LSW_OFFSET, Value);
}u32 XGpioPs_ReadPin(XGpioPs *InstancePtr, u32 Pin)
{u8 Bank;u8 PinNumber;/** Get the Bank number and Pin number within the bank.*/XGpioPs_GetBankPin((u8)Pin, &Bank, &PinNumber);return (XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr,((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +XGPIOPS_DATA_LSW_OFFSET) >> (u32)PinNumber) & (u32)1;}void mygpio_init(int mioPinNum)
{XGpioPs Gpio;g_GpioConfig = &XGpioPs_ConfigTable[0];//Initialize the GPIO device.Gpio.IsReady = 0U;Gpio.GpioConfig.BaseAddr = g_GpioConfig->BaseAddr;Gpio.GpioConfig.DeviceId = 0;/** Indicate the component is now ready to use.*/Gpio.IsReady = 0x11111111U;//Initialize the GPIO device. endXGpioPs_SetDirectionPin(&Gpio, mioPinNum, 1);// MIO0XGpioPs_WritePin(&Gpio, mioPinNum, 0x1);if(XGpioPs_ReadPin(&Gpio,mioPinNum) != 1)printf("mio reset phy failed \n\r");udelay(2000);XGpioPs_WritePin(&Gpio, mioPinNum, 0x0);if(XGpioPs_ReadPin(&Gpio,mioPinNum) != 0)printf("mio reset phy failed \n\r");udelay(2000);XGpioPs_WritePin(&Gpio, mioPinNum, 0x1);if(XGpioPs_ReadPin(&Gpio,mioPinNum) != 1)printf("mio reset phy failed \n\r");}//
/* JEM5396 读写通用代码 */
//
#ifndef TRUE
#define TRUE 1U
#endif#ifndef FALSE
#define FALSE 0U
#endif#ifndef NULL
#define NULL 0U
#endif#ifndef FPAR_SPIPS_0_DEVICE_ID#define FPS_SPI0_DEVICE_ID (0)
#else#define FPS_SPI0_DEVICE_ID FPAR_SPIPS_0_DEVICE_ID
#endif#ifndef FPS_SPI0_BASEADDR#define FPS_SPI0_BASEADDR (0xe0001000)
#endif#ifndef FPAR_SPIPS_1_DEVICE_ID#define FPS_SPI1_DEVICE_ID (1)
#else#define FPS_SPI1_DEVICE_ID FPAR_SPIPS_1_DEVICE_ID
#endif#ifndef FPS_SPI1_BASEADDR#define FPS_SPI1_BASEADDR (0xe0021000)
#endif#define SLCR_SPI0_CTRL (0x300)
#define SLCR_SPI1_CTRL (0x300)
#define SPI0_APB_RST (0x0)
#define SPI1_APB_RST (0x1)
#define SPI0_REF_RST (0x2)
#define SPI1_REF_RST (0x3)
#define SLCR_LOCK (0x004)
#define SLCR_UNLOCK (0x008)
#define FPS_SLCR_BASEADDR (0xE0026000)register
#define SPIPS_MSTR_OFFSET (0x100)
#define SPIPS_CTRLR0_OFFSET (0x00)
#define SPIPS_CTRLR1_OFFSET (0x04)
#define SPIPS_SSIENR_OFFSET (0x08)
#define SPIPS_MVCR_OFFSET (0x0C)
#define SPIPS_SER_OFFSET (0x10)
#define SPIPS_BAUDR_OFFSET (0x14)
#define SPIPS_TXFTLR_OFFSET (0x18)
#define SPIPS_RXFTLR_OFFSET (0x1C)
#define SPIPS_TXFLR_OFFSET (0x20)
#define SPIPS_RXFLR_OFFSET (0x24)
#define SPIPS_SR_OFFSET (0x28)
#define SPIPS_IMR_OFFSET (0x2C)
#define SPIPS_ISR_OFFSET (0x30)
#define SPIPS_RISR_OFFSET (0x34)
#define SPIPS_TXOICR_OFFSET (0x38)
#define SPIPS_RXOICR_OFFSET (0x3C)
#define SPIPS_RXUICR_OFFSET (0x40)
#define SPIPS_MSTICR_OFFSET (0x44)
#define SPIPS_ICR_OFFSET (0x48)
#define SPIPS_DMACR_OFFSET (0x4C)
#define SPIPS_DMATDLR_OFFSET (0x50)
#define SPIPS_DMARDLR_OFFSET (0x54)
#define SPIPS_IDR_OFFSET (0x58)
#define SPIPS_VERSION_OFFSET (0x5C)
#define SPIPS_DR_OFFSET (0x60)
#define SPIPS_RX_SAMPLE_OFFSET (0xf0)
#define SPIPS_SCTRLR0_OFFSET (0xf4)
#define SPIPS_RSVD1_OFFSET (0xf8)
#define SPIPS_RSVD2_OFFSET (0xfc)#define FMSH_ReadReg(baseAddr, offSet) *((volatile unsigned int *)(baseAddr + offSet))
#define FMSH_WriteReg(baseAddr, offSet, data) *((volatile unsigned int *)(baseAddr + offSet)) = datatypedef struct {u16 deviceId; /**< Unique ID of device */u32 baseAddress; /**< APB Base address of the device */
} FSpiPs_Config_T;#define FPS_SPI_NUM_INSTANCES (1)FSpiPs_Config_T FSpiPs_ConfigTable[] =
{{FPS_SPI0_DEVICE_ID,FPS_SPI0_BASEADDR},{FPS_SPI1_DEVICE_ID,FPS_SPI1_BASEADDR}
};
FSpiPs_Config_T* FSpiPs_LookupConfig(u16 deviceId)
{int index;FSpiPs_Config_T* cfgPtr = NULL;for (index = 0; index < FPS_SPI_NUM_INSTANCES; index++) {if (FSpiPs_ConfigTable[index].deviceId == deviceId) {cfgPtr = &FSpiPs_ConfigTable[index];break;}}return cfgPtr;
}typedef unsigned char BOOL;typedef void (*FSpiPs_StatusHandler) (void *CallBackRef, u32 StatusEvent,u32 ByteCount);typedef struct FSpiPs_Tag{FSpiPs_Config_T config; /**< Configuration structure */u32 flag;BOOL isEnable;BOOL isBusy;BOOL isMaster; /**< Master/Slave */u8 frameSize;u32 totalBytes;u32 remainingBytes;u32 requestedBytes;u8* sendBufferPtr; /**< Buffer to send (state) */u8* recvBufferPtr; /**< Buffer to receive (state) */int (*Transfer)(struct FSpiPs_Tag spi, void* sendBuffer, void* recvBuffer, u32 byteCount);FSpiPs_StatusHandler statusHandler;void* statusRef;
} FSpiPs_T;static void StubStatusHandler(void *callBackRef, u32 statusEvent,u32 byteCount)
{(void) callBackRef;(void) statusEvent;(void) byteCount;
}#define FMSH_SUCCESS 0L
#define FMSH_FAILURE 1Lint FSpiPs_CfgInitialize(FSpiPs_T* spi, FSpiPs_Config_T* configPtr)
{spi->config = *configPtr;spi->isBusy = FALSE;spi->remainingBytes = 0;spi->requestedBytes = 0;spi->sendBufferPtr = NULL;spi->recvBufferPtr = NULL;spi->flag = 0;spi->isEnable = FALSE;spi->isMaster = FALSE;spi->totalBytes = 0;spi->statusHandler = StubStatusHandler;return FMSH_SUCCESS;
}void FSpiPs_Enable(FSpiPs_T* spi)
{FMSH_WriteReg(spi->config.baseAddress, SPIPS_SSIENR_OFFSET, 0x1);spi->isEnable = TRUE;
#if 0
u32 temp=0;//add by fzx
printf("#########FMSH SPI REG IS BELOW\n");
temp=FMSH_ReadReg(spi->config.baseAddress, SPIPS_MSTR_OFFSET);
printf("SPIPS_MSTR_OFFSET is 0x%x\n",temp);temp=FMSH_ReadReg(spi->config.baseAddress, SPIPS_CTRLR0_OFFSET);
printf("SPIPS_CTRLR0_OFFSET is 0x%x\n",temp);temp=FMSH_ReadReg(spi->config.baseAddress, SPIPS_CTRLR1_OFFSET);
printf("SPIPS_CTRLR1_OFFSET is 0x%x\n",temp);temp=FMSH_ReadReg(spi->config.baseAddress, SPIPS_SSIENR_OFFSET);
printf("SPIPS_SSIENR_OFFSET is 0x%x\n",temp);temp=FMSH_ReadReg(spi->config.baseAddress, SPIPS_MVCR_OFFSET);
printf("SPIPS_MVCR_OFFSET is 0x%x\n",temp);temp=FMSH_ReadReg(spi->config.baseAddress, SPIPS_SER_OFFSET);
printf("SPIPS_SER_OFFSET is 0x%x\n",temp);temp=FMSH_ReadReg(spi->config.baseAddress, SPIPS_BAUDR_OFFSET);
printf("SPIPS_BAUDR_OFFSET is 0x%x\n",temp);temp=FMSH_ReadReg(spi->config.baseAddress, SPIPS_SR_OFFSET);
printf("SPIPS_SR_OFFSET is 0x%x\n",temp);
printf("############################\n");
printf("############################\n");
#endif}void FSpiPs_Disable(FSpiPs_T* spi)
{FMSH_WriteReg(spi->config.baseAddress, SPIPS_SSIENR_OFFSET, 0x0);spi->isEnable = FALSE;
}void FSpiPs_Mst(FSpiPs_T *spi)
{FMSH_WriteReg(spi->config.baseAddress, SPIPS_MSTR_OFFSET, 0x1);spi->isMaster = TRUE;
}#define SPIPS_CTRL0_SCPH_MASK (0x1 << 6)
#define SPIPS_CTRL0_SCPOL_MASK (0x1 << 7)
#define SPIPS_CTRL0_TMOD_MASK (0x3 << 8)
#define SPIPS_CTRL0_SLVOE_MASK (0x1 << 10)
#define SPIPS_CTRL0_SRL_MASK (0x1 << 11)
#define SPIPS_CTRL0_DFS32_MASK (0x1f << 16)#define SPIPS_CTRL0_SCPH_SHIFT (6)
#define SPIPS_CTRL0_TMOD_SHIFT (8)
#define SPIPS_CTRL0_DFS32_SHIFT (16)#define SPIPS_TRANSFER_STATE (0x0)
#define SPIPS_TRANSMIT_ONLY_STATE (0x1)
#define SPIPS_RECEIVE_ONLY_STATE (0x2)
#define SPIPS_EEPROM_STATE (0x3)int FSpiPs_SetTMod(FSpiPs_T* spi, u32 tmod)
{u32 configReg;if(spi->isEnable == TRUE){return FMSH_FAILURE;}if(tmod > 3){return FMSH_FAILURE;}configReg = FMSH_ReadReg(spi->config.baseAddress, SPIPS_CTRLR0_OFFSET);configReg &= ~SPIPS_CTRL0_TMOD_MASK;configReg |= (tmod << SPIPS_CTRL0_TMOD_SHIFT);FMSH_WriteReg(spi->config.baseAddress, SPIPS_CTRLR0_OFFSET, configReg);return FMSH_SUCCESS;
}int FSpiPs_SetSckMode(FSpiPs_T* spi, u32 sckMode)
{u32 configReg;if(spi->isEnable == TRUE){return FMSH_FAILURE;}if(sckMode > 3){return FMSH_FAILURE;}configReg = FMSH_ReadReg(spi->config.baseAddress, SPIPS_CTRLR0_OFFSET);configReg &= ~(SPIPS_CTRL0_SCPH_MASK | SPIPS_CTRL0_SCPOL_MASK);configReg |= (sckMode << SPIPS_CTRL0_SCPH_SHIFT);FMSH_WriteReg(spi->config.baseAddress, SPIPS_CTRLR0_OFFSET, configReg);return FMSH_SUCCESS;
}int FSpiPs_SetSckDv(FSpiPs_T* spi, u32 sckdv)
{if(spi->isEnable == TRUE || spi->isMaster == FALSE){return FMSH_FAILURE;}FMSH_WriteReg(spi->config.baseAddress, SPIPS_BAUDR_OFFSET, sckdv);return FMSH_SUCCESS;
}int FSpiPs_SetDFS32(FSpiPs_T* spi, u32 dfs32)
{u32 configReg;if(spi->isEnable == TRUE){return FMSH_FAILURE;}if(dfs32<4 || dfs32 > 0x20){return FMSH_FAILURE;}configReg = FMSH_ReadReg(spi->config.baseAddress, SPIPS_CTRLR0_OFFSET);configReg &= ~SPIPS_CTRL0_DFS32_MASK;configReg |= ((dfs32-1) << SPIPS_CTRL0_DFS32_SHIFT);FMSH_WriteReg(spi->config.baseAddress, SPIPS_CTRLR0_OFFSET, configReg);spi->frameSize = dfs32;return FMSH_SUCCESS;
}int FSpiPs_SetLoopBack(FSpiPs_T* spi, BOOL enable)
{u32 configReg;if(spi->isEnable == TRUE){return FMSH_FAILURE;}configReg = FMSH_ReadReg(spi->config.baseAddress, SPIPS_CTRLR0_OFFSET);if(enable){configReg |= SPIPS_CTRL0_SRL_MASK;}else{configReg &= ~SPIPS_CTRL0_SRL_MASK;}FMSH_WriteReg(spi->config.baseAddress, SPIPS_CTRLR0_OFFSET, configReg);return FMSH_SUCCESS;
}int FSpiPs_SetDFNum(FSpiPs_T* spi, u32 dfNum)
{if(spi->isEnable == TRUE || spi->isMaster == FALSE){return FMSH_FAILURE;}FMSH_WriteReg(spi->config.baseAddress, SPIPS_CTRLR1_OFFSET, dfNum-1);return FMSH_SUCCESS;
}int FSpiPs_SetTxEmptyLvl(FSpiPs_T* spi, u8 tlvl)
{if(spi->isEnable == TRUE){return FMSH_FAILURE;}FMSH_WriteReg(spi->config.baseAddress, SPIPS_TXFTLR_OFFSET, tlvl);return FMSH_SUCCESS;
}int FSpiPs_SetRxFullLvl(FSpiPs_T* spi, u8 tlvl)
{if(spi->isEnable == TRUE){return FMSH_FAILURE;}FMSH_WriteReg(spi->config.baseAddress, SPIPS_RXFTLR_OFFSET, tlvl);return FMSH_SUCCESS;
}void FSpiPs_SetDMATLvl(FSpiPs_T* spi, u32 tlvl)
{FMSH_WriteReg(spi->config.baseAddress, SPIPS_DMATDLR_OFFSET, tlvl);
}void FSpiPs_SetDMARLvl(FSpiPs_T* spi, u32 tlvl)
{FMSH_WriteReg(spi->config.baseAddress, SPIPS_DMARDLR_OFFSET, tlvl);
}void FSpiPs_DisableIntr( FSpiPs_T* spi, u32 mask)
{u32 configReg;configReg = FMSH_ReadReg(spi->config.baseAddress, SPIPS_IMR_OFFSET);configReg &= ~mask;FMSH_WriteReg(spi->config.baseAddress, SPIPS_IMR_OFFSET, configReg);
}int FSpiPs_SetSlave(FSpiPs_T* spi, u32 slaveNo)
{if(spi->isMaster == FALSE){return FMSH_FAILURE;}if(slaveNo == 0){FMSH_WriteReg(spi->config.baseAddress, SPIPS_SER_OFFSET, 0x0);}else{FMSH_WriteReg(spi->config.baseAddress, SPIPS_SER_OFFSET, 0x1 << (slaveNo - 1));}return FMSH_SUCCESS;
}#define SPIPS_INTR_ALL (0x3f)int FSpiPs_Initialize_Master(FSpiPs_T* spi)
{int err = 0;// Check whether there is another transfer in progress. Not thread-safeif(spi->isBusy == TRUE){return FMSH_FAILURE;}// Disable deviceFSpiPs_Disable(spi);// Select device as MasterFSpiPs_Mst(spi);// CTRL (TMode, CkMode, BaudRate, DFSize, DFNum, isLoopBack)err |= FSpiPs_SetTMod(spi, SPIPS_TRANSFER_STATE);err |= FSpiPs_SetSckMode(spi, 3);err |= FSpiPs_SetSckDv(spi, 120);err |= FSpiPs_SetDFS32(spi, 8);err |= FSpiPs_SetLoopBack(spi, FALSE);err |= FSpiPs_SetDFNum(spi, 128);// Config Tx/Rx Thresholderr |= FSpiPs_SetTxEmptyLvl(spi, 20);err |= FSpiPs_SetRxFullLvl(spi, 12);FSpiPs_SetDMATLvl(spi, 12);FSpiPs_SetDMARLvl(spi, 20);// Config IMRFSpiPs_DisableIntr(spi, SPIPS_INTR_ALL);// SlaveSelecterr |= FSpiPs_SetSlave(spi, 1);if(err){return FMSH_FAILURE;}// Enable deviceFSpiPs_Enable(spi);return FMSH_SUCCESS;
}#define NREAD (0x60)
#define NWRITE (0x61)#define SIO (0xF0)
#define STS (0xFE)
#define SPG (0xFF)#define SPIPS_SR_DCOL (0x40)
#define SPIPS_SR_TXE (0x20)
#define SPIPS_SR_RFF (0x10)
#define SPIPS_SR_RFNE (0x08)
#define SPIPS_SR_TFE (0x04)
#define SPIPS_SR_TFNF (0x02)
#define SPIPS_SR_BUSY (0x01)void delay_us(u32 time_us)
{for(u32 i = 0; i < 100000; i++);
}void delay_ms(u32 time_ms)
{for(u32 i = 0; i < 1000000; i++);
}void FSpiPs_Send(FSpiPs_T* spi, u32 Data )
{u32 count = 0;u8 status;status = FMSH_ReadReg(spi->config.baseAddress, SPIPS_SR_OFFSET);while((status & SPIPS_SR_TFNF) == 0) /* loop if TX fifo full */{delay_us(1);count++;if(count > 10000){break;}status = FMSH_ReadReg(spi->config.baseAddress, SPIPS_SR_OFFSET);}FMSH_WriteReg(spi->config.baseAddress, SPIPS_DR_OFFSET, Data);
}u32 FSpiPs_Recv(FSpiPs_T* spi )
{u32 count = 0;u8 status;status = FMSH_ReadReg(spi->config.baseAddress, SPIPS_SR_OFFSET);while((status & SPIPS_SR_RFNE) == 0) /* loop if RX fifo empty */{delay_us(1);count++;if(count > 10000){break;}status = FMSH_ReadReg(spi->config.baseAddress, SPIPS_SR_OFFSET);}return FMSH_ReadReg(spi->config.baseAddress, SPIPS_DR_OFFSET);
}#define SPIPS_FIFO_DEPTH (0x20)int FSpiPs_PolledTransfer(FSpiPs_T* spi, u8* sendBuffer, u8* recvBuffer, u32 byteCount)
{u8 tmod;// Check whether there is another transfer in progress. Not thread-safeif(spi->isBusy == TRUE){return FMSH_FAILURE;}// Get transfer modetmod = (FMSH_ReadReg(spi->config.baseAddress, SPIPS_CTRLR0_OFFSET) & SPIPS_CTRL0_TMOD_MASK)>> SPIPS_CTRL0_TMOD_SHIFT;if(tmod == SPIPS_TRANSFER_STATE){if(sendBuffer == NULL || recvBuffer == NULL){return FMSH_FAILURE;}spi->totalBytes = byteCount;spi->remainingBytes = byteCount;spi->requestedBytes = byteCount;spi->sendBufferPtr = sendBuffer;spi->recvBufferPtr = recvBuffer;}else if(tmod == SPIPS_TRANSMIT_ONLY_STATE){if(sendBuffer == NULL){return FMSH_FAILURE;}spi->totalBytes = byteCount;spi->requestedBytes = 0;spi->remainingBytes = byteCount;}else if(tmod == SPIPS_RECEIVE_ONLY_STATE){if(recvBuffer == NULL){return FMSH_FAILURE;}spi->totalBytes = byteCount;spi->requestedBytes = byteCount;spi->remainingBytes = 0;/* Write one dummy data word to Tx FIFO */FSpiPs_Send(spi, 0xff);}else if(tmod == SPIPS_EEPROM_STATE){if(sendBuffer == NULL || recvBuffer == NULL){return FMSH_FAILURE;}spi->totalBytes = byteCount;spi->requestedBytes = 0;spi->remainingBytes = byteCount;}// Set the busy flag, cleared when transfer is donespi->isBusy = TRUE;//disable interruptFSpiPs_DisableIntr(spi, SPIPS_INTR_ALL);//enable spiFSpiPs_Enable(spi);//polling tx fifo level until transfer completeint cnt;u32 txLvl;u32 txEmptyLvl = 10;while(spi->remainingBytes !=0 || spi->requestedBytes != 0){txLvl = FMSH_ReadReg(spi->config.baseAddress, SPIPS_TXFLR_OFFSET);if(txLvl <= txEmptyLvl){cnt = FMSH_ReadReg(spi->config.baseAddress, SPIPS_RXFLR_OFFSET);while(cnt > 0 && spi->requestedBytes != 0){if(spi->frameSize == 8){*(u8*)(spi->recvBufferPtr) = (u8)FSpiPs_Recv(spi);}else if(spi->frameSize == 16){*(u16*)(spi->recvBufferPtr) = (u16)FSpiPs_Recv(spi);}else if(spi->frameSize == 32){*(u32*)(spi->recvBufferPtr) = (u32)FSpiPs_Recv(spi);}spi->recvBufferPtr += spi->frameSize >> 3;spi->requestedBytes -= spi->frameSize >> 3;cnt--;}cnt = SPIPS_FIFO_DEPTH - txEmptyLvl;while(cnt > 0 && spi->remainingBytes != 0){if(spi->frameSize == 8){FSpiPs_Send(spi, *(u8*)spi->sendBufferPtr);}else if(spi->frameSize == 16){FSpiPs_Send(spi, *(u16*)spi->sendBufferPtr);}else if(spi->frameSize == 32){FSpiPs_Send(spi, *(u32*)spi->sendBufferPtr);}spi->sendBufferPtr += spi->frameSize >> 3;spi->remainingBytes -= spi->frameSize >> 3;cnt--;}}}//Clear the busy flagspi->isBusy = FALSE;//disable spiFSpiPs_Disable(spi);return FMSH_SUCCESS;
}#define SPIF (0x80)
#define RACK (0x20)
#define RXRDY (0x02)
#define TXRDY (0x01#define TIMEOUT_HANDLER (retVal= FMSH_FAILURE);int writeBCM5396( FSpiPs_T *Spi_ptr,u8 page, u8 offset, u8 *pBuffer )
{u8 data[20];u8 data_recv[20];s32 retVal;u32 u32SendNum, u32ReqRetNum;int i;for(i=0;i<20;i++)data[i]=i;// Set Pagedata[0] = NWRITE;data[1] = SPG;data[2] = page;u32SendNum = 3;u32ReqRetNum = 0;retVal = FSpiPs_PolledTransfer(Spi_ptr,data,data_recv,u32SendNum);//pBufferif( retVal != FMSH_SUCCESS ){printf("Call XSpiPs_PT_SL 1 Failed\n\r");}// Read STS
READ_STS_1:data[0] = NREAD;data[1] = STS;u32SendNum = 2;u32ReqRetNum = 1;retVal = FSpiPs_PolledTransfer(Spi_ptr,data,data_recv,u32SendNum+u32ReqRetNum);if( retVal == FMSH_SUCCESS ){if((data_recv[2] & SPIF)==0)//( workBuf[2] & SPIF ){// Set Pagedata[0] = NWRITE;data[1] = SPG;data[2] = page;u32SendNum = 3;u32ReqRetNum = 0;retVal = FSpiPs_PolledTransfer(Spi_ptr,data,data_recv,u32SendNum+u32ReqRetNum);if( retVal != FMSH_SUCCESS ){printf("Call XSpiPs_PT_SL 1 Failed\n\r");}// Write Datadata[0] = NWRITE;data[1] = offset;data[2] = pBuffer[0];data[3] = pBuffer[1];u32SendNum = 4;u32ReqRetNum = 0;//1;retVal = FSpiPs_PolledTransfer(Spi_ptr,data,data_recv,u32SendNum+u32ReqRetNum);if( retVal != FMSH_SUCCESS ){printf("Call XSpiPs_PT_SL 2 Failed\n\r");}}else{TIMEOUT_HANDLER;printf( "Timeout 1 Occured!\n\r" );delay_ms(100);// Set Pagedata[0] = NWRITE;data[1] = SPG;data[2] = page;u32SendNum = 3;u32ReqRetNum = 0;retVal = FSpiPs_PolledTransfer(Spi_ptr,data,data_recv,u32SendNum+u32ReqRetNum);if( retVal != FMSH_SUCCESS ){printf("Call XSpiPs_PT_SL 1 Failed\n\r");}goto READ_STS_1;}}elseprintf("Call XSpiPs_PT_SL 4 Failed\n\r");return retVal;
}int readBCM5396(FSpiPs_T *Spi_ptr, u8 page, u8 offset, u8 *pBuffer )
{
// _BCM_CMD_ bcmCmd;u8 data[8];//u8Idx;u8 data_recv[8] = {0};s32 retVal;u32 u32SendNum, u32ReqRetNum;// Set Pagedata[0] = NWRITE;data[1] = SPG;data[2] = page;u32SendNum = 3;u32ReqRetNum = 0;retVal = FSpiPs_PolledTransfer(Spi_ptr,data,data_recv,u32SendNum);if( retVal != FMSH_SUCCESS ){printf("Call XSpiPs_PT_SL 1 Failed\n\r");}delay_ms(10);// Read STS
READ_STS_1:data[0] = NREAD;data[1] = STS;u32SendNum = 2;u32ReqRetNum = 1;retVal = FSpiPs_PolledTransfer(Spi_ptr,data,data_recv,u32SendNum+u32ReqRetNum);delay_ms(10);if( retVal == FMSH_SUCCESS ){if( (data_recv[2] & SPIF)==0){// Set Pagedata[0] = NWRITE;data[1] = SPG;data[2] = page;u32SendNum = 3;u32ReqRetNum = 0;retVal = FSpiPs_PolledTransfer(Spi_ptr,data,data_recv,u32SendNum+u32ReqRetNum);if( retVal != FMSH_SUCCESS ){printf("Call XSpiPs_PT_SL 1 Failed\n\r");}// Set Offset in Page, "Null" operation :)data[0] = NREAD;data[1] = offset;u32SendNum = 2;u32ReqRetNum = 1;retVal = FSpiPs_PolledTransfer(Spi_ptr,data,data_recv,u32SendNum+u32ReqRetNum);if( retVal != FMSH_SUCCESS ){printf("Call XSpiPs_PT_SL 2 Failed\n\r");}// Read STS
READ_STS_2:data[0] = NREAD;data[1] = STS;u32SendNum = 2;u32ReqRetNum = 1;retVal = FSpiPs_PolledTransfer(Spi_ptr,data,data_recv,u32SendNum+u32ReqRetNum);if( retVal == FMSH_SUCCESS ){if( data_recv[2] & RACK ){/*bcmCmd.cmd = NREAD;bcmCmd.regAdrs = SIO;*/data[0] = NREAD;data[1] = SIO;u32SendNum = 2;u32ReqRetNum = 4;retVal = FSpiPs_PolledTransfer(Spi_ptr,data,pBuffer,u32SendNum+u32ReqRetNum);}else{TIMEOUT_HANDLER;printf( "Timeout 2 Occured!\n\r" );delay_ms(10);// Set Pagedata[0] = NWRITE;data[1] = SPG;data[2] = page;u32SendNum = 3;u32ReqRetNum = 0;retVal = FSpiPs_PolledTransfer(Spi_ptr,data,data_recv,u32SendNum+u32ReqRetNum);if( retVal != FMSH_SUCCESS ){printf("Call XSpiPs_PT_SL 1 Failed\n\r");}goto READ_STS_2;}}elseprintf("Call XSpiPs_PT_SL 3 Failed\n\r");}else{TIMEOUT_HANDLER;printf( "Timeout 1 Occured!\n\r" );delay_ms(100);// Set Pagedata[0] = NWRITE;data[1] = SPG;data[2] = page;u32SendNum = 3;u32ReqRetNum = 0;retVal = FSpiPs_PolledTransfer(Spi_ptr,data,pBuffer,u32SendNum+u32ReqRetNum);if( retVal != FMSH_SUCCESS ){printf("Call XSpiPs_PT_SL 1 Failed\n\r");}goto READ_STS_1;}}elseprintf("Call XSpiPs_PT_SL 4 Failed\n\r");return retVal;
}int writeBCM5396_2( FSpiPs_T *Spi_ptr,u8 page, u8 offset, u8 *pBuffer )
{u8 data[20];u8 data_recv[20];s32 retVal;u32 u32SendNum, u32ReqRetNum;int i;for(i=0;i<20;i++)data[i]=i;// Set Pagedata[0] = NWRITE;data[1] = SPG;data[2] = page;u32SendNum = 3;u32ReqRetNum = 0;retVal = FSpiPs_PolledTransfer(Spi_ptr,data,data_recv,u32SendNum);//pBufferif( retVal != FMSH_SUCCESS ){printf("Call XSpiPs_PT_SL 1 Failed\n\r");}// Read STS
READ_STS_1:data[0] = NREAD;data[1] = STS;u32SendNum = 2;u32ReqRetNum = 1;retVal = FSpiPs_PolledTransfer(Spi_ptr,data,data_recv,u32SendNum+u32ReqRetNum);//if( retVal == FMSH_SUCCESS ) {if((data_recv[2] & SPIF)==0)//( workBuf[2] & SPIF ){// Set Pagedata[0] = NWRITE;data[1] = SPG;data[2] = page;u32SendNum = 3;u32ReqRetNum = 0;retVal = FSpiPs_PolledTransfer(Spi_ptr,data,data_recv,u32SendNum+u32ReqRetNum);if( retVal != FMSH_SUCCESS ){printf("Call XSpiPs_PT_SL 1 Failed\n\r");}// Write Datadata[0] = NWRITE;data[1] = offset;data[2] = pBuffer[0]; u32SendNum = 3;u32ReqRetNum = 0;//1;retVal = FSpiPs_PolledTransfer(Spi_ptr,data,data_recv,u32SendNum+u32ReqRetNum);if( retVal != FMSH_SUCCESS ){printf("Call XSpiPs_PT_SL 2 Failed\n\r");}}else{TIMEOUT_HANDLER;printf( "Timeout 1 Occured!\n\r" );delay_ms(50);// Set Pagedata[0] = NWRITE;data[1] = SPG;data[2] = page;u32SendNum = 3;u32ReqRetNum = 0;retVal = FSpiPs_PolledTransfer(Spi_ptr,data,data_recv,u32SendNum+u32ReqRetNum);if( retVal != FMSH_SUCCESS ){printf("Call XSpiPs_PT_SL 1 Failed\n\r");}goto READ_STS_1;}}elseprintf("Call XSpiPs_PT_SL 4 Failed\n\r");return retVal;
}int writeBCM5396_4( FSpiPs_T *Spi_ptr,u8 page, u8 offset, u8 *pBuffer )
{u8 data[20];u8 data_recv[20];s32 retVal;u32 u32SendNum, u32ReqRetNum;int i;for(i=0;i<20;i++)data[i]=i;// Set Pagedata[0] = NWRITE;data[1] = SPG;data[2] = page;u32SendNum = 3;u32ReqRetNum = 0;retVal = FSpiPs_PolledTransfer(Spi_ptr,data,data_recv,u32SendNum);//pBufferif( retVal != FMSH_SUCCESS ){printf("Call XSpiPs_PT_SL 1 Failed\n\r");}// Read STS
READ_STS_1:data[0] = NREAD;data[1] = STS;u32SendNum = 2;u32ReqRetNum = 1;retVal = FSpiPs_PolledTransfer(Spi_ptr,data,data_recv,u32SendNum+u32ReqRetNum);//if( retVal == FMSH_SUCCESS ) {if((data_recv[2] & SPIF)==0)//( workBuf[2] & SPIF ){// Set Pagedata[0] = NWRITE;data[1] = SPG;data[2] = page;u32SendNum = 3;u32ReqRetNum = 0;retVal = FSpiPs_PolledTransfer(Spi_ptr,data,data_recv,u32SendNum+u32ReqRetNum);if( retVal != FMSH_SUCCESS ){printf("Call XSpiPs_PT_SL 1 Failed\n\r");}// Write Datadata[0] = NWRITE;data[1] = offset;data[2] = pBuffer[0]; u32SendNum = 6;u32ReqRetNum = 0;//1;retVal = FSpiPs_PolledTransfer(Spi_ptr,data,data_recv,u32SendNum+u32ReqRetNum);if( retVal != FMSH_SUCCESS ){printf("Call XSpiPs_PT_SL 2 Failed\n\r");}}else{TIMEOUT_HANDLER;printf( "Timeout 1 Occured!\n\r" );delay_ms(50);// Set Pagedata[0] = NWRITE;data[1] = SPG;data[2] = page;u32SendNum = 3;u32ReqRetNum = 0;retVal = FSpiPs_PolledTransfer(Spi_ptr,data,data_recv,u32SendNum+u32ReqRetNum);if( retVal != FMSH_SUCCESS ){printf("Call XSpiPs_PT_SL 1 Failed\n\r");}goto READ_STS_1;}}elseprintf("Call XSpiPs_PT_SL 4 Failed\n\r");return retVal;
}FSpiPs_T spi;
FSpiPs_T Spi[2];int port_vlan_set(unsigned int port, unsigned int mask)
{u8 workBuf[10];int Status = 0;int offset = 0;offset = port*4;// printf("--------Set Port Vlan:port:%d-offset:%0x-mask:%0x---------\n\r", port, mask);workBuf[0] = (mask&0x000000ff);workBuf[1] = (mask&0x0000ff00)>>8;workBuf[2] = (mask&0x00010000)>>16;Status = writeBCM5396_4(&spi, 0x31, offset, workBuf); return Status;
}
/***************************************BOARD SW1706 JEM5396 REG READ/WRITE*****************************/void testwrite5396(int port, unsigned int offset ,unsigned int value)
{u8 workBuf[10];workBuf[0]=value & 0xff;workBuf[1]=(value>>8) & 0xff;writeBCM5396(&spi, port, offset, workBuf);udelay(1000);readBCM5396(&spi, port, offset, workBuf );printf("port=%d,offset=%xh,data=0x%x\n\r",port,offset,workBuf[2]);printf("port=%d,offset=%xh,data=0x%x\n\r",port,offset,workBuf[3]);
}
void testread5396()
{u8 workBuf[10];readBCM5396(&spi, 2, 0x30, workBuf);printf("5396 Mode_ID=0x%x\n\r", workBuf[2]);
}int ckoff_spi_5396()
{int ret = 0;int Status = 0;u8 workBuf[10];int i=0;/*init spi and read bcm5396 device id*/FSpiPs_Config_T *spi_cfgptr;spi_cfgptr = FSpiPs_LookupConfig(0);ret = FSpiPs_CfgInitialize(&spi, spi_cfgptr);if(ret == FMSH_SUCCESS){printf("5396 Spi Init Success!\n\r");} else{printf("5396 Spi Init Failed!\n\r");return -1;}/*Init master*/ret = FSpiPs_Initialize_Master(&spi);if(ret == FMSH_SUCCESS){printf("spi Init Master Success!\n\r");}else{printf("spi Init Master Failed!\n\r");return -1;} workBuf[0]=0xf1;workBuf[1]=0x28;workBuf[2]=0;for(i=0x10;i<=0x1f;i++){Status = writeBCM5396(&spi, i, 0x12, workBuf );}workBuf[0]=0xf0;workBuf[1]=0x28;workBuf[2]=0;for(i=0x10;i<=0x1f;i++){Status = writeBCM5396(&spi, i, 0x12, workBuf );}printf("JEM5396 CHECK OFF DONW\n");return 0;
}/***************************************BOARD SW1706 JEM5396 REG READ/WRITE*****************************/
int init_spi_5396()
{int ret = 0;int Status = 0;u8 workBuf[10];int i=0;/*init spi and read bcm5396 device id*/
#if 0FSpiPs_Config_T *spi_cfgptr;spi_cfgptr = FSpiPs_LookupConfig(0);ret = FSpiPs_CfgInitialize(&spi, spi_cfgptr);if(ret == FMSH_SUCCESS){printf("5396 Spi Init Success!\n\r");} else{printf("5396 Spi Init Failed!\n\r");return -1;}/*Init master*/ret = FSpiPs_Initialize_Master(&spi);if(ret == FMSH_SUCCESS){printf("spi Init Master Success!\n\r");}else{printf("spi Init Master Failed!\n\r");return -1;}
#endifStatus=readBCM5396(&spi, 2, 0x30, workBuf);printf("5396 Mode_ID=0x%x\n\r", workBuf[2]);Status=readBCM5396(&spi, 2, 0x40, workBuf);printf("5396 Reversion_ID=0x%x\n\r", workBuf[2]);/***************************************JEM5396 CONFIG*****************************//**PORT N STATE OVERRIDE REGISTER [0:15] (PAGE 00H: ADDRESS 60H–6FH) **//**强制千兆全双工模式**/for(i=0x60;i<=0x6f;i++){workBuf[0] = 0x8b;workBuf[1] = 0x0;if(i==0x65){continue;}writeBCM5396_2(&spi, 0, i, workBuf);}workBuf[0]=0xf0;workBuf[1]=0x1;workBuf[2]=0;for(i=0x10;i<=0x1f;i++){if(i==0x15){continue;}Status = writeBCM5396(&spi, i, 0x20, workBuf );}workBuf[0]=0x40;workBuf[1]=0x13;workBuf[2]=0;for(i=0x10;i<=0x1f;i++){if(i==0x15){continue;}Status = writeBCM5396(&spi, i, 0x0, workBuf );}printf("Set Port 5 CONNECT TO ZYNQ SPEED FIXED 1000M\n");workBuf[0] = 0x8b;workBuf[1] = 0x0;writeBCM5396_2(&spi, 0, 0x65, workBuf); workBuf[0] = 0x40;workBuf[1] = 0x1; Status = writeBCM5396(&spi, 0x15, 0x0, workBuf ); printf("*****************Read SPI Reg of 5396******************\r\n");printf("---BMC Status Registers(PAGE 0x10-0x1F)---\n");for(i=0x10;i<=0x1f;i++){Status = readBCM5396(&spi, i, 0x28, workBuf );printf("port=%d,offset=0x28,data=0x%x\n",(i-0x10),workBuf[2]);printf("port=%d,offset=0x29,data=0x%x\n",(i-0x10),workBuf[3]);}printf("---BMC Status Registers(PAGE 0x10-0x1F)---\n\r");for(i=0x10;i<=0x1f;i++){Status = readBCM5396(&spi, i, 0x20, workBuf );printf("port=%d,offset=0x20,data=0x%x\n\r",(i-0x10),workBuf[2]);printf("port=%d,offset=0x21,data=0x%x\n\r",(i-0x10),workBuf[3]);}#if 0workBuf[0]=0x00;workBuf[1]=0x00;workBuf[2]=0x00;Status =writeBCM5396(&spi, 0x31, 0x00, workBuf);//Port 0Status =writeBCM5396(&spi, 0x31, 0x04, workBuf);//Port 1Status =writeBCM5396(&spi, 0x31, 0x08, workBuf);//Port 2Status =writeBCM5396(&spi, 0x31, 0x0c, workBuf);//Port 3Status =writeBCM5396(&spi, 0x31, 0x10, workBuf);//Port 4Status =writeBCM5396(&spi, 0x31, 0x14, workBuf);//Port 5Status =writeBCM5396(&spi, 0x31, 0x18, workBuf);//Port 6Status =writeBCM5396(&spi, 0x31, 0x1c, workBuf);//Port 7Status =writeBCM5396(&spi, 0x31, 0x20, workBuf);//Port 8Status =writeBCM5396(&spi, 0x31, 0x24, workBuf);//Port 9Status =writeBCM5396(&spi, 0x31, 0x28, workBuf);//Port 10Status =writeBCM5396(&spi, 0x31, 0x2c, workBuf);//Port 11Status =writeBCM5396(&spi, 0x31, 0x30, workBuf);//Port 12Status =writeBCM5396(&spi, 0x31, 0x34, workBuf);//Port 13Status =writeBCM5396(&spi, 0x31, 0x38, workBuf);//Port 14Status =writeBCM5396(&spi, 0x31, 0x3c, workBuf);//Port 15Status =writeBCM5396(&spi, 0x31, 0x40, workBuf);//Port 15printf("5396 ALL Port Disconnect\n\r");
#endifreturn 0;
}void FSlcrPs_setBitTo1(u32 baseAddr, u32 offSet,u32 bit_num)
{u32 value = 0;//First get the current value of the registervalue = FMSH_ReadReg(baseAddr, offSet);//Then write the given bit of data as 1value |= (1 << bit_num);//Finally, write the modified data to the registerFMSH_WriteReg(baseAddr, offSet, value);
}
void FSlcrPs_setBitTo0(u32 baseAddr, u32 offSet,u32 bit_num)
{u32 value = 0;//First get the current value of the registervalue = FMSH_ReadReg(baseAddr, offSet);//Then write the given bit of data as 0value &= ~(1 << bit_num);//Finally, write the modified data to the registerFMSH_WriteReg(baseAddr, offSet, value);
}void FSlcrPs_unlock(void)
{FMSH_WriteReg(FPS_SLCR_BASEADDR,SLCR_UNLOCK,0xDF0D767B); //SLCR UNLOCK
}
void FSlcrPs_lock(void)
{FMSH_WriteReg(FPS_SLCR_BASEADDR,SLCR_LOCK,0xDF0D767B); //SLCR LOCK
}
void FSlcrPs_ipSetRst(u32 rst_id, u32 rst_mode)
{FSlcrPs_unlock();FSlcrPs_setBitTo1(FPS_SLCR_BASEADDR,rst_id,rst_mode);FSlcrPs_lock();
}
void FSlcrPs_ipReleaseRst(u32 rst_id, u32 rst_mode)
{FSlcrPs_unlock();FSlcrPs_setBitTo0(FPS_SLCR_BASEADDR,rst_id,rst_mode);FSlcrPs_lock();
}
void FSpiPs_Reset(FSpiPs_T* spi)
{if(spi->config.deviceId == FPS_SPI0_DEVICE_ID){FSlcrPs_ipSetRst(SLCR_SPI0_CTRL, SPI0_APB_RST);FSlcrPs_ipSetRst(SLCR_SPI0_CTRL, SPI0_REF_RST);FSlcrPs_ipReleaseRst(SLCR_SPI0_CTRL, SPI0_APB_RST);FSlcrPs_ipReleaseRst(SLCR_SPI0_CTRL, SPI0_REF_RST);}else if(spi->config.deviceId == FPS_SPI1_DEVICE_ID){FSlcrPs_ipSetRst(SLCR_SPI1_CTRL, SPI1_APB_RST);FSlcrPs_ipSetRst(SLCR_SPI1_CTRL, SPI1_REF_RST);FSlcrPs_ipReleaseRst(SLCR_SPI1_CTRL, SPI1_APB_RST);FSlcrPs_ipReleaseRst(SLCR_SPI1_CTRL, SPI1_REF_RST);}
}
配置完成后,网络就能ping通了