📄 hw_spi.c
字号:
/******************************************************************/
/* Copyright (C) 2007 ROCK-CHIPS FUZHOU . All Rights Reserved. */
/*******************************************************************
File : spi.c
Desc : SPI接口函数的实现
Author : huangxinyu
Date : 2007-06-10
Notes :
$Log: hw_spi.c,v $
Revision 1.2 2008/06/19 04:43:36 Administrator
代码整理!
Revision 1.1.1.1 2008/05/07 04:15:08 Administrator
no message
Revision 1.1.1.1 2008/03/06 13:29:08 Lingzhaojun
no message
Revision 1.4 2007/11/10 04:30:41 Huangxinyu
调试修改
Revision 1.3 2007/10/17 02:00:06 Huangxinyu
增加spi接口
Revision 1.2 2007/10/08 02:38:50 Lingzhaojun
添加版本自动注释脚本
*********************************************************************/
//#include "include.h"
#include <stdio.h>
#include <string.h>
#include "hw_spi.h"
#include "hwapi_interrupt.h"
#include "hw_serial.h"
extern INT32U DummyWriteReg ; /* In case that both code&data are cacheable,write a word before
read any uncacheable io reg.*/
#define TEST_MEMORY_BASE 0x60820000
#define PATTERN_BUFFER_BASE TEST_MEMORY_BASE
#define PATTERN_BUFFER_SIZE 2048
#define RECEIVE_DATA_BASE PATTERN_BUFFER_BASE+PATTERN_BUFFER_SIZE
#define PHY_RECEIVE_DATA_BASE RECEIVE_DATA_BASE
#define RECEIVE_DATA_SIZE 2048
#define TESTING_DATA_SIZE 512
// flag variables
volatile BOOL spiReadyTx;
volatile BOOL spiBufferedTx;
volatile BOOL spiFIFO;
#define pSPIReg ((pSPIReg_t)SPI_REG_BASE)
//static pSPIReg_t pSPIReg = (pSPIReg_t)SPI_REG_BASE;
static UINT8 gSpiDataAlign;
static UINT32 spiconfig = UNIDIRECTION | LSB_FIRST | SCLK_1ST_EdGE | LOW_IDLE | TX_RX_NO_CONCURRENT | CLOCK_ASSERT | LENGTH_8BITS | ((1000 * 1000) << 16);
#define IS_SPI_RUNNING() (ReadReg32(&pSPIReg->SPI_FWCR) & SPI_RUN)
#define SPI_START_TRANSFER() SetRegBits32(&pSPIReg->SPI_FWCR, SPI_RUN)
#define SPI_LOOPBACK_EN() SetRegBits32(&pSPIReg->SPI_FWCR, LOOPBACK_ENABLE)
#define SPI_LOOPBACK_DIS() ClrRegBits32(&pSPIReg->SPI_FWCR, LOOPBACK_ENABLE)
#define SPI_BIDIRECTION_EN() SetRegBits32(&pSPIReg->SPI_FWCR, BIDIRECTION_ENABLE)
#define SPI_BIDIRECTION_DIS() ClrRegBits32(&pSPIReg->SPI_FWCR, BIDIRECTION_ENABLE)
#define SPI_LSBFIRST_EN() SetRegBits32(&pSPIReg->SPI_FWCR, LSB_FIRST_EN)
#define SPI_MSBFIRST_EN() ClrRegBits32(&pSPIReg->SPI_FWCR, LSB_FIRST_EN)
#define SPI_SECOND_PHASE() SetRegBits32(&pSPIReg->SPI_FWCR, CLOCK_PHASE)
#define SPI_FIRST_PHASE() ClrRegBits32(&pSPIReg->SPI_FWCR, CLOCK_PHASE)
#define SPI_LOW_IDLE() SetRegBits32(&pSPIReg->SPI_FWCR, CLOCK_POLARITY)
#define SPI_HIGH_IDLE() ClrRegBits32(&pSPIReg->SPI_FWCR, CLOCK_POLARITY)
#define SPI_CONCURRENT_EN() SetRegBits32(&pSPIReg->SPI_FWCR, CONCURRENT_ENABLE)
#define SPI_CONCURRENT_DIS() ClrRegBits32(&pSPIReg->SPI_FWCR, CONCURRENT_ENABLE)
#define SPI_CLOCK_IDLE_EN() SetRegBits32(&pSPIReg->SPI_FWCR, CLOCK_IDLE_ASSERT)
#define SPI_CLOCK_IDLE_DIS() ClrRegBits32(&pSPIReg->SPI_FWCR, CLOCK_IDLE_ASSERT)
#define SPI_MASETR_EN() SetRegBits32(&pSPIReg->SPI_FWCR, MASETR_ENABLE)
#define SPI_MASETR_DIS() ClrRegBits32(&pSPIReg->SPI_FWCR, MASETR_ENABLE)
#define SPI_RESET() SetRegBits32(&pSPIReg->SPI_FWCR, RESET_CONTROL)
#define IS_RX_DATA_AVAILABLE() (ReadReg32(&pSPIReg->SPI_FCR) & RECEIVE_DATA_AVAILABLE)
#define IS_TX_FIFO_FULL() (ReadReg32(&pSPIReg->SPI_FCR) & TRANSMIT_FIFO_FULL)
#define SPI_CLEAR_TX_FIFO() SetRegBits32(&pSPIReg->SPI_FCR, CLEAR_TRANSMIT)
#define SPI_CLEAR_RX_FIFO() SetRegBits32(&pSPIReg->SPI_FCR, CLEAR_RECEIVE)
#define SPI_TX_FIFO_THRESH_2() MaskRegBits32(&pSPIReg->SPI_FCR, TRANSMIT_LEVEL_MASK, SPI_TX_THRESH_2)
#define SPI_TX_FIFO_THRESH_4() MaskRegBits32(&pSPIReg->SPI_FCR, TRANSMIT_LEVEL_MASK, SPI_TX_THRESH_4)
#define SPI_TX_FIFO_THRESH_6() MaskRegBits32(&pSPIReg->SPI_FCR, TRANSMIT_LEVEL_MASK, SPI_TX_THRESH_6)
#define SPI_RX_FIFO_THRESH_2() MaskRegBits32(&pSPIReg->SPI_FCR, RECEIVE_LEVEL_MASK, SPI_RX_THRESH_2)
#define SPI_RX_FIFO_THRESH_4() MaskRegBits32(&pSPIReg->SPI_FCR, RECEIVE_LEVEL_MASK, SPI_RX_THRESH_4)
#define SPI_RX_FIFO_THRESH_6() MaskRegBits32(&pSPIReg->SPI_FCR, RECEIVE_LEVEL_MASK, SPI_RX_THRESH_6)
#define SPI_COMPLETE_INT_EN() SetRegBits32(&pSPIReg->SPI_IER, TRANSFER_COMPLETE)
#define SPI_COMPLETE_INT_DIS() ClrRegBits32(&pSPIReg->SPI_IER, TRANSFER_COMPLETE)
#define SPI_OVERRUN_INT_EN() SetRegBits32(&pSPIReg->SPI_IER, RECEIVE_FIFO_OVERRUN)
#define SPI_OVERRUN_INT_DIS() ClrRegBits32(&pSPIReg->SPI_IER, RECEIVE_FIFO_OVERRUN)
#define SPI_RECEIVE_INT_EN() SetRegBits32(&pSPIReg->SPI_IER, RECEIVE_DATA)
#define SPI_RECEIVE_INT_DIS() ClrRegBits32(&pSPIReg->SPI_IER, RECEIVE_DATA)
#define SPI_TRANSMIT_INT_EN() SetRegBits32(&pSPIReg->SPI_IER, TRANSMIT_DATA )
#define SPI_TRANSMIT_INT_DIS() ClrRegBits32(&pSPIReg->SPI_IER, TRANSMIT_DATA )
#define SPI_INT_ENABLE(x) SetRegBits32(&pSPIReg->SPI_IER, (x))
#define SPI_INT_DISABLE(x) ClrRegBits32(&pSPIReg->SPI_IER, (x))
#define IS_TRANSFER_COMPLETE() (ReadReg32(&pSPIReg->SPI_ISR) & TRANSFER_COMPLETE_INT)
#define IS_OVERRUN() (ReadReg32(&pSPIReg->SPI_ISR) & OVERRUN_INT)
#define IS_RECEVIE_FIFO() (ReadReg32(&pSPIReg->SPI_ISR) & RECEIVE_FIFO_INT)
#define IS_TRANSMIT_FIFO() (ReadReg32(&pSPIReg->SPI_ISR) & TRANSMIT_FIFO_INT)
// data read & write control
#define SPI_WRITE_DATA(x) WriteReg32(&pSPIReg->SPI_TxR, (x))
#define SPI_READ_DATA() ReadReg32(&pSPIReg->SPI_RxR)
// Transmit & Receive data count setting
#define SET_TRANSMIT_COUNT(x) WriteReg32(&pSPIReg->SPI_TxCR, (x))
#define SET_RECEIVE_COUNT(x) WriteReg32(&pSPIReg->SPI_RxCR, (x))
#define GET_TRANSMIT_COUNT() ReadReg32(&pSPIReg->SPI_TxCR)
#define GET_RECEIVE_COUNT() ReadReg32(&pSPIReg->SPI_RxCR)
#define ACTIVE_DELAY_HALF() MaskRegBits32(&pSPIReg->SPI_DLYCR, ACTIVE_DELAY_MASK, CLOCK_HALF)
#define ACTIVE_DELAY_4() MaskRegBits32(&pSPIReg->SPI_DLYCR, ACTIVE_DELAY_MASK, CLOCK_4)
#define ACTIVE_DELAY_8() MaskRegBits32(&pSPIReg->SPI_DLYCR, ACTIVE_DELAY_MASK, CLOCK_8)
#define ACTIVE_DELAY_16() MaskRegBits32(&pSPIReg->SPI_DLYCR, ACTIVE_DELAY_MASK, CLOCK_16 )
#define ACTIVE_DELAY_32() MaskRegBits32(&pSPIReg->SPI_DLYCR, ACTIVE_DELAY_MASK, CLOCK_32 )
#define ACTIVE_DELAY_64() MaskRegBits32(&pSPIReg->SPI_DLYCR, ACTIVE_DELAY_MASK, CLOCK_64 )
#define ACTIVE_DELAY_128() MaskRegBits32(&pSPIReg->SPI_DLYCR, ACTIVE_DELAY_MASK, CLOCK_128 )
#define ACTIVE_DELAY_256() MaskRegBits32(&pSPIReg->SPI_DLYCR, ACTIVE_DELAY_MASK, CLOCK_256 )
#define SET_ACTIVE_DELAY(x) MaskRegBits32(&pSPIReg->SPI_DLYCR, ACTIVE_DELAY_MASK, (x) )
#define TRANSFER_DELAY_ZERO() MaskRegBits32(&pSPIReg->SPI_DLYCR, TRANSFER_DELAY_MASK, CLOCK_ZERO )
#define TRANSFER_DELAY_4() MaskRegBits32(&pSPIReg->SPI_DLYCR, TRANSFER_DELAY_MASK, CLOCK_4 )
#define TRANSFER_DELAY_8() MaskRegBits32(&pSPIReg->SPI_DLYCR, TRANSFER_DELAY_MASK, CLOCK_8 )
#define TRANSFER_DELAY_16() MaskRegBits32(&pSPIReg->SPI_DLYCR, TRANSFER_DELAY_MASK, CLOCK_16 )
#define TRANSFER_DELAY_32() MaskRegBits32(&pSPIReg->SPI_DLYCR, TRANSFER_DELAY_MASK, CLOCK_32 )
#define TRANSFER_DELAY_64() MaskRegBits32(&pSPIReg->SPI_DLYCR, TRANSFER_DELAY_MASK, CLOCK_64 )
#define TRANSFER_DELAY_128() MaskRegBits32(&pSPIReg->SPI_DLYCR, TRANSFER_DELAY_MASK, CLOCK_128 )
#define TRANSFER_DELAY_256() MaskRegBits32(&pSPIReg->SPI_DLYCR, TRANSFER_DELAY_MASK, CLOCK_256 )
#define SET_TRANSFER_DELAY(x) MaskRegBits32(&pSPIReg->SPI_DLYCR, TRANSFER_DELAY_MASK, (x))
#define TxRx_DELAY_ZERO() MaskRegBits32(&pSPIReg->SPI_DLYCR, TxRx_DELAY_MASK, CLOCK_ZERO )
#define TxRx_DELAY_4() MaskRegBits32(&pSPIReg->SPI_DLYCR, TxRx_DELAY_MASK, CLOCK_4 )
#define TxRx_DELAY_8() MaskRegBits32(&pSPIReg->SPI_DLYCR, TxRx_DELAY_MASK, CLOCK_8 )
#define TxRx_DELAY_16() MaskRegBits32(&pSPIReg->SPI_DLYCR, TxRx_DELAY_MASK, CLOCK_16 )
#define TxRx_DELAY_32() MaskRegBits32(&pSPIReg->SPI_DLYCR, TxRx_DELAY_MASK, CLOCK_32 )
#define TxRx_DELAY_64() MaskRegBits32(&pSPIReg->SPI_DLYCR, TxRx_DELAY_MASK, CLOCK_64 )
#define TxRx_DELAY_128() MaskRegBits32(&pSPIReg->SPI_DLYCR, TxRx_DELAY_MASK, CLOCK_128 )
#define TxRx_DELAY_256() MaskRegBits32(&pSPIReg->SPI_DLYCR, TxRx_DELAY_MASK, CLOCK_256 )
#define SET_TxRx_DELAY(x) MaskRegBits32(&pSPIReg->SPI_DLYCR, TxRx_DELAY_MASK, (x) )
#define SET_CLOCK_DIVISOR(x) MaskRegBits32(&pSPIReg->SPI_SSCR, CLOCK_DIVISOR_MASK, (x))
#define SPI_SELECT_SLAVE(x) MaskRegBits32(&pSPIReg->SPI_SSCR, SLAVE_SELECT_MASK, (x << 8))
#define SET_BIT_LENGTH(x) MaskRegBits32(&pSPIReg->SPI_SSCR, SLAVE_SELECT_MASK, (x << 11))
#define CHECK_RECEVIE_COMPLETE(x) ((x) & TRANSFER_COMPLETE_INT)
#define CHECK_OVERRUN(x) ((x) & OVERRUN_INT)
#define CHECK_RECEVIE_FIFO(x) ((x) & RECEIVE_FIFO_INT)
#define CHECK_TRANSMIT_FIFO(x) ((x) & TRANSMIT_FIFO_INT)
// receive and transmit buffers
unsigned char spiRxBufferSpace[1024];
unsigned char spiTxBufferSpace[1024];
cBuffer spiRxBuffer;
cBuffer spiTxBuffer;
/**************************************************************************
* 函数描述: 初始化buffer结构成员,供SPIInitBuffers调用
* 入口参数: buffer -- 待初始化的buffer
* start -- buffer的起始位置
* size -- buffer大小
* 出口参数: 无
* 返回值: 无
***************************************************************************/
void bufferInit(cBuffer* buffer, unsigned char *start, unsigned short size)
{
// set start pointer of the buffer
buffer->dataptr = start;
buffer->size = size;
// initialize index and length
buffer->dataindex = 0;
buffer->datalength = 0;
}
/**************************************************************************
* 函数描述: 在buffer内向后开始送数
* 入口参数: buffer -- 将要送数的buffer
* data -- 将要送的数(char型)
* 出口参数: 无
* 返回值: TRUE -- 成功送数
* FALSE -- 送数失败
***************************************************************************/
BOOL bufferAddToEnd(cBuffer* buffer, unsigned char data)
{
// make sure the buffer has room
if (buffer->datalength < buffer->size)
{
// save data byte at end of buffer
buffer->dataptr[(buffer->dataindex + buffer->datalength) % buffer->size] = data;
// increment the length
buffer->datalength++;
return TRUE;
}
else return FALSE;
}
/**************************************************************************
* 函数描述: 在buffer内从前开始取数
* 入口参数: buffer -- 将要取数的buffer
* 出口参数: 无
* 返回值: data -- 取出的数(char型)
***************************************************************************/
unsigned char bufferGetFromFront(cBuffer* buffer)
{
unsigned char data = 0;
// check to see if there's data in the buffer
if (buffer->datalength)
{
// get the first character from buffer
data = buffer->dataptr[buffer->dataindex];
// move index down and decrement length
buffer->dataindex++;
if (buffer->dataindex >= buffer->size)
{
buffer->dataindex %= buffer->size;
}
buffer->datalength--;
}
// return
return data;
}
/**************************************************************************
* 函数描述: 清空buffer内容
* 入口参数: buffer -- 清空的buffer
* 出口参数: 无
* 返回值: 无
***************************************************************************/
void bufferFlush(cBuffer* buffer)
{
// flush contents of the buffer
buffer->datalength = 0;
}
void initSPITestPattern(unsigned char *buffer, int size)
{
int i = 0;
unsigned char *ptr = buffer;
for (i = 0; i < size; ptr++)
{
*ptr = (unsigned char)((++i));
}
}
/**************************************************************************
* 函数描述: SPI buffer结构初始化
* 入口参数: 无
* 出口参数: 无
* 返回值: 无
***************************************************************************/
void SPIInitBuffers(void)
{
// initialize the SPI receive buffer
bufferInit(&spiRxBuffer, spiRxBufferSpace, sizeof(spiRxBufferSpace));
//serial_printf("spiRxBufferSpace = 0x%x \n",spiRxBufferSpace);
// initialize the SPI transmit buffer
bufferInit(&spiTxBuffer, spiTxBufferSpace, sizeof(spiTxBufferSpace));
//serial_printf("spiTxBufferSpace = 0x%x \n",spiTxBufferSpace);
}
/**************************************************************************
* 函数描述: SPI中断处理
* 入口参数: pparam -- 备用的指针参数
* 出口参数: 无
* 返回值: 无
***************************************************************************/
void SPI_IntrHandler(void)
{
register volatile UINT32 status;
do
{
// read & clear interrupt status
status = ReadReg32(&(pSPIReg->SPI_ISR));
// check is receive complete
if (CHECK_RECEVIE_COMPLETE(status))
{
// get receive data in FIFO
while (IS_RX_DATA_AVAILABLE())
{
if (!bufferAddToEnd(&spiRxBuffer, SPI_READ_DATA())) // 收到的数据添加到spiRxBuffer结尾
{
// no space - do something to signal an overflow
//printfProgStrM("SPI RX OVFL");
}
}
spiBufferedTx = FALSE;
spiReadyTx = TRUE;
// receive complete - do something to signal an complete
return;
}
// check is receive data available
if (CHECK_RECEVIE_FIFO(status))
{
while (IS_RX_DATA_AVAILABLE())
{
if (!bufferAddToEnd(&spiRxBuffer, SPI_READ_DATA())) // 收到的数据添加到spiRxBuffer结尾
{
// no space - do something to signal an overflow
//printfProgStrM("SPI RX OVFL");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -