Added gamepad, gamepadshift, and i2cslave

This commit is contained in:
dherrada 2020-05-07 15:10:44 -04:00
parent a3d5adb43c
commit 4f33a20d17
No known key found for this signature in database
GPG Key ID: CE2ADBAB8775CE81
6 changed files with 146 additions and 149 deletions

View File

@ -34,65 +34,65 @@
#include "shared-bindings/digitalio/DigitalInOut.h"
#include "supervisor/shared/translate.h"
//| .. currentmodule:: gamepad
//| class GamePad:
//| """.. currentmodule:: gamepad
//|
//| :class:`GamePad` -- Scan buttons for presses
//| ============================================
//| :class:`GamePad` -- Scan buttons for presses
//| ============================================
//|
//| Usage::
//| Usage::
//|
//| import board
//| import digitalio
//| import gamepad
//| import time
//| import board
//| import digitalio
//| import gamepad
//| import time
//|
//| B_UP = 1 << 0
//| B_DOWN = 1 << 1
//| B_UP = 1 << 0
//| B_DOWN = 1 << 1
//|
//|
//| pad = gamepad.GamePad(
//| digitalio.DigitalInOut(board.D10),
//| digitalio.DigitalInOut(board.D11),
//| )
//| pad = gamepad.GamePad(
//| digitalio.DigitalInOut(board.D10),
//| digitalio.DigitalInOut(board.D11),
//| )
//|
//| y = 0
//| while True:
//| buttons = pad.get_pressed()
//| if buttons & B_UP:
//| y -= 1
//| print(y)
//| elif buttons & B_DOWN:
//| y += 1
//| print(y)
//| time.sleep(0.1)
//| while buttons:
//| # Wait for all buttons to be released.
//| y = 0
//| while True:
//| buttons = pad.get_pressed()
//| if buttons & B_UP:
//| y -= 1
//| print(y)
//| elif buttons & B_DOWN:
//| y += 1
//| print(y)
//| time.sleep(0.1)
//| while buttons:
//| # Wait for all buttons to be released.
//| buttons = pad.get_pressed()
//| time.sleep(0.1)"""
//|
//| .. class:: GamePad([b1[, b2[, b3[, b4[, b5[, b6[, b7[, b8]]]]]]]])
//| def __init__(self, b1: Any, b2: Any, b3: Any, b4: Any, b5: Any, b6: Any, b7: Any, b8: Any):
//| """Initializes button scanning routines.
//|
//| Initializes button scanning routines.
//| The ``b1``-``b8`` parameters are ``DigitalInOut`` objects, which
//| immediately get switched to input with a pull-up, (unless they already
//| were set to pull-down, in which case they remain so), and then scanned
//| regularly for button presses. The order is the same as the order of
//| bits returned by the ``get_pressed`` function. You can re-initialize
//| it with different keys, then the new object will replace the previous
//| one.
//|
//| The ``b1``-``b8`` parameters are ``DigitalInOut`` objects, which
//| immediately get switched to input with a pull-up, (unless they already
//| were set to pull-down, in which case they remain so), and then scanned
//| regularly for button presses. The order is the same as the order of
//| bits returned by the ``get_pressed`` function. You can re-initialize
//| it with different keys, then the new object will replace the previous
//| one.
//| The basic feature required here is the ability to poll the keys at
//| regular intervals (so that de-bouncing is consistent) and fast enough
//| (so that we don't miss short button presses) while at the same time
//| letting the user code run normally, call blocking functions and wait
//| on delays.
//|
//| The basic feature required here is the ability to poll the keys at
//| regular intervals (so that de-bouncing is consistent) and fast enough
//| (so that we don't miss short button presses) while at the same time
//| letting the user code run normally, call blocking functions and wait
//| on delays.
//|
//| They button presses are accumulated, until the ``get_pressed`` method
//| is called, at which point the button state is cleared, and the new
//| button presses start to be recorded.
//| They button presses are accumulated, until the ``get_pressed`` method
//| is called, at which point the button state is cleared, and the new
//| button presses start to be recorded."""
//| ...
//|
STATIC mp_obj_t gamepad_make_new(const mp_obj_type_t *type, size_t n_args,
const mp_obj_t *args, mp_map_t *kw_args) {
@ -114,15 +114,15 @@ STATIC mp_obj_t gamepad_make_new(const mp_obj_type_t *type, size_t n_args,
return MP_OBJ_FROM_PTR(gamepad_singleton);
}
//| .. method:: get_pressed()
//|
//| Get the status of buttons pressed since the last call and clear it.
//| def get_pressed(self, ) -> Any:
//| """Get the status of buttons pressed since the last call and clear it.
//|
//| Returns an 8-bit number, with bits that correspond to buttons,
//| which have been pressed (or held down) since the last call to this
//| function set to 1, and the remaining bits set to 0. Then it clears
//| the button state, so that new button presses (or buttons that are
//| held down) can be recorded for the next call.
//| held down) can be recorded for the next call."""
//| ...
//|
STATIC mp_obj_t gamepad_get_pressed(mp_obj_t self_in) {
gamepad_obj_t* gamepad_singleton = MP_STATE_VM(gamepad_singleton);
@ -133,9 +133,9 @@ STATIC mp_obj_t gamepad_get_pressed(mp_obj_t self_in) {
MP_DEFINE_CONST_FUN_OBJ_1(gamepad_get_pressed_obj, gamepad_get_pressed);
//| .. method:: deinit()
//|
//| Disable button scanning.
//| def deinit(self, ) -> Any:
//| """Disable button scanning."""
//| ...
//|
STATIC mp_obj_t gamepad_deinit(mp_obj_t self_in) {
common_hal_gamepad_gamepad_deinit(self_in);

View File

@ -29,7 +29,7 @@
#include "shared-bindings/gamepad/GamePad.h"
#include "shared-bindings/util.h"
//| :mod:`gamepad` --- Button handling
//| """:mod:`gamepad` --- Button handling
//| ==================================
//|
//| .. module:: gamepad
@ -39,7 +39,7 @@
//| .. toctree::
//| :maxdepth: 3
//|
//| GamePad
//| GamePad"""
//|
STATIC const mp_rom_map_elem_t gamepad_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_gamepad) },

View File

@ -32,24 +32,25 @@
#include "shared-bindings/gamepadshift/__init__.h"
#include "supervisor/shared/translate.h"
//| .. currentmodule:: gamepadshift
//| class GamePadShift:
//| """.. currentmodule:: gamepadshift
//|
//| :class:`GamePadShift` -- Scan buttons for presses through a shift register
//| ===========================================================================
//| :class:`GamePadShift` -- Scan buttons for presses through a shift register
//| ==========================================================================="""
//|
//| .. class:: GamePadShift(clock, data, latch)
//| def __init__(self, clock: Any, data: Any, latch: Any):
//| """Initializes button scanning routines.
//|
//| Initializes button scanning routines.
//| The ``clock``, ``data`` and ``latch`` parameters are ``DigitalInOut``
//| objects connected to the shift register controlling the buttons.
//|
//| The ``clock``, ``data`` and ``latch`` parameters are ``DigitalInOut``
//| objects connected to the shift register controlling the buttons.
//| They button presses are accumulated, until the ``get_pressed`` method
//| is called, at which point the button state is cleared, and the new
//| button presses start to be recorded.
//|
//| They button presses are accumulated, until the ``get_pressed`` method
//| is called, at which point the button state is cleared, and the new
//| button presses start to be recorded.
//|
//| Only one gamepad (`gamepad.GamePad` or `gamepadshift.GamePadShift`)
//| may be used at a time.
//| Only one gamepad (`gamepad.GamePad` or `gamepadshift.GamePadShift`)
//| may be used at a time."""
//| ...
//|
STATIC mp_obj_t gamepadshift_make_new(const mp_obj_type_t *type, size_t n_args,
const mp_obj_t *pos_args, mp_map_t *kw_args) {
@ -81,15 +82,15 @@ STATIC mp_obj_t gamepadshift_make_new(const mp_obj_type_t *type, size_t n_args,
return MP_OBJ_FROM_PTR(gamepad_singleton);
}
//| .. method:: get_pressed()
//|
//| Get the status of buttons pressed since the last call and clear it.
//| def get_pressed(self, ) -> Any:
//| """Get the status of buttons pressed since the last call and clear it.
//|
//| Returns an 8-bit number, with bits that correspond to buttons,
//| which have been pressed (or held down) since the last call to this
//| function set to 1, and the remaining bits set to 0. Then it clears
//| the button state, so that new button presses (or buttons that are
//| held down) can be recorded for the next call.
//| held down) can be recorded for the next call."""
//| ...
//|
STATIC mp_obj_t gamepadshift_get_pressed(mp_obj_t self_in) {
gamepadshift_obj_t* gamepad_singleton = MP_STATE_VM(gamepad_singleton);
@ -99,9 +100,9 @@ STATIC mp_obj_t gamepadshift_get_pressed(mp_obj_t self_in) {
}
MP_DEFINE_CONST_FUN_OBJ_1(gamepadshift_get_pressed_obj, gamepadshift_get_pressed);
//| .. method:: deinit()
//|
//| Disable button scanning.
//| def deinit(self, ) -> Any:
//| """Disable button scanning."""
//| ...
//|
STATIC mp_obj_t gamepadshift_deinit(mp_obj_t self_in) {
common_hal_gamepadshift_gamepadshift_deinit(self_in);

View File

@ -30,7 +30,7 @@
#include "shared-bindings/digitalio/DigitalInOut.h"
#include "shared-bindings/util.h"
//| :mod:`gamepadshift` --- Tracks button presses read through a shift register
//| """:mod:`gamepadshift` --- Tracks button presses read through a shift register
//| ===========================================================================
//|
//| .. module:: gamepadshift
@ -40,7 +40,7 @@
//| .. toctree::
//| :maxdepth: 3
//|
//| GamePadShift
//| GamePadShift"""
//|
STATIC const mp_rom_map_elem_t gamepadshift_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_gamepadshift) },

View File

@ -49,20 +49,21 @@ STATIC mp_obj_t mp_obj_new_i2cslave_i2c_slave_request(i2cslave_i2c_slave_obj_t *
return (mp_obj_t)self;
}
//| .. currentmodule:: i2cslave
//| class I2CSlave:
//| """.. currentmodule:: i2cslave
//|
//| :class:`I2CSlave` --- Two wire serial protocol slave
//| ----------------------------------------------------
//| :class:`I2CSlave` --- Two wire serial protocol slave
//| ----------------------------------------------------"""
//|
//| .. class:: I2CSlave(scl, sda, addresses, smbus=False)
//| def __init__(self, scl: microcontroller.Pin, sda: microcontroller.Pin, addresses: tuple, smbus: bool = False):
//| """I2C is a two-wire protocol for communicating between devices.
//| This implements the slave side.
//|
//| I2C is a two-wire protocol for communicating between devices.
//| This implements the slave side.
//|
//| :param ~microcontroller.Pin scl: The clock pin
//| :param ~microcontroller.Pin sda: The data pin
//| :param tuple addresses: The I2C addresses to respond to (how many is hw dependent).
//| :param bool smbus: Use SMBUS timings if the hardware supports it
//| :param ~microcontroller.Pin scl: The clock pin
//| :param ~microcontroller.Pin sda: The data pin
//| :param tuple addresses: The I2C addresses to respond to (how many is hw dependent).
//| :param bool smbus: Use SMBUS timings if the hardware supports it"""
//| ...
//|
STATIC mp_obj_t i2cslave_i2c_slave_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
i2cslave_i2c_slave_obj_t *self = m_new_obj(i2cslave_i2c_slave_obj_t);
@ -104,9 +105,9 @@ STATIC mp_obj_t i2cslave_i2c_slave_make_new(const mp_obj_type_t *type, size_t n_
return (mp_obj_t)self;
}
//| .. method:: deinit()
//|
//| Releases control of the underlying hardware so other classes can use it.
//| def deinit(self, ) -> Any:
//| """Releases control of the underlying hardware so other classes can use it."""
//| ...
//|
STATIC mp_obj_t i2cslave_i2c_slave_obj_deinit(mp_obj_t self_in) {
mp_check_self(MP_OBJ_IS_TYPE(self_in, &i2cslave_i2c_slave_type));
@ -116,16 +117,16 @@ STATIC mp_obj_t i2cslave_i2c_slave_obj_deinit(mp_obj_t self_in) {
}
MP_DEFINE_CONST_FUN_OBJ_1(i2cslave_i2c_slave_deinit_obj, i2cslave_i2c_slave_obj_deinit);
//| .. method:: __enter__()
//|
//| No-op used in Context Managers.
//| def __enter__(self, ) -> Any:
//| """No-op used in Context Managers."""
//| ...
//|
// Provided by context manager helper.
//| .. method:: __exit__()
//|
//| Automatically deinitializes the hardware on context exit. See
//| :ref:`lifetime-and-contextmanagers` for more info.
//| def __exit__(self, ) -> Any:
//| """Automatically deinitializes the hardware on context exit. See
//| :ref:`lifetime-and-contextmanagers` for more info."""
//| ...
//|
STATIC mp_obj_t i2cslave_i2c_slave_obj___exit__(size_t n_args, const mp_obj_t *args) {
mp_check_self(MP_OBJ_IS_TYPE(args[0], &i2cslave_i2c_slave_type));
@ -135,13 +136,12 @@ STATIC mp_obj_t i2cslave_i2c_slave_obj___exit__(size_t n_args, const mp_obj_t *a
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(i2cslave_i2c_slave___exit___obj, 4, 4, i2cslave_i2c_slave_obj___exit__);
//| .. method:: request(timeout=-1)
//| def request(self, timeout: float = -1) -> Any:
//| """Wait for an I2C request from a master.
//|
//| Wait for an I2C request from a master.
//|
//| :param float timeout: Timeout in seconds. Zero means wait forever, a negative value means check once
//| :return: I2C Slave Request or None if timeout=-1 and there's no request
//| :rtype: ~i2cslave.I2CSlaveRequest
//| :param float timeout: Timeout in seconds. Zero means wait forever, a negative value means check once
//| :return: I2C Slave Request or None if timeout=-1 and there's no request
//| :rtype: ~i2cslave.I2CSlaveRequest"""
//|
STATIC mp_obj_t i2cslave_i2c_slave_request(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
mp_check_self(MP_OBJ_IS_TYPE(pos_args[0], &i2cslave_i2c_slave_type));
@ -228,34 +228,33 @@ const mp_obj_type_t i2cslave_i2c_slave_type = {
.locals_dict = (mp_obj_dict_t*)&i2cslave_i2c_slave_locals_dict,
};
//| :class:`I2CSlaveRequest` --- I2C Slave Request
//| ----------------------------------------------
//| class I2CSlaveRequest:
//| """:class:`I2CSlaveRequest` --- I2C Slave Request
//| ----------------------------------------------"""
//|
//| .. class:: I2CSlaveRequest(slave, address, is_read, is_restart)
//| def __init__(self, slave: i2cslave.I2CSlave, address: int, is_read: bool, is_restart: bool):
//| """I2C transfer request from a master.
//| This cannot be instantiated directly, but is returned by :py:meth:`I2CSlave.request`.
//|
//| I2C transfer request from a master.
//| This cannot be instantiated directly, but is returned by :py:meth:`I2CSlave.request`.
//|
//| :param ~i2cslave.I2CSlave slave: The I2C Slave receiving this request
//| :param int address: I2C address
//| :param bool is_read: I2C Master read request
//| :param bool is_restart: Repeated Start Condition
//| :param ~i2cslave.I2CSlave slave: The I2C Slave receiving this request
//| :param int address: I2C address
//| :param bool is_read: I2C Master read request
//| :param bool is_restart: Repeated Start Condition"""
//|
STATIC mp_obj_t i2cslave_i2c_slave_request_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
mp_arg_check_num(n_args, kw_args, 4, 4, false);
return mp_obj_new_i2cslave_i2c_slave_request(args[0], mp_obj_get_int(args[1]), mp_obj_is_true(args[2]), mp_obj_is_true(args[3]));
}
//| .. method:: __enter__()
//|
//| No-op used in Context Managers.
//| def __enter__(self, ) -> Any:
//| """No-op used in Context Managers."""
//| ...
//|
// Provided by context manager helper.
//| .. method:: __exit__()
//|
//| Close the request.
//| def __exit__(self, ) -> Any:
//| """Close the request."""
//| ...
//|
STATIC mp_obj_t i2cslave_i2c_slave_request_obj___exit__(size_t n_args, const mp_obj_t *args) {
mp_check_self(MP_OBJ_IS_TYPE(args[0], &i2cslave_i2c_slave_request_type));
@ -265,9 +264,8 @@ STATIC mp_obj_t i2cslave_i2c_slave_request_obj___exit__(size_t n_args, const mp_
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(i2cslave_i2c_slave_request___exit___obj, 4, 4, i2cslave_i2c_slave_request_obj___exit__);
//| .. attribute:: address
//|
//| The I2C address of the request.
//| address: Any = ...
//| """The I2C address of the request."""
//|
STATIC mp_obj_t i2cslave_i2c_slave_request_get_address(mp_obj_t self_in) {
mp_check_self(MP_OBJ_IS_TYPE(self_in, &i2cslave_i2c_slave_request_type));
@ -276,9 +274,8 @@ STATIC mp_obj_t i2cslave_i2c_slave_request_get_address(mp_obj_t self_in) {
}
MP_DEFINE_CONST_PROP_GET(i2cslave_i2c_slave_request_address_obj, i2cslave_i2c_slave_request_get_address);
//| .. attribute:: is_read
//|
//| The I2C master is reading from the device.
//| is_read: Any = ...
//| """The I2C master is reading from the device."""
//|
STATIC mp_obj_t i2cslave_i2c_slave_request_get_is_read(mp_obj_t self_in) {
mp_check_self(MP_OBJ_IS_TYPE(self_in, &i2cslave_i2c_slave_request_type));
@ -287,9 +284,8 @@ STATIC mp_obj_t i2cslave_i2c_slave_request_get_is_read(mp_obj_t self_in) {
}
MP_DEFINE_CONST_PROP_GET(i2cslave_i2c_slave_request_is_read_obj, i2cslave_i2c_slave_request_get_is_read);
//| .. attribute:: is_restart
//|
//| Is Repeated Start Condition.
//| is_restart: Any = ...
//| """Is Repeated Start Condition."""
//|
STATIC mp_obj_t i2cslave_i2c_slave_request_get_is_restart(mp_obj_t self_in) {
mp_check_self(MP_OBJ_IS_TYPE(self_in, &i2cslave_i2c_slave_request_type));
@ -298,15 +294,15 @@ STATIC mp_obj_t i2cslave_i2c_slave_request_get_is_restart(mp_obj_t self_in) {
}
MP_DEFINE_CONST_PROP_GET(i2cslave_i2c_slave_request_is_restart_obj, i2cslave_i2c_slave_request_get_is_restart);
//| .. method:: read(n=-1, ack=True)
//| def read(self, n: int = -1, ack: bool = True) -> Any:
//| """Read data.
//| If ack=False, the caller is responsible for calling :py:meth:`I2CSlaveRequest.ack`.
//|
//| Read data.
//| If ack=False, the caller is responsible for calling :py:meth:`I2CSlaveRequest.ack`.
//|
//| :param int n: Number of bytes to read (negative means all)
//| :param bool ack: Whether or not to send an ACK after the n'th byte
//| :return: Bytes read
//| :rtype: bytearray
//| :param int n: Number of bytes to read (negative means all)
//| :param bool ack: Whether or not to send an ACK after the n'th byte
//| :return: Bytes read
//| :rtype: bytearray"""
//| ...
//|
STATIC mp_obj_t i2cslave_i2c_slave_request_read(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
mp_check_self(MP_OBJ_IS_TYPE(pos_args[0], &i2cslave_i2c_slave_request_type));
@ -359,12 +355,12 @@ STATIC mp_obj_t i2cslave_i2c_slave_request_read(size_t n_args, const mp_obj_t *p
}
MP_DEFINE_CONST_FUN_OBJ_KW(i2cslave_i2c_slave_request_read_obj, 1, i2cslave_i2c_slave_request_read);
//| .. method:: write(buffer)
//| def write(self, buffer: bytearray) -> Any:
//| """Write the data contained in buffer.
//|
//| Write the data contained in buffer.
//|
//| :param bytearray buffer: Write out the data in this buffer
//| :return: Number of bytes written
//| :param bytearray buffer: Write out the data in this buffer
//| :return: Number of bytes written"""
//| ...
//|
STATIC mp_obj_t i2cslave_i2c_slave_request_write(mp_obj_t self_in, mp_obj_t buf_in) {
mp_check_self(MP_OBJ_IS_TYPE(self_in, &i2cslave_i2c_slave_request_type));
@ -393,12 +389,12 @@ STATIC mp_obj_t i2cslave_i2c_slave_request_write(mp_obj_t self_in, mp_obj_t buf_
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(i2cslave_i2c_slave_request_write_obj, i2cslave_i2c_slave_request_write);
//| .. method:: ack(ack=True)
//| def ack(self, ack: bool = True) -> Any:
//| """Acknowledge or Not Acknowledge last byte received.
//| Use together with :py:meth:`I2CSlaveRequest.read` ack=False.
//|
//| Acknowledge or Not Acknowledge last byte received.
//| Use together with :py:meth:`I2CSlaveRequest.read` ack=False.
//|
//| :param bool ack: Whether to send an ACK or NACK
//| :param bool ack: Whether to send an ACK or NACK"""
//| ...
//|
STATIC mp_obj_t i2cslave_i2c_slave_request_ack(uint n_args, const mp_obj_t *args) {
mp_check_self(MP_OBJ_IS_TYPE(args[0], &i2cslave_i2c_slave_request_type));

View File

@ -35,7 +35,7 @@
#include "py/runtime.h"
//| :mod:`i2cslave` --- Two wire serial protocol slave
//| """:mod:`i2cslave` --- Two wire serial protocol slave
//| ==================================================
//|
//| .. module:: i2cslave
@ -101,7 +101,7 @@
//|
//| Raspberry Pi in particular does not support this with its I2C hw block.
//| This can be worked around by using the ``i2c-gpio`` bit banging driver.
//| Since the RPi firmware uses the hw i2c, it's not possible to emulate a HAT eeprom.
//| Since the RPi firmware uses the hw i2c, it's not possible to emulate a HAT eeprom."""
//|
STATIC const mp_rom_map_elem_t i2cslave_module_globals_table[] = {