⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 spi_simulate.c

📁 这是ARM在Vxworks的驱动源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/************************************************************************/
/*																		*/
/*           Copyright 2005 - 2008, Baud Data Communication Ltd.    	*/
/*                      ALL RIGHTS RESERVED								*/
/*																		*/
/*   Permission is hereby granted to licensees of Baud Data				*/ 
/*   Communication Ltd. products to use or abstract this computer 		*/
/*   program for the sole purpose of implementing a product based 		*/
/*   on Baud Data Communication Ltd. products.   No other rights to 	*/
/*   reproduce, use, or disseminate this computer program, whether 		*/
/*   in part or in whole, are granted.									*/
/*																		*/
/*   Baud Data Communication, Ltd. makes no representation or warranties*/
/*   with respect to the performance of this computer program, and     	*/
/*   specifically disclaims any responsibility for any damages,        	*/
/*   special or consequential, connected with the use of this program. 	*/
/*                                                           			*/
/*----------------------------------------------------------------------*/
/*																		*/
/*		MODULE NAME		:	SPI Simulate Module							*/
/*		FILE NAME		:	spi_simulate.c								*/
/*		AUTHOR			:	zhu zhangming								*/
/*		DATE			:	05/09/27									*/
/*		PURPOSE:		:	software simulate spi manage port 		    */
/*						:	Useful When some PowerPCs have no spi port,	*/
/*						:	but switch chip need one            		*/
/*																		*/
/************************************************************************/
#include "IxTypes.h"
#include "vxWorks.h"
#include "ixp425Gpio.h"


/*#define SPI_SIM_DEBUG*/
/*#define FAST_READ*/

#ifdef SPI_SIM_DEBUG
#define SPI_SIM_LOG(x1, x2) printf(x1, x2)
#else 
#define SPI_SIM_LOG(x1, x2)
#endif
 
#define SPI_MAX_BUF 0x10
#define RETRY_LOOP  2
#define COMMAND_HEAD_LEN 2   /*command byte+ register address byte*/

#if 0
#define BCM_OK 0
#define BCM_ERROR -1
#else
#define BCM_OK IX_SUCCESS
#define BCM_ERROR IX_FAIL
#endif
#define SPI_BASE_ADDR  (0xc8004000)
#define SPI_INPUT_ADDR (0xc8004008)
#define SPI_FLAG  (*(volatile unsigned int*)SPI_BASE_ADDR)
#define SPI_INPUT_VALUE (*(volatile unsigned int*)SPI_INPUT_ADDR)

#define SPIMISO      0x0080
#define SPIMOSI      0x0100
#define SCLK         0x0200
/*#define SPCS         0x0800*/
#define SPCS(x)	(0x0400<<(x))

#define DISABLE_SPISEL(x)         SPI_FLAG |=  SPCS(x)
#define ENABLE_SPISEL(x)          do{SPI_FLAG &= ~SPCS(x); DISABLE_SPISEL(1-x);}while(0)
							   

#define LOW_SPICLK          SPI_FLAG &= ~SCLK
#define HIGH_SPICLK         SPI_FLAG |= SCLK
#define LOW_SPIMOSI         SPI_FLAG &= ~SPIMOSI
#define HIGH_SPIMOSI        SPI_FLAG |= SPIMOSI
/*#define IS_HIGH_SPIMISO     (SPI_FLAG & SPIMISO) */
#define IS_HIGH_SPIMISO (SPI_INPUT_VALUE & SPIMISO)

/*| 0 | 1 | 1 | mode=0 | chip id 2 | chip id 1 | chip id 0 | r/w |*/
#define NORMAL_SPI_CMD 0x60
#define SPI_READ         0x00
#define SPI_WRITE        0x01
/*#define SPI_CHIP(chip)   (chip << 1)*/
#define SPI_CHIP(chip)	0x0

/*| x | x | x | mode=1 | chip id 2 | chip id 1 | chip id 0 | r/w |*/
#define FAST_SPI_CMD    0x10
#define OFFSET_BYTE(byte)  (byte << 5)

/*register address */
#define PAGE_REG        0xff
#define STAT_REG        0xfe
#define DATA_REG        0xf0         /*0xf0~~~0xf7*/

/*SPI status register */
#define SPIF               0x80
#define WCOL              0x40
#define RACK               0x20
#define READ_READY_ACK   RACK
#define RXRDY              0x02
#define TXRDY              0x01     

#if 0
/* This value MUST match the Sandpoint system 60x bus speed */
#define DEC_CLOCK_FREQ         (dec_get_clock_freq()) 	/*66000000*/        /* 66MHz default */
/* PPC Decrementer - used as vxWorks system clock */
#define DELTA(a,b)     		(abs((int)a - (int)b))
#endif

/*  external functions  */
int spi8xx_read_bcm53x8_register(int chip, UINT8 page, UINT8 reg, char *pbuf, int reg_len);
int spi8xx_write_bcm53x8_register(int chip, UINT8 page, UINT8 reg, char* pbuf, int len);
void spi8xx_init(void);
#ifdef FAST_READ
int spi_simulate_fast_read_bcm_register(int chip, UINT8 page, UINT8 reg, char *pbuf, int reg_len);
#endif


static UINT8 txbuf[SPI_MAX_BUF];
static UINT8 rxbuf;

/*internal functions*/
 static int spi_simulate_send_bytes(UINT8* buf, UINT8 nbyte);
 static int spi_simulate_recv_bytes(UINT8* buf, UINT8 nbyte);
 static void spi_simulate_read_bytes_cont(int chip, char* pbuf, int reg_len);
 static void         setup_page_address(int chip, UINT8 page);
 static void         write_page_address(int chip, UINT8 page);
 static void         setup_reg_address(int chip, UINT8 reg);
 static UINT8        read_spi_status(int chip);
 static void         spi_delay(void);


/****************************************************************/
/*																*/
/* FUNCTION NAME: spi_simulate_init    							*/
/*																*/
/* INPUTS		: void						                	*/
/*				: 												*/      
/*																*/
/* RETURN		: void									 		*/
/*																*/
/* NOTE			: initial the spi simulate module				*/
/*				: disable slave-select, serial clock,                  */
/*				: set MISO, MOSI to high   	    				*/
/*																*/
/****************************************************************/
void spiSimulate_init(void)
{

	SPI_SIM_LOG("before spi_init SPI_FLAG = 0x%4x\n", SPI_FLAG);
	/*spi gpio init*/
	ixp425GPIOLineConfig(IXP425_GPIO_PIN_7, IXP425_GPIO_IN);
	ixp425GPIOLineConfig(IXP425_GPIO_PIN_8, IXP425_GPIO_OUT);
	ixp425GPIOLineConfig(IXP425_GPIO_PIN_9, IXP425_GPIO_OUT);
	ixp425GPIOLineConfig(IXP425_GPIO_PIN_10, IXP425_GPIO_OUT);
	ixp425GPIOLineConfig(IXP425_GPIO_PIN_11, IXP425_GPIO_OUT);
	/**/
	DISABLE_SPISEL(0);
	DISABLE_SPISEL(1);
	HIGH_SPICLK;
	HIGH_SPIMOSI;
	read_spi_status(0);
	read_spi_status(1);
	SPI_SIM_LOG("after spi_init SPI_FLAG = 0x%4x\n", SPI_FLAG);	

}




/****************************************************************/
/*																*/
/* FUNCTION NAME: spi_simulate_read_bcm_register				*/
/*																*/
/* INPUTS		: chip - the chip ID		                	*/
/*				: page - page address							*/
/*              : reg -  register address			            */
/*				: reg_len - register length to be read              */
/*																*/
/* OUTPUTS     : pbuf - pointer to the buffer of read data          */
/*																*/
/* RETURN		: the status of broadcom SPI			 		*/
/*																*/
/* NOTE			: read data from the broadcom chip to pbuf[].	*/
/*				: using CHIP ID, PAGE address, Register address     */
/*				: the data length is reg_len   					*/
/*																*/
/****************************************************************/
extern unsigned long Print(char *format, ...);
int spi8xx_read_bcm53x8_register(int chip, UINT8 page, UINT8 reg, char *pbuf, int reg_len)
{
#ifdef FAST_READ

	return spi_simulate_fast_read_bcm_register(chip, page, reg, pbuf, reg_len);

#else
	UINT8 spi_status=0;
	ULONG i = 0;
//	SPI_SIM_LOG("spi_simulate_read_bcm_register.....\n", 1);
//	Print("chip:%d, page:%d, reg:%d, pbuf:0x%x, reg_len:%d\n",
//		chip, page, reg, pbuf, reg_len);
		
	setup_page_address(chip, page);		
	
	setup_reg_address(chip, reg);
	
	/*test RACK==1*/
	for (i=0; i<RETRY_LOOP; ++i)
	{	
		
		spi_status = read_spi_status(chip);
		
		SPI_SIM_LOG("new spi_status = 0x%x\n", spi_status);
		//Print("new spi_status = 0x%x\n", spi_status);

		if (spi_status & RACK)
			break;
		spi_delay();
	}
	if (i == RETRY_LOOP)
	{		
		return BCM_ERROR;
	}
	
	spi_simulate_read_bytes_cont(chip, pbuf, reg_len);
	//Print("pbuf:0x%x 0x%x \n", pbuf[0], pbuf[1]);
	
	return BCM_OK;
#endif
}

/****************************************************************/
/*																*/
/* FUNCTION NAME: spi_simulate_write_bcm_register				*/
/*																*/
/* INPUTS		: chip - the chip ID		                	*/
/*				: page - page address							*/
/*              : reg -  register address			            */
/*				: len -  length of data to write                    */
/*													 			*/
/* OUTPUTS     : pbuf - pointer to the buffer of write data          */
/*																*/
/* RETURN		: the status of broadcom SPI			 		*/
/*																*/
/* NOTE			: write data in pbuf[] to the broadcom chip .	*/
/*				: using CHIP ID, PAGE address, Register address     */
/*				: the data length is len   			     		*/
/*																*/
/****************************************************************/
int spi8xx_write_bcm53x8_register(int chip, UINT8 page, UINT8 reg, char *pbuf, int len)
{	
	int i = 0;
	SPI_SIM_LOG("spi_simulate_write_bcm_registser......\n", 1);	

	
	setup_page_address(chip, page);	
	

	/*write pbuf[0:len-1] to register address*/
	txbuf[0] = NORMAL_SPI_CMD | SPI_WRITE | SPI_CHIP(chip);
	txbuf[1] = reg;
	for (i=0; i<len; ++i)
	{
		txbuf[COMMAND_HEAD_LEN+i] = pbuf[i];
	}
	
	ENABLE_SPISEL(chip);
	spi_simulate_send_bytes(txbuf, len+COMMAND_HEAD_LEN);
	DISABLE_SPISEL(chip);
		
	return BCM_OK;
}


/****************************************************************/
/*																*/
/* FUNCTION NAME: spi_simulate_fast_read_bcm_register				*/
/*																*/
/* INPUTS		: chip - the chip ID		                	*/
/*				: page - page address							*/
/*              : reg -  register address			            */
/*				: reg_len - register length to be read              */
/*																*/
/* OUTPUTS     : pbuf - pointer to the buffer of read data          */
/*																*/
/* RETURN		: the status of broadcom SPI			 		*/
/*																*/
/* NOTE			: fast read data from the broadcom chip to pbuf[].   */
/*				: using CHIP ID, PAGE address, Register address     */
/*				: the data length is reg_len   					*/
/*																*/
/****************************************************************/
#ifdef FAST_READ
int spi_simulate_fast_read_bcm_register(int chip, UINT8 page, UINT8 reg, char *pbuf, int reg_len)
{
#define S_SEND 0
#define S_POLL 2
#define S_RECV 3	
	
  UINT8 state = S_SEND;
  UINT8 loop = 0xFF;
  UINT8 send;
  UINT8 mask;
  UINT8 rcvd=0;  
  UINT8 buf[SPI_MAX_BUF];
  int i=0;
  int byte = 0;

  buf[0] = FAST_SPI_CMD | SPI_READ |SPI_CHIP(chip) | OFFSET_BYTE(byte);	/* cmd */
  buf[1] = reg;	                                       /* reg address */
  for (i=COMMAND_HEAD_LEN; i<SPI_MAX_BUF; ++i)
  	buf[i] = 0;
 
  setup_page_address(chip, page);
    
  ENABLE_SPISEL(chip);  

  for (i=0; i<reg_len+byte+COMMAND_HEAD_LEN; ++i)
  {
    send = (state==S_POLL) ? 0 : buf[i];
    
    for( mask=0x80, rcvd=0; mask!=0; mask=mask>>1 )
    {
      LOW_SPICLK;       
     
      if( mask & send ) HIGH_SPIMOSI;
      else LOW_SPIMOSI;
      
      HIGH_SPICLK;
      spi_delay();
      if( IS_HIGH_SPIMISO ) rcvd |= mask;       
    }

    /*Print("i = %d \t send = 0x%x \t recv = 0x%x\n", i, send, rcvd);*/
    
    
    if( state == S_POLL )
    {
     
      if( rcvd & 0x02 )
        state = S_RECV;
      else if( --loop == 0 )
      {       
        DISABLE_SPISEL(chip);
        return BCM_ERROR;
      }
      --i;
    }
    else
    {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -