@@ -53,6 +53,138 @@ class EPHandler {
5353 virtual uint32_t available () const = 0;
5454};
5555
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+
56188
57189const uint16_t STRING_LANGUAGE[2 ] = {
58190 (3 <<8 ) | (2 +2 ),
0 commit comments