📄 spi.c
字号:
/*******************************************************************************
* Copyright: Copyright (c) 2007. Hisilicon Technologies, CO., LTD.
* Version: V300R001B03
* Filename: spi.c
* Description: spi总线驱动的功能实现
* History:
1.Created by wubin on 2007/12/21
*******************************************************************************/
#include "spi.h"
#ifdef DEBUG
PSPI_REG pSPI2;
volatile PUINT32 pSysConReg;
BOOL InitLcdSPI(void)
{
#ifdef HISI3610_CHIP
OUTREG32(IOCMG_BASE_ADDR + 0x92C, 0x0);
OUTREG32(IOCMG_BASE_ADDR + 0x930, 0x5);
OUTREG32(IOCMG_BASE_ADDR + 0x934, 0x0);
OUTREG32(IOCMG_BASE_ADDR + 0x8b4, 0x0);
//OUTREG32(IOCMG_BASE_ADDR + 0x938, 0x8);
//OUTREG32(IOCMG_BASE_ADDR + 0x93C, 0x8);
OUTREG32(IOCMG_BASE_ADDR + 0x048, 0);
OUTREG32(IOCMG_BASE_ADDR + 0x04C, 0);
OUTREG32(IOCMG_BASE_ADDR + 0x024, 0x0);//choose SPI2_CS1
#endif
pSPI2 = (PSPI_REG)SPI2_BASE;
pSysConReg = (PUINT32)SYS_CONTROL_LCD_BASE_ADDRESS;
OUTREG32(&pSPI2->SSPCR0,(SCR | SPH | SPO | FRF | DSS));
OUTREG32(&pSPI2->SSPCR1,(SOD | MS | SSE_DIS | LBM));
OUTREG32(&pSPI2->SSPCPSR,CPSDVSR);
return TRUE;
}
BOOL WriteLCDRegister(const UINT8 *pData, UINT8 length)
{
BOOL bXchDone = FALSE;
UINT32 xchTxCnt = 0;
#ifdef HISI3610_CHIP
CLRREG32(pSysConReg,0x00000800);
CLRREG32(pSysConReg,0x00000400);
SETREG32(pSysConReg,0x00001000);
#else
CLRREG32(pSysConReg,0x00000800);
SETREG32(pSysConReg,0x00000400); //片选lcd。
#endif
// disable all interrupts
OUTREG32(&pSPI2->SSPIMSC, 0);
// until we are done with requested transfers
while(!bXchDone)
{
UINT8 i = MMU5_NUM;
// disable ssp
CLRREG32(&pSPI2->SSPCR1, SSE_BIT);
// load Tx FIFO until full, or until we run out of data
while ((INREG32(&pSPI2->SSPSR) & CSP_BITFMASK(CSPI_SSPSR_TNF))//TNF TFE
&& (xchTxCnt < length) && (i != 0))
{
// put next Tx data into CSPI FIFO
OUTREG32(&pSPI2->SSPDR, *pData);
//DEBUGMSG(ZONE_FUNCTION, (TEXT(" Send data 0x%x to TxFIFO\r\n"), pfnTxBufRd(pTxBuf)));
// increment Tx Buffer to next data point
pData++;
// increment Tx exchange counter
xchTxCnt ++;
i-=1;
}
// enable ssp
SETREG32(&pSPI2->SSPCR1, SSE_BIT);
while (INREG32(&pSPI2->SSPSR) & CSP_BITFMASK(CSPI_SSPSR_BSY));
if (xchTxCnt == length)
{
bXchDone = TRUE;
CLRREG32(&pSPI2->SSPCR1, SSE_BIT);
}
} // while(!bXchDone)
return TRUE;
}
#endif
PSPI_REG pSPI3;
BOOL InitHi6421SPI(void)
{
#ifdef HISI3610_CHIP
UINT32 regValue;
/* SCRSTCTRL2, 模块级软复位控制寄存器2, 需要撤销SPI1、2、3的复位 */
/* 此处吴学诚已经处理*/
/* SCPERCTRL1, 外设控制寄存器1,用于外设的通用控制. 需要配置SPI的时钟选择
[6:4] SPISel 0x7 SPI时钟选择。Bit6表示SPI3、Bit5表示SPI2、Bit4表示SPI1。
0:选择异步桥时钟。
1:选择26MHz时钟。*/
regValue= INREG32(HISI3610_SYSCTRL_SCPERCTRL1);
regValue = regValue & 0xffffff8f; // 选择异步桥时钟
OUTREG32(HISI3610_SYSCTRL_SCPERCTRL1, regValue);
/* SCPEREN, 外设时钟使能寄存器。需要使能SPI的时钟.
Bit24:SPI1;
Bit25:SPI2;
Bit26:SPI3;*/
/* 此处吴学诚已经处理*/
#endif
/*物理地址转换成虚拟地址*/
pSPI3 = (PSPI_REG)SPI3_BASE;
/*配置SSPCR0寄存器,scr取4,字长度为8bit*/
OUTREG32(&pSPI3->SSPCR0, SPI3CR0);
/*配置SSPCR0寄存器,0x0009:禁止spi3,master,环回模式*/
/* 0x0008:禁止spi3,master,正常模式*/
OUTREG32(&pSPI3->SSPCR1, SPI3CR1);
/* cpsdvsr必须为偶数,分频比为cpsdvsr*(1+scr) */
OUTREG32(&pSPI3->SSPCPSR, SPI3CPSR);
return TRUE;
}
BOOL ReadHi6421Register(UINT8 ucRegAddr, UINT8 *pData)
{
UINT8 tmp = 0;
/*如果SPI控制器忙或者接收FIFO中还有未处理的数据,则等待*/
while ((INREG32(&pSPI3->SSPSR) & CSP_BITFMASK(CSPI_SSPSR_BSY))
|| (INREG32(&pSPI3->SSPSR) & CSP_BITFMASK(CSPI_SSPSR_RNE)))
{
}
/*禁止SPI传输*/
SETBITVALUE32(&pSPI3->SSPCR1, CSP_BITFMASK(CSPI_SSPCR1_SSE),
CSP_BITFVAL(CSPI_SSPCR1_SSE, CSPI_SSPCR1_SSE_DISABLE));
/*往发送FIFO中写读寄存器命令*/
OUTREG8(&pSPI3->SSPDR, ((ucRegAddr<<1)|READBIT));
//OALMSGS(OAL_FUNC,(L"ReadSpi: Send data 0x%x to TxFIFO\r\n",((ucRegAddr<<1)|READBIT)));
/*往发送FIFO中写8位空数据,此时接收FIFO中将接收到Hi6421寄存器内容*/
OUTREG8(&pSPI3->SSPDR, DUMMYDATA);
//OALMSGS(OAL_FUNC,(L"WriteSpi: Send data 0x%x to TxFIFO\r\n",DUMMYDATA));
/*使能SPI传输*/
SETBITVALUE32(&pSPI3->SSPCR1, CSP_BITFMASK(CSPI_SSPCR1_SSE),
CSP_BITFVAL(CSPI_SSPCR1_SSE, CSPI_SSPCR1_SSE_ENABLE));
/*从接收FIFO中读无用数据*/
while (!(INREG32(&pSPI3->SSPSR) & CSP_BITFMASK(CSPI_SSPSR_RNE)))
{
;
}
tmp = INREG8(&pSPI3->SSPDR);
//OALMSGS(OAL_FUNC,(L"WriteSpi: Receive data 0x%x from RxFIFO\r\n",tmp));
/*从接收FIFO中读寄存器数据*/
while (!(INREG32(&pSPI3->SSPSR) & CSP_BITFMASK(CSPI_SSPSR_RNE)))
{
;
}
*pData = INREG8(&pSPI3->SSPDR);
//OALMSGS(OAL_FUNC,(L"WriteSpi: Receive data 0x%x from RxFIFO\r\n",*pData));
return TRUE;
}
BOOL WriteHi6421Register(UINT8 ucRegAddr, UINT8 ucData, UINT8 ucMask)
{
UINT8 RegWriteVal = ucData;
UINT8 RegReadVal = 0;
UINT8 tmp = 0;
/*如果屏蔽标志位不为0*/
/*则先读出该寄存器,再写入该寄存器*/
if (ucMask != 0)
{
ReadHi6421Register(ucRegAddr, &RegReadVal);
/*根据Mask位和读到的寄存器值计算要写入的寄存器值*/
RegWriteVal = (RegReadVal & ucMask) | (ucData & (~ucMask));
}
/*如果SPI控制器忙或者接收FIFO中还有未处理的数据,则等待*/
while ((INREG32(&pSPI3->SSPSR) & CSP_BITFMASK(CSPI_SSPSR_BSY))
|| (INREG32(&pSPI3->SSPSR) & CSP_BITFMASK(CSPI_SSPSR_RNE)))
{
}
/*禁止SPI传输*/
SETBITVALUE32(&pSPI3->SSPCR1, CSP_BITFMASK(CSPI_SSPCR1_SSE),
CSP_BITFVAL(CSPI_SSPCR1_SSE, CSPI_SSPCR1_SSE_DISABLE));
/*往发送FIFO中写写寄存器命令*/
OUTREG8(&pSPI3->SSPDR, ((ucRegAddr<<1)|WRITEBIT));
//OALMSGS(OAL_FUNC,(L"WriteSpi: Send data 0x%x to TxFIFO\r\n",((ucRegAddr<<1)|WRITEBIT)));
/*往发送FIFO中写待写的寄存器内容*/
OUTREG8(&pSPI3->SSPDR, RegWriteVal);
//OALMSGS(OAL_FUNC,(L"WriteSpi: Send data 0x%x to TxFIFO\r\n",RegWriteVal));
/*使能SPI传输*/
SETBITVALUE32(&pSPI3->SSPCR1, CSP_BITFMASK(CSPI_SSPCR1_SSE),
CSP_BITFVAL(CSPI_SSPCR1_SSE, CSPI_SSPCR1_SSE_ENABLE));
/*从接收FIFO中读无用数据*/
while (!(INREG32(&pSPI3->SSPSR) & CSP_BITFMASK(CSPI_SSPSR_RNE)))
{
;
}
tmp = INREG8(&pSPI3->SSPDR);
//OALMSGS(OAL_FUNC,(L"WriteSpi: Receive data 0x%x from RxFIFO\r\n",tmp));
/*从接收FIFO中读无用数据*/
while (!(INREG32(&pSPI3->SSPSR) & CSP_BITFMASK(CSPI_SSPSR_RNE)))
{
;
}
tmp = INREG8(&pSPI3->SSPDR);
return TRUE;
}
#define PMU_RTC_MR 0x23
BOOL ReadPmuBootFlag(UINT8 *pBuffer)
{
BOOL bRlt = TRUE;
UINT8 i;
for(i=0; i<4; i++)
{
bRlt = bRlt && ReadHi6421Register(PMU_RTC_MR+i, pBuffer+i);
}
return bRlt;
}
BOOL WritePmuBootFlag(UINT8 *pBuffer)
{
BOOL bRlt = TRUE;
UINT8 i;
for(i=0; i<4; i++)
{
bRlt = bRlt && WriteHi6421Register(PMU_RTC_MR+i, *(pBuffer+i), 0);
}
return bRlt;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -