1 /******************************************************************************
2 * Copyright (C) 2016, Huada Semiconductor Co.,Ltd All rights reserved.
3 *
4 * This software is owned and published by:
5 * Huada Semiconductor Co.,Ltd ("HDSC").
6 *
7 * BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE, YOU AGREE TO BE BOUND
8 * BY ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT.
9 *
10 * This software contains source code for use with HDSC
11 * components. This software is licensed by HDSC to be adapted only
12 * for use in systems utilizing HDSC components. HDSC shall not be
13 * responsible for misuse or illegal use of this software for devices not
14 * supported herein. HDSC is providing this software "AS IS" and will
15 * not be responsible for issues arising from incorrect user implementation
16 * of the software.
17 *
18 * Disclaimer:
19 * HDSC MAKES NO WARRANTY, EXPRESS OR IMPLIED, ARISING BY LAW OR OTHERWISE,
20 * REGARDING THE SOFTWARE (INCLUDING ANY ACOOMPANYING WRITTEN MATERIALS),
21 * ITS PERFORMANCE OR SUITABILITY FOR YOUR INTENDED USE, INCLUDING,
22 * WITHOUT LIMITATION, THE IMPLIED WARRANTY OF MERCHANTABILITY, THE IMPLIED
23 * WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE OR USE, AND THE IMPLIED
24 * WARRANTY OF NONINFRINGEMENT.
25 * HDSC SHALL HAVE NO LIABILITY (WHETHER IN CONTRACT, WARRANTY, TORT,
26 * NEGLIGENCE OR OTHERWISE) FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT
27 * LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION,
28 * LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) ARISING FROM USE OR
29 * INABILITY TO USE THE SOFTWARE, INCLUDING, WITHOUT LIMITATION, ANY DIRECT,
30 * INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOSS OF DATA,
31 * SAVINGS OR PROFITS,
32 * EVEN IF Disclaimer HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
33 * YOU ASSUME ALL RESPONSIBILITIES FOR SELECTION OF THE SOFTWARE TO ACHIEVE YOUR
34 * INTENDED RESULTS, AND FOR THE INSTALLATION OF, USE OF, AND RESULTS OBTAINED
35 * FROM, THE SOFTWARE.
36 *
37 * This software may be replicated in part or whole for the licensed use,
38 * with the restriction that this Disclaimer and Copyright notice must be
39 * included with eaenCh copy of this software, whether used in part or whole,
40 * at all times.
41 */
42 /*****************************************************************************/
43 /** \file spi.c
44  **
45  ** SPI driver API.
46  ** @link Driver Group Some description @endlink
47  **
48  **   - 2018-05-17  1.0  Devi First version for Device Driver Library of
49  **                      Module.
50  **
51  *****************************************************************************/
52 
53 /******************************************************************************
54  * Include files
55  *****************************************************************************/
56 #include "hc32l196_spi.h"
57 
58 /**
59  ******************************************************************************
60  ** \addtogroup SpiGroup
61  *****************************************************************************/
62 //@{
63 
64 /******************************************************************************
65  * Local pre-processor symbols/macros ('#define')
66  *****************************************************************************/
67 
68 #define IS_VALID_STAT(x)            (   SpiIf == (x)||\
69                                         SpiSserr == (x)||\
70                                         SpiBusy == (x)||\
71                                         SpiMdf == (x)||\
72                                         SpiTxe == (x)||\
73                                         SpiRxne == (x))
74 
75 
76 /******************************************************************************/
77 /* Local function prototypes ('static')                                       */
78 /******************************************************************************/
79 
80 /******************************************************************************/
81 /* Local variable prototypes ('static')                                       */
82 /******************************************************************************/
83 
84 /**
85  ******************************************************************************
86  ** \brief  SPI 请求状态获取
87  **
88  ** \param [in]SPIx 通道, enStatus 获取请求
89  **
90  ** \retval 请求状态
91  **
92  ******************************************************************************/
Spi_GetStatus(M0P_SPI_TypeDef * SPIx,en_spi_status_t enStatus)93 boolean_t Spi_GetStatus(M0P_SPI_TypeDef* SPIx, en_spi_status_t enStatus)
94 {
95     ASSERT(IS_VALID_STAT(enStatus));
96 
97     if(SPIx->STAT&enStatus)
98     {
99         return TRUE;
100     }
101     else
102     {
103         return FALSE;
104     }
105 
106 }
107 /**
108  ******************************************************************************
109  ** \brief  SPI中断清除
110  **
111  ** \param [in]SPIx 通道选择
112  **
113  ** \retval 请求状态
114  **
115  ******************************************************************************/
Spi_ClearStatus(M0P_SPI_TypeDef * SPIx)116 en_result_t Spi_ClearStatus(M0P_SPI_TypeDef* SPIx)
117 {
118     SPIx->ICLR = 0;
119 
120     return Ok;
121 }
122 
123 /**
124  ******************************************************************************
125  ** \brief  SPI 中断使能函数
126  **
127  ** \param [in] SPIx 通道
128  **
129  ** \retval Ok成功
130  **
131  ******************************************************************************/
Spi_IrqEnable(M0P_SPI_TypeDef * SPIx)132 en_result_t Spi_IrqEnable(M0P_SPI_TypeDef* SPIx)
133 {
134     SPIx->CR2 |= 0x4u;
135 
136     return Ok;
137 }
138 
139 /**
140  ******************************************************************************
141  ** \brief  SPI 中断禁止函数
142  **
143  ** \param [in] enCh通道
144  **
145  ** \retval Ok成功
146  **
147  ******************************************************************************/
Spi_IrqDisable(M0P_SPI_TypeDef * SPIx)148 en_result_t Spi_IrqDisable(M0P_SPI_TypeDef* SPIx)
149 {
150     SPIx->CR2 &= ~0x4u;
151 
152     return Ok;
153 }
154 
155 /**
156  ******************************************************************************
157  ** \brief  SPI 功能使能函数
158  **
159  ** \param [in] SPIx 通道,enFunc功能
160  **
161  ** \retval Ok初始化成功
162  **
163  ******************************************************************************/
Spi_FuncEnable(M0P_SPI_TypeDef * SPIx,en_spi_func_t enFunc)164 en_result_t Spi_FuncEnable(M0P_SPI_TypeDef* SPIx, en_spi_func_t enFunc)
165 {
166     SPIx->CR2 |= enFunc;
167 
168     return Ok;
169 }
170 
171 /**
172  ******************************************************************************
173  ** \brief  SPI 功能禁止函数
174  **
175  ** \param [in] SPIx 通道,enFunc功能
176  **
177  ** \retval Ok初始化成功
178  **
179  ******************************************************************************/
Spi_FuncDisable(M0P_SPI_TypeDef * SPIx,en_spi_func_t enFunc)180 en_result_t Spi_FuncDisable(M0P_SPI_TypeDef* SPIx, en_spi_func_t enFunc)
181 {
182     SPIx->CR2 &= ~(uint32_t)enFunc;
183 
184     return Ok;
185 }
186 
187 /**
188  ******************************************************************************
189  ** \brief  SPI 总体初始化函数
190  **
191  ** \param [in] SPIx 通道
192  ** \param [in] pstcSpiCfg 初始化结构体
193  **
194  ** \retval Ok初始化成功
195  ** \retval ErrorInvalidParameter 初始化错误
196  ******************************************************************************/
Spi_Init(M0P_SPI_TypeDef * SPIx,stc_spi_cfg_t * pstcSpiCfg)197 en_result_t Spi_Init(M0P_SPI_TypeDef* SPIx, stc_spi_cfg_t *pstcSpiCfg)
198 {
199     ASSERT(NULL != pstcSpiCfg);
200 
201     SPIx->CR = 0;
202 
203     SPIx->SSN = TRUE;
204 
205     SPIx->CR =  (uint32_t)pstcSpiCfg->enSpiMode |
206                 (uint32_t)pstcSpiCfg->enPclkDiv |
207                 (uint32_t)pstcSpiCfg->enCPOL    |
208                 (uint32_t)pstcSpiCfg->enCPHA    |
209                 (uint32_t)0x40;
210 
211     SPIx->STAT = 0x00;
212 
213     return Ok;
214 }
215 
216 /**
217  ******************************************************************************
218  ** \brief  SPI 配置主发送的电平
219  **
220  ** \param [in] SPIx 通道选择,bFlag高低电平
221  **
222  ** \retval 无
223  **
224  ******************************************************************************/
Spi_SetCS(M0P_SPI_TypeDef * SPIx,boolean_t bFlag)225 void Spi_SetCS(M0P_SPI_TypeDef* SPIx, boolean_t bFlag)
226 {
227     SPIx->SSN = bFlag;
228 }
229 /**
230  ******************************************************************************
231  ** \brief  SPI 发送一字节函数
232  **
233  ** \param [in] SPIx 通道选择,u8Data发送字节
234  **
235  ** \retval Ok发送成功
236  **
237  ******************************************************************************/
Spi_SendData(M0P_SPI_TypeDef * SPIx,uint8_t u8Data)238 en_result_t Spi_SendData(M0P_SPI_TypeDef* SPIx, uint8_t u8Data)
239 {
240     SPIx->DATA = u8Data;
241 
242     return Ok;
243 }
244 
245 /**
246  ******************************************************************************
247  ** \brief  SPI 读/写一字节函数
248  **
249  ** \param [in] SPIx   通道选择
250  ** \param [in] u8Data 发送一字节数据
251  **
252  ** \retval 接收一字节数据
253  **
254  ******************************************************************************/
Spi_RWByte(M0P_SPI_TypeDef * SPIx,uint8_t u8Data)255 uint8_t Spi_RWByte(M0P_SPI_TypeDef* SPIx, uint8_t u8Data)
256 {
257     while(FALSE == SPIx->STAT_f.TXE){;}
258     SPIx->DATA = u8Data;
259     while(FALSE == SPIx->STAT_f.RXNE){;}
260     return SPIx->DATA;
261 }
262 
263 /**
264  ******************************************************************************
265 ** \brief  SPI 从机预准备第一字节数据
266  **
267  ** \param [in] SPIx   通道选择
268  ** \param [in] u8Data 预准备第一字节数据
269  **
270  ** \retval None
271  **
272  ******************************************************************************/
Spi_Slave_DummyWriteData(M0P_SPI_TypeDef * SPIx,uint8_t u8Data)273 void Spi_Slave_DummyWriteData(M0P_SPI_TypeDef* SPIx, uint8_t u8Data)
274 {
275     while(FALSE == SPIx->STAT_f.TXE){;}
276     SPIx->DATA = u8Data;
277 }
278 
279 /**
280  ******************************************************************************
281  ** \brief  SPI 连续发送多字节函数
282  **
283  ** \param [in] SPIx   通道选择
284  ** \param [in] pu8Buf 发送数据指针
285  **
286  ** \retval Ok发送成功
287  **
288  ******************************************************************************/
Spi_SendBuf(M0P_SPI_TypeDef * SPIx,uint8_t * pu8Buf,uint32_t u32Len)289 en_result_t Spi_SendBuf(M0P_SPI_TypeDef* SPIx, uint8_t* pu8Buf, uint32_t u32Len)
290 {
291     uint32_t u32Index=0;
292 
293     for(u32Index=0; u32Index<u32Len; u32Index++)
294     {
295         while(FALSE == SPIx->STAT_f.TXE){;}
296         SPIx->DATA = pu8Buf[u32Index];
297         while(FALSE == SPIx->STAT_f.RXNE){;}
298         pu8Buf[u32Index] = SPIx->DATA;
299     }
300 
301     while(FALSE == SPIx->STAT_f.TXE){;}
302     while(TRUE == SPIx->STAT_f.BUSY){;}
303 
304     return Ok;
305 }
306 
307 /**
308  ******************************************************************************
309  ** \brief  SPI 接收一字节函数
310  **
311  ** \param [in] SPIx接收通道
312  **
313  ** \retval 接收一字节数据
314  **
315  ******************************************************************************/
Spi_ReceiveData(M0P_SPI_TypeDef * SPIx)316 uint8_t Spi_ReceiveData(M0P_SPI_TypeDef* SPIx)
317 {
318     return SPIx->DATA;
319 }
320 
321 /**
322  ******************************************************************************
323  ** \brief  SPI 连续接收多字节函数
324  **
325  ** \param [in] SPIx   通道选择
326  ** \param [in] pu8Buf 发送数据指针
327  **
328  ** \retval Ok发送成功
329  **
330  ******************************************************************************/
Spi_ReceiveBuf(M0P_SPI_TypeDef * SPIx,uint8_t * pu8Buf,uint32_t u32Len)331 en_result_t Spi_ReceiveBuf(M0P_SPI_TypeDef* SPIx, uint8_t* pu8Buf, uint32_t u32Len)
332 {
333     uint32_t u32Index=0;
334 
335     for(u32Index=0; u32Index<u32Len; u32Index++)
336     {
337         while(FALSE == SPIx->STAT_f.TXE){;}
338         SPIx->DATA = 0x00;
339         while(FALSE == SPIx->STAT_f.RXNE){;}
340         pu8Buf[u32Index] = SPIx->DATA;
341     }
342 
343     while(TRUE == SPIx->STAT_f.BUSY){;}
344 
345     return Ok;
346 }
347 
348 //@} // SpiGroup
349 /******************************************************************************
350  * EOF (not truncated)
351  *****************************************************************************/
352 
353