• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  * Copyright (c) 2022 Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK")
3  * All rights reserved.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *****************************************************************************/
18 /**	@page USBHW
19  *
20  *	Introduction
21  *	===============
22  *	USB hard ware .
23  *
24  *	API Reference
25  *	===============
26  *	Header File: usbhw.h
27  */
28 
29 #pragma once
30 
31 #include "analog.h"
32 #include "gpio.h"
33 #include "reg_include/register_b91.h"
34 
35 typedef enum {
36     USB_IRQ_RESET_MASK = BIT(0),
37     USB_IRQ_250US_MASK = BIT(1),
38     USB_IRQ_SUSPEND_MASK = BIT(2),
39 } usb_irq_mask_e;
40 
41 typedef enum {
42     USB_IRQ_RESET_STATUS = BIT(5),
43     USB_IRQ_250US_STATUS = BIT(6),
44     USB_IRQ_SUSPEND_STATUS = BIT(7),
45 } usb_irq_status_e;
46 
47 /**
48  * @brief     This function servers to set ed8 to fifo mode.
49  * @return    none.
50  */
usbhw_set_ep8_fifo_mode(void)51 static inline void usbhw_set_ep8_fifo_mode(void)
52 {
53     BM_SET(reg_usb_ep8_fifo_mode, FLD_USB_ENP8_FIFO_MODE);
54 }
55 
56 /**
57  * @brief     This function servers to reset the pointer of control Endpoint.
58  * @return    none.
59  */
usbhw_reset_ctrl_ep_ptr(void)60 static inline void usbhw_reset_ctrl_ep_ptr(void)
61 {
62     reg_ctrl_ep_ptr = 0;
63 }
64 
65 /**
66  * @brief     This function servers to get the irq status of control Endpoint.
67  * @return    none.
68  */
usbhw_get_ctrl_ep_irq(void)69 static inline unsigned int usbhw_get_ctrl_ep_irq(void)
70 {
71     return reg_ctrl_ep_irq_sta;
72 }
73 
74 /**
75  * @brief     This function servers to clear the irq status of control Endpoint.
76  * @param[in] ep - selected  the Endpoint
77  * @return    none.
78  */
usbhw_clr_ctrl_ep_irq(int ep)79 static inline void usbhw_clr_ctrl_ep_irq(int ep)
80 {
81 #ifdef WIN32
82     BM_CLR(reg_ctrl_ep_irq_sta, ep);
83 #else
84     reg_ctrl_ep_irq_sta = ep;
85 #endif
86 }
87 
88 /**
89  * @brief     This function servers to set the value of control Endpoint.
90  * @param[in] data - the value of control Endpoint
91  * @return    none.
92  */
usbhw_write_ctrl_ep_ctrl(unsigned char data)93 static inline void usbhw_write_ctrl_ep_ctrl(unsigned char data)
94 {
95     reg_ctrl_ep_ctrl = data;
96 }
97 
98 /**
99  * @brief     This function servers to read the data of control Endpoint.
100  * @return    the value of control Endpoint data
101  */
usbhw_read_ctrl_ep_data(void)102 static inline unsigned char usbhw_read_ctrl_ep_data(void)
103 {
104     return reg_ctrl_ep_dat;
105 }
106 
107 /**
108  * @brief     This function servers to write the data of control Endpoint.
109  * @param[in] data -  the data of control Endpoint to write
110  * @return    none
111  */
usbhw_write_ctrl_ep_data(unsigned char data)112 static inline void usbhw_write_ctrl_ep_data(unsigned char data)
113 {
114     reg_ctrl_ep_dat = data;
115 }
116 
117 /**
118  * @brief     This function servers to determine whether control Endpoint is busy.
119  * @return    1: busy; 0: not busy.
120  */
usbhw_is_ctrl_ep_busy(void)121 static inline int usbhw_is_ctrl_ep_busy(void)
122 {
123     return reg_ctrl_ep_irq_sta & FLD_USB_EP_BUSY;
124 }
125 
126 /**
127  * @brief     This function servers to reset the pointer of Endpoint.
128  * @param[in] ep - select the Endpoint
129  * @return    none.
130  */
usbhw_reset_ep_ptr(unsigned int ep)131 static inline void usbhw_reset_ep_ptr(unsigned int ep)
132 {
133     reg_usb_ep_ptr(ep) = 0;
134 }
135 
136 /**
137  * @brief     This function servers to set the irq mask of Endpoint.
138  * @return    none.
139  */
usbhw_set_eps_irq_mask(usb_ep_irq_e mask)140 static inline void usbhw_set_eps_irq_mask(usb_ep_irq_e mask)
141 {
142     reg_usb_ep_irq_mask |= mask;
143 }
144 
145 /**
146  * @brief     This function servers to clr the irq mask of Endpoint.
147  * @return    none.
148  */
usbhw_clr_eps_irq_mask(usb_ep_irq_e mask)149 static inline void usbhw_clr_eps_irq_mask(usb_ep_irq_e mask)
150 {
151     reg_usb_ep_irq_mask &= (~mask);
152 }
153 
154 /**
155  * @brief     This function servers to get the irq status of Endpoint.
156  * @return    none.
157  */
usbhw_get_eps_irq(void)158 static inline unsigned int usbhw_get_eps_irq(void)
159 {
160     return reg_usb_ep_irq_status;
161 }
162 
163 /**
164  * @brief     This function servers to clear the irq status of Endpoint.
165  * @param[in] ep - selected  the Endpoint
166  * @return    none.
167  */
usbhw_clr_eps_irq(int ep)168 static inline void usbhw_clr_eps_irq(int ep)
169 {
170     reg_usb_ep_irq_status = ep;
171 }
172 
173 /**
174  * @brief     This function servers to set usb irq mask.
175  * @param[in]  mask -the  irq mask of usb.
176  * @return    none.
177  */
usbhw_set_irq_mask(usb_irq_mask_e mask)178 static inline void usbhw_set_irq_mask(usb_irq_mask_e mask)
179 {
180     reg_usb_irq_mask |= mask;
181 }
182 
183 /**
184  * @brief     This function servers to clr usb irq mask.
185  * @param[in]  mask -the  irq mask of usb.
186  * @return    none.
187  */
usbhw_clr_irq_mask(usb_irq_mask_e mask)188 static inline void usbhw_clr_irq_mask(usb_irq_mask_e mask)
189 {
190     reg_usb_irq_mask &= (~mask);
191 }
192 
193 /**
194  * @brief     This function servers to get usb irq status.
195  * @param[in]  status -the  irq status of usb.
196  * @return    the status of irq.
197  */
usbhw_get_irq_status(usb_irq_status_e status)198 static inline unsigned char usbhw_get_irq_status(usb_irq_status_e status)
199 {
200     return reg_usb_irq_mask & status;
201 }
202 
203 /**
204  * @brief     This function servers to clr usb irq status.
205  * @param[in]  status -the  irq status of usb.
206  * @return    none.
207  */
usbhw_clr_irq_status(usb_irq_status_e status)208 static inline void usbhw_clr_irq_status(usb_irq_status_e status)
209 {
210     reg_usb_irq_mask |= status;
211 }
212 
213 /**
214  * @brief     This function servers to enable Endpoint.
215  * @param[in] ep - selected  the Endpoint
216  * @return    none.
217  */
usbhw_set_eps_en(usb_ep_en_e ep)218 static inline void usbhw_set_eps_en(usb_ep_en_e ep)
219 {
220     reg_usb_edp_en = ep;
221 }
222 
223 /**
224  * @brief     This function servers to enable Endpoint.
225  * @param[in] ep - selected  the Endpoint
226  * @return    none.
227  */
usbhw_set_eps_dis(usb_ep_en_e ep)228 static inline void usbhw_set_eps_dis(usb_ep_en_e ep)
229 {
230     reg_usb_edp_en &= (~ep);
231 }
232 
233 /**
234  * @brief     This function servers to read the data of Endpoint.
235  * @param[in] ep - selected the Endpoint
236  * @return    the value of Endpoint
237  */
usbhw_read_ep_data(unsigned int ep)238 static inline unsigned char usbhw_read_ep_data(unsigned int ep)
239 {
240     return reg_usb_ep_dat(ep);
241 }
242 
243 /**
244  * @brief     This function servers to write the data of Endpoint.
245  * @param[in] ep   -  selected the Endpoint
246  * @param[in] data -  the value of Endpoint
247  * @return    none
248  */
usbhw_write_ep_data(unsigned int ep,unsigned char data)249 static inline void usbhw_write_ep_data(unsigned int ep, unsigned char data)
250 {
251     reg_usb_ep_dat(ep) = data;
252 }
253 
254 /**
255  * @brief     This function servers to enable the specified Endpoint.
256  * @param[in] ep -  selected the Endpoint
257  * @param[in] en -  1:enable,0:disable
258  * @return    none
259  */
usbhw_set_ep_en(unsigned int ep,unsigned char en)260 static inline void usbhw_set_ep_en(unsigned int ep, unsigned char en)
261 {
262     if (en) {
263         reg_usb_edp_en |= ep;
264     } else {
265         reg_usb_edp_en &= ~(ep);
266     }
267 }
268 
269 /**
270  * @brief     This function servers to determine whether Endpoint is busy.
271  * @param[in] ep -  selected the Endpoint
272  * @return    1: busy; 0: not busy.
273  */
usbhw_is_ep_busy(unsigned int ep)274 static inline unsigned int usbhw_is_ep_busy(unsigned int ep)
275 {
276     return reg_usb_ep_ctrl(ep) & FLD_USB_EP_BUSY;
277 }
278 
279 /**
280  * @brief     This function servers to set the specified data EndPoint to ack.
281  * @param[in] ep -  select the data EndPoint.
282  * @return    none.
283  */
usbhw_data_ep_ack(unsigned int ep)284 static inline void usbhw_data_ep_ack(unsigned int ep)
285 {
286     reg_usb_ep_ctrl(ep) = FLD_USB_EP_BUSY;
287 }
288 
289 /**
290  * @brief     This function servers to set the specified data EndPoint to stall.
291  * @param[in] ep -  select the data EndPoint.
292  * @return    none.
293  */
usbhw_data_ep_stall(unsigned int ep)294 static inline void usbhw_data_ep_stall(unsigned int ep)
295 {
296     reg_usb_ep_ctrl(ep) = FLD_USB_EP_STALL;
297 }
298 
299 /**
300  * @brief     This function servers to set the threshold of printer.
301  * @param[in] th - set the threshold for printer
302  * @return    none.
303  */
usbhw_set_printer_threshold(unsigned char th)304 static inline void usbhw_set_printer_threshold(unsigned char th)
305 {
306     reg_usb_ep8_send_thre = th;
307 }
308 
309 enum {
310     USB_EDP_PRINTER_IN = 8,              // default hw buf len = 64
311     USB_EDP_MOUSE = 2,                   // default hw buf len = 8
312     USB_EDP_KEYBOARD_IN = 1,             // default hw buf len = 8
313     USB_EDP_IN = 3,                      // default hw buf len = 16
314     USB_EDP_AUDIO_IN = 4,                // default hw buf len = 64
315     USB_EDP_PRINTER_OUT = 5,             // default hw buf len = 64
316     USB_EDP_SPEAKER = 6,                 // default hw buf len = 16
317     USB_EDP_MIC = 7,                     // default hw buf len = 16
318     USB_EDP_MS_IN = USB_EDP_PRINTER_IN,  // mass storage
319     USB_EDP_MS_OUT = USB_EDP_PRINTER_OUT,
320     USB_EDP_SOMATIC_IN = USB_EDP_AUDIO_IN,  //  when USB_SOMATIC_ENABLE, USB_EDP_PRINTER_OUT disable
321     USB_EDP_SOMATIC_OUT = USB_EDP_PRINTER_OUT,
322     USB_EDP_CDC_IN = 4,
323     USB_EDP_CDC_OUT = 5,
324 };
325 
326 // #defined in the standard spec
327 enum {
328     USB_HID_AUDIO = 2,
329     USB_HID_MOUSE = 1,
330     USB_HID_KB_MEDIA = 3,  // media
331     USB_HID_KB_SYS = 4,    // system : power,sleep,wakeup
332     USB_HID_SOMATIC = 5,   // somatic sensor,  may have many report ids
333 };
334 
335 /**
336  * @brief      This function disables the manual interrupt
337  *             (Endpont8 is the alias of endpoint0)
338  * @param[in]  m - the irq mode needs to set
339  * @return     none
340  */
341 void usbhw_disable_manual_interrupt(int m);
342 
343 /**
344  * @brief      This function enable the manual interrupt
345  * @param[in]  m - the irq mode needs to set
346  * @return     none
347  */
348 void usbhw_enable_manual_interrupt(int m);
349 
350 /**
351  * @brief      This function sends a bulk of data to host via the specified endpoint
352  * @param[in]  ep - the number of the endpoint
353  * @param[in]  data - pointer to the data need to send
354  * @param[in]  len - length in byte of the data need to send
355  * @return     none
356  */
357 void usbhw_write_ep(unsigned int ep, unsigned char *data, int len);
358 
359 /**
360  * @brief      This function sends two bytes data to host via the control endpoint
361  *             (handy help function)
362  * @param[in]  v - the two bytes data need to send
363  * @return     none
364  */
365 void usbhw_write_ctrl_ep_u16(unsigned short v);
366 
367 /**
368  * @brief   This function reads two bytes data from host via the control endpoint
369  * @return  the two bytes data read from the control endpoint
370  */
371 unsigned short usbhw_read_ctrl_ep_u16(void);
372 
373 /**
374  * @brief      This function enables or disables the internal pull-up resistor of DP pin of USB interface
375  * @param[in]  en - enables or disables the internal pull-up resistor(1: enable 0: disable)
376  * @return     none
377  */
usb_dp_pullup_en(int en)378 static inline void usb_dp_pullup_en(int en)
379 {
380     unsigned char dat = analog_read_reg8(0x0b);
381     if (en) {
382         dat = dat | BIT(7);
383     } else {
384         dat = dat & 0x7f;
385     }
386 
387     analog_write_reg8(0x0b, dat);
388 }
389 
390 /**
391  * @brief      This function serves to power on or down USB module
392  * @param[in]  en - 1: power on 0: power down
393  * @return     none
394  */
usb_power_on(unsigned char en)395 static inline void usb_power_on(unsigned char en)
396 {
397     if (en) {
398         analog_write_reg8(0x7d, analog_read_reg8(0x7d) & 0xfd);
399     } else {
400         analog_write_reg8(0x7d, analog_read_reg8(0x7d) | 0x02);
401     }
402 }
403 
404 /**
405  * @brief      This function serves to set GPIO MUX function as DP and DM pin of USB
406  * @return     none.
407  */
usb_set_pin_en(void)408 static inline void usb_set_pin_en(void)
409 {
410     reg_gpio_func_mux(GPIO_PA5) = reg_gpio_func_mux(GPIO_PA5) & (~BIT_RNG(2, 3));
411     gpio_function_dis(GPIO_PA5);
412     reg_gpio_func_mux(GPIO_PA6) = reg_gpio_func_mux(GPIO_PA6) & (~BIT_RNG(4, 5));
413     gpio_function_dis(GPIO_PA6);
414     gpio_input_en(GPIO_PA5 | GPIO_PA6);  // DP/DM must set input enable
415     usb_dp_pullup_en(1);
416 }
417