1 /*******************************************************************************
2  * Copyright 2019-2020 Microchip FPGA Embedded Systems Solutions.
3  *
4  * SPDX-License-Identifier: MIT
5  *
6  * PolarFire SoC MSS USB Driver Stack
7  *      USB Core Interface Layer (USB-CIFL)
8  *          USBH-CIF driver
9  *
10  * USBH-CIF driver public API.
11  *
12  */
13 
14 #ifndef __MSS_USB_HOST_CIF_H_
15 #define __MSS_USB_HOST_CIF_H_
16 
17 #include "mss_usb_common_cif.h"
18 #include "mss_usb_core_regs.h"
19 
20 #ifdef __cplusplus
21 extern "C" {
22 #endif
23 
24 #ifdef MSS_USB_HOST_ENABLED
25 
26 /*-------------------------------------------------------------------------*//**
27   Constant values which can be used by class component or the application.
28  */
29 #define USB_HS_BULK_MAX_PKT_SIZE                    512u
30 #define USB_HS_INTERRUPT_MAX_PKT_SIZE               1024u
31 #define USB_HS_ISO_MAX_PKT_SIZE                     1024u
32 
33 #define USB_FS_BULK_MAX_PKT_SIZE                    64u
34 #define USB_FS_INTERRUPT_MAX_PKT_SIZE               64u
35 #define USB_FS_ISO_MAX_PKT_SIZE                     1023u
36 
37 typedef struct {
38     void(*usbh_tx_complete)(uint8_t ep_num, uint8_t status);
39     void(*usbh_rx)(uint8_t ep_num, uint8_t status);
40     void(*usbh_cep)(uint8_t status);
41     void(*usbh_sof)(uint32_t frame_number);
42     void(*usbh_connect)(mss_usb_device_speed_t target_speed,
43                         mss_usb_vbus_level_t vbus_level);
44 
45     void(*usbh_disconnect)(void);
46     void(*usbh_vbus_error)(mss_usb_vbus_level_t);
47     void(*usbh_babble_error)(void);
48     void(*usbh_session_request)(void);
49     void(*usbh_dma_handler)(mss_usb_ep_num_t ep_num, mss_usb_dma_dir_t dma_dir,
50                             uint8_t status, uint32_t dma_addr_val);
51 } mss_usbh_cb_t;
52 
53 /*--------------------------------Public APIs---------------------------------*/
54 
55 /*-------------------------------------------------------------------------*//**
56   MSS_USBH_CIF_init()
57 
58   @param
59 
60   @return
61 
62   Example:
63   @code
64   @endcode
65 */
66 void
67 MSS_USBH_CIF_init
68 (
69     void
70 );
71 
72 /*-------------------------------------------------------------------------*//**
73   MSS_USBH_CIF_handle_connect_irq()
74 
75   @param
76 
77   @return
78 
79   Example:
80   @code
81   @endcode
82 */
83 void
84 MSS_USBH_CIF_handle_connect_irq
85 (
86     void
87 );
88 
89 /*-------------------------------------------------------------------------*//**
90   MSS_USBH_CIF_cep_configure()
91 
92   @param
93 
94   @return
95 
96   Example:
97   @code
98   @endcode
99 */
100 void
101 MSS_USBH_CIF_cep_configure
102 (
103     mss_usb_ep_t* cep
104 );
105 
106 /*-------------------------------------------------------------------------*//**
107   MSS_USBH_CIF_tx_ep_configure()
108 
109   @param
110 
111   @return
112 
113   Example:
114   @code
115   @endcode
116 */
117 void
118 MSS_USBH_CIF_tx_ep_configure
119 (
120     mss_usb_ep_t* host_ep
121 );
122 
123 /*-------------------------------------------------------------------------*//**
124   MSS_USBH_CIF_rx_ep_configure()
125 
126   @param
127 
128   @return
129 
130   Example:
131   @code
132   @endcode
133 */
134 void
135 MSS_USBH_CIF_rx_ep_configure
136 (
137     mss_usb_ep_t* host_ep
138 );
139 
140 /*-------------------------------------------------------------------------*//**
141   MSS_USBH_CIF_bus_suspend()
142 
143   @param
144 
145   @return
146 
147   Example:
148   @code
149   @endcode
150 */
151 void
152 MSS_USBH_CIF_bus_suspend
153 (
154     uint32_t enable_suspendm
155 );
156 
157 /*-------------------------------------------------------------------------*//**
158   MSS_USBH_CIF_bus_resume()
159 
160   @param
161 
162   @return
163 
164   Example:
165   @code
166   @endcode
167 */
168 void
169 MSS_USBH_CIF_bus_resume
170 (
171     void
172 );
173 
174 /*-------------------------------------------------------------------------*//**
175   MSS_USBH_CIF_read_vbus_level()
176 
177   @param
178 
179   @return
180 
181   Example:
182   @code
183   @endcode
184 */
185 mss_usb_vbus_level_t
186 MSS_USBH_CIF_read_vbus_level
187 (
188     void
189 );
190 
191 /*-------------------------------------------------------------------------*//**
192   MSS_USBH_CIF_ep_tx_start()
193 
194   @param
195 
196   @return
197 
198   Example:
199   @code
200   @endcode
201 */
202 void
203 MSS_USBH_CIF_ep_tx_start
204 (
205     mss_usb_ep_t* host_ep
206 );
207 
208 /*-------------------------------------------------------------------------*//**
209   MSS_USBH_CIF_tx_ep_mp_configure()
210 
211   @param
212 
213   @return
214 
215   Example:
216   @code
217   @endcode
218 */
219 uint32_t
220 MSS_USBH_CIF_tx_ep_mp_configure
221 (
222     uint8_t outpipe_num,
223     uint8_t tdev_ep_num,
224     uint8_t tdev_addr,
225     uint8_t tdev_hub_addr,
226     uint8_t tdev_hub_port,
227     uint8_t tdev_hub_mtt,
228     mss_usb_device_speed_t speed,
229     uint32_t tdev_interval,
230     mss_usb_xfr_type_t xfr_type
231 );
232 
233 /*-------------------------------------------------------------------------*//**
234   MSS_USBH_CIF_rx_ep_mp_configure()
235 
236   @param
237 
238   @return
239 
240   Example:
241   @code
242   @endcode
243 */
244 uint32_t
245 MSS_USBH_CIF_rx_ep_mp_configure
246 (
247     uint8_t inpipe_num,
248     uint8_t tdev_ep_num,
249     uint8_t tdev_addr,
250     uint8_t tdev_hub_addr,
251     uint8_t tdev_hub_port,
252     uint8_t tdev_hub_mtt,
253     mss_usb_device_speed_t speed,
254     uint32_t tdev_interval,
255     mss_usb_xfr_type_t xfr_type
256 );
257 
258 /*-------------------------------------------------------------------------*//**
259   MSS_USBH_CIF_cep_write_pkt()
260 
261   @param
262 
263   @return
264 
265   Example:
266   @code
267   @endcode
268 */
269 void
270 MSS_USBH_CIF_cep_write_pkt
271 (
272     mss_usb_ep_t* cep
273 );
274 
275 /*-------------------------------------------------------------------------*//**
276   MSS_USBH_CIF_cep_start_xfr()
277 
278   @param
279 
280   @return
281 
282   Example:
283   @code
284   @endcode
285 */
286 void
287 MSS_USBH_CIF_cep_start_xfr
288 (
289     mss_usb_ep_state_t state
290 );
291 
292 /*-------------------------------------------------------------------------*//**
293   MSS_USBH_CIF_cep_abort_xfr()
294 
295   @param
296 
297   @return
298 
299   Example:
300   @code
301   @endcode
302 */
303 void
304 MSS_USBH_CIF_cep_abort_xfr
305 (
306     void
307 );
308 
309 /*-------------------------------------------------------------------------*//**
310   MSS_USBH_CIF_cep_read_pkt()
311 
312   @param
313 
314   @return
315 
316   Example:
317   @code
318   @endcode
319 */
320 void
321 MSS_USBH_CIF_cep_read_pkt
322 (
323     mss_usb_ep_t* hcep
324 );
325 
326 /*-------------------------------------------------------------------------*//**
327   Static __Inline functions
328  */
MSS_USBH_CIF_assert_bus_reset(void)329 static __INLINE void MSS_USBH_CIF_assert_bus_reset(void)
330 {
331     USB->POWER |= POWER_REG_BUS_RESET_SIGNAL_MASK;
332 }
333 
MSS_USBH_CIF_clr_bus_reset(void)334 static __INLINE void MSS_USBH_CIF_clr_bus_reset(void)
335 {
336     USB->POWER &= ~POWER_REG_BUS_RESET_SIGNAL_MASK;
337 }
338 
MSS_USBH_CIF_assert_bus_resume(void)339 static __INLINE void MSS_USBH_CIF_assert_bus_resume(void)
340 {
341     USB->POWER |= POWER_REG_RESUME_SIGNAL_MASK;
342     /*clear after min. 20ms*/
343 }
344 
MSS_USBH_CIF_clr_bus_resume(void)345 static __INLINE void MSS_USBH_CIF_clr_bus_resume(void)
346 {
347     USB->POWER &= ~POWER_REG_RESUME_SIGNAL_MASK;
348 }
349 
MSS_USBH_CIF_enable_suspendm_out(void)350 static __INLINE void MSS_USBH_CIF_enable_suspendm_out(void)
351 {
352     USB->POWER |= POWER_REG_ENABLE_SUSPENDM_MASK;
353 }
354 
MSS_USBH_CIF_disable_suspendm_out(void)355 static __INLINE void MSS_USBH_CIF_disable_suspendm_out(void)
356 {
357     USB->POWER &= ~POWER_REG_ENABLE_SUSPENDM_MASK;
358 }
359 
MSS_USBH_CIF_assert_suspend_bus(void)360 static __INLINE void MSS_USBH_CIF_assert_suspend_bus(void)
361 {
362     USB->POWER |= POWER_REG_SUSPEND_MODE_MASK;
363 }
364 
MSS_USBH_CIF_clr_suspend_bus(void)365 static __INLINE void MSS_USBH_CIF_clr_suspend_bus(void)
366 {
367     USB->POWER &= ~POWER_REG_SUSPEND_MODE_MASK;
368 }
369 
MSS_USBH_CIF_is_host_suspended(void)370 static __INLINE uint8_t MSS_USBH_CIF_is_host_suspended(void)
371 {
372     return (((USB->POWER & POWER_REG_SUSPEND_MODE_MASK) ? MSS_USB_BOOLEAN_TRUE
373                                                         : MSS_USB_BOOLEAN_FALSE));
374 }
375 
MSS_USBH_CIF_end_session(void)376 static __INLINE void MSS_USBH_CIF_end_session(void)
377 {
378     USB->DEV_CTRL &= ~DEV_CTRL_SESSION_MASK;
379 }
380 /*-------------------------------------------------------------------------*//**
381   DEVCTL register related APIs
382  */
MSS_USBH_CIF_is_target_ls(void)383 static __INLINE uint8_t MSS_USBH_CIF_is_target_ls(void)
384 {
385     return (((USB->DEV_CTRL & DEV_CTRL_LS_DEV_MASK) ? MSS_USB_BOOLEAN_TRUE
386                                                     : MSS_USB_BOOLEAN_FALSE));
387 }
388 
MSS_USBH_CIF_is_target_fs(void)389 static __INLINE uint8_t MSS_USBH_CIF_is_target_fs(void)
390 {
391     return (((USB->DEV_CTRL & DEV_CTRL_FS_DEV_MASK) ? MSS_USB_BOOLEAN_TRUE
392                                                     : MSS_USB_BOOLEAN_FALSE));
393 }
394 
MSS_USBH_CIF_is_hs_mode(void)395 static __INLINE uint8_t MSS_USBH_CIF_is_hs_mode(void)
396 {
397     return(((USB->POWER & POWER_REG_HS_MODE_MASK) ?
398                                 MSS_USB_BOOLEAN_TRUE : MSS_USB_BOOLEAN_FALSE));
399 }
400 
401 /*-------------------------------------------------------------------------*//**
402   CSR0L register related APIs
403  */
404 static __INLINE void
MSS_USBH_CIF_cep_clr_rxpktrdy(void)405 MSS_USBH_CIF_cep_clr_rxpktrdy(void)
406 {
407     USB->ENDPOINT[MSS_USB_CEP].TX_CSR &= ~CSR0L_HOST_RX_PKT_RDY_MASK;
408 }
409 
MSS_USBH_CIF_cep_set_request_in_pkt(void)410 static __INLINE void MSS_USBH_CIF_cep_set_request_in_pkt(void)
411 {
412     /* Cleared when RxPktRdy is cleared */
413     USB->ENDPOINT[MSS_USB_CEP].TX_CSR |= CSR0L_HOST_IN_PKT_REQ_MASK;
414 }
415 
MSS_USBH_CIF_cep_set_setuppktonly(void)416 static __INLINE void MSS_USBH_CIF_cep_set_setuppktonly(void)
417 {
418     USB->ENDPOINT[MSS_USB_CEP].TX_CSR |= (CSR0L_HOST_SETUP_PKT_MASK);
419 }
MSS_USBH_CIF_cep_set_setuppktrdy(void)420 static __INLINE void MSS_USBH_CIF_cep_set_setuppktrdy(void)
421 {
422     USB->ENDPOINT[MSS_USB_CEP].TX_CSR |= (CSR0L_HOST_SETUP_PKT_MASK |
423                                               CSR0L_HOST_TX_PKT_RDY_MASK);
424 }
425 
MSS_USBH_CIF_cep_set_statuspktrdy_after_out(void)426 static __INLINE void MSS_USBH_CIF_cep_set_statuspktrdy_after_out(void)
427 {
428     USB->ENDPOINT[MSS_USB_CEP].TX_CSR |= (CSR0L_HOST_STATUS_PKT_MASK |
429                                               CSR0L_HOST_IN_PKT_REQ_MASK);
430 }
431 
MSS_USBH_CIF_cep_set_statuspktrdy_after_in(void)432 static __INLINE void MSS_USBH_CIF_cep_set_statuspktrdy_after_in(void)
433 {
434     USB->ENDPOINT[MSS_USB_CEP].TX_CSR |= (CSR0L_HOST_STATUS_PKT_MASK |
435                                               CSR0L_HOST_TX_PKT_RDY_MASK);
436 }
437 
MSS_USBH_CIF_cep_clr_statusRxpktrdy(void)438 static __INLINE void MSS_USBH_CIF_cep_clr_statusRxpktrdy(void)
439 {
440     if(CSR0L_HOST_RX_PKT_RDY_MASK | USB->ENDPOINT[MSS_USB_CEP].TX_CSR)
441     {
442         USB->ENDPOINT[MSS_USB_CEP].TX_CSR &= ~(CSR0L_HOST_STATUS_PKT_MASK |
443                                                   CSR0L_HOST_RX_PKT_RDY_MASK);
444     }
445     else
446     {
447         USB->ENDPOINT[MSS_USB_CEP].TX_CSR &= ~(CSR0L_HOST_STATUS_PKT_MASK);
448     }
449 }
450 
MSS_USBH_CIF_cep_read_csr_reg(void)451 static __INLINE uint16_t MSS_USBH_CIF_cep_read_csr_reg(void)
452 {
453     return(USB->ENDPOINT[MSS_USB_CEP].TX_CSR);
454 }
455 
MSS_USBH_CIF_cep_set_txpktrdy(void)456 static __INLINE void MSS_USBH_CIF_cep_set_txpktrdy(void)
457 {
458     USB->ENDPOINT[MSS_USB_CEP].TX_CSR |= CSR0L_HOST_TX_PKT_RDY_MASK;
459 }
460 
461 static __INLINE void
MSS_USBH_CIF_cep_clr_data_tog(void)462 MSS_USBH_CIF_cep_clr_data_tog
463 (
464     void
465 )
466 {
467     USB->ENDPOINT[MSS_USB_CEP].TX_CSR &= ~CSR0H_HOST_DATA_TOG_MASK;
468 }
469 
470 static __INLINE void
MSS_USBH_CIF_cep_set_data_tog_we(void)471 MSS_USBH_CIF_cep_set_data_tog_we
472 (
473     void
474 )
475 {
476     USB->ENDPOINT[MSS_USB_CEP].TX_CSR &= ~CSR0H_HOST_DATA_TOG_WE_MASK;
477 }
478 
479 static __INLINE void
MSS_USBH_CIF_cep_clr_data_tog_we(void)480 MSS_USBH_CIF_cep_clr_data_tog_we
481 (
482     void
483 )
484 {
485     USB->ENDPOINT[MSS_USB_CEP].TX_CSR &= ~CSR0H_HOST_DATA_TOG_WE_MASK;
486 }
487 
488 static __INLINE void
MSS_USBH_CIF_cep_set_data_tog(void)489 MSS_USBH_CIF_cep_set_data_tog
490 (
491     void
492 )
493 {
494     USB->ENDPOINT[MSS_USB_CEP].TX_CSR |= CSR0H_HOST_DATA_TOG_MASK;
495 }
496 
497 /*-------------------------------------------------------------------------*//**
498   FIFOx register related APIs
499  */
MSS_USBH_CIF_load_tx_fifo(mss_usb_ep_num_t ep_num,void * in_data,uint32_t length)500 static __INLINE void MSS_USBH_CIF_load_tx_fifo(mss_usb_ep_num_t ep_num,
501                                                void * in_data,
502                                                uint32_t length)
503 {
504     uint32_t idx;
505     uint32_t* temp;
506     uint8_t* temp_8bit;
507 
508     uint16_t words = length / 4;
509     temp =in_data;
510     temp_8bit = in_data;
511 
512     for(idx = 0u; idx < words; ++idx)
513     {
514         USB->FIFO[ep_num].WORD.VALUE = (uint32_t)temp[idx];
515     }
516 
517     for(idx = (length - (length % 4)); idx < length; ++idx)
518     {
519         USB->FIFO[ep_num].BYTE.VALUE = (uint8_t)temp_8bit[idx];
520     }
521 }
522 
MSS_USBH_CIF_read_rx_fifo(mss_usb_ep_num_t ep_num,void * out_data,uint32_t length)523 static __INLINE void MSS_USBH_CIF_read_rx_fifo(mss_usb_ep_num_t ep_num,
524                                                void * out_data,
525                                                uint32_t length)
526 {
527     uint32_t idx;
528     uint32_t* temp;
529     uint8_t* temp_8bit;
530 
531     uint16_t words = length / 4;
532     temp = out_data;
533     temp_8bit = out_data;
534 
535     for(idx = 0u; idx < words; ++idx)
536     {
537         temp[idx] = USB->FIFO[ep_num].WORD.VALUE;
538     }
539 
540     for(idx = (length - (length % 4u)); idx < length; ++idx)
541     {
542         temp_8bit[idx] = USB->FIFO[ep_num].BYTE.VALUE;
543     }
544 }
545 
546 /*-------------------------------------------------------------------------*//**
547   TXFUNCADDR register related APIs
548  */
549 static __INLINE void
MSS_USBH_CIF_tx_ep_set_target_func_addr(mss_usb_ep_num_t ep_num,uint8_t addr)550 MSS_USBH_CIF_tx_ep_set_target_func_addr
551 (
552     mss_usb_ep_num_t ep_num,
553     uint8_t addr
554 )
555 {
556     /*
557      * Device number of the target - initially zero, then determined by
558      * enumeration process.
559      */
560     USB->TAR[ep_num].TX_FUNC_ADDR = (addr & 0x7Fu);
561 }
562 
563 /*-------------------------------------------------------------------------*//**
564   TYPE0 register related APIs
565  */
566 static __INLINE void
MSS_USBH_CIF_cep_set_type0_reg(mss_usb_device_speed_t speed)567 MSS_USBH_CIF_cep_set_type0_reg
568 (
569     mss_usb_device_speed_t speed
570 )
571 {
572     USB->ENDPOINT[MSS_USB_CEP].TX_TYPE = (speed << TYPE0_HOST_MP_TARGET_SPEED_SHIFT);
573 }
574 
575 static __INLINE mss_usb_device_speed_t
MSS_USBH_CIF_cep_get_type0_reg(void)576 MSS_USBH_CIF_cep_get_type0_reg
577 (
578     void
579 )
580 {
581     return ((mss_usb_device_speed_t)(USB->ENDPOINT[MSS_USB_CEP].TX_TYPE >>
582                                      TYPE0_HOST_MP_TARGET_SPEED_SHIFT));
583 }
584 
585 static __INLINE void
MSS_USBH_CIF_rx_ep_set_reqpkt(mss_usb_ep_num_t ep_num)586 MSS_USBH_CIF_rx_ep_set_reqpkt
587 (
588     mss_usb_ep_num_t ep_num
589 )
590 {
591     USB->ENDPOINT[ep_num].RX_CSR |= RXCSRL_HOST_EPN_IN_PKT_REQ_MASK;
592 }
593 
594 static __INLINE void
MSS_USBH_CIF_rx_ep_clr_reqpkt(mss_usb_ep_num_t ep_num)595 MSS_USBH_CIF_rx_ep_clr_reqpkt
596 (
597     mss_usb_ep_num_t ep_num
598 )
599 {
600     USB->ENDPOINT[ep_num].RX_CSR &= ~RXCSRL_HOST_EPN_IN_PKT_REQ_MASK;
601 }
602 
603 static __INLINE uint8_t
MSS_USBH_CIF_rx_ep_is_reqpkt(mss_usb_ep_num_t ep_num)604 MSS_USBH_CIF_rx_ep_is_reqpkt
605 (
606     mss_usb_ep_num_t ep_num
607 )
608 {
609     return((USB->ENDPOINT[ep_num].RX_CSR &RXCSRL_HOST_EPN_IN_PKT_REQ_MASK)? MSS_USB_BOOLEAN_TRUE : MSS_USB_BOOLEAN_FALSE);
610 }
611 #endif /* MSS_USB_HOST_ENABLED */
612 
613 #ifdef __cplusplus
614 }
615 #endif
616 
617 #endif  /* __MSS_USB_HOST_CIF_H_ */
618