1 /******************************************************************************************************************************************
2 * 文件名称: SWM341_usbh.c
3 * 功能说明: SWM341单片机的USB主机功能驱动库
4 * 技术支持: http://www.synwit.com.cn/e/tool/gbook/?bid=1
5 * 注意事项:
6 * 版本日期: V1.1.0      2020年11月3日
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 <string.h>
22 #include "SWM341.h"
23 #include "SWM341_usbh.h"
24 
25 
26 static uint32_t Speed;
27 
28 
29 /******************************************************************************************************************************************
30 * 函数名称: USBH_HW_Init()
31 * 功能说明: USB Host Hardware 初始化
32 * 输    入: 无
33 * 输    出: 无
34 * 注意事项: 无
35 ******************************************************************************************************************************************/
USBH_HW_Init(void)36 void USBH_HW_Init(void)
37 {
38     SYS->USBCR = 0;
39     for(int i = 0; i < CyclesPerUs; i++) __NOP();
40     SYS->USBCR |= (1 << SYS_USBCR_RST48M_Pos); __DSB();
41     SYS->USBCR |= (1 << SYS_USBCR_RST12M_Pos); __DSB();
42     SYS->USBCR |= (1 << SYS_USBCR_RSTPLL_Pos); __DSB();
43     for(int i = 0; i < CyclesPerUs; i++) __NOP();
44 
45     SYS->USBCR &= ~SYS_USBCR_ROLE_Msk;
46     SYS->USBCR |= (2 << SYS_USBCR_ROLE_Pos);
47 
48     SYS->USBCR |= (1 << SYS_USBCR_VBUS_Pos);
49 
50     SYS->CLKEN0 |= (0x01 << SYS_CLKEN0_USB_Pos);
51 
52     USBH->CR = USBH_CR_FLUSHFF_Msk;
53 
54     USBD->DEVCR = (0 << USBD_DEVCR_DEVICE_Pos) |    // 主机模式
55                   (3 << USBD_DEVCR_SPEED_Pos)  |
56                   (1 << USBD_DEVCR_CSRDONE_Pos);
57 
58     USBH->PORTSR = USBH_PORTSR_POWER_Msk;
59 }
60 
61 
62 /******************************************************************************************************************************************
63 * 函数名称: USBH_ResetPort()
64 * 功能说明: 复位端口
65 * 输    入: 无
66 * 输    出: 无
67 * 注意事项: 无
68 ******************************************************************************************************************************************/
USBH_ResetPort(void)69 void USBH_ResetPort(void)
70 {
71     USBH->PORTSR = USBH_PORTSR_RESET_Msk;
72 }
73 
74 
75 /******************************************************************************************************************************************
76 * 函数名称: USBH_IsDeviceConnected()
77 * 功能说明: 是否有设备连接到端口
78 * 输    入: 无
79 * 输    出: 无
80 * 注意事项: 无
81 ******************************************************************************************************************************************/
USBH_IsDeviceConnected(void)82 uint32_t USBH_IsDeviceConnected(void)
83 {
84     return (USBH->PORTSR & USBH_PORTSR_CONN_Msk) ? 1 : 0;
85 }
86 
87 
88 /******************************************************************************************************************************************
89 * 函数名称: USBH_IsPortEnabled()
90 * 功能说明: 端口是否使能
91 * 输    入: 无
92 * 输    出: 无
93 * 注意事项: 无
94 ******************************************************************************************************************************************/
USBH_IsPortEnabled(void)95 uint32_t USBH_IsPortEnabled(void)
96 {
97     return (USBH->PORTSR & USBH_PORTSR_ENA_Msk) ? 1 : 0;
98 }
99 
100 
101 /******************************************************************************************************************************************
102 * 函数名称: USBH_GetDeviceSpeed()
103 * 功能说明: 设备速度
104 * 输    入: 无
105 * 输    出: uint32_t          2 低速   3 全速
106 * 注意事项: 无
107 ******************************************************************************************************************************************/
USBH_GetDeviceSpeed(void)108 uint32_t USBH_GetDeviceSpeed(void)
109 {
110     Speed = (USBH->PORTSR & USBH_PORTSR_SPEED_Msk) ? 2 : 3;
111 
112     return Speed;
113 }
114 
115 
116 /******************************************************************************************************************************************
117 * 函数名称: USBH_State()
118 * 功能说明:
119 * 输    入: 无
120 * 输    出: 无
121 * 注意事项: 无
122 ******************************************************************************************************************************************/
USBH_State(void)123 USBH_Resp USBH_State(void)
124 {
125     if(USBH->IF & USBH_IF_RXSTAT_Msk)
126     {
127         USBH->IF = USBH_IF_RXSTAT_Msk;
128 
129         switch(USBH->SR & USBH_SR_RESP_Msk)
130         {
131         case USBR_ACK:
132         case USBR_NAK:
133         case USBR_STALL:
134             return (USBH->SR & USBH_SR_RESP_Msk);
135 
136         case USBR_ERR_PID:
137         case USBR_ERR_CRC:
138         case USBR_ERR_STUFF:
139         case USBR_ERR_TOGGLE:
140         case USBR_TIMEOUT:
141         case USBR_UNEXPECTED_PID:
142             return USBR_ERROR;
143         }
144     }
145 
146     return USBR_NO;
147 }
148 
149 
150 /******************************************************************************************************************************************
151 * 函数名称: USBH_SendSetupPacket()
152 * 功能说明: 发送 Setup 包
153 * 输    入: 无
154 * 输    出: 无
155 * 注意事项: 无
156 ******************************************************************************************************************************************/
USBH_SendSetupPacket(uint8_t addr,uint8_t * data,uint16_t size)157 uint32_t USBH_SendSetupPacket(uint8_t addr, uint8_t *data, uint16_t size)
158 {
159     uint32_t res;
160 
161     __disable_irq();
162 
163     if((USBH->FRAMERM < 10000) && (USBH->FRAMERM > 2000))
164     {
165         USBH->TXTRSZ = size;
166         for(uint32_t i = 0; i < size; i++)
167         {
168             ((uint8_t *)USBH->TXBUF)[i] = data[i];
169         }
170 
171         USBH->TOKEN = (addr  << USBH_TOKEN_ADDR_Pos)  |
172                       (0     << USBH_TOKEN_EPNR_Pos)  |
173                       (13    << USBH_TOKEN_TYPE_Pos)  |
174                       (0     << USBH_TOKEN_DATAX_Pos) |
175                       (Speed << USBH_TOKEN_SPEED_Pos) |
176                       (size  << USBH_TOKEN_TRSZ_Pos);
177 
178         res = 1;
179     }
180     else
181     {
182         res = 0;
183     }
184 
185     __enable_irq();
186 
187     return res;
188 }
189 
190 
191 /******************************************************************************************************************************************
192 * 函数名称: USBH_SendOutPacket()
193 * 功能说明: 发送 Out 包
194 * 输    入: 无
195 * 输    出: 无
196 * 注意事项: 无
197 ******************************************************************************************************************************************/
USBH_SendOutPacket(uint8_t addr,uint8_t endp,uint8_t DATAx,uint8_t * data,uint16_t size)198 uint32_t USBH_SendOutPacket(uint8_t addr, uint8_t endp, uint8_t DATAx, uint8_t *data, uint16_t size)
199 {
200     uint32_t res;
201 
202     __disable_irq();
203 
204     if((USBH->FRAMERM < 10000) && (USBH->FRAMERM > 2000))
205     {
206         USBH->TXTRSZ = size;
207         for(uint32_t i = 0; i < size; i++)
208         {
209             ((uint8_t *)USBH->TXBUF)[i] = data[i];
210         }
211 
212         USBH->TOKEN = (addr  << USBH_TOKEN_ADDR_Pos)  |
213                       (endp  << USBH_TOKEN_EPNR_Pos)  |
214                       (1     << USBH_TOKEN_TYPE_Pos)  |
215                       (DATAx << USBH_TOKEN_DATAX_Pos) |
216                       (Speed << USBH_TOKEN_SPEED_Pos) |
217                       (size  << USBH_TOKEN_TRSZ_Pos);
218 
219         res = 1;
220     }
221     else
222     {
223         res = 0;
224     }
225 
226     __enable_irq();
227 
228     return res;
229 }
230 
231 
232 /******************************************************************************************************************************************
233 * 函数名称: USBH_SendInPacket()
234 * 功能说明: 发送 In 包
235 * 输    入: 无
236 * 输    出: 无
237 * 注意事项: 无
238 ******************************************************************************************************************************************/
USBH_SendInPacket(uint8_t addr,uint8_t endp,uint8_t DATAx,uint16_t size)239 uint32_t USBH_SendInPacket(uint8_t addr, uint8_t endp, uint8_t DATAx, uint16_t size)
240 {
241     uint32_t res;
242 
243     __disable_irq();
244 
245     if((USBH->FRAMERM < 10000) && (USBH->FRAMERM > 2000))
246     {
247         endp &= 0x0F;
248 
249         USBH->TOKEN = (addr  << USBH_TOKEN_ADDR_Pos)  |
250                       (endp  << USBH_TOKEN_EPNR_Pos)  |
251                       (9     << USBH_TOKEN_TYPE_Pos)  |
252                       (DATAx << USBH_TOKEN_DATAX_Pos) |
253                       (Speed << USBH_TOKEN_SPEED_Pos) |
254                       (size  << USBH_TOKEN_TRSZ_Pos);
255 
256         res = 1;
257     }
258     else
259     {
260         res = 0;
261     }
262 
263     __enable_irq();
264 
265     return res;
266 }
267 
268 
269 /******************************************************************************************************************************************
270 * 函数名称: USBH_ReadRxBuffer()
271 * 功能说明: 读取接收到的数据
272 * 输    入: 无
273 * 输    出: 无
274 * 注意事项: 无
275 ******************************************************************************************************************************************/
USBH_ReadRxBuffer(uint8_t * buff,uint32_t size)276 uint32_t USBH_ReadRxBuffer(uint8_t *buff, uint32_t size)
277 {
278     uint32_t real_size = (USBH->SR & USBH_SR_TRSZ_Msk) >> USBH_SR_TRSZ_Pos;
279 
280     if(size > real_size)
281         size = real_size;
282 
283     USBD_memcpy(buff, (uint8_t *)USBH->RXBUF, size);
284 
285     return size;
286 }
287 
288