1 /******************************************************************************************************************************************
2 * 文件名称: SWM320_spi.c
3 * 功能说明: SWM320单片机的SPI功能驱动库
4 * 技术支持: http://www.synwit.com.cn/e/tool/gbook/?bid=1
5 * 注意事项:
6 * 版本日期: V1.1.0 2017年10月25日
7 * 升级记录:
8 *
9 *
10 *******************************************************************************************************************************************
11 * @attention
12 *
13 * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS WITH CODING INFORMATION
14 * REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. AS A RESULT, SYNWIT SHALL NOT BE HELD LIABLE
15 * FOR ANY DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
16 * OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION CONTAINED HEREIN IN CONN-
17 * -ECTION WITH THEIR PRODUCTS.
18 *
19 * COPYRIGHT 2012 Synwit Technology
20 *******************************************************************************************************************************************/
21 #include "SWM320.h"
22 #include "SWM320_spi.h"
23
24
25 /******************************************************************************************************************************************
26 * 函数名称: SPI_Init()
27 * 功能说明: SPI同步串行接口初始化,包括帧长度设定、时序设定、速度设定、中断设定、FIFO触发设定
28 * 输 入: SPI_TypeDef * SPIx 指定要被设置的SPI,有效值包括SPI0、SPI1
29 * SPI_InitStructure * initStruct 包含SPI相关设定值的结构体
30 * 输 出: 无
31 * 注意事项: 无
32 ******************************************************************************************************************************************/
SPI_Init(SPI_TypeDef * SPIx,SPI_InitStructure * initStruct)33 void SPI_Init(SPI_TypeDef * SPIx, SPI_InitStructure * initStruct)
34 {
35 switch((uint32_t)SPIx)
36 {
37 case ((uint32_t)SPI0):
38 SYS->CLKEN |= (0x01 << SYS_CLKEN_SPI0_Pos);
39 break;
40
41 case ((uint32_t)SPI1):
42 SYS->CLKEN |= (0x01 << SYS_CLKEN_SPI0_Pos); //与SPI0使用同一位时钟使能
43 break;
44 }
45
46 SPI_Close(SPIx); //一些关键寄存器只能在SPI关闭时设置
47
48 SPIx->CTRL &= ~(SPI_CTRL_FFS_Msk | SPI_CTRL_CPHA_Msk | SPI_CTRL_CPOL_Msk |
49 SPI_CTRL_SIZE_Msk | SPI_CTRL_MSTR_Msk | SPI_CTRL_CLKDIV_Msk | SPI_CTRL_SSN_H_Msk);
50 SPIx->CTRL |= (initStruct->FrameFormat << SPI_CTRL_FFS_Pos) |
51 (initStruct->SampleEdge << SPI_CTRL_CPHA_Pos) |
52 (initStruct->IdleLevel << SPI_CTRL_CPOL_Pos) |
53 ((initStruct->WordSize-1) << SPI_CTRL_SIZE_Pos) |
54 (initStruct->Master << SPI_CTRL_MSTR_Pos) |
55 (initStruct->clkDiv << SPI_CTRL_CLKDIV_Pos) |
56 (0 << SPI_CTRL_SSN_H_Pos);
57
58 SPIx->IF = (0x01 << SPI_IF_RFOVF_Pos); //清除中断标志
59 SPIx->IE &= ~(SPI_IE_RFHF_Msk | SPI_IE_TFHF_Msk | SPI_IE_FTC_Msk);
60 SPIx->IE |= (initStruct->RXHFullIEn << SPI_IE_RFHF_Pos) |
61 (initStruct->TXEmptyIEn << SPI_IE_TFE_Pos) |
62 (initStruct->TXCompleteIEn << SPI_IE_FTC_Pos);
63
64 switch((uint32_t)SPIx)
65 {
66 case ((uint32_t)SPI0):
67 if(initStruct->RXHFullIEn | initStruct->TXEmptyIEn | initStruct->TXCompleteIEn)
68 {
69 NVIC_EnableIRQ(SPI0_IRQn);
70 }
71 else
72 {
73 NVIC_DisableIRQ(SPI0_IRQn);
74 }
75 break;
76
77 case ((uint32_t)SPI1):
78 if(initStruct->RXHFullIEn | initStruct->TXEmptyIEn | initStruct->TXCompleteIEn)
79 {
80 NVIC_EnableIRQ(SPI1_IRQn);
81 }
82 else
83 {
84 NVIC_DisableIRQ(SPI1_IRQn);
85 }
86 break;
87 }
88 }
89
90 /******************************************************************************************************************************************
91 * 函数名称: SPI_Open()
92 * 功能说明: SPI打开,允许收发
93 * 输 入: SPI_TypeDef * SPIx 指定要被设置的SPI,有效值包括SPI0、SPI1
94 * 输 出: 无
95 * 注意事项: 无
96 ******************************************************************************************************************************************/
SPI_Open(SPI_TypeDef * SPIx)97 void SPI_Open(SPI_TypeDef * SPIx)
98 {
99 SPIx->CTRL |= (0x01 << SPI_CTRL_EN_Pos);
100 }
101
102 /******************************************************************************************************************************************
103 * 函数名称: SPI_Close()
104 * 功能说明: SPI关闭,禁止收发
105 * 输 入: SPI_TypeDef * SPIx 指定要被设置的SPI,有效值包括SPI0、SPI1
106 * 输 出: 无
107 * 注意事项: 无
108 ******************************************************************************************************************************************/
SPI_Close(SPI_TypeDef * SPIx)109 void SPI_Close(SPI_TypeDef * SPIx)
110 {
111 SPIx->CTRL &= ~SPI_CTRL_EN_Msk;
112 }
113
114 /******************************************************************************************************************************************
115 * 函数名称: SPI_Read()
116 * 功能说明: 读取一个数据
117 * 输 入: SPI_TypeDef * SPIx 指定要被设置的SPI,有效值包括SPI0、SPI1
118 * 输 出: uint32_t 读取到的数据
119 * 注意事项: 无
120 ******************************************************************************************************************************************/
SPI_Read(SPI_TypeDef * SPIx)121 uint32_t SPI_Read(SPI_TypeDef * SPIx)
122 {
123 return SPIx->DATA;
124 }
125
126 /******************************************************************************************************************************************
127 * 函数名称: SPI_Write()
128 * 功能说明: 写入一个数据
129 * 输 入: SPI_TypeDef * SPIx 指定要被设置的SPI,有效值包括SPI0、SPI1
130 * uint32_t 要写入的数据
131 * 输 出: 无
132 * 注意事项: 无
133 ******************************************************************************************************************************************/
SPI_Write(SPI_TypeDef * SPIx,uint32_t data)134 void SPI_Write(SPI_TypeDef * SPIx, uint32_t data)
135 {
136 SPIx->DATA = data;
137 }
138
139 /******************************************************************************************************************************************
140 * 函数名称: SPI_WriteWithWait()
141 * 功能说明: 写入一个数据并等待数据完全发送出去
142 * 输 入: SPI_TypeDef * SPIx 指定要被设置的SPI,有效值包括SPI0、SPI1、SPI1
143 * uint32_t 要写入的数据
144 * 输 出: 无
145 * 注意事项: 无
146 ******************************************************************************************************************************************/
SPI_WriteWithWait(SPI_TypeDef * SPIx,uint32_t data)147 void SPI_WriteWithWait(SPI_TypeDef * SPIx, uint32_t data)
148 {
149 SPIx->STAT |= (1 << SPI_STAT_WTC_Pos);
150
151 SPIx->DATA = data;
152
153 while((SPIx->STAT & SPI_STAT_WTC_Msk) == 0);
154 }
155
156 /******************************************************************************************************************************************
157 * 函数名称: SPI_ReadWrite()
158 * 功能说明: 发送一个数据,并返回发送过程中接收到的
159 * 输 入: SPI_TypeDef * SPIx 指定要被设置的SPI,有效值包括SPI0、SPI1
160 * uint32_t data 要发送的数据
161 * 输 出: uint32_t 接收到的数据
162 * 注意事项: 对于同一个SPI模块,此函数不应与SPI_Write()混着用,因为SPI_Write()不清除SPI_STAT_RFNE状态
163 ******************************************************************************************************************************************/
SPI_ReadWrite(SPI_TypeDef * SPIx,uint32_t data)164 uint32_t SPI_ReadWrite(SPI_TypeDef * SPIx, uint32_t data)
165 {
166 SPIx->DATA = data;
167 while(!(SPIx->STAT & SPI_STAT_RFNE_Msk));
168
169 return SPIx->DATA;
170 }
171
172 /******************************************************************************************************************************************
173 * 函数名称: SPI_IsRXEmpty()
174 * 功能说明: 接收FIFO是否空,如果不空则可以继续SPI_Read()
175 * 输 入: SPI_TypeDef * SPIx 指定要被设置的SPI,有效值包括SPI0、SPI1
176 * 输 出: uint32_t 1 接收FIFO空 0 接收FIFO非空
177 * 注意事项: 无
178 ******************************************************************************************************************************************/
SPI_IsRXEmpty(SPI_TypeDef * SPIx)179 uint32_t SPI_IsRXEmpty(SPI_TypeDef * SPIx)
180 {
181 return (SPIx->STAT & SPI_STAT_RFNE_Msk) ? 0 : 1;
182 }
183
184 /******************************************************************************************************************************************
185 * 函数名称: SPI_IsTXFull()
186 * 功能说明: 发送FIFO是否满,如果不满则可以继续SPI_Write()
187 * 输 入: SPI_TypeDef * SPIx 指定要被设置的SPI,有效值包括SPI0、SPI1
188 * 输 出: uint32_t 1 发送FIFO满 0 发送FIFO不满
189 * 注意事项: 无
190 ******************************************************************************************************************************************/
SPI_IsTXFull(SPI_TypeDef * SPIx)191 uint32_t SPI_IsTXFull(SPI_TypeDef * SPIx)
192 {
193 return (SPIx->STAT & SPI_STAT_TFNF_Msk) ? 0 : 1;
194 }
195
196 /******************************************************************************************************************************************
197 * 函数名称: SPI_IsTXEmpty()
198 * 功能说明: 发送FIFO是否空
199 * 输 入: SPI_TypeDef * SPIx 指定要被设置的SPI,有效值包括SPI0、SPI1
200 * 输 出: uint32_t 1 发送FIFO空 0 发送FIFO非空
201 * 注意事项: 无
202 ******************************************************************************************************************************************/
SPI_IsTXEmpty(SPI_TypeDef * SPIx)203 uint32_t SPI_IsTXEmpty(SPI_TypeDef * SPIx)
204 {
205 return (SPIx->STAT & SPI_STAT_TFE_Msk) ? 1 : 0;
206 }
207
208 /******************************************************************************************************************************************
209 * 函数名称: SPI_INTEn()
210 * 功能说明: 中断使能
211 * 输 入: SPI_TypeDef * SPIx 指定要被设置的SPI,有效值包括SPI0、SPI1
212 * uint32_t it interrupt type,有效值SPI_IT_RX_OVF、SPI_IT_RX_FULL、SPI_IT_RX_HFULL、SPI_IT_TX_EMPTY、SPI_IT_TX_HFULL、
213 * SPI_IT_TX_DONE 及其“或”
214 * 输 出: 无
215 * 注意事项: 无
216 ******************************************************************************************************************************************/
SPI_INTEn(SPI_TypeDef * SPIx,uint32_t it)217 void SPI_INTEn(SPI_TypeDef * SPIx, uint32_t it)
218 {
219 SPIx->IE |= it;
220 }
221
222 /******************************************************************************************************************************************
223 * 函数名称: SPI_INTDis()
224 * 功能说明: 中断禁止
225 * 输 入: SPI_TypeDef * SPIx 指定要被设置的SPI,有效值包括SPI0、SPI1
226 * uint32_t it interrupt type,有效值SPI_IT_RX_OVF、SPI_IT_RX_FULL、SPI_IT_RX_HFULL、SPI_IT_TX_EMPTY、SPI_IT_TX_HFULL、
227 * SPI_IT_TX_DONE 及其“或”
228 * 输 出: 无
229 * 注意事项: 无
230 ******************************************************************************************************************************************/
SPI_INTDis(SPI_TypeDef * SPIx,uint32_t it)231 void SPI_INTDis(SPI_TypeDef * SPIx, uint32_t it)
232 {
233 SPIx->IE &= ~it;
234 }
235
236 /******************************************************************************************************************************************
237 * 函数名称: SPI_INTClr()
238 * 功能说明: 中断标志清除
239 * 输 入: SPI_TypeDef * SPIx 指定要被设置的SPI,有效值包括SPI0、SPI1
240 * uint32_t it interrupt type,有效值SPI_IT_RX_OVF、SPI_IT_RX_FULL、SPI_IT_RX_HFULL、SPI_IT_TX_EMPTY、SPI_IT_TX_HFULL、
241 * SPI_IT_TX_DONE 及其“或”
242 * 输 出: 无
243 * 注意事项: 无
244 ******************************************************************************************************************************************/
SPI_INTClr(SPI_TypeDef * SPIx,uint32_t it)245 void SPI_INTClr(SPI_TypeDef * SPIx, uint32_t it)
246 {
247 SPIx->IF = it;
248 }
249
250 /******************************************************************************************************************************************
251 * 函数名称: SPI_INTStat()
252 * 功能说明: 中断状态查询
253 * 输 入: SPI_TypeDef * SPIx 指定要被设置的SPI,有效值包括SPI0、SPI1
254 * uint32_t it interrupt type,有效值SPI_IT_RX_OVF、SPI_IT_RX_FULL、SPI_IT_RX_HFULL、SPI_IT_TX_EMPTY、SPI_IT_TX_HFULL、
255 * SPI_IT_TX_DONE 及其“或”
256 * 输 出: uint32_t 1 中断发生 0 中断未发生
257 * 注意事项: 无
258 ******************************************************************************************************************************************/
SPI_INTStat(SPI_TypeDef * SPIx,uint32_t it)259 uint32_t SPI_INTStat(SPI_TypeDef * SPIx, uint32_t it)
260 {
261 return (SPIx->IF & it) ? 1 : 0;
262 }
263