1 /*****************************************************************************
2 * Copyright (c) 2022, Nations Technologies Inc.
3 *
4 * All rights reserved.
5 * ****************************************************************************
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 *
10 * - Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the disclaimer below.
12 *
13 * Nations' name may not be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY NATIONS "AS IS" AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
19 * DISCLAIMED. IN NO EVENT SHALL NATIONS BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
22 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
25 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 * ****************************************************************************/
27
28 /**
29 * @file usb_int.c
30 * @author Nations
31 * @version v1.2.0
32 *
33 * @copyright Copyright (c) 2022, Nations Technologies Inc. All rights reserved.
34 */
35 #include "usb_lib.h"
36
37 __IO uint16_t SaveRState;
38 __IO uint16_t SaveTState;
39
40 extern void (*pEpInt_IN[7])(void); /* Handles IN interrupts */
41 extern void (*pEpInt_OUT[7])(void); /* Handles OUT interrupts */
42
43 /**
44 * @brief Low priority Endpoint Correct Transfer interrupt's service routine.
45 */
USB_CorrectTransferLp(void)46 void USB_CorrectTransferLp(void)
47 {
48 __IO uint16_t wEPVal = 0;
49 /* stay in loop while pending interrupts */
50 while (((wIstr = _GetISTR()) & STS_CTRS) != 0)
51 {
52 /* extract highest priority endpoint number */
53 EPindex = (uint8_t)(wIstr & STS_EP_ID);
54 if (EPindex == 0)
55 {
56 /* Decode and service control endpoint interrupt */
57 /* calling related service routine */
58 /* (USB_ProcessSetup0, USB_ProcessIn0, USB_ProcessOut0) */
59
60 /* save RX & TX status */
61 /* and set both to NAK */
62
63 SaveRState = _GetENDPOINT(ENDP0);
64 SaveTState = SaveRState & EPTX_STS;
65 SaveRState &= EPRX_STS;
66 _SetEPRxTxStatus(ENDP0, EP_RX_NAK, EP_TX_NAK);
67
68 /* DIR bit = origin of the interrupt */
69
70 if ((wIstr & STS_DIR) == 0)
71 {
72 /* DIR = 0 */
73
74 /* DIR = 0 => IN int */
75 /* DIR = 0 implies that (EP_CTRS_TX = 1) always */
76
77 _ClearEP_CTR_TX(ENDP0);
78 USB_ProcessIn0();
79
80 /* before terminate set Tx & Rx status */
81
82 _SetEPRxTxStatus(ENDP0, SaveRState, SaveTState);
83 return;
84 }
85 else
86 {
87 /* DIR = 1 */
88
89 /* DIR = 1 & CTR_RX => SETUP or OUT int */
90 /* DIR = 1 & (CTR_TX | CTR_RX) => 2 int pending */
91
92 wEPVal = _GetENDPOINT(ENDP0);
93
94 if ((wEPVal & EP_SETUP) != 0)
95 {
96 _ClearEP_CTR_RX(ENDP0); /* SETUP bit kept frozen while CTR_RX = 1 */
97 USB_ProcessSetup0();
98 /* before terminate set Tx & Rx status */
99
100 _SetEPRxTxStatus(ENDP0, SaveRState, SaveTState);
101 return;
102 }
103
104 else if ((wEPVal & EP_CTRS_RX) != 0)
105 {
106 _ClearEP_CTR_RX(ENDP0);
107 USB_ProcessOut0();
108 /* before terminate set Tx & Rx status */
109
110 _SetEPRxTxStatus(ENDP0, SaveRState, SaveTState);
111 return;
112 }
113 }
114 } /* if (EPindex == 0) */
115 else
116 {
117 /* Decode and service non control endpoints interrupt */
118
119 /* process related endpoint register */
120 wEPVal = _GetENDPOINT(EPindex);
121 if ((wEPVal & EP_CTRS_RX) != 0)
122 {
123 /* clear int flag */
124 _ClearEP_CTR_RX(EPindex);
125
126 /* call OUT service function */
127 (*pEpInt_OUT[EPindex - 1])();
128
129 } /* if ((wEPVal & EP_CTRS_RX) */
130
131 if ((wEPVal & EP_CTRS_TX) != 0)
132 {
133 /* clear int flag */
134 _ClearEP_CTR_TX(EPindex);
135
136 /* call IN service function */
137 (*pEpInt_IN[EPindex - 1])();
138 } /* if ((wEPVal & EP_CTRS_TX) != 0) */
139
140 } /* if (EPindex == 0) else */
141
142 } /* while (...) */
143 }
144
145 /**
146 * @brief High Priority Endpoint Correct Transfer interrupt's service routine.
147 */
USB_CorrectTransferHp(void)148 void USB_CorrectTransferHp(void)
149 {
150 uint32_t wEPVal = 0;
151
152 while (((wIstr = _GetISTR()) & STS_CTRS) != 0)
153 {
154 _SetISTR((uint16_t)CLR_CTRS); /* clear CTR flag */
155 /* extract highest priority endpoint number */
156 EPindex = (uint8_t)(wIstr & STS_EP_ID);
157 /* process related endpoint register */
158 wEPVal = _GetENDPOINT(EPindex);
159 if ((wEPVal & EP_CTRS_RX) != 0)
160 {
161 /* clear int flag */
162 _ClearEP_CTR_RX(EPindex);
163
164 /* call OUT service function */
165 (*pEpInt_OUT[EPindex - 1])();
166
167 } /* if ((wEPVal & EP_CTRS_RX) */
168 else if ((wEPVal & EP_CTRS_TX) != 0)
169 {
170 /* clear int flag */
171 _ClearEP_CTR_TX(EPindex);
172
173 /* call IN service function */
174 (*pEpInt_IN[EPindex - 1])();
175
176 } /* if ((wEPVal & EP_CTRS_TX) != 0) */
177
178 } /* while (...) */
179 }
180