1 /*
2  * @ : Copyright (c) 2021 Phytium Information Technology, Inc.
3  *
4  * SPDX-License-Identifier: Apache-2.0.
5  *
6  * @Date: 2021-04-25 14:00:25
7  * @LastEditTime: 2021-05-24 14:34:28
8  * @Description:  This files is for
9  *
10  * @Modify History:
11  *  Ver   Who        Date         Changes
12  * ----- ------     --------    --------------------------------------
13  */
14 
15 #include "ft_assert.h"
16 #include "ft_spi.h"
17 #include "ft_spi_hw.h"
18 #include "ft_generic_timer.h"
19 #include "ft_gpio.h"
20 
FSpi_DumpAllStatus(FT_IN FSpi_Ctrl_t * pCtrl,FT_IN char * tag)21 void FSpi_DumpAllStatus(FT_IN FSpi_Ctrl_t *pCtrl, FT_IN char *tag)
22 {
23     FT_SPI_DEBUG_I("***%s status******\r\n", tag);
24     FT_SPI_DEBUG_I("busy: %d", SPI_STATUS_REG(pCtrl)->val.Busy);
25     FT_SPI_DEBUG_I("tx fifo not empty: %d", SPI_STATUS_REG(pCtrl)->val.Tfnf);
26     FT_SPI_DEBUG_I("tx fifo empty: %d", SPI_STATUS_REG(pCtrl)->val.Tfe);
27     FT_SPI_DEBUG_I("rx fifo not empty: %d", SPI_STATUS_REG(pCtrl)->val.Rfne);
28     FT_SPI_DEBUG_I("rx fifo full: %d", SPI_STATUS_REG(pCtrl)->val.Rff);
29     FT_SPI_DEBUG_I("trans error: %d", SPI_STATUS_REG(pCtrl)->val.Txe);
30     FT_SPI_DEBUG_I("trans conflict error: %d", SPI_STATUS_REG(pCtrl)->val.Dcol);
31 }
32 
FSpi_ReadWriteByte(FT_INOUT FSpi_Ctrl_t * pCtrl,FT_IN u8 TxData,FT_OUT u8 * pRxData)33 u32 FSpi_ReadWriteByte(FT_INOUT FSpi_Ctrl_t *pCtrl, FT_IN u8 TxData,
34                        FT_OUT u8 *pRxData)
35 {
36     u32 Retry = 0;
37     u32 Ret = ERR_SPI_OK;
38     u16 RxData;
39 
40     if (!pCtrl->IsReady)
41     {
42         return ERR_SPI_NOT_READY;
43     }
44 
45     while (FSPI_TX_FIFO_NOT_EMPTY(pCtrl))
46     {
47         //Ft_GenericTimer_UsDelay(2);
48         if ((Retry++) > SPI_TIMEOUT)
49         {
50             Ret = ERR_SPI_TX_TIMEOUT;
51             goto __EXIT;
52         }
53     }
54     FSPI_WRITE_DATA(pCtrl, (u16)TxData);
55 
56     Retry = 0;
57 
58     while (FSPI_RX_FIFO_EMPTY(pCtrl))
59     {
60         //Ft_GenericTimer_UsDelay(2);
61         if ((Retry++) > SPI_TIMEOUT)
62         {
63             Ret = ERR_SPI_RX_TIMEOUT;
64             goto __EXIT;
65         }
66     }
67     RxData = FSPI_READ_DATA(pCtrl);
68 
69     if (pRxData)
70     {
71         *pRxData = (u8)RxData;
72     }
73 
74 __EXIT:
75     return Ret;
76 }
77 
FSpi_Init(FT_INOUT FSpi_Ctrl_t * pCtrl)78 u32 FSpi_Init(FT_INOUT FSpi_Ctrl_t *pCtrl)
79 {
80     u32 Ret = ERR_SPI_OK;
81 
82     FSPI_DISABLE(pCtrl);
83 
84     /* config spi ctrl register */
85     SPI_CTRL0_REG(pCtrl)->val.Dfs = SPI_DFS_DEFAULT;
86     SPI_CTRL0_REG(pCtrl)->val.Frf = SPI_FRF_DEFAULT;
87 
88     if (SPI_CTRL_CPHA_1EDGE == pCtrl->Config.Cpha)
89     {
90         SPI_CTRL0_REG(pCtrl)->val.Scph = SPI_SCPH_SW_CLK_AT_DATA_BEG;
91     }
92     else if (SPI_CTRL_CPHA_2EDGE == pCtrl->Config.Cpha)
93     {
94         SPI_CTRL0_REG(pCtrl)->val.Scph = SPI_SCPH_SW_CLK_AT_DATA_MID;
95     }
96     else
97     {
98         Ft_assertNoneReturn(0);
99     }
100 
101     if (SPI_CTRL_CPOL_LOW == pCtrl->Config.Cpol)
102     {
103         SPI_CTRL0_REG(pCtrl)->val.Scpol = SPI_SCPOL_NOT_ACT_LOW;
104     }
105     else if (SPI_CTRL_CPOL_HIGH == pCtrl->Config.Cpol)
106     {
107         SPI_CTRL0_REG(pCtrl)->val.Scpol = SPI_SCPOL_NOT_ACT_HIGH;
108     }
109     else
110     {
111         Ft_assertNoneReturn(0);
112     }
113 
114     SPI_CTRL0_REG(pCtrl)->val.Tmod = SPI_TMOD_TX_RX_MODE;
115     SPI_CTRL0_REG(pCtrl)->val.SlvOE = SPI_SLV_OE_DISABLE;
116     SPI_CTRL0_REG(pCtrl)->val.Srl = SPI_SRL_NORMAL_MODE;
117     SPI_CTRL0_REG(pCtrl)->val.Cfs = SPI_CFS_DEFAULT;
118 
119     /* config spi clock */
120     FSPI_SET_BAUDR(pCtrl, pCtrl->Config.BaudRDiv);
121 
122     /* config rx and tx fifo, fifo depth to trigger intr */
123     SPI_TXFTL_REG(pCtrl)->val.Tft = 0;
124     SPI_RXFTL_REG(pCtrl)->val.Rft = 0;
125     SPI_TXFL_REG(pCtrl)->val.Txtfl = 0;
126     SPI_RXFL_REG(pCtrl)->val.Rxtfl = 0;
127 
128     SPI_RXSAMPLE_DLY_REG(pCtrl)->val.Rsd = SPI_DEFAULT_RSD;
129 
130     FSPI_ENABLE(pCtrl);
131 
132     /* set spi ready flag */
133     if (ERR_SPI_OK == Ret)
134     {
135         pCtrl->IsReady = TRUE;
136     }
137 
138     return Ret;
139 }
140 
FSpi_ToggleCSPin(FT_INOUT FSpi_Ctrl_t * pCtrl,FT_IN FSpi_DevId_t DevId,FT_IN bool_t select)141 static void FSpi_ToggleCSPin(FT_INOUT FSpi_Ctrl_t *pCtrl, FT_IN FSpi_DevId_t DevId,
142                              FT_IN bool_t select)
143 {
144     u32 setVal = ((TRUE == select) ? GPIO_OFF : GPIO_ON);
145 
146     Ft_assertNoneReturn(NULL != pCtrl);
147 
148     if (FGpio_ReadPinA(GPIO_CTRL_ID_1, pCtrl->CsPin) != setVal)
149     {
150         FGpio_WritePinA(GPIO_CTRL_ID_1, pCtrl->CsPin, setVal);
151     }
152 
153     Ft_GenericTimer_UsDelay(10);
154     return;
155 }
156 
FSpi_SelectSlave(FT_INOUT FSpi_Ctrl_t * pCtrl,FT_IN FSpi_DevId_t DevId,FT_IN bool_t select)157 void FSpi_SelectSlave(FT_INOUT FSpi_Ctrl_t *pCtrl, FT_IN FSpi_DevId_t DevId,
158                       FT_IN bool_t select)
159 {
160     FSpi_SeReg_t *pSelReg;
161     u32 setVal = ((TRUE == select) ? SPI_SE_SELECTED : SPI_SE_UNSELECTED);
162 
163     FSPI_DISABLE(pCtrl);
164     /* enable or disable specific spi slave device */
165     pSelReg = SPI_SE_REG(pCtrl);
166     switch (DevId)
167     {
168     case SPI_DEV_ID_0:
169         pSelReg->val.SelSlave_0 = setVal;
170         break;
171     case SPI_DEV_ID_1:
172         pSelReg->val.SelSlave_1 = setVal;
173         Ft_assertNoneReturn(0);
174         break;
175     case SPI_DEV_ID_2:
176         pSelReg->val.SelSlave_2 = setVal;
177         Ft_assertNoneReturn(0);
178         break;
179     case SPI_DEV_ID_3:
180         pSelReg->val.SelSlave_3 = setVal;
181         Ft_assertNoneReturn(0);
182         break;
183     default:
184         Ft_assertNoneReturn(0);
185         break;
186     }
187 
188     FSpi_ToggleCSPin(pCtrl, DevId, select);
189     FSPI_ENABLE(pCtrl);
190 
191     return;
192 }
193