123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398 |
- /**
- * @file hv_drv_Spi.c
- * @brief SPI drviver layer file.
- *
- * @author HiView SoC Software Team
- * @version 1.0.0
- * @date 2023-06-19
- * @copyright Copyright(c),2023-6, Hiview Software. All rights reserved.
- * </table>
- */
- #include "hv_vos_Comm.h"
- #include "hv_comm_Assert.h"
- #include "hv_chip_Config.h"
- #include "hv_comm_Define.h"
- #include "hv_drv_Spi.h"
- struct _SpiSelf
- {
- SpiInitParam stInitParam; /* SPI communication parameters */
- UINT32 uiBaseOffset; /* SPI addr offset*/
- UCHAR8 *pucCmdAddr; /*!< Pointer to spi command and address buffer.*/
- USHORT16 usCmdAddrSize; /*!< Spi command and address size. */
- UCHAR8 *pucTxBuff; /* Pointer to SPI Tx transfer Buffer */
- USHORT16 usTxXferSize; /* SPI Tx transfer size */
- USHORT16 usTxXferCount; /* SPI Tx transfer counter */
- UCHAR8 *pucRxBuff; /* Pointer to SPI Rx transfer Buffer */
- USHORT16 usRxXferSize; /* SPI Rx transfer size */
- USHORT16 usRxXferCount; /* SPI Rx transfer counter */
- USHORT16 usDumSize; /*!< The Dummy size of receive. */
- SpiState enState; /* SPI communication state */
- SpiError enErrorCode; /* SPI Error code */
- SpiTransState enTransCompleteFlag; /* SPI Transmit Complete flag */
- DmaSelf *pstDmaTx; /* SPI Send Dma */
- DmaSelf *pstDmaRx; /* SPI Receive Dma */
- };
- static SpiSelf s_Spi = {0};
- static VOID Hv_Spi_ModeSelect(const SpiSelf* pstSelf)
- {
- if (pstSelf->stInitParam.enMode == SPI_MODE_MASTER)
- {
- HV_W32_FIELD_EX(CPU_SYS_SPI0_MODE_CTL0, pstSelf->uiBaseOffset, reg_ssi_master, 1);
- }
- else if (pstSelf->stInitParam.enMode == SPI_MODE_SLAVE)
- {
- HV_W32_FIELD_EX(CPU_SYS_SPI0_MODE_CTL0, pstSelf->uiBaseOffset, reg_ssi_master, 0);
- }
- }
- static UCHAR8 Hv_Spi_GetFlag(const SpiSelf *pstSelf, SpiFlag enFlag)
- {
- UINT32 val = 0;
- if (pstSelf->stInitParam.enMode == SPI_MODE_MASTER)
- {
- val = HV_R32(CPU_SYS_SPI0_M_SR + pstSelf->uiBaseOffset);
- }
- else if (pstSelf->stInitParam.enMode == SPI_MODE_SLAVE)
- {
- val = HV_R32(CPU_SYS_SPI0_S_SR + pstSelf->uiBaseOffset);
- }
- return (((val & enFlag) == enFlag) ? 1 : 0);
- }
- static Status Hv_Spi_WaitOnFlagUntilTimeout(SpiSelf *pstSelf, SpiFlag enflag, UINT32 uiStatus, UINT32 uiTimeout)
- {
- UINT64 ullTickstart = 0;
- ullTickstart = Hv_Vos_GetTick();
- if (uiStatus == HV_SET)
- {
- while (Hv_Spi_GetFlag(pstSelf, enflag) == 0)/* Wait the flag set*/
- {
- if ((uiTimeout == 0) || ((Hv_Vos_GetTick() - ullTickstart ) > uiTimeout))
- {
- pstSelf->enErrorCode = SPI_ERROR_TIMEOUT;
- pstSelf->enState = SPI_STATE_READY;
- return HV_TIMEOUT;
- }
- }
- }
- else
- {
- while (Hv_Spi_GetFlag(pstSelf, enflag) == 1)/* Wait the flag reset*/
- {
- if ((uiTimeout == 0) || ((Hv_Vos_GetTick() - ullTickstart ) > uiTimeout))
- {
- pstSelf->enErrorCode = SPI_ERROR_TIMEOUT;
- pstSelf->enState = SPI_STATE_READY;
- return HV_TIMEOUT;
- }
- }
- }
- return HV_SUCCESS;
- }
- static VOID Hv_Spi_Enable(const SpiSelf* pstSelf)
- {
- if (pstSelf->stInitParam.enMode == SPI_MODE_MASTER)
- {
- HV_W32_FIELD_EX(CPU_SYS_SPI0_M_SSIENR, pstSelf->uiBaseOffset, SSI_EN, 1);
- }
- else if (pstSelf->stInitParam.enMode == SPI_MODE_SLAVE)
- {
- HV_W32_FIELD_EX(CPU_SYS_SPI0_S_SSIENR, pstSelf->uiBaseOffset, SSI_EN, 1);
- }
- }
- static VOID Hv_Spi_Disable(const SpiSelf *pstSelf)
- {
- if (pstSelf->stInitParam.enMode == SPI_MODE_MASTER)
- {
- HV_W32_FIELD_EX(CPU_SYS_SPI0_M_SSIENR, pstSelf->uiBaseOffset, SSI_EN, 0); /* Enable spi0 master */
- }
- else if (pstSelf->stInitParam.enMode == SPI_MODE_SLAVE)
- {
- HV_W32_FIELD_EX(CPU_SYS_SPI0_S_SSIENR, pstSelf->uiBaseOffset, SSI_EN, 0); /* Enable spi0 slave */
- }
- return;
- }
- static VOID Hv_Spi_MaskInt(const SpiSelf *pstSelf)
- {
- if (pstSelf->stInitParam.enMode == SPI_MODE_MASTER)
- {
- HV_W32(CPU_SYS_SPI0_M_IMR + pstSelf->uiBaseOffset, 0x00);
- }
- else if (pstSelf->stInitParam.enMode == SPI_MODE_SLAVE)
- {
- HV_W32(CPU_SYS_SPI0_S_IMR + pstSelf->uiBaseOffset, 0x00);
- }
- return;
- }
- static VOID Hv_Spi_InterruptEnable(const SpiSelf *pstSelf, UINT32 uiIntType)
- {
- UINT32 uiVal = 0;
- if (pstSelf->stInitParam.enMode == SPI_MODE_MASTER)
- {
- uiVal = HV_R32(CPU_SYS_SPI0_M_IMR + pstSelf->uiBaseOffset);
- uiVal |= uiIntType;
- HV_W32(CPU_SYS_SPI0_M_IMR + pstSelf->uiBaseOffset, uiVal);
- } else if (pstSelf->stInitParam.enMode == SPI_MODE_SLAVE)
- {
- uiVal = HV_R32(CPU_SYS_SPI0_S_IMR + pstSelf->uiBaseOffset);
- uiVal |= uiIntType;
- HV_W32(CPU_SYS_SPI0_S_IMR + pstSelf->uiBaseOffset, uiVal);
- }
- else
- {
- //do nothing
- }
- }
- static VOID Hv_Spi_InterruptDisable(const SpiSelf *pstSelf, UINT32 uiIntType)
- {
- UINT32 uiVal = 0;
- if (pstSelf->stInitParam.enMode == SPI_MODE_MASTER)
- {
- uiVal = HV_R32(CPU_SYS_SPI0_M_IMR + pstSelf->uiBaseOffset);
- uiVal &= ~uiIntType;
- HV_W32(CPU_SYS_SPI0_M_IMR + pstSelf->uiBaseOffset, uiVal);
- }
- else if (pstSelf->stInitParam.enMode == SPI_MODE_SLAVE)
- {
- uiVal = HV_R32(CPU_SYS_SPI0_S_IMR + pstSelf->uiBaseOffset);
- uiVal &= ~uiIntType;
- HV_W32(CPU_SYS_SPI0_S_IMR + pstSelf->uiBaseOffset, uiVal);
- }
- else
- {
- //do nothing
- }
- }
- static UINT32 Hv_Spi_GetIntStateVal(const SpiSelf *pstSelf)
- {
- UINT32 uiVal = 0;
- if (pstSelf->stInitParam.enMode == SPI_MODE_MASTER)
- {
- uiVal = HV_R32(CPU_SYS_SPI0_M_ISR + pstSelf->uiBaseOffset);
- }
- else if (pstSelf->stInitParam.enMode == SPI_MODE_SLAVE)
- {
- uiVal = HV_R32(CPU_SYS_SPI0_S_ISR + pstSelf->uiBaseOffset);
- }
- return uiVal;
- }
- static UCHAR8 Hv_Spi_GetTxFifoLevel(const SpiSelf *pstSelf)
- {
- UCHAR8 uiVal = 0;
- HV_R32_DECL_VAR();
- if (pstSelf->stInitParam.enMode == SPI_MODE_MASTER)
- {
- uiVal = HV_R32_FIELD_EX(CPU_SYS_SPI0_M_TXFLR, pstSelf->uiBaseOffset, TXTFL) & 0x1f;
- }
- else if (pstSelf->stInitParam.enMode == SPI_MODE_SLAVE)
- {
- uiVal = HV_R32_FIELD_EX(CPU_SYS_SPI0_S_TXFLR, pstSelf->uiBaseOffset, TXTFL) & 0x1f;
- }
- return uiVal;
- }
- static UCHAR8 Hv_Spi_GetRxFifoLevel(const SpiSelf *pstSelf)
- {
- UCHAR8 uiVal = 0;
- HV_R32_DECL_VAR();
- if (pstSelf->stInitParam.enMode == SPI_MODE_MASTER)
- {
- uiVal = HV_R32_FIELD_EX(CPU_SYS_SPI0_M_RXFLR, pstSelf->uiBaseOffset, RXTFL) & 0x1f;
- }
- else if (pstSelf->stInitParam.enMode == SPI_MODE_SLAVE)
- {
- uiVal = HV_R32_FIELD_EX(CPU_SYS_SPI0_S_RXFLR, pstSelf->uiBaseOffset, RXTFL) & 0x1f;
- }
- return uiVal;
- }
- static VOID Hv_Spi_CsAlwaysLowSet(const SpiSelf *pstSelf)
- {
- UINT32 uiVal = 0;
- uiVal = HV_R32(CPU_SYS_SPI0_MODE_CTL0 + pstSelf->uiBaseOffset);
- cpu_sys_spi0_mode_ctl0(uiVal)->cs_oe_ctrl = 1;
- cpu_sys_spi0_mode_ctl0(uiVal)->reg_cs_oe = 1;
- cpu_sys_spi0_mode_ctl0(uiVal)->sck_oe_ctrl = 1;
- cpu_sys_spi0_mode_ctl0(uiVal)->reg_sck_oe = 1;
- cpu_sys_spi0_mode_ctl0(uiVal)->mosi_oe_ctrl = 1;
- cpu_sys_spi0_mode_ctl0(uiVal)->reg_mosi_oe = 1;
- HV_W32(CPU_SYS_SPI0_MODE_CTL0 + pstSelf->uiBaseOffset, uiVal);
- return;
- }
- static VOID Hv_Spi_CsAlwaysLowRelease(const SpiSelf *pstSelf)
- {
- UINT32 uiVal = 0;
- uiVal = HV_R32(CPU_SYS_SPI0_MODE_CTL0 + pstSelf->uiBaseOffset);
- cpu_sys_spi0_mode_ctl0(uiVal)->cs_oe_ctrl = 0;
- cpu_sys_spi0_mode_ctl0(uiVal)->reg_cs_oe = 0;
- cpu_sys_spi0_mode_ctl0(uiVal)->sck_oe_ctrl = 0;
- cpu_sys_spi0_mode_ctl0(uiVal)->reg_sck_oe = 0;
- cpu_sys_spi0_mode_ctl0(uiVal)->mosi_oe_ctrl = 0;
- cpu_sys_spi0_mode_ctl0(uiVal)->reg_mosi_oe = 0;
- HV_W32(CPU_SYS_SPI0_MODE_CTL0 + pstSelf->uiBaseOffset, uiVal);
- return;
- }
- static UCHAR8* Hv_Spi_TransmitOne(const SpiSelf *pstSelf, UINT32 uiCmdDataRegAddr, UCHAR8* pucData)
- {
- UCHAR8 ucToDR0Val = 0;
- UINT32 uiToDR0Val = 0;
- if (pstSelf->stInitParam.enDataSize == SPI_BITWIDTH_8)
- {
- ucToDR0Val = *pucData++;
- uiToDR0Val = (UINT32)ucToDR0Val;
- }
- else if (pstSelf->stInitParam.enDataSize == SPI_BITWIDTH_32)
- {
- uiToDR0Val = CHANGE_TO_U32_BE(pucData);
- pucData = pucData + 4;
- }
- else if (pstSelf->stInitParam.enDataSize == SPI_BITWIDTH_16)
- {
- uiToDR0Val = CHANGE_TO_U16_BE(pucData);
- pucData = pucData + 2;
- }
- HV_W32(uiCmdDataRegAddr, uiToDR0Val);
- return pucData;
- }
- static UCHAR8* Hv_Spi_ReceiveOne(const SpiSelf *pstSelf, UINT32 uiCmdDataRegAddr, UCHAR8* pucData)
- {
- UINT32 uiFromDR0Val = HV_R32(uiCmdDataRegAddr);
- if (pstSelf->stInitParam.enDataSize == SPI_BITWIDTH_8)
- {
- *pucData++ = (UCHAR8)((uiFromDR0Val ) & 0xff);
- }
- else if (pstSelf->stInitParam.enDataSize == SPI_BITWIDTH_32)
- {
- *((UINT32*)(pucData)) = HV_SWAP32(uiFromDR0Val);//CHANGE_ENDIAN_U32(uiFromDR0Val);
- pucData = pucData + 4;
- }
- else if (pstSelf->stInitParam.enDataSize == SPI_BITWIDTH_16)
- {
- *((USHORT16*)(pucData)) = CHANGE_ENDIAN_U16((uiFromDR0Val) & 0xffff);
- pucData = pucData + 2;
- }
- return pucData;
- }
- static Status Hv_Spi_IntTransmitCpltCallback(SpiSelf *pstSelf)
- {
- if (Hv_Spi_WaitOnFlagUntilTimeout(pstSelf, SPI_FLAG_TFE, HV_SET, HV_SPI_TIMEOUT) != HV_SUCCESS)
- {
- return HV_TIMEOUT;
- }
- if (pstSelf->stInitParam.enCsCtlMode != SPI_CSMODE_ALWAYS_LOW)
- {
- if (Hv_Spi_WaitOnFlagUntilTimeout(pstSelf, SPI_FLAG_BUSY, HV_RESET, HV_SPI_TIMEOUT) != HV_SUCCESS)
- {
- return HV_TIMEOUT;
- }
- }
- pstSelf->enState = SPI_STATE_READY;
- pstSelf->enTransCompleteFlag = SPI_TRANS_END;
- if (pstSelf->stInitParam.pfSpiCpltCallback != NULL)
- {
- pstSelf->stInitParam.pfSpiCpltCallback(SPI_TRANSMIT, (VOID*)pstSelf);
- }
- return HV_SUCCESS;
- }
- static Status Hv_Spi_IntReceiveCpltCallback(SpiSelf *pstSelf)
- {
- if ((pstSelf->stInitParam.enMode == SPI_MODE_MASTER)
- && (pstSelf->stInitParam.enCsCtlMode != SPI_CSMODE_ALWAYS_LOW))
- {
- if (Hv_Spi_WaitOnFlagUntilTimeout(pstSelf, SPI_FLAG_BUSY, HV_RESET, HV_SPI_TIMEOUT) != HV_SUCCESS)
- {
- return HV_TIMEOUT;
- }
- }
- pstSelf->enState = SPI_STATE_READY;
- pstSelf->enTransCompleteFlag = SPI_TRANS_END;
- if (pstSelf->stInitParam.pfSpiCpltCallback != NULL)
- {
- pstSelf->stInitParam.pfSpiCpltCallback(SPI_RECEIVE, (VOID*)pstSelf);
- }
- return HV_SUCCESS;
- }
- static Status Hv_Spi_IntTransmitHandler(SpiSelf *pstSelf)
- {
- UINT32 i = 0;
- UINT32 uiTxFifoSurplusLev = 0;
- UINT32 uiTxDataNumOnce = 0;
- UINT32 uiTxDataTotalNum = pstSelf->usCmdAddrSize + pstSelf->usTxXferSize;
- UCHAR8 *pucTxData = NULL;
- UINT32 uiCmdDataRegAddr = 0;
- if (pstSelf->stInitParam.enMode == SPI_MODE_MASTER)
- {
- uiCmdDataRegAddr = CPU_SYS_SPI0_M_DR0 + pstSelf->uiBaseOffset;
- }
- else if (pstSelf->stInitParam.enMode == SPI_MODE_SLAVE)
- {
- uiCmdDataRegAddr = CPU_SYS_SPI0_S_DR0 + pstSelf->uiBaseOffset;
- }
- if (pstSelf->enState == SPI_STATE_BUSY_TX)
- {
- if (pstSelf->usTxXferSize != 0)
- {
- if (pstSelf->stInitParam.enDataSize == SPI_BITWIDTH_8)
- {
- pucTxData = &pstSelf->pucTxBuff[pstSelf->usTxXferCount];
- }
- else if (pstSelf->stInitParam.enDataSize == SPI_BITWIDTH_16)
- {
- pucTxData = &pstSelf->pucTxBuff[2 * pstSelf->usTxXferCount];
- }
- else if (pstSelf->stInitParam.enDataSize == SPI_BITWIDTH_32)
- {
- pucTxData = &pstSelf->pucTxBuff[4 * pstSelf->usTxXferCount];
- }
- else
- {
- //do nothing
- }
- }
- }
- uiTxFifoSurplusLev = HV_SPI_FIFO_DEPTH - Hv_Spi_GetTxFifoLevel(pstSelf);
- uiTxDataNumOnce = (uiTxDataTotalNum > uiTxFifoSurplusLev) ? uiTxFifoSurplusLev : uiTxDataTotalNum;
- for (i = 0; i < uiTxDataNumOnce; i++)
- {
- if (pstSelf->usCmdAddrSize == 0)
- {
- if (pstSelf->enState == SPI_STATE_BUSY_TX)
- {
- pucTxData = Hv_Spi_TransmitOne(pstSelf, uiCmdDataRegAddr, pucTxData);
- pstSelf->usTxXferCount++;
- }
- else if (pstSelf->enState == SPI_STATE_BUSY_RX)
- {
- UCHAR8 ucDummy[4] = {0};
- Hv_Spi_TransmitOne(pstSelf, uiCmdDataRegAddr, ucDummy);
- }
- pstSelf->usTxXferSize--;
- uiCmdDataRegAddr = uiCmdDataRegAddr + 4;
- }
- else
- {
- pstSelf->pucCmdAddr = Hv_Spi_TransmitOne(pstSelf, uiCmdDataRegAddr, pstSelf->pucCmdAddr);
- pstSelf->usCmdAddrSize--;
- uiCmdDataRegAddr = uiCmdDataRegAddr + 4;
- }
- }
- if ((pstSelf->usCmdAddrSize + pstSelf->usTxXferSize) == 0)
- {
- UINT32 uiIntFlag = 0;
- uiIntFlag = SPI_INTERRUPT_TXEIR | SPI_INTERRUPT_TXOIR;
- Hv_Spi_InterruptDisable(pstSelf, uiIntFlag);
- if (pstSelf->enState == SPI_STATE_BUSY_TX)
- {
- Hv_Spi_IntTransmitCpltCallback(pstSelf);
- }
- }
- return HV_SUCCESS;
- }
- static Status Hv_Spi_IntReceiveHandler(SpiSelf *pstSelf)
- {
- UINT32 i = 0;
- UINT32 uiRxFifoDataLev = 0;
- UCHAR8 *pucRxData = NULL;
- UCHAR8 ucDumSize[4] = {0};
- UINT32 uiCmdDataRegAddrBase = 0;
- if (pstSelf->stInitParam.enMode == SPI_MODE_MASTER)
- {
- uiCmdDataRegAddrBase = CPU_SYS_SPI0_M_DR0 + pstSelf->uiBaseOffset;
- }
- else if (pstSelf->stInitParam.enMode == SPI_MODE_SLAVE)
- {
- uiCmdDataRegAddrBase = CPU_SYS_SPI0_S_DR0 + pstSelf->uiBaseOffset;
- }
- if (pstSelf->stInitParam.enDataSize == SPI_BITWIDTH_8)
- {
- pucRxData = &pstSelf->pucRxBuff[pstSelf->usRxXferCount];
- }
- else if (pstSelf->stInitParam.enDataSize == SPI_BITWIDTH_16)
- {
- pucRxData = &pstSelf->pucRxBuff[2 * pstSelf->usRxXferCount];
- }
- else if (pstSelf->stInitParam.enDataSize == SPI_BITWIDTH_32)
- {
- pucRxData = &pstSelf->pucRxBuff[4 * pstSelf->usRxXferCount];
- }
- uiRxFifoDataLev = Hv_Spi_GetRxFifoLevel(pstSelf);
- for (i = 0; i < uiRxFifoDataLev; i++)
- {
- if (pstSelf->usDumSize != 0)
- {
- Hv_Spi_ReceiveOne(pstSelf,uiCmdDataRegAddrBase, ucDumSize);
- pstSelf->usDumSize--;
- }
- else
- {
- pucRxData = Hv_Spi_ReceiveOne(pstSelf, uiCmdDataRegAddrBase, pucRxData);
- pstSelf->usRxXferCount++;
- }
- pstSelf->usRxXferSize--;
- }
- if (pstSelf->usRxXferSize == 0)
- {
- UINT32 uiIntFlag = 0;
- uiIntFlag = SPI_INTERRUPT_RXFIR|SPI_INTERRUPT_RXUIR|SPI_INTERRUPT_RXOIR;
- Hv_Spi_InterruptDisable(pstSelf, uiIntFlag);
- Hv_Spi_IntReceiveCpltCallback(pstSelf);
- }
- return HV_SUCCESS;
- }
- HV_VOS_ISR_RESULT_E Hv_Spi_IrqHandler(UINT32 uiIrqNum, VOID *pArg)
- {
- UINT32 uiIntStaVal = 0;
- SpiSelf *pstSelf;
- HV_UNUSED(uiIrqNum);
- pstSelf = (SpiSelf *)pArg;
- uiIntStaVal = Hv_Spi_GetIntStateVal(pstSelf);
- if (uiIntStaVal & SPI_INTERRUPT_TXEIR)
- {
- // HV_LOGI("Now enter tx int.\n");
- Hv_Spi_IntTransmitHandler(pstSelf);
- }
- if (uiIntStaVal & SPI_INTERRUPT_RXFIR)
- {
- //HV_LOGI("Now enter rx int.\n");
- Hv_Spi_IntReceiveHandler(pstSelf);
- }
- if (uiIntStaVal & SPI_INTERRUPT_TXOIR)
- {
- }
- if (uiIntStaVal & SPI_INTERRUPT_RXUIR)
- {
- }
- if (uiIntStaVal & SPI_INTERRUPT_RXOIR)
- {
- }
- if (uiIntStaVal & SPI_INTERRUPT_MSTIR)
- {
- }
- return HV_VOS_ISR_HANDLED;
- }
- static VOID Hv_Spi_ConfigDmaTxReg(SpiSelf *pstSelf, UINT32 uiEnFlag, UINT32 uiSpiTxDmaThres)
- {
- Hv_Spi_Disable(pstSelf);
- if (pstSelf->stInitParam.enMode == SPI_MODE_MASTER)
- {
- HV_W32_FIELD_EX(CPU_SYS_SPI0_M_DMACR, pstSelf->uiBaseOffset, TDMAE, uiEnFlag);
- HV_W32_FIELD_EX(CPU_SYS_SPI0_M_DMATDLR, pstSelf->uiBaseOffset, DMATDL, uiSpiTxDmaThres);
- }
- else if (pstSelf->stInitParam.enMode == SPI_MODE_SLAVE)
- {
- HV_W32_FIELD_EX(CPU_SYS_SPI0_S_DMACR, pstSelf->uiBaseOffset, TDMAE, uiEnFlag);
- HV_W32_FIELD_EX(CPU_SYS_SPI0_S_DMATDLR, pstSelf->uiBaseOffset, DMATDL, uiSpiTxDmaThres);
- }
- }
- static VOID Hv_Spi_ConfigDmaRxReg(SpiSelf *pstSelf, UINT32 uiEnFlag, UINT32 uiSpiRxDmaThres)
- {
- Hv_Spi_Disable(pstSelf);
- if (pstSelf->stInitParam.enMode == SPI_MODE_MASTER)
- {
- HV_W32_FIELD_EX(CPU_SYS_SPI0_M_DMACR, pstSelf->uiBaseOffset, RDMAE, uiEnFlag);
- HV_W32_FIELD_EX(CPU_SYS_SPI0_M_DMARDLR, pstSelf->uiBaseOffset, DMARDL, uiSpiRxDmaThres);
- }
- else if (pstSelf->stInitParam.enMode == SPI_MODE_SLAVE)
- {
- HV_W32_FIELD_EX(CPU_SYS_SPI0_S_DMACR, pstSelf->uiBaseOffset, RDMAE, uiEnFlag);
- HV_W32_FIELD_EX(CPU_SYS_SPI0_S_DMARDLR, pstSelf->uiBaseOffset, DMARDL, uiSpiRxDmaThres);
- }
- }
- static Status Hv_Spi_DmaTransmitCpltCallback(DmaSelf* pstArg)
- {
- SpiSelf* pstSelf = (SpiSelf *)Hv_Cal_Dma_GetParent(pstArg);
- Hv_Cal_Dma_XferCallbackUnBond(pstSelf->pstDmaTx);
- if (pstSelf->enState == SPI_STATE_BUSY_TX)
- {
- if (Hv_Spi_WaitOnFlagUntilTimeout(pstSelf, SPI_FLAG_TFE, HV_SET, HV_SPI_TIMEOUT) != HV_SUCCESS)
- {
- return HV_TIMEOUT;
- }
- if (pstSelf->stInitParam.enCsCtlMode != SPI_CSMODE_ALWAYS_LOW)
- {
- if (Hv_Spi_WaitOnFlagUntilTimeout(pstSelf, SPI_FLAG_BUSY, HV_RESET, HV_SPI_TIMEOUT) != HV_SUCCESS)
- {
- return HV_TIMEOUT;
- }
- }
- Hv_Spi_Disable(pstSelf);
- Hv_Spi_ConfigDmaTxReg(pstSelf, SPI_DMATX_DISABLE, HV_SPI_DMA_TX_THRESHOLD);
- Hv_Vos_InvalidAllDCache();
- pstSelf->enState = SPI_STATE_READY;
- pstSelf->enTransCompleteFlag = SPI_TRANS_END;
- if (pstSelf->stInitParam.pfSpiCpltCallback != NULL)
- {
- pstSelf->stInitParam.pfSpiCpltCallback(SPI_TRANSMIT, (VOID*)pstSelf);
- }
- }
- return HV_SUCCESS;
- }
- static Status Hv_Spi_DmaReceiveCpltCallback(DmaSelf* pArg)
- {
- SpiSelf* pstSelf = (SpiSelf *)Hv_Cal_Dma_GetParent(pArg);
- if ((pstSelf->stInitParam.enMode == SPI_MODE_MASTER)
- && (pstSelf->stInitParam.enCsCtlMode != SPI_CSMODE_ALWAYS_LOW))
- {
- if (Hv_Spi_WaitOnFlagUntilTimeout(pstSelf, SPI_FLAG_BUSY, HV_RESET, 1000) != HV_SUCCESS)
- {
- return HV_TIMEOUT;
- }
- }
- Hv_Spi_Disable(pstSelf);
- if (pstSelf->stInitParam.enMode == SPI_MODE_MASTER)
- {
- Hv_Spi_ConfigDmaTxReg(pstSelf, SPI_DMATX_DISABLE, HV_SPI_DMA_TX_THRESHOLD);
- }
- Hv_Spi_ConfigDmaRxReg(pstSelf, SPI_DMARX_DISABLE, HV_SPI_DMA_RX_THRESHOLD);
- Hv_Cal_Dma_XferCallbackUnBond(pstSelf->pstDmaRx);
- Hv_Vos_InvalidAllDCache();
- pstSelf->enState = SPI_STATE_READY;
- pstSelf->enTransCompleteFlag = SPI_TRANS_END;
- if (pstSelf->stInitParam.pfSpiCpltCallback != NULL)
- {
- pstSelf->stInitParam.pfSpiCpltCallback(SPI_RECEIVE, (VOID*)pstSelf);
- }
- return HV_SUCCESS;
- }
- /**@brief Get spi state
- * @param self pointer to spi structure
- * @retval spi state
- */
- UCHAR8 Hv_Drv_Spi_GetState(const SpiSelf* pstSelf)
- {
- return pstSelf->enState;
- }
- /**@brief Set spi transmit DMA
- * @param self pointer to spi structure.
- * @param transmit DMA structure
- * @retval none
- */
- VOID Hv_Drv_Spi_SetDmaTx(SpiSelf *pstSelf, DmaSelf *pstDmaTx)
- {
- pstSelf->pstDmaTx = pstDmaTx;
- Hv_Cal_Dma_SetParent(pstDmaTx, (VOID*)pstSelf);
- if (pstSelf->stInitParam.enMode == SPI_MODE_MASTER)
- {
- Hv_Cal_Dma_SetDstAddr(pstDmaTx, CPU_SYS_SPI0_M_DR0 + pstSelf->uiBaseOffset);
- }
- else
- {
- Hv_Cal_Dma_SetDstAddr(pstDmaTx, CPU_SYS_SPI0_S_DR0 + pstSelf->uiBaseOffset);
- }
- if (pstSelf->stInitParam.enDataSize == SPI_BITWIDTH_8)
- {
- Hv_Cal_Dma_SetSrcFrameSize(pstDmaTx, DMA_DATA_SIZE_32Bits);
- Hv_Cal_Dma_SetDstFrameSize(pstDmaTx, DMA_DATA_SIZE_8Bits);
- }
- return;
- }
- /**@brief Set spi receive DMA
- * @param self pointer to spi structure.
- * @param receive DMA structure
- * @retval none
- */
- VOID Hv_Drv_Spi_SetDmaRx(SpiSelf *pstSelf, DmaSelf *pstDmaRx)
- {
- pstSelf->pstDmaRx = pstDmaRx;
- Hv_Cal_Dma_SetParent(pstDmaRx,(VOID*)pstSelf);
- if (pstSelf->stInitParam.enMode == SPI_MODE_MASTER)
- {
- Hv_Cal_Dma_SetSrcAddr(pstDmaRx, CPU_SYS_SPI0_M_DR0 + pstSelf->uiBaseOffset);
- }
- else
- {
- Hv_Cal_Dma_SetSrcAddr(pstDmaRx, CPU_SYS_SPI0_S_DR0 + pstSelf->uiBaseOffset);
- }
- if (pstSelf->stInitParam.enDataSize == SPI_BITWIDTH_8)
- {
- Hv_Cal_Dma_SetSrcFrameSize(pstDmaRx, DMA_DATA_SIZE_8Bits);
- Hv_Cal_Dma_SetDstFrameSize(pstDmaRx, DMA_DATA_SIZE_32Bits);
- }
- return;
- }
- /**@brief Bond the complete callback
- * @param self pointer to spi structure.
- * @param CallbackFunc callback defined by user
- * @retval none
- */
- VOID Hv_Drv_Spi_SetCpltCallBack(SpiSelf *pstSelf, SpiCpltCallback pfCallbackFunc)
- {
- pstSelf->stInitParam.pfSpiCpltCallback = pfCallbackFunc;
- }
- /**@brief Set the spi direction
- * @param self pointer to spi structure.
- * @param enDirection
- * @retval none
- */
- VOID Hv_Drv_Spi_SetDirection(SpiSelf *pstSelf, SpiDirection enDirection)
- {
- Hv_Spi_Disable(pstSelf);
- if (pstSelf->stInitParam.enMode == SPI_MODE_MASTER)
- {
- HV_W32_FIELD_EX(CPU_SYS_SPI0_M_CTRLR0, pstSelf->uiBaseOffset, TMOD, enDirection);
- }
- else if (pstSelf->stInitParam.enMode == SPI_MODE_SLAVE)
- {
- HV_W32_FIELD_EX(CPU_SYS_SPI0_S_CTRLR0, pstSelf->uiBaseOffset, TMOD, enDirection);
- }
- pstSelf->stInitParam.enDirection = enDirection;
- return;
- }
- /**@brief Set spi data frame size
- * @param self pointer to spi structure.
- * @param enFrameWidth Indicates how many bits of data are serially transmitted in a frame.
- * @retval none
- */
- VOID Hv_Drv_Spi_SetBitsWidth(SpiSelf *pstSelf, SpiBandWidth enFrameWidth)
- {
- Hv_Spi_Disable(pstSelf);
- if (pstSelf->stInitParam.enMode == SPI_MODE_MASTER)
- {
- HV_W32_FIELD_EX(CPU_SYS_SPI0_M_CTRLR0, pstSelf->uiBaseOffset, DFS_32, (UINT32)enFrameWidth);
- }
- else if (pstSelf->stInitParam.enMode == SPI_MODE_SLAVE)
- {
- HV_W32_FIELD_EX(CPU_SYS_SPI0_S_CTRLR0, pstSelf->uiBaseOffset, DFS_32, (UINT32)enFrameWidth);
- }
- pstSelf->stInitParam.enDataSize = enFrameWidth;
- return;
- }
- /**@brief Set spi the baudrate
- * @param self pointer to spi structure.
- * @param BaudRate baudrate which will set as SCKDV.
- * @retval none
- */
- VOID Hv_Drv_Spi_SetBaudRate(SpiSelf *pstSelf, SPiDivRatio enDivRatio)
- {
- Hv_Spi_Disable(pstSelf);
- HV_W32_FIELD_EX(CPU_SYS_SPI0_M_BAUDR, pstSelf->uiBaseOffset, SCKDV, (UINT32)enDivRatio);
- pstSelf->stInitParam.enBaudRatePrescaler = enDivRatio;
- return;
- }
- /**@brief Initializes the SPI according to the specified parameters and create the associated handle.
- * @param initParam pointer to the configuration information for SPI module.
- * @return spi handler
- */
- SpiSelf* Hv_Drv_Spi_Init(SpiInitParam *pstInitParam)
- {
- SpiSelf *pstSelf = NULL;
- HV_ASSERT_VALID_PTR_RET(pstInitParam, NULL);
- HV_ASSERT_TRUE_RET((pstInitParam->enCsCtlMode < SPI_CSMODE_MAX), NULL);
- pstSelf = &s_Spi;
- HV_MEMCPY(&pstSelf->stInitParam, pstInitParam, sizeof(*pstInitParam));
- pstSelf->uiBaseOffset = 0;
- Hv_Spi_ModeSelect(pstSelf);
- Hv_Spi_Disable(pstSelf);
- Hv_Spi_MaskInt(pstSelf);
- if (pstInitParam->enMode == SPI_MODE_MASTER)
- {
- rs_cpu_sys_spi0_m_ctrlr0 regCtrl0Val = {0}; /* Config spi0 master ctrl0 reg*/
- regCtrl0Val.FRF = 0;
- regCtrl0Val.SCPH = pstInitParam->enClkPhase;
- regCtrl0Val.SCPOL = pstInitParam->enClkPolarity;
- regCtrl0Val.TMOD = pstInitParam->enDirection;
- regCtrl0Val.SRL = 0;
- regCtrl0Val.DFS_32 = pstInitParam->enDataSize;
- regCtrl0Val.SPI_FRF = 0;
- regCtrl0Val.SSTE = 0;/* No toggle*/
- HV_W32_REG(CPU_SYS_SPI0_M_CTRLR0 + pstSelf->uiBaseOffset, regCtrl0Val);
- HV_W32(CPU_SYS_SPI0_M_BAUDR + pstSelf->uiBaseOffset, pstInitParam->enBaudRatePrescaler);
- HV_W32_FIELD_EX(CPU_SYS_SPI0_M_TXFTLR, pstSelf->uiBaseOffset, TFT, 8);
- HV_W32_FIELD_EX(CPU_SYS_SPI0_M_RXFTLR, pstSelf->uiBaseOffset, RFT, 0);
- HV_W32(CPU_SYS_SPI0_M_CTRLR1 + pstSelf->uiBaseOffset, 0x03);
- HV_W32_FIELD_EX(CPU_SYS_SPI0_M_SER, pstSelf->uiBaseOffset, SER, 1);
- }
- else if (pstInitParam->enMode == SPI_MODE_SLAVE)
- {
- rs_cpu_sys_spi0_s_ctrlr0 regCtrl0Val = {0};/* Config spi0 slave ctrl0 reg*/
- regCtrl0Val.FRF = 0;
- regCtrl0Val.SCPH = pstInitParam->enClkPhase; /* if need to config */
- regCtrl0Val.SCPOL = pstInitParam->enClkPolarity;
- regCtrl0Val.TMOD = pstInitParam->enDirection;
- regCtrl0Val.SLV_OE = 0;
- regCtrl0Val.SRL = 0;
- regCtrl0Val.DFS_32 = pstInitParam->enDataSize;
- regCtrl0Val.SPI_FRF = 0;
- regCtrl0Val.SSTE = 0;
- HV_W32_REG(CPU_SYS_SPI0_S_CTRLR0 + pstSelf->uiBaseOffset, regCtrl0Val);
- HV_W32_FIELD_EX(CPU_SYS_SPI0_S_TXFTLR, pstSelf->uiBaseOffset, TFT, 8);
- HV_W32_FIELD_EX(CPU_SYS_SPI0_S_RXFTLR, pstSelf->uiBaseOffset, RFT, 0);
- }
- HV_W32_FIELD_EX(CPU_SYS_SPI0_M_RX_SAMPLE_DLY, pstSelf->uiBaseOffset, RSD, 1);
- Hv_Vos_ConfigIrq(HV_CHIP_IRQ_SPI0, HV_TRUE, 0);
- Hv_Vos_AttachIsr(HV_CHIP_IRQ_SPI0, Hv_Spi_IrqHandler, pstSelf);
- Hv_Vos_UnmaskIrq(HV_CHIP_IRQ_SPI0);
- if (pstSelf->stInitParam.enCsCtlMode == SPI_CSMODE_ALWAYS_LOW)
- {
- Hv_Spi_CsAlwaysLowSet(pstSelf);
- }
- pstSelf->enState = SPI_STATE_READY;
- pstSelf->enErrorCode = SPI_ERROR_NONE;
- return pstSelf;
- }
- /**@brief De-initializes the SPI.
- * @param self pointer to spi structure.
- * @retval result
- */
- Status Hv_Drv_Spi_Cleanup(SpiSelf *pstSelf)
- {
- Hv_Vos_MaskIrq(HV_CHIP_IRQ_SPI0);
- Hv_Vos_DetachIsr(HV_CHIP_IRQ_SPI0, Hv_Spi_IrqHandler);
- if (pstSelf->stInitParam.enCsCtlMode == SPI_CSMODE_ALWAYS_LOW)
- {
- Hv_Spi_CsAlwaysLowRelease(pstSelf);
- }
- Hv_Spi_Disable(pstSelf);
- pstSelf->enErrorCode = SPI_ERROR_NONE;
- pstSelf->enState = SPI_STATE_RESET;
- return HV_SUCCESS;
- }
- /**@brief Transmit an amount of data in blocking mode
- * @param self pointer to spi structure
- * @param pucCmdAddr pointer to command buffer
- * @param pucTxData pointer to data buffer
- * @param usDataSize amount of data to be sent
- * @param uiTimeout Timeout duration
- * @retval result
- */
- Status Hv_Drv_Spi_PollingTransmit(SpiSelf *pstSelf, UCHAR8 *pucCmdAddr, USHORT16 usCmdAddrSize,
- UCHAR8 *pucTxData, USHORT16 usDataSize, UINT32 uiTimeout)
- {
- UINT32 i = 0;
- UINT32 uiTxFifoSurplusLev = 0;
- UINT32 uiTxDataNumOnce = 0;
- USHORT16 usCmdAddrSizeTemp = 0;
- USHORT16 usDataSizeTemp = 0;
- USHORT16 usTxTotalSize = 0;
- UINT32 uiCmdDataRegAddrBase = 0;
- UINT32 uiCmdDataRegAddr = 0;
- HV_UNUSED(uiTimeout);
- if (pstSelf->enState == SPI_STATE_READY)
- {
- if (((pucCmdAddr == NULL ) && (pucTxData == NULL))
- || ((usCmdAddrSize == 0) && (usDataSize == 0)))
- {
- return HV_FAILURE;
- }
- if ((pstSelf->stInitParam.enDirection != SPI_DIRECTION_TXRX)
- && (pstSelf->stInitParam.enDirection != SPI_DIRECTION_TX))
- {
- return HV_FAILURE;
- }
- if (pstSelf->stInitParam.enDataSize == SPI_BITWIDTH_8)
- {
- usCmdAddrSizeTemp = usCmdAddrSize;
- usDataSizeTemp = usDataSize;
- }
- else if (pstSelf->stInitParam.enDataSize == SPI_BITWIDTH_16)
- {
- usCmdAddrSizeTemp = usCmdAddrSize / 2;
- usDataSizeTemp = usDataSize / 2;
- }
- else if (pstSelf->stInitParam.enDataSize == SPI_BITWIDTH_32)
- {
- usCmdAddrSizeTemp = usCmdAddrSize / 4;
- usDataSizeTemp = usDataSize / 4;
- }
- if (pstSelf->stInitParam.enMode == SPI_MODE_SLAVE)
- {
- HV_ASSERT(pucCmdAddr == NULL);
- HV_ASSERT(usCmdAddrSizeTemp == 0);
- }
- usTxTotalSize = usCmdAddrSizeTemp + usDataSizeTemp;
- pstSelf->enState = SPI_STATE_BUSY_TX;
- pstSelf->enErrorCode = SPI_ERROR_NONE;
- Hv_Spi_Enable(pstSelf);
- if (pstSelf->stInitParam.enMode == SPI_MODE_MASTER)
- {
- uiCmdDataRegAddrBase = CPU_SYS_SPI0_M_DR0 + pstSelf->uiBaseOffset;
- uiCmdDataRegAddr = uiCmdDataRegAddrBase;
- }
- else if (pstSelf->stInitParam.enMode == SPI_MODE_SLAVE)/*Preventing from TXE Erro*/
- {
- uiCmdDataRegAddrBase = CPU_SYS_SPI0_S_DR0 + pstSelf->uiBaseOffset;
- uiCmdDataRegAddr = uiCmdDataRegAddrBase;
- pucTxData = Hv_Spi_TransmitOne(pstSelf, uiCmdDataRegAddr, pucTxData);
- uiCmdDataRegAddr = uiCmdDataRegAddr + 4;
- pstSelf->usTxXferSize--;
- }
- while (usTxTotalSize > 0)
- {
- uiTxFifoSurplusLev = HV_SPI_FIFO_DEPTH - Hv_Spi_GetTxFifoLevel(pstSelf);
- uiTxDataNumOnce = (usTxTotalSize > uiTxFifoSurplusLev) ? uiTxFifoSurplusLev : usTxTotalSize;
- for (i = 0; i < uiTxDataNumOnce; i++)
- {
- if (usCmdAddrSizeTemp == 0)
- {
- pucTxData = Hv_Spi_TransmitOne(pstSelf, uiCmdDataRegAddr, pucTxData);
- }
- else
- {
- pucCmdAddr = Hv_Spi_TransmitOne(pstSelf, uiCmdDataRegAddr, pucCmdAddr);
- usCmdAddrSizeTemp--;
- }
- uiCmdDataRegAddr = uiCmdDataRegAddr + 4;
- if ((uiCmdDataRegAddr - uiCmdDataRegAddrBase) == HV_SPI_DR_ADDR_RANGE_TOTAL)
- {
- uiCmdDataRegAddr = uiCmdDataRegAddrBase;
- }
- usTxTotalSize--;
- }
- }
- if (Hv_Spi_WaitOnFlagUntilTimeout(pstSelf, SPI_FLAG_TFE, HV_SET, HV_SPI_TIMEOUT) != HV_SUCCESS)
- {
- return HV_TIMEOUT;
- }
- if (pstSelf->stInitParam.enCsCtlMode != SPI_CSMODE_ALWAYS_LOW)
- {
- if (Hv_Spi_WaitOnFlagUntilTimeout(pstSelf, SPI_FLAG_BUSY, HV_RESET, HV_SPI_TIMEOUT) != HV_SUCCESS)
- {
- return HV_TIMEOUT;
- }
- }
- pstSelf->enState = SPI_STATE_READY;
- Hv_Spi_Disable(pstSelf);
- return HV_SUCCESS;
- }
- else
- {
- return HV_BUSY;
- }
- }
- /**@brief Transmit an amount of data in no-blocking mode with interrupt
- * @param self pointer to spi structure
- * @param pucCmdAddr pointer to command buffer
- * @param pucTxData pointer to data buffer
- * @param usDataSize amount of data to be sent
- * @retval result
- */
- Status Hv_Drv_Spi_IntTransmit(SpiSelf *pstSelf, UCHAR8 *pucCmdAddr, USHORT16 usCmdAddrSize, UCHAR8 *pucTxData, USHORT16 usDataSize)
- {
- UINT32 uiIntFlag = 0;
- USHORT16 usCmdAddrSizeTemp = 0;
- USHORT16 usDataSizeTemp = 0;
- if (pstSelf->enState == SPI_STATE_READY)
- {
- if (((pucCmdAddr == NULL ) && (pucTxData == NULL))
- || ((usCmdAddrSize == 0) && (usDataSize == 0)))
- {
- return HV_FAILURE;
- }
- if ((pstSelf->stInitParam.enDirection != SPI_DIRECTION_TXRX)
- && (pstSelf->stInitParam.enDirection != SPI_DIRECTION_TX))
- {
- return HV_FAILURE;
- }
- if (pstSelf->stInitParam.enDataSize == SPI_BITWIDTH_8)
- {
- usCmdAddrSizeTemp = usCmdAddrSize;
- usDataSizeTemp = usDataSize;
- }
- else if (pstSelf->stInitParam.enDataSize == SPI_BITWIDTH_16)
- {
- usCmdAddrSizeTemp = usCmdAddrSize / 2;
- usDataSizeTemp = usDataSize / 2;
- }else if (pstSelf->stInitParam.enDataSize == SPI_BITWIDTH_32)
- {
- usCmdAddrSizeTemp = usCmdAddrSize / 4;
- usDataSizeTemp = usDataSize / 4;
- }
- if (pstSelf->stInitParam.enMode == SPI_MODE_MASTER)
- {
- pstSelf->pucCmdAddr = pucCmdAddr;
- pstSelf->usCmdAddrSize = usCmdAddrSizeTemp;
- }
- else if (pstSelf->stInitParam.enMode == SPI_MODE_SLAVE)
- {
- HV_ASSERT(pucCmdAddr == NULL);
- HV_ASSERT(usCmdAddrSizeTemp == 0);
- }
- pstSelf->pucTxBuff = pucTxData;
- pstSelf->usTxXferSize = usDataSizeTemp;
- pstSelf->usTxXferCount = 0;
- pstSelf->enState = SPI_STATE_BUSY_TX;
- pstSelf->enErrorCode = SPI_ERROR_NONE;
- pstSelf->enTransCompleteFlag = SPI_TRANS_IN_PROCESS;
- uiIntFlag = SPI_INTERRUPT_TXEIR | SPI_INTERRUPT_TXOIR;
- Hv_Spi_InterruptEnable(pstSelf, uiIntFlag);
- Hv_Spi_Enable(pstSelf);
- return HV_SUCCESS;
- }
- else
- {
- return HV_BUSY;
- }
- }
- /**@brief Transmit an amount of data in no-blocking mode with DMA
- * @param self pointer to spi structure
- * @param pucData pointer to data buffer
- * @param usDataSize amount of data to be sent
- * @retval result
- */
- Status Hv_Drv_Spi_DmaTransmit(SpiSelf *pstSelf, UCHAR8* pucData, USHORT16 usDataSize)
- {
- USHORT16 usBlockSize = 0;
- if (pstSelf->enState == SPI_STATE_READY)
- {
- if ((pstSelf->stInitParam.enDirection != SPI_DIRECTION_TXRX)
- && (pstSelf->stInitParam.enDirection != SPI_DIRECTION_TX))
- {
- return HV_FAILURE;
- }
- if (pstSelf->stInitParam.enDataSize == SPI_BITWIDTH_8)
- {
- HV_ASSERT((usDataSize % 4) == 0);
- usBlockSize = usDataSize / 4;
- }else if (pstSelf->stInitParam.enDataSize == SPI_BITWIDTH_32){
- HV_ASSERT((usDataSize % 4) == 0);
- usBlockSize = usDataSize / 4;
- }
- Hv_Spi_ConfigDmaTxReg(pstSelf, SPI_DMATX_ENABLE, HV_SPI_DMA_TX_THRESHOLD);
- Hv_Spi_Enable(pstSelf);
- Hv_Cal_Dma_XferCallbackBond(pstSelf->pstDmaTx, Hv_Spi_DmaTransmitCpltCallback);
- Hv_Cal_Dma_SetBlockSize(pstSelf->pstDmaTx, usBlockSize);
- Hv_Cal_Dma_SetSrcAddr(pstSelf->pstDmaTx, (UINT32)pucData);
- pstSelf->enState = SPI_STATE_BUSY_TX;
- pstSelf->enErrorCode = SPI_ERROR_NONE;
- pstSelf->enTransCompleteFlag = SPI_TRANS_IN_PROCESS;
- Hv_Cal_Dma_ChannelEn(pstSelf->pstDmaTx);
- return HV_SUCCESS;
- }
- else
- {
- return HV_BUSY;
- }
- }
- /**@brief Receive an amount of data in blocking mode
- * @param self pointer to spi structure
- * @param pucCmdAddr pointer to command buffer
- * @param pucRxData pointer to data buffer
- * @param usDataSize amount of data to be sent
- * @param uiTimeout Timeout duration
- * @retval result
- */
- Status Hv_Drv_Spi_PollingReceive(SpiSelf *pstSelf, UCHAR8 *pucCmdAddr, USHORT16 usCmdAddrSize,
- UCHAR8 *pucRxData, USHORT16 usDataSize, UINT32 uiTimeout)
- {
- UINT32 uiLoop = 0;
- UINT32 uiTxFifoSurplusLev = 0;
- UINT32 uiTxDataNumOnce = 0;
- UINT32 uiRxFifoDataLev = 0;
- UCHAR8 ucDummy[4] = {0};
- UINT32 uiDummySize = 0;
- UINT64 ullTickstart = Hv_Vos_GetTick();
- USHORT16 usCmdAddrSizeTemp = 0;
- USHORT16 usDataSizeTemp = 0;
- USHORT16 usTxTotalSize = 0;
- UINT32 uiCmdDataRegAddrBase = 0;
- UINT32 uiCmdDataRegAddr = 0;
- if (pstSelf->enState == SPI_STATE_READY)
- {
- if ((pstSelf->stInitParam.enDirection != SPI_DIRECTION_TXRX)
- && (pstSelf->stInitParam.enDirection != SPI_DIRECTION_RX))
- {
- return HV_FAILURE;
- }
- if (pstSelf->stInitParam.enDataSize == SPI_BITWIDTH_8)
- {
- usCmdAddrSizeTemp = usCmdAddrSize;
- usDataSizeTemp = usDataSize;
- }
- else if (pstSelf->stInitParam.enDataSize == SPI_BITWIDTH_16)
- {
- usCmdAddrSizeTemp = usCmdAddrSize / 2;
- usDataSizeTemp = usDataSize / 2;
- }
- else if (pstSelf->stInitParam.enDataSize == SPI_BITWIDTH_32)
- {
- usCmdAddrSizeTemp = usCmdAddrSize / 4;
- usDataSizeTemp = usDataSize / 4;
- }
- if (pstSelf->stInitParam.enMode == SPI_MODE_MASTER)
- {
- if (usDataSize != 0)
- {
- uiDummySize = usCmdAddrSizeTemp;
- }
- usTxTotalSize = usCmdAddrSizeTemp + usDataSizeTemp;
- pstSelf->usRxXferSize = usCmdAddrSizeTemp + usDataSizeTemp;
- uiCmdDataRegAddrBase = CPU_SYS_SPI0_M_DR0 + pstSelf->uiBaseOffset;
- uiCmdDataRegAddr = uiCmdDataRegAddrBase;
- }
- else if (pstSelf->stInitParam.enMode == SPI_MODE_SLAVE)
- {
- HV_ASSERT(pucCmdAddr == NULL);
- HV_ASSERT(usCmdAddrSize == 0);
- pstSelf->usRxXferSize = usDataSizeTemp;
- uiCmdDataRegAddrBase = CPU_SYS_SPI0_S_DR0 + pstSelf->uiBaseOffset;
- uiCmdDataRegAddr = uiCmdDataRegAddrBase;
- }
- pstSelf->enState = SPI_STATE_BUSY_RX;
- pstSelf->enErrorCode = SPI_ERROR_NONE;
- Hv_Spi_Enable(pstSelf);
- if (pstSelf->stInitParam.enMode == SPI_MODE_MASTER) /*read more need read at the moment*/
- {
- while (usTxTotalSize > 0)
- {
- uiTxFifoSurplusLev = HV_SPI_FIFO_DEPTH - Hv_Spi_GetTxFifoLevel(pstSelf);
- uiTxDataNumOnce = (usTxTotalSize > uiTxFifoSurplusLev)? uiTxFifoSurplusLev : usTxTotalSize;
- for (uiLoop = 0; uiLoop < uiTxDataNumOnce; uiLoop++)
- {
- if (usCmdAddrSizeTemp == 0)
- {
- Hv_Spi_TransmitOne(pstSelf, uiCmdDataRegAddr, ucDummy);
- uiCmdDataRegAddr = uiCmdDataRegAddr + 4;
- }
- else
- {
- pucCmdAddr = Hv_Spi_TransmitOne(pstSelf, uiCmdDataRegAddr, pucCmdAddr);
- usCmdAddrSizeTemp--;
- uiCmdDataRegAddr = uiCmdDataRegAddr + 4;
- }
- if ((uiCmdDataRegAddr - uiCmdDataRegAddrBase) == HV_SPI_DR_ADDR_RANGE_TOTAL)
- {
- uiCmdDataRegAddr = uiCmdDataRegAddrBase;
- }
- usTxTotalSize--;
- }
- uiRxFifoDataLev = Hv_Spi_GetRxFifoLevel(pstSelf);
- if (uiRxFifoDataLev > pstSelf->usRxXferSize)
- {
- uiRxFifoDataLev = pstSelf->usRxXferSize;
- }
- for (uiLoop = 0; uiLoop < uiRxFifoDataLev; uiLoop++)
- {
- if (uiDummySize == 0)
- {
- pucRxData = Hv_Spi_ReceiveOne(pstSelf, uiCmdDataRegAddrBase, pucRxData);
- }
- else
- {
- Hv_Spi_ReceiveOne(pstSelf, uiCmdDataRegAddrBase, ucDummy);
- uiDummySize--;
- }
- pstSelf->usRxXferSize--;
- }
- }
- }
- while (pstSelf->usRxXferSize > 0)
- {
- uiRxFifoDataLev = Hv_Spi_GetRxFifoLevel(pstSelf);
- if (uiRxFifoDataLev > pstSelf->usRxXferSize)
- {
- uiRxFifoDataLev = pstSelf->usRxXferSize;
- }
- for (uiLoop = 0; uiLoop < uiRxFifoDataLev; uiLoop++)
- {
- if (uiDummySize == 0)
- {
- pucRxData = Hv_Spi_ReceiveOne(pstSelf, uiCmdDataRegAddrBase, pucRxData);
- }
- else
- {
- Hv_Spi_ReceiveOne(pstSelf, uiCmdDataRegAddrBase, ucDummy);
- uiDummySize--;
- }
- pstSelf->usRxXferSize--;
- }
- if (pstSelf->stInitParam.enMode == SPI_MODE_MASTER)
- {
- if ((Hv_Vos_GetTick() - ullTickstart) > uiTimeout)
- {
- return HV_TIMEOUT;
- }
- }
- }
- if ((pstSelf->stInitParam.enMode == SPI_MODE_MASTER)
- && (pstSelf->stInitParam.enCsCtlMode != SPI_CSMODE_ALWAYS_LOW))
- {
- if (Hv_Spi_WaitOnFlagUntilTimeout(pstSelf, SPI_FLAG_BUSY, HV_RESET, HV_SPI_TIMEOUT) != HV_SUCCESS)
- {
- return HV_TIMEOUT;
- }
- }
- pstSelf->enState = SPI_STATE_READY;
- Hv_Spi_Disable(pstSelf);
- return HV_SUCCESS;
- }
- else
- {
- return HV_BUSY;
- }
- }
- /**@brief Receive an amount of data in no-blocking mode with interrupt
- * @param self pointer to spi structure
- * @param pCmd pointer to command buffer
- * @param pRxData pointer to data buffer
- * @param size amount of data to be sent
- * @retval result
- */
- Status Hv_Drv_Spi_IntReceive(SpiSelf *pstSelf, UCHAR8 *pucCmdAddr, USHORT16 usCmdAddrSize,
- UCHAR8 *pucRxData,USHORT16 usDataSize)
- {
- UINT32 uiIntFlag = 0;
- USHORT16 usCmdAddrSizeTemp = 0;
- USHORT16 usDataSizeTemp = 0;
- if (pstSelf->enState == SPI_STATE_READY)
- {
- if ((pstSelf->stInitParam.enDirection != SPI_DIRECTION_TXRX)
- && (pstSelf->stInitParam.enDirection != SPI_DIRECTION_RX))
- {
- return HV_FAILURE;
- }
- if (pstSelf->stInitParam.enDataSize == SPI_BITWIDTH_8)
- {
- usCmdAddrSizeTemp = usCmdAddrSize;
- usDataSizeTemp = usDataSize;
- }
- else if (pstSelf->stInitParam.enDataSize == SPI_BITWIDTH_16)
- {
- usCmdAddrSizeTemp = usCmdAddrSize / 2;
- usDataSizeTemp = usDataSize / 2;
- }
- else if (pstSelf->stInitParam.enDataSize == SPI_BITWIDTH_32)
- {
- usCmdAddrSizeTemp = usCmdAddrSize / 4;
- usDataSizeTemp = usDataSize / 4;
- }
- if (pstSelf->stInitParam.enMode == SPI_MODE_MASTER)
- {
- pstSelf->usDumSize= usCmdAddrSizeTemp;
- pstSelf->usCmdAddrSize = usCmdAddrSizeTemp;
- pstSelf->pucCmdAddr = pucCmdAddr;
- pstSelf->pucTxBuff = NULL;
- pstSelf->usTxXferSize = usDataSizeTemp;
- pstSelf->usTxXferCount = 0;
- }
- else if (pstSelf->stInitParam.enMode == SPI_MODE_SLAVE)
- {
- HV_ASSERT(pucCmdAddr == NULL);
- HV_ASSERT(usCmdAddrSize == 0);
- }
- pstSelf->pucRxBuff = pucRxData;
- pstSelf->usRxXferSize = usDataSizeTemp + pstSelf->usDumSize;
- pstSelf->usRxXferCount = 0;
- pstSelf->enState = SPI_STATE_BUSY_RX;
- pstSelf->enErrorCode = SPI_ERROR_NONE;
- pstSelf->enTransCompleteFlag = SPI_TRANS_IN_PROCESS;
- if (pstSelf->stInitParam.enMode == SPI_MODE_MASTER)
- {
- uiIntFlag = SPI_INTERRUPT_TXEIR | SPI_INTERRUPT_TXOIR | SPI_INTERRUPT_RXFIR | SPI_INTERRUPT_RXOIR | SPI_INTERRUPT_RXUIR;
- } else {
- uiIntFlag = SPI_INTERRUPT_RXFIR | SPI_INTERRUPT_RXOIR | SPI_INTERRUPT_RXUIR;
- }
- Hv_Spi_InterruptEnable(pstSelf, uiIntFlag);
- Hv_Spi_Enable(pstSelf);
- return HV_SUCCESS;
- }
- else
- {
- return HV_BUSY;
- }
- }
- /**@brief Receive an amount of data in no-blocking mode with DMA
- * @param self pointer to spi structure
- * @param pucCmd pointer to command buffer
- * @param pucRxData pointer to data buffer
- * @param usDataSize amount of data to be sent
- * @retval result
- */
- Status Hv_Drv_Spi_DmaReceive(SpiSelf *pstSelf, UCHAR8 *pucCmd, UCHAR8* pucRxData, USHORT16 usDataSize)
- {
- UINT32 uiTxBlockSize = 0;
- UINT32 uiRxBlockSize = 0;
- if (pstSelf->enState == SPI_STATE_READY)
- {
- if ((pstSelf->stInitParam.enDirection != SPI_DIRECTION_TXRX)
- && (pstSelf->stInitParam.enDirection != SPI_DIRECTION_RX))
- {
- return HV_FAILURE;
- }
- if (pstSelf->stInitParam.enDataSize == SPI_BITWIDTH_8)
- {
- HV_ASSERT((usDataSize % 4) == 0);
- uiTxBlockSize = usDataSize / 4;
- uiRxBlockSize = usDataSize;
- }
- else if (pstSelf->stInitParam.enDataSize == SPI_BITWIDTH_32)
- {
- uiTxBlockSize = usDataSize / 4;
- uiRxBlockSize = usDataSize / 4;
- }
- Hv_Cal_Dma_XferCallbackBond(pstSelf->pstDmaRx, Hv_Spi_DmaReceiveCpltCallback);
- Hv_Cal_Dma_SetBlockSize(pstSelf->pstDmaRx, uiRxBlockSize);
- Hv_Cal_Dma_SetDstAddr(pstSelf->pstDmaRx, (UINT32)pucRxData);
- Hv_Cal_Dma_ChannelEn(pstSelf->pstDmaRx);
- if (pstSelf->stInitParam.enMode == SPI_MODE_MASTER)
- {
- Hv_Spi_ConfigDmaTxReg(pstSelf, SPI_DMATX_ENABLE, HV_SPI_DMA_TX_THRESHOLD);
- }
- Hv_Spi_ConfigDmaRxReg(pstSelf, SPI_DMARX_ENABLE, HV_SPI_DMA_RX_THRESHOLD);
- Hv_Spi_Enable(pstSelf);
- pstSelf->enState = SPI_STATE_BUSY_RX;
- pstSelf->enErrorCode = SPI_ERROR_NONE;
- pstSelf->enTransCompleteFlag = SPI_TRANS_IN_PROCESS;
- if (pstSelf->stInitParam.enMode == SPI_MODE_MASTER)
- {
- Hv_Cal_Dma_XferCallbackBond(pstSelf->pstDmaTx, Hv_Spi_DmaTransmitCpltCallback);
- Hv_Cal_Dma_SetBlockSize(pstSelf->pstDmaTx, uiTxBlockSize);
- Hv_Cal_Dma_SetSrcAddr(pstSelf->pstDmaTx, (UINT32)pucCmd);
- Hv_Cal_Dma_ChannelEn(pstSelf->pstDmaTx);
- }
- return HV_SUCCESS;
- }
- else
- {
- return HV_BUSY;
- }
- }
- /**@brief check spi transfer complete yes or not
- * @param self pointer to spi structure
- * @retval HV_TRUE/HV_FALSE
- */
- BOOL Hv_Drv_Spi_TransferIsComplete(SpiSelf *pstSelf)
- {
- if (pstSelf->enTransCompleteFlag == SPI_TRANS_IN_PROCESS)
- {
- return HV_FALSE;
- }
- else if (pstSelf->enTransCompleteFlag == SPI_TRANS_END)
- {
- return HV_TRUE;
- }
- return HV_FALSE;
- }
- /**@brief read spi rx fifo data
- * @param self pointer to spi structure
- * @retval none
- */
- VOID Hv_Drv_Spi_SaveModeReadEmptyFifo(SpiSelf *pstSelf)
- {
- UINT32 i = 0;
- UINT32 uiRxFifoDataLev = 0;
- UCHAR8 ucDataTmp[128] = {0};
- //UINT32 uiData = 0;
- UINT32 uiCmdDataRegAddrBase = 0;
- uiCmdDataRegAddrBase = CPU_SYS_SPI0_S_DR0 + pstSelf->uiBaseOffset;
- uiRxFifoDataLev = Hv_Spi_GetRxFifoLevel(pstSelf);
- if (uiRxFifoDataLev > pstSelf->usRxXferSize)
- {
- uiRxFifoDataLev = pstSelf->usRxXferSize;
- }
- for (i = 0; i < uiRxFifoDataLev; i++)
- {
- Hv_Spi_ReceiveOne(pstSelf, uiCmdDataRegAddrBase, ucDataTmp);
- //uiData = *((UINT32 *)cmdDataRegAddrBase);
- }
- return;
- }
|