@@ -53,6 +53,138 @@ class EPHandler {
53
53
virtual uint32_t available () const = 0;
54
54
};
55
55
56
+ class DoubleBufferedEPOutHandler : public EPHandler {
57
+ public:
58
+ DoubleBufferedEPOutHandler (uint32_t endPoint, uint32_t bufferSize) :
59
+ ep (endPoint), size(bufferSize),
60
+ current (0 ), incoming(0 ),
61
+ first0 (0 ), last0(0 ), ready0(false ),
62
+ first1 (0 ), last1(0 ), ready1(false ),
63
+ notify (false )
64
+ {
65
+ data0 = reinterpret_cast <uint8_t *>(malloc (size));
66
+ data1 = reinterpret_cast <uint8_t *>(malloc (size));
67
+
68
+ usbd.epBank0SetSize (ep, 64 );
69
+ usbd.epBank0SetType (ep, 3 ); // BULK OUT
70
+
71
+ release ();
72
+ }
73
+
74
+ // Read one byte from the buffer, if the buffer is empty -1 is returned
75
+ int read () {
76
+ if (current == 0 ) {
77
+ if (!ready0) {
78
+ return -1 ;
79
+ }
80
+ if (first0 == last0) {
81
+ first0 = 0 ;
82
+ last0 = 0 ;
83
+ ready0 = false ;
84
+ if (notify) {
85
+ release ();
86
+ }
87
+ current = 1 ;
88
+ return -1 ;
89
+ }
90
+ return data0[first0++];
91
+ } else {
92
+ if (!ready1) {
93
+ return -1 ;
94
+ }
95
+ if (first1 == last1) {
96
+ first1 = 0 ;
97
+ last1 = 0 ;
98
+ ready1 = false ;
99
+ if (notify) {
100
+ release ();
101
+ }
102
+ current = 0 ;
103
+ return -1 ;
104
+ }
105
+ return data1[first1++];
106
+ }
107
+ }
108
+
109
+ virtual void handleEndpoint ()
110
+ {
111
+ if (usbd.epBank0IsTransferComplete (ep))
112
+ {
113
+ // Ack Transfer complete
114
+ usbd.epBank0AckTransferComplete (ep);
115
+
116
+ // Update counters and swap banks
117
+ if (incoming == 0 ) {
118
+ last0 = usbd.epBank0ByteCount (ep);
119
+ ready0 = true ;
120
+ incoming = 1 ;
121
+ } else {
122
+ last1 = usbd.epBank0ByteCount (ep);
123
+ ready1 = true ;
124
+ incoming = 0 ;
125
+ }
126
+ release ();
127
+ }
128
+ }
129
+
130
+ virtual uint32_t recv (void *_data, uint32_t len)
131
+ {
132
+ uint8_t *data = reinterpret_cast <uint8_t *>(_data);
133
+ uint32_t i;
134
+ for (i=0 ; i<len; i++) {
135
+ int c = read ();
136
+ if (c == -1 ) break ;
137
+ data[i] = c;
138
+ }
139
+ return i;
140
+ }
141
+
142
+ // Returns how many bytes are stored in the buffers
143
+ virtual uint32_t available () const {
144
+ return (last0 - first0) + (last1 - first1);
145
+ }
146
+
147
+ void release () {
148
+ if (incoming == 0 ) {
149
+ if (ready0) {
150
+ notify = true ;
151
+ return ;
152
+ }
153
+ usbd.epBank0SetAddress (ep, data0);
154
+ } else {
155
+ if (ready1) {
156
+ notify = true ;
157
+ return ;
158
+ }
159
+ usbd.epBank0SetAddress (ep, data1);
160
+ }
161
+ usbd.epBank0AckTransferComplete (ep);
162
+ // usbd.epBank0AckTransferFailed(ep);
163
+ usbd.epBank0EnableTransferComplete (ep);
164
+
165
+ // Release OUT EP
166
+ usbd.epBank0SetMultiPacketSize (ep, size);
167
+ usbd.epBank0SetByteCount (ep, 0 );
168
+ usbd.epBank0ResetReady (ep);
169
+ notify = false ;
170
+ }
171
+
172
+ private:
173
+ const uint32_t ep;
174
+ const uint32_t size;
175
+ uint32_t current, incoming;
176
+
177
+ uint8_t *data0;
178
+ uint32_t first0, last0;
179
+ bool ready0;
180
+
181
+ uint8_t *data1;
182
+ uint32_t first1, last1;
183
+ bool ready1;
184
+
185
+ bool notify;
186
+ };
187
+
56
188
57
189
const uint16_t STRING_LANGUAGE[2 ] = {
58
190
(3 <<8 ) | (2 +2 ),
0 commit comments