Zynq-Linux移植学习笔记之66- 国产ZYNQ通过裕太PHY8521连接国产交换芯片

news2024/11/20 22:42:45

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通了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1232725.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LeetCode(31)无重复字符的最长子串【滑动窗口】【中等】

目录 1.题目2.答案3.提交结果截图 链接&#xff1a; 无重复字符的最长子串 1.题目 给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长子串 的长度。 示例 1: 输入: s "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc"&…

Linux安全之AIDE系统入侵检测工具安装和使用

一、AIDE 系统入侵检测工具简介 AIDE&#xff0c;全称为Advanced Intrusion Detection Environment&#xff0c;是一个主要用于检测文件完整性的入侵检测工具。它能够构建一个指定文件的数据库&#xff0c;并使用aide.conf作为其配置文件。AIDE数据库能够保存文件的各种属性&am…

APP外包开发项目验收

应用外包开发的验收是确保项目交付质量和客户满意度的关键阶段。以下是一些建议&#xff0c;帮助你进行有效的APP外包开发验收&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 1.明确验收标准&#xf…

[Android] Amazon 的 android 音视频开发文档

https://developer.amazon.com/zh/docs/fire-tv/audio-video-synchronization.html#22-getplaybackheadposition-api-level-3https://developer.amazon.com/zh/docs/fire-tv/audio-video-synchronization.html#22-getplaybackheadposition-api-level-3

掌握源码,轻松搭建:一站式建站系统源码 附完整搭建步骤与教程

随着互联网的快速发展&#xff0c;网站已成为人们生活中不可或缺的一部分。然而&#xff0c;对于许多初学者或中小企业来说&#xff0c;搭建一个完整的网站系统并非易事。这涉及到前端和后端的开发、数据库管理等多个环节。为了解决这一痛点&#xff0c;我们推出了一站式建站系…

Double 4 VR智能互动系统在轨道交通实训教学中的应用

Double 4 VR智能互动系统是一种集成了虚拟现实技术、人工智能和物联网技术的教学系统。计算机通过模拟真实的轨道交通环境&#xff0c;为学生提供了一个高度仿真的学习环境&#xff0c;帮助他们更好地理解和掌握轨道交通的相关知识和技能。 首先&#xff0c;Double 4 VR智能互动…

第十篇 基于JSP 技术的网上购书系统——管理员后台管理主界面、订单管理、产品管理功能实现(网上商城、仿淘宝、当当、亚马逊)

目录 1.管理员后台管理——主界面 1.1功能说明 1.2界面设计 1.3处理流程 2.订单管理 2.1功能说明 2.2界面设计 2.3处理流程 2.4数据来源和算法 2.4.1数据来源 2.4.2查询条件 2.4.3表间关系 2.4.4相关sql实例 3.产品管理 3.1功能说明 3.2界面设计 3.3处理流程…

第十一篇 基于JSP 技术的网上购书系统——产品类别管理、评论/留言管理、注册用户管理、新闻管理功能实现(网上商城、仿淘宝、当当、亚马逊)

目录 1.产品类别管理 1.1功能说明 1.2界面设计 1.3处理流程 1.4数据来源和算法 1.4.1数据来源 1.4.2 查询条件 1.4.3相关sql实例 2. 评论/留言管理 2.1功能说明 2.2 界面设计 2.3处理流程 2.4数据来源和算法 2.4.1数据来源 2.4.2 查询条件 2.4.3相关sql实例…

【AI】行业消息精选和分析(11月21日 星期二)

技术发展 &#x1f525; OpenAI 员工集体签署信件&#xff1a; - 员工要求董事会辞职并重新任命首席执行官奥特曼。 - 否则可能集体加入微软。 昨天就玩我们领导发言&#xff0c;后面大家接龙收到的那一套了。 &#x1f632; 奥特曼加入微软引发猜测&#xff1a; - 对于一个公…

RESTful API 设计指南——开篇词

引言 十年后的今天&#xff0c;我终于学会了RESTful API。 以上&#xff0c;就是我最近一个月的心路历程。入职新公司不到2周&#xff0c;自己都还没完全理解RESTful API就要求给校招应届生培训&#xff0c;着实压力山大。培训结束后也感觉收获颇丰&#xff0c;遂总结分享出来&…

JavaSwing实现银行账户交易系统(含教程)可加数据库 Java课程设计

8.银行账户交易系统 视频教程&#xff1a; 【课程设计】银行账户交易系统-Java Swing-你的课程我设计 功能描述&#xff1a; 系统有银行柜员和普通用户两个角色; 银行柜员登录后可查看用户账号信息、开户、修改账户、存钱、取钱、注销账户、查看交易记录&#xff1b; 用户登录…

【旅游行业】Axure旅游社交平台APP端原型图,攻略门票酒店民宿原型案例

作品概况 页面数量&#xff1a;共 110 页 兼容软件&#xff1a;Axure RP 9/10&#xff0c;不支持低版本 应用领域&#xff1a;旅游平台&#xff0c;酒店住宿 作品申明&#xff1a;页面内容仅用于功能演示&#xff0c;无实际功能 作品特色 本作品为「旅游社交平台」移动端…

lenovo联想笔记本ThinkPad P1 Gen5/X1 Extreme Gen5原装出厂Windows11预装OEM系统

链接&#xff1a;https://pan.baidu.com/s/13E97Nwc-0-N7ffPjEeeeOw?pwdep4l 提取码&#xff1a;ep41 原装出厂系统自带所有驱动、出厂主题壁纸、Office办公软件、联想电脑管家等预装程序 所需要工具&#xff1a;32G或以上的U盘 文件格式&#xff1a;ISO 文件大小&#xff…

数据结构中树、森林 与 二叉树的转换

1 树转换为 二叉树 将树转换成二叉树的步骤是&#xff1a; 加线。在所有的兄弟结点之间加一条线。去线。对于树中的每个结点&#xff0c;只保留它与第一个孩子结点的连线&#xff0c;删除该结点其他孩子结点之间的连线。调整。以树的根结点为轴心&#xff0c;将整个树顺时针旋…

微信小程序校园运动场预约系统xuvvt

本论文的内容是关于运动场预约&#xff0c;主要内容不仅包括了小程序的分析和设计还对几个主要模块进行详细阐述与分析。此微信小程序运动场预约分为管理员操作和教师操作、学生操作。学生的操作主要是可以在网页上浏览到场地信息、运动视频、心情动态等功能&#xff0c;用户可…

护眼灯买哪种好?考研必备的护眼台灯推荐

家里顶灯太暗了且高度太高&#xff0c;还是原始的LED灯&#xff0c;晚上用着眼睛都有点难受&#xff0c;还好遇到了儿童护眼灯。下面小编为大家介绍下儿童护眼灯哪个牌子好&#xff1f;什么护眼台灯比较专业 1、色温 台灯的色温也是一个需要考虑的因素&#xff0c;所谓的色温其…

机器学习与计算机视觉 D2

整合为学习笔记&#xff01;参考阅读了几位大佬的作品&#xff0c;已标注出处~ 机器学习的数学基础 线性与非线性变换 从几何意义上&#xff0c;线性变换表示的是直线的特性&#xff0c;符合两个性质: 变换前后零点不变&#xff0c;变换前后直线还是直线。 线性变换意味着可以…

从字典到 CookieJar 的转换技巧

在使用requests库进行HTTP请求时&#xff0c;经常需要传递cookies参数来实现一些特定的功能&#xff0c;例如保持用户会话状态或者进行身份验证。 在HTTP请求中&#xff0c;Cookie是一种用来在客户端和服务器之间传递状态信息的方式&#xff0c;通常用于记录用户的身份验证信息…

Linux中,查看Tomcat版本、如何查看Tomcat版本

方法 在tomcat的bin目录下&#xff0c;执行version.sh命令即可 结果

XmlElement注解在Java的数组属性上,以产生多个相同的XML元素

例如&#xff0c;下面这段XML数据&#xff0c;有多个data元素&#xff0c;并且它们级别相同: <?xml version"1.0" encoding"UTF-8"?><request><reqtype>05</reqtype><secret>test</secret><body><userid&…