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