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