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