kopia lustrzana https://github.com/micropython/micropython
Porównaj commity
5 Commity
3f8b7a9f33
...
c826d3b8df
Autor | SHA1 | Data |
---|---|---|
Sandor Attila Gerendi | c826d3b8df | |
Angus Gratton | d11ca092f7 | |
Sandor Attila Gerendi | c79be30ca6 | |
Sandor Attila Gerendi | 5366ead756 | |
Sandor Attila Gerendi | 564fafd6d5 |
|
@ -130,15 +130,25 @@ Methods
|
||||||
|
|
||||||
Second argument is a memoryview to read the USB control request
|
Second argument is a memoryview to read the USB control request
|
||||||
data for this stage. The memoryview is only valid until the
|
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:
|
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.
|
- ``True`` to continue the transfer to the next stage.
|
||||||
- A buffer object to provide data for this stage of the transfer.
|
- A buffer object can be returned at the SETUP stage when the transfer
|
||||||
This should be a writable buffer for an ``OUT`` direction transfer, or a
|
will send or receive additional data. Typically this is the case when
|
||||||
readable buffer with data for an ``IN`` direction transfer.
|
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
|
- ``xfer_cb`` - This callback is called whenever a non-control
|
||||||
transfer submitted by calling :func:`USBDevice.submit_xfer` completes.
|
transfer submitted by calling :func:`USBDevice.submit_xfer` completes.
|
||||||
|
|
|
@ -0,0 +1,101 @@
|
||||||
|
"""
|
||||||
|
This implementation offloads the quadrature sensor continuous pooling to the StateMachine pio_quadrature,
|
||||||
|
pio_quadrature will detect state changes and push the values then raises an interrupt that is handled by
|
||||||
|
encoder_state_changed_irq_handler
|
||||||
|
|
||||||
|
encoder_state_changed_irq_handler was inspired from
|
||||||
|
https://electronics.stackexchange.com/questions/360637/quadrature-encoder-most-efficient-software-implementation
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
from machine import Pin
|
||||||
|
import rp2
|
||||||
|
from rp2 import PIO, StateMachine
|
||||||
|
import utime
|
||||||
|
import array
|
||||||
|
|
||||||
|
|
||||||
|
state_look_up_table = array.array("b", [
|
||||||
|
#Direction = 1
|
||||||
|
0, # 00 to 00
|
||||||
|
-1, # 00 to 01
|
||||||
|
+1, # 00 to 10
|
||||||
|
+2, # 00 to 11
|
||||||
|
|
||||||
|
+1, # 01 to 00
|
||||||
|
0, # 01 to 01
|
||||||
|
+2, # 01 to 10
|
||||||
|
-1, # 01 to 11
|
||||||
|
|
||||||
|
-1, # 10 to 00
|
||||||
|
+2, # 10 to 01
|
||||||
|
0, # 10 to 10
|
||||||
|
+1, # 10 to 11
|
||||||
|
|
||||||
|
+2, # 11 to 00
|
||||||
|
+1, # 11 to 01
|
||||||
|
-1, # 11 to 10
|
||||||
|
0, # 11 to 11
|
||||||
|
|
||||||
|
#Direction = 0
|
||||||
|
0, # 00 to 00
|
||||||
|
-1, # 00 to 01
|
||||||
|
+1, # 00 to 10
|
||||||
|
-2, # 00 to 11
|
||||||
|
|
||||||
|
+1, # 01 to 00
|
||||||
|
0, # 01 to 01
|
||||||
|
-2, # 01 to 10
|
||||||
|
-1, # 01 to 11
|
||||||
|
|
||||||
|
-1, # 10 to 00
|
||||||
|
-2, # 10 to 01
|
||||||
|
0, # 10 to 10
|
||||||
|
+1, # 10 to 11
|
||||||
|
|
||||||
|
-2, # 11 to 00
|
||||||
|
+1, # 11 to 01
|
||||||
|
-1, # 11 to 10
|
||||||
|
0, # 11 to 11
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
counter = 0
|
||||||
|
direction = 0
|
||||||
|
lut_index = 0
|
||||||
|
|
||||||
|
def encoder_state_changed_irq_handler(sm):
|
||||||
|
global counter, direction, lut_index
|
||||||
|
while sm.rx_fifo():
|
||||||
|
lut_index |= sm.get() & 3
|
||||||
|
counter += state_look_up_table[lut_index]
|
||||||
|
if state_look_up_table[lut_index] != 0:
|
||||||
|
direction = 1 if (state_look_up_table[lut_index] > 0) else 0
|
||||||
|
lut_index = ((lut_index << 2) & 0b1100) | (direction << 4)
|
||||||
|
|
||||||
|
|
||||||
|
@rp2.asm_pio()
|
||||||
|
def pio_quadrature(in_init=rp2.PIO.IN_LOW):
|
||||||
|
wrap_target()
|
||||||
|
label("again")
|
||||||
|
in_(pins, 2)
|
||||||
|
mov(x, isr)
|
||||||
|
jmp(x_not_y, "push_data")
|
||||||
|
mov(isr, null)
|
||||||
|
jmp("again")
|
||||||
|
label("push_data")
|
||||||
|
push()
|
||||||
|
irq(block, rel(0))
|
||||||
|
mov(y, x)
|
||||||
|
wrap()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
sm = StateMachine(0, pio_quadrature, freq=160000, in_base=Pin(2))
|
||||||
|
sm.irq(encoder_state_changed_irq_handler)
|
||||||
|
sm.exec("set(y, 99)") # add a last value for y that would be always different then the input
|
||||||
|
sm.active(1)
|
||||||
|
|
||||||
|
while True:
|
||||||
|
utime.sleep(2)
|
||||||
|
print(counter)
|
|
@ -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));
|
mp_obj_usb_device_t *usbd = MP_OBJ_TO_PTR(MP_STATE_VM(usbd));
|
||||||
tusb_dir_t dir = request->bmRequestType_bit.direction;
|
tusb_dir_t dir = request->bmRequestType_bit.direction;
|
||||||
mp_buffer_info_t buf_info;
|
mp_buffer_info_t buf_info;
|
||||||
|
bool result;
|
||||||
|
|
||||||
if (!usbd) {
|
if (!usbd) {
|
||||||
return false;
|
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
|
// 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)) {
|
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,
|
request,
|
||||||
buf_info.buf,
|
buf_info.buf,
|
||||||
buf_info.len);
|
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
|
// Keep buffer object alive until the transfer completes
|
||||||
usbd->xfer_data[0][dir] = cb_res;
|
usbd->xfer_data[0][dir] = cb_res;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
|
||||||
} else {
|
} else {
|
||||||
// Expect True or False to stall or continue
|
// 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
|
// Allow data to be GCed once it's no longer in use
|
||||||
usbd->xfer_data[0][dir] = mp_const_none;
|
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) {
|
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