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

📄 hal_spi.c

📁 电子盘DEMO板程序
💻 C
字号:
/******************************************************************************/
/*                                                                            */
/*  Copyright (C), 1995-2006, msystems Ltd. All rights reserved.              */
/*                                                                            */
/*  Redistribution and use in source and binary forms, with or without        */
/*  modification, are permitted provided that the following conditions are    */
/*  met:                                                                      */
/*  1. Redistributions of source code must retain the above copyright notice, */
/*     this list of conditions and the following disclaimer.                  */
/*  2. Redistributions in binary form must reproduce the above copyright      */
/*     notice, this list of conditions and the following disclaimer in the    */
/*     documentation and/or other materials provided with the distribution.   */
/*  3. Neither the name of msystems nor the names of its contributors may be  */
/*     used to endorse or promote products derived from this software without */
/*     specific prior written permission.                                     */
/*                                                                            */
/*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS       */
/*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED */
/*  TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR             */
/*  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT      */
/*  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,     */
/*  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED  */
/*  TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR    */
/*  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF    */
/*  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING      */
/*  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS        */
/*  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
/*                                                                            */
/******************************************************************************/

/*
 * $Log:   V:/PVCSDB/DiskOnChip/archives/Test for 7.x/src/H3/hal_spi.c-arc  $
 * 
 *    Rev 1.9   Sep 11 2006 13:44:14   yaniv.iarovici
 * Legal header added
 * 
 *    Rev 1.8   Aug 16 2006 08:41:06   Yaniv.Iarovici
 * Add check for (pdev == NULL) in hal_init_spi()
 * 
 *    Rev 1.7   Aug 08 2006 15:28:42   Polina.Marimont
 * initial version for DOC Driver 1.0
 */

/*
 * includes
 */

#include "flcustom.h"
#include "flsystem.h"
#include "flcommon.h"
#include "hal_spi.h"
#include "doch_sys.h"
#include "doch_ata.h"

#include "hib.h"

#include "aardvark.h"

#ifdef __cplusplus
extern "C" {
#endif

/*
 * Defines
 */
#define MAX_SPI_DEVS		16
//#define SPI_BITRATE		200
//#define SPI_BITRATE			1000
#define SPI_BITRATE			4000

#define SPI_READ_CMD		0x09
#define SPI_WRITE_CMD		0x06

#define SPI_READ_DEBUG_CMD	13
	//registers is ignored; any number of bytes is read
#define SPI_WRITE_DEBUG_CMD	11
	//4LSB of registers is number of bytes to write - which can be 1 or 2

/*
 * Externals
 */
extern FLDword gAccessLayerType;

/*
 * Global vars
 */
Aardvark SpiHandle = 0;

void spi_ChannelClose(void);
unsigned char spi_RegRead(int reg);
void spi_RegWrite(int reg, unsigned char value);
int spi_DataRead(void *buf, int len);
int spi_DataWrite(void *buf, int len);
int spi_openDevice(int TargetID);
void spi_DebugWrite(unsigned short value);		// We write one or 2 characters
int spi_DebugRead(char * readPtr, int readLen);

int spi_ChannelSetup(void)
{
	aa_u16 ports[MAX_SPI_DEVS];
	int count;
	int i;

	count = aa_find_devices(MAX_SPI_DEVS,ports);
	if (count < 1) {
		return 0;
	}

	/* finding first unused port to open */
	if (count > MAX_SPI_DEVS) {
		count = MAX_SPI_DEVS;
	}

	for (i = 0; i < count; i++) {
		if (0 == (ports[i] & AA_PORT_NOT_FREE)) {
			SpiHandle = aa_open(i);
			break;
		}
	}

	if (SpiHandle <= 0)
		return 0;

	aa_configure(SpiHandle, AA_CONFIG_SPI_I2C);

	aa_target_power(SpiHandle, AA_TARGET_POWER_BOTH);

	aa_spi_configure(SpiHandle, AA_SPI_POL_RISING_FALLING, AA_SPI_PHASE_SAMPLE_SETUP, AA_SPI_BITORDER_MSB);
	aa_spi_bitrate(SpiHandle, SPI_BITRATE);

/*	ataChannelClose = spi_ChannelClose;
	ataRegRead = spi_RegRead;
	ataRegWrite = spi_RegWrite;
	ataDataRead = spi_DataRead;
	ataDataWrite = spi_DataWrite;
	ataOpenDevice = spi_openDevice;
*/
	return 1;
}

char * static_out_buf = NULL;
char * static_in_buf = NULL;
int static_buf_len = 0;

int haveBuffers(int buffLen)  {

if (buffLen > static_buf_len)  {
  if (static_out_buf)  {
    FL_FREE(static_out_buf);
    FL_FREE(static_in_buf);
    static_buf_len = 0;
    }

  static_out_buf = (char *)FL_MALLOC(buffLen);
  static_in_buf = (char *)FL_MALLOC(buffLen);
  if (!static_out_buf || !static_in_buf) return FALSE;
  static_buf_len = buffLen;
  }

return TRUE;
}

/****************************************************************************** 
 *                                                                            * 
 *                        d o c h _ s y s _ i n i t                           * 
 *                                                                            * 
 *  Initialize BSP specific part of DOCH driver.                              * 
 *                                                                            * 
 *  Parameters :                                                              *
 *      socketNo            : Socket # (0...DOCH_MAX_SOCKETS-1)               *
 *                                                                            * 
 *  Returns :                                                                 * 
 *      0 if success, otherwise respective error code.                        *
 *                                                                            * 
 ******************************************************************************/

DOCH_Error hal_init_spi ( FLSNative  socketNo)
{
	DOCH_Socket* pdev;
	DOCH_get_socket(pdev, socketNo);

	/*If socket is not registered, return error*/
	if(pdev == NULL)
		return DOCH_DiskNotFound;

	/*Register access layer routines*/
	pdev->halRoutines.hal_get_ata_reg	= hal_get_ata_reg_spi;
	pdev->halRoutines.hal_set_ata_reg	= hal_set_ata_reg_spi;
	pdev->halRoutines.hal_get_ctrl_reg	= hal_get_ctrl_reg_spi;
	pdev->halRoutines.hal_set_ctrl_reg	= hal_set_ctrl_reg_spi;
	pdev->halRoutines.hal_blk_read		= hal_blk_read_spi;
	pdev->halRoutines.hal_blk_write		= hal_blk_write_spi;
	pdev->halRoutines.hal_doch_release	= doch_sys_release_spi;

	gAccessLayerType = DOCH_AL_SPI;

	/*Setup a channel*/
	if (!spi_ChannelSetup()) {

		DBG_PRINT_ERR(FLZONE_ATA, "Unable to communicate with adapter\n");
		return DOCH_AdapterNotFound;
	}

	gDochAccessNanosec = DOCH_SPI_ACCESS_NANOSEC;

	return DOCH_OK;
}

DOCH_Error hal_init_spi_noFunc ( FLSNative  socketNo)
{
	gAccessLayerType = DOCH_AL_SPI;
	
	return DOCH_OK;
}

/*********************************************************/
/* Function name	: doch_sys_release_spi*/
/* Description	    : */
/* Return type		: */
/* Argument         : int socketNo*/
/*********************************************************/
FLSNative doch_sys_release_spi(int socketNo)
{	
	aa_close(SpiHandle);

	return flOK;
}

/****************************************************************************** 
 *                                                                            * 
 *                   d o c h_ s y s _ g e t _ r e g X                         * 
 *                                                                            * 
 *  Reads DOCH register.                                                      * 
 *                                                                            * 
 *  Parameters :                                                              *
 *      base                 : pointer to the base of DOCH register set       *
 *      reg                  : ATA register number						      *
 *                                                                            * 
 *  Returns :                                                                 * 
 *      value of specified register                                           *
 *                                                                            * 
 ******************************************************************************/

FLByte hal_get_ata_reg_spi(volatile FLByte *base, FLSNative  reg)
{
	unsigned char out_buffer[3], in_buffer[3];

	out_buffer[0] = SPI_READ_CMD;
	out_buffer[1] = (reg << 4) | 1; // We read one register here

	aa_spi_write(SpiHandle,3,out_buffer,in_buffer);

	return in_buffer[2];
}

FLWord hal_get_ctrl_reg_spi ( volatile FLByte * base, 
                              FLSNative         reg )
{
	if(reg == HIB_CHIPID1_REG)
		return 0x4833;
	else if(reg == HIB_CHIPID2_REG)
		return 0xB7CC;
	else 
		return 0;
}


/****************************************************************************** 
 *                                                                            * 
 *                  d o c h _ s y s _ s e t _ r e g X                         * 
 *                                                                            * 
 *  Writes DOCH register.                                                     * 
 *                                                                            * 
 *  Parameters :                                                              *
 *      base                 : pointer to the base of DOCH register set       *
 *      reg                  : ATA register number						      *
 *      val                  : value to write to register                     *
 *                                                                            * 
 *  Returns :                                                                 * 
 *      value of specified register                                           *
 *                                                                            * 
 ******************************************************************************/

void hal_set_ata_reg_spi ( volatile FLByte *   base, 
						   FLSNative           reg,
                           FLNative            val )
{
	unsigned char out_buffer[3], in_buffer[3];

	out_buffer[0] = SPI_WRITE_CMD;
	out_buffer[1] = (reg << 4) | 1; // We read one register here
	out_buffer[2] = val;

	aa_spi_write(SpiHandle,3,out_buffer,in_buffer);
}

void hal_set_ctrl_reg_spi ( volatile FLByte *   base, 
                         FLSNative			 reg,
                         FLNative			 val )
{
	return;
	/*TBD*/
}


/****************************************************************************** 
 *                                                                            * 
 *                  d o c h _ s y s _ b l k _ r e a d                         * 
 *                                                                            * 
 *  Read 'bytes' bytes from DOCH (usually 512 bytes).                         * 
 *                                                                            * 
 *  Parameters :                                                              *
 *      base                 : pointer to the base of DOCH register set       *
 *      buf                  : buffer to read to                              *
 *      bytes                : number of bytes to read (must be even)         *
 *                                                                            * 
 *  Returns :                                                                 * 
 *      always zero (success)                                                 *
 *                                                                            * 
 ******************************************************************************/

FLSNative hal_blk_read_spi ( volatile FLByte   * base, 
							 FLByte            * buf, 
							 FLSNative           bytes )
{

	int readlen = 0;
	int res = 0;

	bytes = bytes<<DOCH_SECTOR_SIZE_BITS;

	readlen = (bytes + DOCH_SECTOR_SIZE - 1) & -DOCH_SECTOR_SIZE;

	if (!haveBuffers(readlen + 2)) return FALSE;

	static_out_buf[0] = SPI_READ_CMD;
	static_out_buf[1] = (readlen / DOCH_SECTOR_SIZE) & 0x0F;

	res = aa_spi_write(SpiHandle, (unsigned short)(readlen + 2), (const aa_u08 *)static_out_buf, (aa_u08 *)static_in_buf);

	tffscpy(buf, static_in_buf + 2, bytes);

	return 0;
}




/****************************************************************************** 
 *                                                                            * 
 *                  d o c h _ s y s _ b l k _ w r i t e                       * 
 *                                                                            * 
 *  Write 'bytes' bytes to DOCH (usually 512 bytes).                          * 
 *                                                                            * 
 *  Parameters :                                                              *
 *      base                 : pointer to the base of DOCH register set       *
 *      buf                  : buffer to write from                           *
 *      bytes                : number of bytes to write (must be even)        *
 *                                                                            * 
 *  Returns :                                                                 * 
 *      always zero (success)                                                 *
 *                                                                            * 
 ******************************************************************************/

FLSNative hal_blk_write_spi ( volatile FLByte * base, 
							  FLByte          * buf, 
							  FLSNative         bytes )
{
	int writelen = 0;

	bytes = bytes<<DOCH_SECTOR_SIZE_BITS;
	writelen = (bytes + DOCH_SECTOR_SIZE - 1) & -DOCH_SECTOR_SIZE;

    if (!haveBuffers(writelen + 2)) return FALSE;

	static_out_buf[0] = SPI_WRITE_CMD;
	static_out_buf[1] = (writelen / DOCH_SECTOR_SIZE) & 0x0F;

	memcpy(static_out_buf + 2, buf, bytes);

	aa_spi_write(SpiHandle, (unsigned short)(writelen + 2), (const aa_u08 *)static_out_buf, (aa_u08 *)static_in_buf);

	return 0;
}

#ifdef __cplusplus
}
#endif

⌨️ 快捷键说明

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