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