| Index: emcore/trunk/tools/emcore.py | 
| — | — | @@ -407,10 +407,13 @@ | 
| 408 | 408 | """ | 
| 409 | 409 | Reads data from the USB console continuously | 
| 410 | 410 | """ | 
|  | 411 | +        size = 48 | 
| 411 | 412 | while True: | 
| 412 |  | -            resp = self.emcore.usbcread()
 | 
|  | 413 | +            resp = self.emcore.usbcread(size) | 
| 413 | 414 | self.logger.write(resp.data, target = "stdout") | 
| 414 |  | -#            time.sleep(0.1 / resp.maxsize * (resp.maxsize - len(resp.data)))
 | 
|  | 415 | +            size = max(48, min(len(resp.data), size) + resp.queuesize) | 
|  | 416 | +            if size < 0x800: | 
|  | 417 | +                time.sleep(0.1 / 0x800 * (0x800 - size)) | 
| 415 | 418 |  | 
| 416 | 419 | @command | 
| 417 | 420 | def writeusbconsole(self, *args): | 
| Index: emcore/trunk/tools/libemcore.py | 
| — | — | @@ -239,12 +239,12 @@ | 
| 240 | 240 | return self.lib.monitorcommand(struct.pack("<IBBBBII%ds" % size, 9, index, slaveaddr, startaddr, size, 0, 0, data), "III", (None, None, None)) | 
| 241 | 241 |  | 
| 242 | 242 | @command() | 
| 243 |  | -    def usbcread(self):
 | 
|  | 243 | +    def usbcread(self, maxsize = 48): | 
| 244 | 244 | """ Reads one packet with the maximal cin size from the console """ | 
| 245 |  | -        cin_maxsize = 48
 | 
| 246 |  | -        resp = self.lib.monitorcommand(struct.pack("<IIII", 10, cin_maxsize, 0, 0), "III%ds" % cin_maxsize, ("validsize", "buffersize", "queuesize", "data"))
 | 
|  | 245 | +        maxsize = min(0xff0, maxsize) | 
|  | 246 | +        resp = self.lib.monitorcommand(struct.pack("<IIII", 10, maxsize, 0, 0), "III%ds" % maxsize, ("validsize", "buffersize", "queuesize", "data")) | 
| 247 | 247 | resp.data = resp.data[:resp.validsize].decode("latin_1") | 
| 248 |  | -        resp.maxsize = cin_maxsize
 | 
|  | 248 | +        resp.maxsize = maxsize | 
| 249 | 249 | return resp | 
| 250 | 250 |  | 
| 251 | 251 | @command() | 
| Index: emcore/trunk/usb/usbdebug.c | 
| — | — | @@ -64,8 +64,10 @@ | 
| 65 | 65 | DBGSTATE_IDLE = 0, | 
| 66 | 66 | DBGSTATE_SETUP, | 
| 67 | 67 | DBGSTATE_WRITE_MEM, | 
|  | 68 | +    DBGSTATE_WRITE_CONSOLE, | 
| 68 | 69 | DBGSTATE_ASYNC, | 
| 69 | 70 | DBGSTATE_RESPOND, | 
|  | 71 | +    DBGSTATE_READ_CONSOLE, | 
| 70 | 72 | }; | 
| 71 | 73 |  | 
| 72 | 74 | static struct scheduler_thread dbgthread_handle IBSS_ATTR; | 
| — | — | @@ -157,39 +159,21 @@ | 
| 158 | 160 | break; | 
| 159 | 161 | } | 
| 160 | 162 | case 10:  // READ CONSOLE | 
| 161 |  | -            dbgconsoleattached = true;
 | 
| 162 |  | -            int bytes = dbgconsendwriteidx - dbgconsendreadidx;
 | 
| 163 |  | -            int used = 0;
 | 
| 164 |  | -            if (bytes)
 | 
| 165 |  | -            {
 | 
| 166 |  | -                if (bytes < 0) bytes += sizeof(dbgconsendbuf);
 | 
| 167 |  | -                used = bytes;
 | 
| 168 |  | -                if (bytes > buf[1]) bytes = buf[1];
 | 
| 169 |  | -                int readbytes = bytes;
 | 
| 170 |  | -                char* outptr = (char*)&dbgbuf[4];
 | 
| 171 |  | -                if (dbgconsendreadidx + bytes >= sizeof(dbgconsendbuf))
 | 
| 172 |  | -                {
 | 
| 173 |  | -                    readbytes = sizeof(dbgconsendbuf) - dbgconsendreadidx;
 | 
| 174 |  | -                    memcpy(outptr, &dbgconsendbuf[dbgconsendreadidx], readbytes);
 | 
| 175 |  | -                    dbgconsendreadidx = 0;
 | 
| 176 |  | -                    outptr = &outptr[readbytes];
 | 
| 177 |  | -                    readbytes = bytes - readbytes;
 | 
| 178 |  | -                }
 | 
| 179 |  | -                if (readbytes) memcpy(outptr, &dbgconsendbuf[dbgconsendreadidx], readbytes);
 | 
| 180 |  | -                dbgconsendreadidx += readbytes;
 | 
| 181 |  | -                wakeup_signal(&dbgconsendwakeup);
 | 
| 182 |  | -            }
 | 
| 183 |  | -            dbgbuf[0] = 1;
 | 
| 184 |  | -            dbgbuf[1] = bytes;
 | 
| 185 |  | -            dbgbuf[2] = sizeof(dbgconsendbuf);
 | 
| 186 |  | -            dbgbuf[3] = used - bytes;
 | 
|  | 163 | +            dbgmemaddr = (void*)buf[1]; | 
|  | 164 | +            dbgstate = DBGSTATE_READ_CONSOLE; | 
|  | 165 | +            usb_ep0_start_tx(dbgusb, NULL, 0, true, NULL); | 
|  | 166 | +            return true; | 
| 187 | 167 | break; | 
| 188 | 168 | case 11:  // WRITE CONSOLE | 
| 189 |  | -            bytes = dbgconrecvreadidx - dbgconrecvwriteidx - 1;
 | 
|  | 169 | +        { | 
|  | 170 | +            int total = 0; | 
|  | 171 | +            int bytes = dbgconrecvreadidx - dbgconrecvwriteidx - 1; | 
| 190 | 172 | if (bytes < 0) bytes += sizeof(dbgconrecvbuf); | 
| 191 | 173 | if (bytes) | 
| 192 | 174 | { | 
| 193 | 175 | if (bytes > buf[1]) bytes = buf[1]; | 
|  | 176 | +                total = bytes; | 
|  | 177 | +                if (bytes > 48) bytes = 48; | 
| 194 | 178 | int writebytes = bytes; | 
| 195 | 179 | char* readptr = (char*)&buf[4]; | 
| 196 | 180 | if (dbgconrecvwriteidx + bytes >= sizeof(dbgconrecvbuf)) | 
| — | — | @@ -205,10 +189,18 @@ | 
| 206 | 190 | wakeup_signal(&dbgconrecvwakeup); | 
| 207 | 191 | } | 
| 208 | 192 | dbgbuf[0] = 1; | 
| 209 |  | -            dbgbuf[1] = bytes;
 | 
|  | 193 | +            dbgbuf[1] = total; | 
| 210 | 194 | dbgbuf[2] = sizeof(dbgconrecvbuf); | 
|  | 195 | +            if (total > 48) | 
|  | 196 | +            { | 
|  | 197 | +                dbgmemlen = total - 48; | 
|  | 198 | +                dbgstate = DBGSTATE_WRITE_CONSOLE; | 
|  | 199 | +                usb_ep0_start_rx(dbgusb, 1, usbdebug_handle_data); | 
|  | 200 | +                return true; | 
|  | 201 | +            } | 
| 211 | 202 | dbgbuf[3] = dbgconrecvreadidx - dbgconrecvwriteidx - 1; | 
| 212 | 203 | break; | 
|  | 204 | +        } | 
| 213 | 205 | case 15:  // GET PROCESS INFO | 
| 214 | 206 | dbgbuf[0] = 1; | 
| 215 | 207 | dbgbuf[1] = SCHEDULER_THREAD_INFO_VERSION; | 
| — | — | @@ -267,10 +259,10 @@ | 
| 268 | 260 | break; | 
| 269 | 261 | case DBGSTATE_WRITE_MEM: | 
| 270 | 262 | { | 
| 271 |  | -        int len = MIN(64, dbgmemlen);
 | 
|  | 263 | +        int len = MIN(64 - bytesleft, dbgmemlen); | 
| 272 | 264 | dbgmemlen -= len; | 
| 273 | 265 | memcpy(dbgmemaddr, buf, len); | 
| 274 |  | -        if (dbgmemlen)
 | 
|  | 266 | +        if (dbgmemlen && !bytesleft) | 
| 275 | 267 | { | 
| 276 | 268 | dbgmemaddr += len; | 
| 277 | 269 | usb_ep0_start_rx(dbgusb, 1, usbdebug_handle_data); | 
| — | — | @@ -279,6 +271,34 @@ | 
| 280 | 272 | dbgbuf[0] = 1; | 
| 281 | 273 | break; | 
| 282 | 274 | } | 
|  | 275 | +    case DBGSTATE_WRITE_CONSOLE: | 
|  | 276 | +    { | 
|  | 277 | +        int bytes = MIN(64 - bytesleft, dbgmemlen); | 
|  | 278 | +        dbgmemlen -= bytes; | 
|  | 279 | +        if (bytes) | 
|  | 280 | +        { | 
|  | 281 | +            int writebytes = bytes; | 
|  | 282 | +            char* readptr = (char*)buf; | 
|  | 283 | +            if (dbgconrecvwriteidx + bytes >= sizeof(dbgconrecvbuf)) | 
|  | 284 | +            { | 
|  | 285 | +                writebytes = sizeof(dbgconrecvbuf) - dbgconrecvwriteidx; | 
|  | 286 | +                memcpy(&dbgconrecvbuf[dbgconrecvwriteidx], readptr, writebytes); | 
|  | 287 | +                dbgconrecvwriteidx = 0; | 
|  | 288 | +                readptr = &readptr[writebytes]; | 
|  | 289 | +                writebytes = bytes - writebytes; | 
|  | 290 | +            } | 
|  | 291 | +            if (writebytes) memcpy(&dbgconrecvbuf[dbgconrecvwriteidx], readptr, writebytes); | 
|  | 292 | +            dbgconrecvwriteidx += writebytes; | 
|  | 293 | +            wakeup_signal(&dbgconrecvwakeup); | 
|  | 294 | +            if (dbgmemlen && !bytesleft) | 
|  | 295 | +            { | 
|  | 296 | +                usb_ep0_start_rx(dbgusb, 1, usbdebug_handle_data); | 
|  | 297 | +                return true; | 
|  | 298 | +            } | 
|  | 299 | +        } | 
|  | 300 | +        dbgbuf[3] = dbgconrecvreadidx - dbgconrecvwriteidx - 1; | 
|  | 301 | +        if (dbgbuf[3] < 0) dbgbuf[3] += sizeof(dbgconrecvbuf); | 
|  | 302 | +    } | 
| 283 | 303 | default: break; | 
| 284 | 304 | } | 
| 285 | 305 | dbgstate = DBGSTATE_RESPOND; | 
| — | — | @@ -286,6 +306,39 @@ | 
| 287 | 307 | return true; | 
| 288 | 308 | } | 
| 289 | 309 |  | 
|  | 310 | +bool read_console_callback(const struct usb_instance* data, int bytesleft) | 
|  | 311 | +{ | 
|  | 312 | +    if (bytesleft || !dbgmemaddr) return false; | 
|  | 313 | +    dbgconsoleattached = true; | 
|  | 314 | +    int bytes = MIN(64, dbgmemlen); | 
|  | 315 | +    if (bytes) | 
|  | 316 | +    { | 
|  | 317 | +        int readbytes = bytes; | 
|  | 318 | +        char* outptr = (char*)dbgbuf; | 
|  | 319 | +        if (dbgconsendreadidx + bytes >= sizeof(dbgconsendbuf)) | 
|  | 320 | +        { | 
|  | 321 | +            readbytes = sizeof(dbgconsendbuf) - dbgconsendreadidx; | 
|  | 322 | +            memcpy(outptr, &dbgconsendbuf[dbgconsendreadidx], readbytes); | 
|  | 323 | +            dbgconsendreadidx = 0; | 
|  | 324 | +            outptr = &outptr[readbytes]; | 
|  | 325 | +            readbytes = bytes - readbytes; | 
|  | 326 | +        } | 
|  | 327 | +        if (readbytes) memcpy(outptr, &dbgconsendbuf[dbgconsendreadidx], readbytes); | 
|  | 328 | +        dbgconsendreadidx += readbytes; | 
|  | 329 | +        wakeup_signal(&dbgconsendwakeup); | 
|  | 330 | +        dbgmemlen -= bytes; | 
|  | 331 | +    } | 
|  | 332 | +    bytes = MIN(64, (int)dbgmemaddr); | 
|  | 333 | +    dbgmemaddr -= bytes; | 
|  | 334 | +    if (dbgmemaddr) | 
|  | 335 | +    { | 
|  | 336 | +        usb_ep0_start_rx(dbgusb, 0, NULL); | 
|  | 337 | +        usb_ep0_start_tx(dbgusb, dbgbuf, bytes, false, read_console_callback); | 
|  | 338 | +    } | 
|  | 339 | +    else usb_ep0_start_tx(dbgusb, dbgbuf, bytes, true, NULL); | 
|  | 340 | +    return true; | 
|  | 341 | +} | 
|  | 342 | + | 
| 290 | 343 | int usbdebug_handle_setup(const struct usb_instance* data, int interface, union usb_ep0_buffer* request, const void** response) | 
| 291 | 344 | { | 
| 292 | 345 | int size = -1; | 
| — | — | @@ -315,7 +368,7 @@ | 
| 316 | 369 | usb_ep0_start_rx(dbgusb, 0, NULL); | 
| 317 | 370 | data->state->ep0_tx_ptr = dbgmemaddr - 16; | 
| 318 | 371 | data->state->ep0_tx_len = dbgmemlen; | 
| 319 |  | -                        usb_ep0_start_tx(dbgusb, dbgbuf, len + 16, !data->state->ep0_tx_len, usb_ep0_tx_callback);
 | 
|  | 372 | +                        usb_ep0_start_tx(dbgusb, dbgbuf, len + 16, false, usb_ep0_tx_callback); | 
| 320 | 373 | return -3; | 
| 321 | 374 | } | 
| 322 | 375 | dbgstate = DBGSTATE_IDLE; | 
| — | — | @@ -322,6 +375,47 @@ | 
| 323 | 376 | *response = dbgbuf; | 
| 324 | 377 | return len + 16; | 
| 325 | 378 | } | 
|  | 379 | +                case DBGSTATE_READ_CONSOLE: | 
|  | 380 | +                { | 
|  | 381 | +                    dbgconsoleattached = true; | 
|  | 382 | +                    dbgmemlen = dbgconsendwriteidx - dbgconsendreadidx; | 
|  | 383 | +                    if (dbgmemlen < 0) dbgmemlen += sizeof(dbgconsendbuf); | 
|  | 384 | +                    int used = dbgmemlen; | 
|  | 385 | +                    if (dbgmemlen > (int)dbgmemaddr) dbgmemlen = (int)dbgmemaddr; | 
|  | 386 | +                    int bytes = MIN(48, dbgmemlen); | 
|  | 387 | +                    dbgbuf[0] = 1; | 
|  | 388 | +                    dbgbuf[1] = dbgmemlen; | 
|  | 389 | +                    dbgbuf[2] = sizeof(dbgconsendbuf); | 
|  | 390 | +                    dbgbuf[3] = used - dbgmemlen; | 
|  | 391 | +                    if (bytes) | 
|  | 392 | +                    { | 
|  | 393 | +                        int readbytes = bytes; | 
|  | 394 | +                        char* outptr = (char*)&dbgbuf[4]; | 
|  | 395 | +                        if (dbgconsendreadidx + bytes >= sizeof(dbgconsendbuf)) | 
|  | 396 | +                        { | 
|  | 397 | +                            readbytes = sizeof(dbgconsendbuf) - dbgconsendreadidx; | 
|  | 398 | +                            memcpy(outptr, &dbgconsendbuf[dbgconsendreadidx], readbytes); | 
|  | 399 | +                            dbgconsendreadidx = 0; | 
|  | 400 | +                            outptr = &outptr[readbytes]; | 
|  | 401 | +                            readbytes = bytes - readbytes; | 
|  | 402 | +                        } | 
|  | 403 | +                        if (readbytes) memcpy(outptr, &dbgconsendbuf[dbgconsendreadidx], readbytes); | 
|  | 404 | +                        dbgconsendreadidx += readbytes; | 
|  | 405 | +                        wakeup_signal(&dbgconsendwakeup); | 
|  | 406 | +                    } | 
|  | 407 | +                    dbgmemlen -= bytes; | 
|  | 408 | +                    bytes = MIN(48, (int)dbgmemaddr); | 
|  | 409 | +                    dbgmemaddr -= bytes; | 
|  | 410 | +                    if (dbgmemaddr) | 
|  | 411 | +                    { | 
|  | 412 | +                        usb_ep0_start_rx(dbgusb, 0, NULL); | 
|  | 413 | +                        usb_ep0_start_tx(dbgusb, dbgbuf, bytes + 16, false, read_console_callback); | 
|  | 414 | +                        return -3; | 
|  | 415 | +                    } | 
|  | 416 | +                    dbgstate = DBGSTATE_IDLE; | 
|  | 417 | +                    *response = dbgbuf; | 
|  | 418 | +                    return bytes + 16; | 
|  | 419 | +                } | 
| 326 | 420 | default: return -2; | 
| 327 | 421 | } | 
| 328 | 422 | break; |