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