📄 hal_spi.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 + -