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.c
Author : 123
Version :
Copyright : Your copyright notice
Description : 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 bus
ret = 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 disable
port 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 0x41290000
typedef 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. end
XGpioPs_SetDirectionPin(&Gpio, mioPinNum, 1);
// MIO0
XGpioPs_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)) = data
typedef 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 1L
int 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-safe
if(spi->isBusy == TRUE)
{
return FMSH_FAILURE;
}
// Disable device
FSpiPs_Disable(spi);
// Select device as Master
FSpiPs_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 Threshold
err |= FSpiPs_SetTxEmptyLvl(spi, 20);
err |= FSpiPs_SetRxFullLvl(spi, 12);
FSpiPs_SetDMATLvl(spi, 12);
FSpiPs_SetDMARLvl(spi, 20);
// Config IMR
FSpiPs_DisableIntr(spi, SPIPS_INTR_ALL);
// SlaveSelect
err |= FSpiPs_SetSlave(spi, 1);
if(err)
{
return FMSH_FAILURE;
}
// Enable device
FSpiPs_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-safe
if(spi->isBusy == TRUE)
{
return FMSH_FAILURE;
}
// Get transfer mode
tmod = (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 done
spi->isBusy = TRUE;
//disable interrupt
FSpiPs_DisableIntr(spi, SPIPS_INTR_ALL);
//enable spi
FSpiPs_Enable(spi);
//polling tx fifo level until transfer complete
int 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 flag
spi->isBusy = FALSE;
//disable spi
FSpiPs_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 Page
data[0] = NWRITE;
data[1] = SPG;
data[2] = page;
u32SendNum = 3;
u32ReqRetNum = 0;
retVal = FSpiPs_PolledTransfer(Spi_ptr,data,data_recv,u32SendNum);//pBuffer
if( 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 Page
data[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 Data
data[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 Page
data[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;
}
}
else
printf("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 Page
data[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 Page
data[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 Page
data[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;
}
}
else
printf("Call XSpiPs_PT_SL 3 Failed\n\r");
}
else
{
TIMEOUT_HANDLER;
printf( "Timeout 1 Occured!\n\r" );
delay_ms(100);
// Set Page
data[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;
}
}
else
printf("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 Page
data[0] = NWRITE;
data[1] = SPG;
data[2] = page;
u32SendNum = 3;
u32ReqRetNum = 0;
retVal = FSpiPs_PolledTransfer(Spi_ptr,data,data_recv,u32SendNum);//pBuffer
if( 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 Page
data[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 Data
data[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 Page
data[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;
}
}
else
printf("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 Page
data[0] = NWRITE;
data[1] = SPG;
data[2] = page;
u32SendNum = 3;
u32ReqRetNum = 0;
retVal = FSpiPs_PolledTransfer(Spi_ptr,data,data_recv,u32SendNum);//pBuffer
if( 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 Page
data[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 Data
data[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 Page
data[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;
}
}
else
printf("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 0
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;
}
#endif
Status=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 0
workBuf[0]=0x00;
workBuf[1]=0x00;
workBuf[2]=0x00;
Status =writeBCM5396(&spi, 0x31, 0x00, workBuf);//Port 0
Status =writeBCM5396(&spi, 0x31, 0x04, workBuf);//Port 1
Status =writeBCM5396(&spi, 0x31, 0x08, workBuf);//Port 2
Status =writeBCM5396(&spi, 0x31, 0x0c, workBuf);//Port 3
Status =writeBCM5396(&spi, 0x31, 0x10, workBuf);//Port 4
Status =writeBCM5396(&spi, 0x31, 0x14, workBuf);//Port 5
Status =writeBCM5396(&spi, 0x31, 0x18, workBuf);//Port 6
Status =writeBCM5396(&spi, 0x31, 0x1c, workBuf);//Port 7
Status =writeBCM5396(&spi, 0x31, 0x20, workBuf);//Port 8
Status =writeBCM5396(&spi, 0x31, 0x24, workBuf);//Port 9
Status =writeBCM5396(&spi, 0x31, 0x28, workBuf);//Port 10
Status =writeBCM5396(&spi, 0x31, 0x2c, workBuf);//Port 11
Status =writeBCM5396(&spi, 0x31, 0x30, workBuf);//Port 12
Status =writeBCM5396(&spi, 0x31, 0x34, workBuf);//Port 13
Status =writeBCM5396(&spi, 0x31, 0x38, workBuf);//Port 14
Status =writeBCM5396(&spi, 0x31, 0x3c, workBuf);//Port 15
Status =writeBCM5396(&spi, 0x31, 0x40, workBuf);//Port 15
printf("5396 ALL Port Disconnect\n\r");
#endif
return 0;
}
void FSlcrPs_setBitTo1(u32 baseAddr, u32 offSet,u32 bit_num)
{
u32 value = 0;
//First get the current value of the register
value = FMSH_ReadReg(baseAddr, offSet);
//Then write the given bit of data as 1
value |= (1 << bit_num);
//Finally, write the modified data to the register
FMSH_WriteReg(baseAddr, offSet, value);
}
void FSlcrPs_setBitTo0(u32 baseAddr, u32 offSet,u32 bit_num)
{
u32 value = 0;
//First get the current value of the register
value = FMSH_ReadReg(baseAddr, offSet);
//Then write the given bit of data as 0
value &= ~(1 << bit_num);
//Finally, write the modified data to the register
FMSH_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通了