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  *          USB-CIF driver
9  *
10  * USB-CIF driver implementation:
11  * This source file implements MSS USB Interrupt handler functions. This file
12  * also implements core interface function for the logical layer to control
13  * the MSS USB core. These interface functions are independent of the USB mode.
14  *
15  */
16 #include "mpfs_hal/mss_hal.h"
17 #include "mss_usb_common_cif.h"
18 #include "mss_usb_common_reg_io.h"
19 
20 #ifdef MSS_USB_HOST_ENABLED
21 #include "mss_usb_host_cif.h"
22 #include "mss_usb_host_reg_io.h"
23 #endif  /* MSS_USB_HOST_ENABLED */
24 
25 #ifdef __cplusplus
26 extern "C" {
27 #endif
28 
29 #ifdef MSS_USB_HOST_ENABLED
30 static uint8_t MSS_USB_CIF_host_rx_errchk(mss_usb_ep_num_t ep_num);
31 static uint8_t MSS_USB_CIF_host_tx_errchk(mss_usb_ep_num_t ep_num);
32 #endif  /* MSS_USB_HOST_ENABLED */
33 
34 #ifdef MSS_USB_DEVICE_ENABLED
35 static uint8_t MSS_USB_CIF_device_rx_errchk(mss_usb_ep_num_t ep_num);
36 static uint8_t MSS_USB_CIF_device_tx_errchk(mss_usb_ep_num_t ep_num);
37 #endif  /* MSS_USB_HOST_ENABLED */
38 
39 /***************************************************************************//**
40 * Global variables shared by mss_usb_device_cif.c and mss_usb_common_cif.c
41 */
42 #ifdef MSS_USB_DEVICE_ENABLED
43     extern mss_usbd_cb_t g_mss_usbd_cb;
44     extern volatile mss_usbd_cep_state_t cep_state;
45 #endif  /* MSS_USB_HOST_ENABLED */
46 
47 #ifdef MSS_USB_HOST_ENABLED
48     extern mss_usbh_cb_t g_mss_usbh_cb;
49 #endif /* MSS_USB_HOST_ENABLED */
50 
51 /***************************************************************************//**
52  * Private functions declarations of USB-CIF.
53  ******************************************************************************/
54 static void
55 MSS_USB_CIF_handle_cep_irq
56 (
57     void
58 );
59 
60 static void
61 MSS_USB_CIF_handle_tx_ep_irq
62 (
63     uint16_t irq_num
64 );
65 
66 static void
67 MSS_USB_CIF_handle_rx_ep_irq
68 (
69     uint16_t irq_num
70 );
71 
72 /***************************************************************************//**
73  * Main USB interrupt handler. It checks for TX/RX endpoint interrupts and USB
74  * system level interrupts and calls the appropriate routine.
75  */
usb_mc_plic_IRQHandler(void)76 uint8_t usb_mc_plic_IRQHandler
77 (
78     void
79 )
80 {
81     volatile uint8_t usb_irq;
82     volatile uint16_t tx_ep_irq;
83     volatile uint16_t rx_ep_irq;
84     volatile uint8_t role;
85 
86     usb_irq = MSS_USB_CIF_read_irq_reg();
87     tx_ep_irq = MSS_USB_CIF_read_tx_ep_irq_reg();
88     rx_ep_irq = MSS_USB_CIF_read_rx_ep_irq_reg();
89 
90     /*
91      When operating in Host mode, on detecting Disconnect event, Disconnect
92      Interrupt occurs but the HostMode bit in DevCtl is also cleared.
93      Hence moving Disconnect handling out of get_mode condition.
94      In the event of Disconnection, The decision is made based on the B-Device
95      bit(DevCtl-D7).
96      */
97     if (usb_irq & DISCONNECT_IRQ_MASK)
98     {
99         role = MSS_USB_CIF_get_role();
100 
101 #ifdef MSS_USB_DEVICE_ENABLED
102         if (MSS_USB_DEVICE_ROLE_DEVICE_B == role)
103         {
104             MSS_USB_CIF_enable_usbirq(RESET_IRQ_MASK);
105             g_mss_usbd_cb.usbd_disconnect();
106         }
107 #endif  /* MSS_USB_DEVICE_ENABLED */
108 
109 #ifdef MSS_USB_HOST_ENABLED
110         if (MSS_USB_DEVICE_ROLE_DEVICE_A == role)
111         {
112             /*In Host mode, On removing the attached B-device the session bit
113               somehow remains set.
114               This bit need to be cleared otherwise RESET interrupt is not occurring
115               when B-Device is connected after removing A-Device*/
116             if (MSS_USB_CIF_is_session_on())
117             {
118                 MSS_USB_CIF_stop_session();
119             }
120 
121             MSS_USBH_CIF_read_vbus_level();
122             g_mss_usbh_cb.usbh_disconnect();
123         }
124 #endif /* MSS_USB_HOST_ENABLED */
125     }
126 
127 #ifdef MSS_USB_DEVICE_ENABLED
128     if (MSS_USB_CORE_MODE_DEVICE == MSS_USB_CIF_get_mode())
129     {
130         if (usb_irq & RESUME_IRQ_MASK)
131         {
132             g_mss_usbd_cb.usbd_resume();
133         }
134         if (usb_irq & SUSPEND_IRQ_MASK)
135         {
136             g_mss_usbd_cb.usbd_suspend();
137         }
138         if (usb_irq & RESET_IRQ_MASK)
139         {
140             MSS_USB_CIF_set_index_reg(MSS_USB_CEP);
141             MSS_USB_CIF_enable_usbirq(DISCONNECT_IRQ_MASK | SUSPEND_IRQ_MASK);
142             cep_state = MSS_USB_CTRL_EP_IDLE;
143             MSS_USB_CIF_clr_usb_irq_reg();
144             MSS_USB_CIF_cep_clr_setupend();
145             MSS_USB_CIF_cep_clr_stall_sent();
146             g_mss_usbd_cb.usbd_reset();
147         }
148     }
149 #endif /* MSS_USB_DEVICE_ENABLED */
150 
151 #ifdef MSS_USB_HOST_ENABLED
152     if (MSS_USB_CORE_MODE_HOST == MSS_USB_CIF_get_mode())
153     {
154         role = MSS_USB_CIF_get_role();
155         if (usb_irq & RESUME_IRQ_MASK)
156         {
157             /* Resume interrupt in Host mode means Remote Wakeup request */
158         }
159 
160         /* Vbus_err and session request interrupts are valid only in A device */
161         if (MSS_USB_DEVICE_ROLE_DEVICE_A == role)
162         {
163             if (usb_irq & SESSION_REQUEST_IRQ_MASK)
164             {
165                 /* This means SRP initiated by Target device. */
166             }
167             if (usb_irq & VBUS_ERROR_IRQ_MASK)
168             {
169                 /* Power management */
170                 MSS_USBH_CIF_read_vbus_level();
171             }
172         }
173 
174         if (usb_irq & CONNECT_IRQ_MASK)
175         {
176             MSS_USBH_CIF_handle_connect_irq();
177         }
178 
179         if (usb_irq & BABBLE_IRQ_MASK)
180         {
181             /* Not supported yet */
182         }
183 
184 #if 0   /* SOF interrupt is not processed */
185         if (usb_irq & SOF_IRQ_MASK)
186         {
187             g_mss_usbd_cb.usb_device_sof(0);
188         }
189 #endif /* SOF interrupt is not processed */
190 
191     }
192 #endif    /* MSS_USB_HOST_ENABLED */
193 
194     if (tx_ep_irq & 0x0001u)
195     {
196         /* handle EP0 IRQ */
197         MSS_USB_CIF_handle_cep_irq();
198     }
199 
200     if (tx_ep_irq & 0xFFFEu)    /* EP0 is handled above */
201     {
202         /* Handle TX EP here, pass on the EP numbers.Mask EP0 bit */
203         tx_ep_irq &= 0xFFFEu;
204         MSS_USB_CIF_handle_tx_ep_irq(tx_ep_irq);
205     }
206 
207     if (rx_ep_irq & 0xFFFEu)    /* bit0 is not defined */
208     {
209         /* Handle RX EP here, pass on the EP numbers */
210         MSS_USB_CIF_handle_rx_ep_irq(rx_ep_irq);
211     }
212 
213     return EXT_IRQ_KEEP_ENABLED;
214 }
215 
216 /***************************************************************************//**
217  * Routine to handle the interrupt on Control Endpoint.(EP0)
218  */
219 static void
MSS_USB_CIF_handle_cep_irq(void)220 MSS_USB_CIF_handle_cep_irq
221 (
222     void
223 )
224 {
225     uint8_t status = 0u;
226 
227     MSS_USB_CIF_set_index_reg(MSS_USB_CEP);
228 
229 #ifdef MSS_USB_DEVICE_ENABLED
230     if (MSS_USB_CORE_MODE_DEVICE == MSS_USB_CIF_get_mode())
231     {
232         if (MSS_USB_CIF_cep_is_stall_sent())
233         {
234             status |= CTRL_EP_STALL_ERROR;
235             MSS_USB_CIF_cep_clr_stall_sent();
236             g_mss_usbd_cb.usbd_cep_setup(status);
237         }
238         else
239         {
240             if (MSS_USB_CIF_cep_is_setupend())
241             {
242                 MSS_USB_CIF_cep_clr_setupend();
243 
244                 if (!MSS_USB_CIF_cep_is_rxpktrdy())
245                 {
246                     status |= CTRL_EP_SETUP_END_ERROR;
247                 }
248                 else
249                 {
250                     status &= ~CTRL_EP_SETUP_END_ERROR;
251                 }
252 
253                 g_mss_usbd_cb.usbd_cep_setup(status);
254             }
255             else
256             {
257                 if (cep_state == MSS_USB_CTRL_EP_IDLE)
258                 {
259                     if (MSS_USB_CIF_cep_is_rxpktrdy())
260                     {
261                         g_mss_usbd_cb.usbd_cep_setup(status);
262                     }
263                 }
264                 else if (cep_state == MSS_USB_CTRL_EP_TX)
265                 {
266                     g_mss_usbd_cb.usbd_cep_tx_complete(status);
267                 }
268                 else if (cep_state == MSS_USB_CTRL_EP_RX)
269                 {
270                     if (MSS_USB_CIF_cep_is_rxpktrdy())
271                     {
272                         g_mss_usbd_cb.usbd_cep_rx(status);
273                     }
274                 }
275                 else
276                 {
277                     ASSERT(0);
278                 }
279             }
280         }
281     }
282 #endif  /* MSS_USB_DEVICE_ENABLED */
283 
284 #ifdef MSS_USB_HOST_ENABLED
285     if (MSS_USB_CORE_MODE_HOST == MSS_USB_CIF_get_mode())
286     {
287         if (MSS_USBH_CIF_cep_is_rxstall_err())
288         {
289             status |= MSS_USB_EP_STALL_RCVD;
290             MSS_USBH_CIF_cep_clr_rxstall_err();
291         }
292         if (MSS_USBH_CIF_cep_is_retry_err())
293         {
294             status |= MSS_USB_EP_NO_RESPONSE;
295             MSS_USBH_CIF_cep_clr_retry_err();
296         }
297         if (MSS_USBH_CIF_cep_is_naktimeout_err())
298         {
299             status |= MSS_USB_EP_NAK_TOUT;
300             MSS_USBH_CIF_cep_clr_naktimeout_err();
301         }
302         if (status == 0u)    /* No error was found */
303         {
304             status = MSS_USB_EP_TXN_SUCCESS;
305         }
306         g_mss_usbh_cb.usbh_cep(status);
307     }
308 #endif /* MSS_USB_HOST_ENABLED */
309 
310 }
311 
312 /***************************************************************************//**
313  * Routine to handle the interrupt on TX_EP
314  */
MSS_USB_CIF_handle_tx_ep_irq(uint16_t irq_num)315 static void MSS_USB_CIF_handle_tx_ep_irq
316 (
317     uint16_t irq_num
318 )
319 {
320     mss_usb_ep_num_t ep_num = MSS_USB_TX_EP_1;
321     uint8_t status = 0u;
322 
323     while (irq_num)
324     {
325         irq_num >>= 1u;                                  /*EP1 starts from D1*/
326 
327         if (irq_num & MSS_USB_WORD_BIT_0_MASK)
328         {
329             MSS_USB_CIF_tx_ep_disable_irq(ep_num);
330 #ifdef MSS_USB_DEVICE_ENABLED
331             if (MSS_USB_CORE_MODE_DEVICE == MSS_USB_CIF_get_mode())
332             {
333                 status = MSS_USB_CIF_device_tx_errchk(ep_num);
334                 g_mss_usbd_cb.usbd_ep_tx_complete(ep_num,status);
335             }
336 #endif  /* MSS_USB_DEVICE_ENABLED */
337 
338 #ifdef MSS_USB_HOST_ENABLED
339             if (MSS_USB_CORE_MODE_HOST == MSS_USB_CIF_get_mode())
340             {
341                 status = MSS_USB_CIF_host_tx_errchk(ep_num);
342                 g_mss_usbh_cb.usbh_tx_complete((uint8_t)ep_num, status);
343             }
344 #endif  /* MSS_USB_HOST_ENABLED */
345 
346             MSS_USB_CIF_tx_ep_enable_irq(ep_num);
347         }
348         status = 0u; /*resetting for next EP status*/
349         ++ep_num;
350     }
351 }
352 
353 /***************************************************************************//**
354  * Routine to handle the interrupt on RX EP
355  */
MSS_USB_CIF_handle_rx_ep_irq(uint16_t irq_num)356 static void MSS_USB_CIF_handle_rx_ep_irq
357 (
358     uint16_t irq_num
359 )
360 {
361     mss_usb_ep_num_t ep_num = MSS_USB_RX_EP_1;
362     uint8_t status = 0u;
363 
364     while (irq_num)
365     {
366         irq_num >>= 1u;  /*EP1 starts from D1*/
367 
368         if (irq_num & MSS_USB_WORD_BIT_0_MASK)
369         {
370             MSS_USB_CIF_rx_ep_disable_irq(ep_num);
371 #ifdef MSS_USB_DEVICE_ENABLED
372             if (MSS_USB_CORE_MODE_DEVICE == MSS_USB_CIF_get_mode())
373             {
374                 status = MSS_USB_CIF_device_rx_errchk(ep_num);
375                 g_mss_usbd_cb.usbd_ep_rx(ep_num, status);
376             }
377 #endif /* MSS_USB_DEVICE_ENABLED */
378 
379 #ifdef MSS_USB_HOST_ENABLED
380             if (MSS_USB_CORE_MODE_HOST == MSS_USB_CIF_get_mode())
381             {
382                 status = MSS_USB_CIF_host_rx_errchk(ep_num);
383                 g_mss_usbh_cb.usbh_rx((uint8_t)ep_num, status);
384             }
385 #endif /* MSS_USB_HOST_ENABLED */
386             MSS_USB_CIF_rx_ep_enable_irq(ep_num);
387         }
388         status = 0u; /*resetting for next EP status*/
389         ++ep_num;
390     }
391 }
392 
393 /***************************************************************************//**
394  * Handler for DMA interrupt. Checks for the DMA channel on which interrupt has
395  * Occurred and corresponding EP number then calls-back to upper layer to indicate
396  * the event.
397  */
usb_dma_plic_IRQHandler(void)398 uint8_t usb_dma_plic_IRQHandler(void)
399 {
400     mss_usb_dma_channel_t dma_channel= MSS_USB_DMA_CHANNEL1;
401     uint8_t status = 0;
402     mss_usb_dma_dir_t dma_dir;
403     mss_usb_ep_num_t ep_num;
404     uint8_t dma_irq;
405     uint32_t increamented_addr=0;
406 
407     dma_irq = MSS_USB_CIF_dma_read_irq();
408 
409     while (dma_irq)
410     {
411         if (dma_irq & MSS_USB_BYTE_BIT_0_MASK)
412         {
413             /* DMA Transfer for this channel is complete.Clear Start_transfer
414                bit
415              */
416             MSS_USB_CIF_dma_stop_xfr(dma_channel);
417 
418             ep_num = (mss_usb_ep_num_t)MSS_USB_CIF_dma_get_epnum(dma_channel);
419             dma_dir = (mss_usb_dma_dir_t)MSS_USB_CIF_dma_get_dir(dma_channel);
420 
421             if (MSS_USB_CIF_dma_is_bus_err(dma_channel))
422             {
423                 status |=DMA_XFR_ERROR;
424                 MSS_USB_CIF_dma_clr_bus_err(dma_channel);
425             }
426             else
427             {
428                 increamented_addr = MSS_USB_CIF_dma_read_addr(dma_channel);
429                 if (MSS_USB_DMA_READ == dma_dir)    /*TX EP*/
430                 {
431                     if (MSS_USB_CIF_tx_ep_is_dma_enabled(ep_num))
432                     {
433                         MSS_USB_CIF_tx_ep_disable_dma(ep_num);
434                     }
435                 }
436 #ifdef MSS_USB_HOST_ENABLED
437                 if (MSS_USB_CORE_MODE_HOST == MSS_USB_CIF_get_mode())
438                 {
439                     /* Call the host mode logical layer driver callback
440                        function
441                      */
442                     g_mss_usbh_cb.usbh_dma_handler(ep_num, dma_dir, status,
443                                                              increamented_addr);
444                 }
445 #endif /* MSS_USB_HOST_ENABLED */
446 #ifdef MSS_USB_DEVICE_ENABLED
447                 if (MSS_USB_CORE_MODE_DEVICE == MSS_USB_CIF_get_mode())
448                 {
449                     /* Call the device mode logical layer driver callback
450                        function
451                      */
452                     g_mss_usbd_cb.usbd_dma_handler(ep_num, dma_dir, status,
453                                                              increamented_addr);
454                 }
455 #endif /* MSS_USB_DEVICE_ENABLED */
456 
457             }
458         }
459         dma_channel++;
460         dma_irq >>= 1u;
461     }
462 
463     return EXT_IRQ_KEEP_ENABLED;
464 }
465 
466 /***************************************************************************//**
467  * Prepares the RX EP for receiving data as per parameters provided by upper layer
468  */
469 void
MSS_USB_CIF_rx_ep_read_prepare(mss_usb_ep_num_t ep_num,uint8_t * buf_addr,uint8_t dma_enable,mss_usb_dma_channel_t dma_channel,mss_usb_xfr_type_t xfr_type,uint32_t xfr_length)470 MSS_USB_CIF_rx_ep_read_prepare
471 (
472     mss_usb_ep_num_t ep_num,
473     uint8_t* buf_addr,
474     uint8_t dma_enable,
475     mss_usb_dma_channel_t dma_channel,
476     mss_usb_xfr_type_t xfr_type,
477     uint32_t xfr_length
478 )
479 {
480     /*
481      * Fixed Buffer overwriting issue found with printer driver and issue with
482      * interrupt transfer with DMA by moving the location of interrupt enable
483      * function.
484      */
485     if (DMA_ENABLE == dma_enable)
486     {
487         /* Make sure that address is Modulo-4.Bits D0-D1 are read only.*/
488         ASSERT(!(((uint32_t)buf_addr) & 0x00000002U));
489 
490         MSS_USB_CIF_dma_write_addr(dma_channel, (uint32_t)buf_addr);
491 
492         /*
493          * DMA Count register will be loaded after receive interrupt occurs.
494          * Mode need to be set every time since M1 to M0 transition might have
495          * happened for "short packet".
496          */
497          if (MSS_USB_XFR_BULK == xfr_type)
498         {
499             MSS_USB_CIF_rx_ep_set_dma_mode1(ep_num);
500             MSS_USB_CIF_rx_ep_set_autoclr(ep_num);
501             MSS_USB_CIF_rx_ep_enable_dma(ep_num);
502 
503             MSS_USB_CIF_dma_write_count(dma_channel,
504                                         xfr_length);
505 
506             /* Handling single NULL packet reception */
507             if (0u != xfr_length )
508             {
509                 MSS_USB_CIF_dma_start_xfr(dma_channel);
510             }
511         }
512         else
513         {
514             MSS_USB_CIF_rx_ep_clr_autoclr(ep_num);
515             MSS_USB_CIF_rx_ep_set_dma_mode0(ep_num);
516             MSS_USB_CIF_rx_ep_disable_dma(ep_num);
517         }
518     }
519 }
520 
521 /***************************************************************************//**
522  * Writes packet on TX EP
523  */
524 void
MSS_USB_CIF_ep_write_pkt(mss_usb_ep_num_t ep_num,uint8_t * buf_addr,uint8_t dma_enable,mss_usb_dma_channel_t dma_channel,mss_usb_xfr_type_t xfr_type,uint32_t xfr_length,uint32_t txn_length)525 MSS_USB_CIF_ep_write_pkt
526 (
527     mss_usb_ep_num_t ep_num,
528     uint8_t* buf_addr,
529     uint8_t dma_enable,
530     mss_usb_dma_channel_t dma_channel,
531     mss_usb_xfr_type_t xfr_type,
532     uint32_t xfr_length,
533     uint32_t txn_length
534 )
535 {
536     if (ep_num && (buf_addr != 0))
537     {
538         if (DMA_ENABLE == dma_enable)
539         {
540             /* Make sure that address is Modulo-4.Bits D0-D1 are read only.*/
541             ASSERT(!(((uint32_t)buf_addr) & 0x00000002u));
542 
543             MSS_USB_CIF_dma_write_addr(dma_channel,(uint32_t)(buf_addr));
544 
545             if (MSS_USB_XFR_BULK == xfr_type)
546             {
547                 MSS_USB_CIF_tx_ep_enable_dma(ep_num);
548 
549                  /*
550                   * DMA-m1 will take care of transferring 'xfr_length' data
551                   * as IN packets arrive.
552                   * DMA interrupt will occur when all TxMaxPkt size packets
553                   * are transferred.
554                   */
555                 MSS_USB_CIF_dma_write_count(dma_channel, xfr_length);
556             }
557             else
558             {
559                 /*
560                  * DMA Enable bit in TxCSR is not needed. If set,TX EP
561                  * Interrupt will not occur.
562                  */
563                 MSS_USB_CIF_tx_ep_disable_dma(ep_num);
564 
565                 /* Transfer only one packet with DMA-m0 */
566                 MSS_USB_CIF_dma_write_count(dma_channel, txn_length);
567            }
568 
569              /*
570               * This will start DMA transfer.
571               * TODO: For Null transfer DMA is not needed, but not setting
572               * TxPktRdy bit here, is not invoking EP interrupt.
573               * EP interrupt does get called when Null DMA transfer is done.
574               */
575             MSS_USB_CIF_dma_start_xfr(dma_channel);
576 
577 
578             /*
579              * DMA interrupt will occur when all bytes are written to FIFO
580              * TxPktRdy should be set when the DMA interrupt occurs.
581              */
582         }
583         else    /* no DMA */
584         {
585             MSS_USB_CIF_load_tx_fifo(ep_num,
586                                      buf_addr,
587                                      txn_length);
588             MSS_USB_CIF_tx_ep_set_txpktrdy(ep_num);
589         }
590     }
591 }
592 
593 /***************************************************************************//**
594  * Configures DMA for data transfer operations.
595  */
596 void
MSS_USB_CIF_configure_ep_dma(mss_usb_dma_channel_t dma_channel,mss_usb_dma_dir_t dma_dir,mss_usb_dma_mode_t dma_mode,mss_usb_dma_burst_mode_t burst_mode,mss_usb_ep_num_t ep_num,uint32_t buf_addr)597 MSS_USB_CIF_configure_ep_dma
598 (
599     mss_usb_dma_channel_t dma_channel,
600     mss_usb_dma_dir_t dma_dir,
601     mss_usb_dma_mode_t dma_mode,
602     mss_usb_dma_burst_mode_t burst_mode,
603     mss_usb_ep_num_t ep_num,
604     uint32_t buf_addr
605 )
606 {
607     MSS_USB_CIF_dma_assign_to_epnum(dma_channel, ep_num);
608     MSS_USB_CIF_dma_set_dir(dma_channel, dma_dir);
609     MSS_USB_CIF_dma_set_mode(dma_channel, dma_mode);
610     MSS_USB_CIF_dma_set_burst_mode(dma_channel, burst_mode);
611     MSS_USB_CIF_dma_write_addr(dma_channel, buf_addr);
612     MSS_USB_CIF_dma_enable_irq(dma_channel);
613 }
614 
615 /***************************************************************************//**
616  * Configures the TX EP for data transfer operations as per the parameters
617  * provided by upper layer.
618  */
619 void
MSS_USB_CIF_tx_ep_configure(mss_usb_ep_t * core_ep)620 MSS_USB_CIF_tx_ep_configure
621 
622 (
623     mss_usb_ep_t* core_ep
624 )
625 {
626     uint8_t dpb = 1u;
627     mss_usb_dma_mode_t mode;
628 
629     if (DPB_ENABLE == core_ep->dpb_enable)
630     {
631         dpb = 2u;
632     }
633 
634     MSS_USB_CIF_tx_ep_set_fifo_size(core_ep->num,
635                                     ((core_ep->fifo_size) / dpb),
636                                     core_ep->dpb_enable);
637 
638     MSS_USB_CIF_tx_ep_set_fifo_addr(core_ep->num, core_ep->fifo_addr);
639 
640     if (DPB_ENABLE == core_ep->dpb_enable)
641     {
642         MSS_USB_enable_tx_ep_dpb(core_ep->num);
643     }
644     else if (DPB_DISABLE == core_ep->dpb_enable)
645     {
646         MSS_USB_disable_tx_ep_dpb(core_ep->num);
647     }
648     else
649     {
650         ASSERT(0);
651     }
652 
653     MSS_USB_CIF_tx_ep_set_max_pkt(core_ep->num,
654                                   core_ep->xfr_type,
655                                   core_ep->max_pkt_size,
656                                   core_ep->num_usb_pkt);
657 
658     MSS_USB_CIF_tx_ep_clr_data_tog(core_ep->num);
659 
660     if (DMA_ENABLE == core_ep->dma_enable)
661     {
662         if (MSS_USB_XFR_BULK == core_ep->xfr_type )
663         {
664             MSS_USB_CIF_tx_ep_set_dma_mode1(core_ep->num);
665             MSS_USB_CIF_tx_ep_enable_dma(core_ep->num);
666             mode = MSS_USB_DMA_MODE1;
667         }
668         else
669         {
670             /*
671              * DMA_ENable bit in TXCSRL is not required to be set for m0. if it
672              * is set TX interrupt would not occur.
673              */
674             MSS_USB_CIF_tx_ep_set_dma_mode0(core_ep->num);
675             MSS_USB_CIF_tx_ep_disable_dma(core_ep->num);
676             mode = MSS_USB_DMA_MODE0;
677         }
678 
679         MSS_USB_CIF_configure_ep_dma(core_ep->dma_channel,
680                                      MSS_USB_DMA_READ,
681                                      mode,
682                                      MSS_USB_DMA_BURST_MODE3,
683                                      core_ep->num,
684                                      (uint32_t)(core_ep->buf_addr));
685     }
686 
687     MSS_USB_CIF_tx_ep_enable_irq(core_ep->num);
688 }
689 
690 /***************************************************************************//**
691  * Configures the RX EP for data transfer operations as per the parameters
692  * provided by upper layer.
693  */
694 void
MSS_USB_CIF_rx_ep_configure(mss_usb_ep_t * core_ep)695 MSS_USB_CIF_rx_ep_configure
696 
697 (
698     mss_usb_ep_t* core_ep
699 )
700 {
701     uint8_t dpb = 1u;
702     mss_usb_dma_mode_t mode;
703 
704     if (DPB_ENABLE == core_ep->dpb_enable)
705     {
706         dpb = 2u;
707     }
708 
709     MSS_USB_CIF_rx_ep_set_fifo_size(core_ep->num,
710                                     ((core_ep->fifo_size) / dpb),
711                                     core_ep->dpb_enable);
712 
713     MSS_USB_CIF_rx_ep_set_fifo_addr(core_ep->num,
714                                     core_ep->fifo_addr);
715 
716     if (DPB_ENABLE == core_ep->dpb_enable)
717     {
718         MSS_USB_CIF_enable_rx_ep_dpb(core_ep->num);
719     }
720     else if (DPB_DISABLE == core_ep->dpb_enable)
721     {
722         MSS_USB_CIF_disable_rx_ep_dpb(core_ep->num);
723     }
724     else
725     {
726         ASSERT(0);
727     }
728 
729     MSS_USB_CIF_rx_ep_set_max_pkt(core_ep->num,
730                                   core_ep->xfr_type,
731                                   core_ep->max_pkt_size,
732                                   core_ep->num_usb_pkt);
733 
734     MSS_USB_CIF_rx_ep_clr_data_tog(core_ep->num);
735     MSS_USB_CIF_rx_ep_clr_rxpktrdy(core_ep->num);
736 
737     if (DMA_ENABLE == core_ep->dma_enable)
738     {
739         if (MSS_USB_XFR_BULK == core_ep->xfr_type)
740         {
741             MSS_USB_CIF_rx_ep_set_dma_mode1(core_ep->num);
742             MSS_USB_CIF_rx_ep_enable_dma(core_ep->num);
743             mode = MSS_USB_DMA_MODE1;
744         }
745         else
746         {
747             /*
748              * DMA_ENable bit in RXCSRL is not required to be set in m0. if it is
749              * set RX interrupt would not occur.
750              */
751             MSS_USB_CIF_rx_ep_set_dma_mode0(core_ep->num);
752             MSS_USB_CIF_rx_ep_disable_dma(core_ep->num);
753             mode = MSS_USB_DMA_MODE0;
754         }
755 
756         MSS_USB_CIF_configure_ep_dma(core_ep->dma_channel,
757                                      MSS_USB_DMA_WRITE,
758                                      mode,
759                                      MSS_USB_DMA_BURST_MODE3,
760                                      core_ep->num,
761                                      (uint32_t)(core_ep->buf_addr));
762     }
763 
764     MSS_USB_CIF_rx_ep_enable_irq(core_ep->num);
765 }
766 
767 /***************************************************************************//**
768  * Starts sending Test packet as specified in the USB2.0
769  * This is USB-IF certification requirement.
770  */
MSS_USB_CIF_start_testpacket(void)771 void MSS_USB_CIF_start_testpacket(void)
772 {
773     uint8_t test_pkt[53] =
774     {
775     0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U,
776     0xAAU, 0xAAU, 0xAAU, 0xAAU, 0xAAU, 0xAAU, 0xAAU, 0xAAU, 0xEEU,
777     0xEEU, 0xEEU, 0xEEU, 0xEEU, 0xEEU, 0xEEU, 0xEEU, 0xFEU, 0xFFU,
778     0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU,
779     0xFFU, 0x7FU, 0xBFU, 0xDFU, 0xEFU, 0xF7U, 0xFBU, 0xFDU, 0xFCU,
780     0x7EU, 0xBFU, 0xDFU, 0xEFU, 0xF7U, 0xFBU, 0xFDU, 0x7EU
781     };
782     MSS_USB_CIF_load_tx_fifo(MSS_USB_CEP, test_pkt, 53u);
783     MSS_USB_CIF_start_testpacket_bit();
784     MSS_USB_CIF_cep_set_txpktrdy();
785     MSS_USB_CIF_cep_disable_irq();
786 }
787 
788 #ifdef MSS_USB_HOST_ENABLED
MSS_USB_CIF_host_rx_errchk(mss_usb_ep_num_t ep_num)789 static uint8_t MSS_USB_CIF_host_rx_errchk(mss_usb_ep_num_t ep_num)
790 {
791     uint8_t status = 0u;
792 
793     if (MSS_USBH_CIF_rx_ep_is_rxpktrdy(ep_num))
794     {
795         status = 0u;
796     }
797     if (MSS_USBH_CIF_rx_ep_is_rxstall_err(ep_num))
798     {
799         status |= MSS_USB_EP_STALL_RCVD;
800         MSS_USBH_CIF_rx_ep_clr_rxstall_err(ep_num);
801     }
802     if (MSS_USBH_CIF_rx_ep_is_naktimeout_err(ep_num))
803     {
804         status |= MSS_USB_EP_NAK_TOUT;
805         /* Not clearing NAKTIMEOUT error here. Application may want to abort
806          * transfer. Clearing it here makes Scheduler keep trying the transfer
807          */
808     }
809     if (MSS_USBH_CIF_rx_ep_is_retry_err(ep_num))
810     {
811         status |= MSS_USB_EP_NO_RESPONSE;
812         MSS_USBH_CIF_rx_ep_clr_retry_err(ep_num);
813     }
814 
815     return (status);
816 }
817 
MSS_USB_CIF_host_tx_errchk(mss_usb_ep_num_t ep_num)818 static uint8_t MSS_USB_CIF_host_tx_errchk(mss_usb_ep_num_t ep_num)
819 {
820     uint8_t status = 0;
821 
822     if (MSS_USBH_CIF_tx_ep_is_retry_err(ep_num))
823     {
824         status |= MSS_USB_EP_NO_RESPONSE;
825         MSS_USBH_CIF_tx_ep_clr_retry_err(ep_num);
826     }
827     if (MSS_USBH_CIF_tx_ep_is_rxstall_err(ep_num))
828     {
829         status |= MSS_USB_EP_STALL_RCVD;
830         MSS_USBH_CIF_tx_ep_clr_rxstall_err(ep_num);
831     }
832     if (MSS_USBH_CIF_tx_ep_is_naktimeout_err(ep_num))
833     {
834         status |= MSS_USB_EP_NAK_TOUT;
835         /* Not clearing NAKTIMEOUT error here. Application may want to abort
836          * transfer. Clearing it here makes Scheduler keep trying the transfer
837          */
838     }
839 
840     return(status);
841 }
842 #endif /* MSS_USB_HOST_ENABLED */
843 
844 #ifdef MSS_USB_DEVICE_ENABLED
MSS_USB_CIF_device_rx_errchk(mss_usb_ep_num_t ep_num)845 static uint8_t MSS_USB_CIF_device_rx_errchk(mss_usb_ep_num_t ep_num)
846 {
847     uint8_t status = 0u;
848 
849     if (MSS_USB_CIF_rx_ep_is_overrun(ep_num))
850     {
851         status |= RX_EP_OVER_RUN_ERROR;
852         MSS_USB_CIF_rx_ep_clr_overrun(ep_num);
853     }
854     if (MSS_USB_CIF_rx_ep_is_stall_sent_bit(ep_num))
855     {
856         status |= RX_EP_STALL_ERROR;
857         /*
858          * "sent stall" bit should be cleared."Send Stall" bit is still set.
859          * it should be cleared via Clear feature command or reset"
860          */
861         MSS_USB_CIF_rx_ep_clr_stall_sent_bit(ep_num);
862     }
863     if (MSS_USB_CIF_rx_ep_is_dataerr(ep_num))
864     {
865         /* This error will be cleared when RxPktRdy bit is cleared.
866          */
867         status |= RX_EP_DATA_ERROR;
868 
869     }
870 #if 0
871     /*
872      * PID error and INCOMP error should be checked only in ISO transfers.
873      * This should be moved to logical layer
874      */
875     if (MSS_USB_CIF_rx_ep_is_piderr(ep_num))
876     {
877         status |= RX_EP_PID_ERROR;
878         /* Data sheet doesn't mention about how this error bit is cleared
879          * Assuming that this will be cleared when RxPKTRdy is cleared.*/
880     }
881     if (MSS_USB_CIF_rx_ep_is_isoincomp(ep_num))
882     {
883         status |= RX_EP_ISO_INCOMP_ERROR;
884         /* This error will be cleared when RxPktRdy bit is cleared.*/
885     }
886 #endif /* if 0 */
887 
888     return(status);
889 }
890 
MSS_USB_CIF_device_tx_errchk(mss_usb_ep_num_t ep_num)891 static uint8_t MSS_USB_CIF_device_tx_errchk(mss_usb_ep_num_t ep_num)
892 {
893     uint8_t status = 0u;
894 
895     if (MSS_USB_CIF_tx_ep_is_underrun(ep_num))
896     {
897         /* Under-run errors should happen only for ISO endpoints.*/
898         status |= TX_EP_UNDER_RUN_ERROR;
899         MSS_USB_CIF_tx_ep_clr_underrun(ep_num);
900     }
901     if (MSS_USB_CIF_tx_ep_is_stall_sent_bit(ep_num))
902     {
903         status |= TX_EP_STALL_ERROR;
904         MSS_USB_CIF_tx_ep_clr_stall_sent_bit(ep_num);
905     }
906 
907     return(status);
908 }
909 #endif /* MSS_USB_DEVICE_ENABLED */
910 
911 #ifdef __cplusplus
912 }
913 #endif
914