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