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

📄 hw_spi.c

📁 瑞星微公司RK27XX系列芯片的SDK开发包
💻 C
📖 第 1 页 / 共 3 页
字号:
/******************************************************************/
/*   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 + -