kopia lustrzana https://github.com/micropython/micropython
Porównaj commity
3 Commity
d8980f9c6d
...
49dadc12d5
Autor | SHA1 | Data |
---|---|---|
Jared Hancock | 49dadc12d5 | |
Angus Gratton | d11ca092f7 | |
Jared Hancock | f302d85ed2 |
|
@ -130,15 +130,25 @@ Methods
|
|||
|
||||
Second argument is a memoryview to read the USB control request
|
||||
data for this stage. The memoryview is only valid until the
|
||||
callback function returns.
|
||||
callback function returns. Data in this memoryview will be the same
|
||||
across each of the three stages of a single transfer.
|
||||
|
||||
A successful transfer consists of this callback being called in sequence
|
||||
for the three stages. Generally speaking, if a device wants to do
|
||||
something in response to a control request then it's best to wait until
|
||||
the ACK stage to confirm the host controller completed the transfer as
|
||||
expected.
|
||||
|
||||
The callback should return one of the following values:
|
||||
|
||||
- ``False`` to stall the endpoint and reject the transfer.
|
||||
- ``False`` to stall the endpoint and reject the transfer. It won't
|
||||
proceed to any remaining stages.
|
||||
- ``True`` to continue the transfer to the next stage.
|
||||
- A buffer object to provide data for this stage of the transfer.
|
||||
This should be a writable buffer for an ``OUT`` direction transfer, or a
|
||||
readable buffer with data for an ``IN`` direction transfer.
|
||||
- A buffer object can be returned at the SETUP stage when the transfer
|
||||
will send or receive additional data. Typically this is the case when
|
||||
the ``wLength`` field in the request has a non-zero value. This should
|
||||
be a writable buffer for an ``OUT`` direction transfer, or a readable
|
||||
buffer with data for an ``IN`` direction transfer.
|
||||
|
||||
- ``xfer_cb`` - This callback is called whenever a non-control
|
||||
transfer submitted by calling :func:`USBDevice.submit_xfer` completes.
|
||||
|
|
|
@ -69,6 +69,8 @@
|
|||
#define IP_ADD_MEMBERSHIP 0x400
|
||||
#define IP_DROP_MEMBERSHIP 0x401
|
||||
|
||||
#define TCP_NODELAY TF_NODELAY
|
||||
|
||||
// For compatibilily with older lwIP versions.
|
||||
#ifndef ip_set_option
|
||||
#define ip_set_option(pcb, opt) ((pcb)->so_options |= (opt))
|
||||
|
@ -742,9 +744,10 @@ static mp_uint_t lwip_tcp_send(lwip_socket_obj_t *socket, const byte *buf, mp_ui
|
|||
MICROPY_PY_LWIP_REENTER
|
||||
}
|
||||
|
||||
// If the output buffer is getting full then send the data to the lower layers
|
||||
if (err == ERR_OK && tcp_sndbuf(socket->pcb.tcp) < TCP_SND_BUF / 4) {
|
||||
err = tcp_output(socket->pcb.tcp);
|
||||
// Use nagle algorithm to determine when to send segment buffer (can be
|
||||
// disabled with TCP_NODELAY socket option)
|
||||
if (err == ERR_OK) {
|
||||
err = tcp_output_nagle(socket->pcb.tcp);
|
||||
}
|
||||
|
||||
MICROPY_PY_LWIP_EXIT
|
||||
|
@ -1440,6 +1443,17 @@ static mp_obj_t lwip_socket_setsockopt(size_t n_args, const mp_obj_t *args) {
|
|||
break;
|
||||
}
|
||||
|
||||
// level: IPPROTO_TCP
|
||||
case TCP_NODELAY: {
|
||||
mp_int_t val = mp_obj_get_int(args[3]);
|
||||
if (val) {
|
||||
tcp_set_flags(socket->pcb.tcp, opt);
|
||||
} else {
|
||||
tcp_clear_flags(socket->pcb.tcp, opt);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
printf("Warning: lwip.setsockopt() not implemented\n");
|
||||
}
|
||||
|
@ -1829,6 +1843,9 @@ static const mp_rom_map_elem_t mp_module_lwip_globals_table[] = {
|
|||
{ MP_ROM_QSTR(MP_QSTR_IPPROTO_IP), MP_ROM_INT(0) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_IP_ADD_MEMBERSHIP), MP_ROM_INT(IP_ADD_MEMBERSHIP) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_IP_DROP_MEMBERSHIP), MP_ROM_INT(IP_DROP_MEMBERSHIP) },
|
||||
|
||||
{ MP_ROM_QSTR(MP_QSTR_IPPROTO_TCP), MP_ROM_INT(IP_PROTO_TCP) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_TCP_NODELAY), MP_ROM_INT(TCP_NODELAY) },
|
||||
};
|
||||
|
||||
static MP_DEFINE_CONST_DICT(mp_module_lwip_globals, mp_module_lwip_globals_table);
|
||||
|
|
|
@ -295,6 +295,7 @@ static bool runtime_dev_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_cont
|
|||
mp_obj_usb_device_t *usbd = MP_OBJ_TO_PTR(MP_STATE_VM(usbd));
|
||||
tusb_dir_t dir = request->bmRequestType_bit.direction;
|
||||
mp_buffer_info_t buf_info;
|
||||
bool result;
|
||||
|
||||
if (!usbd) {
|
||||
return false;
|
||||
|
@ -319,7 +320,7 @@ static bool runtime_dev_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_cont
|
|||
|
||||
// Check if callback returned any data to submit
|
||||
if (mp_get_buffer(cb_res, &buf_info, dir == TUSB_DIR_IN ? MP_BUFFER_READ : MP_BUFFER_RW)) {
|
||||
bool result = tud_control_xfer(USBD_RHPORT,
|
||||
result = tud_control_xfer(USBD_RHPORT,
|
||||
request,
|
||||
buf_info.buf,
|
||||
buf_info.len);
|
||||
|
@ -328,17 +329,21 @@ static bool runtime_dev_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_cont
|
|||
// Keep buffer object alive until the transfer completes
|
||||
usbd->xfer_data[0][dir] = cb_res;
|
||||
}
|
||||
|
||||
return result;
|
||||
} else {
|
||||
// Expect True or False to stall or continue
|
||||
result = mp_obj_is_true(cb_res);
|
||||
|
||||
if (stage == CONTROL_STAGE_ACK) {
|
||||
if (stage == CONTROL_STAGE_SETUP && result) {
|
||||
// If no additional data but callback says to continue transfer then
|
||||
// queue a status response.
|
||||
tud_control_status(rhport, request);
|
||||
} else if (stage == CONTROL_STAGE_ACK) {
|
||||
// Allow data to be GCed once it's no longer in use
|
||||
usbd->xfer_data[0][dir] = mp_const_none;
|
||||
}
|
||||
return mp_obj_is_true(cb_res);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool runtime_dev_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) {
|
||||
|
|
Ładowanie…
Reference in New Issue