diff --git a/Documentation/conf.py b/Documentation/conf.py index 769dbc5df08d1425dd5c99e3c85f251720442bc2..7dafb1841c521151d8a63dc91f1b892e9b2193e4 100644 --- a/Documentation/conf.py +++ b/Documentation/conf.py @@ -87,7 +87,7 @@ html_context = { # }}} # -- Options for Auto-Doc ---------------------------------------------------- {{{ -autodoc_mock_imports = ["sys_display", "ucollections", "urandom", "utime"] +autodoc_mock_imports = ["sys_display", "sys_leds", "ucollections", "urandom", "utime"] autodoc_member_order = "bysource" # }}} diff --git a/Documentation/pycardium/leds.rst b/Documentation/pycardium/leds.rst index 6f556f4f266ea666d6e917b12118db7cd59d1b30..e3cae9ab077af93e7d11bbe39e50d5bea425cfb1 100644 --- a/Documentation/pycardium/leds.rst +++ b/Documentation/pycardium/leds.rst @@ -1,5 +1,8 @@ ``leds`` - LEDs =============== +The ``leds`` module provides functions to interact with card10's RGB LEDs. +This is the 11 LEDs above the display and 4 LEDs on the underside of the +top-board, in the four corners. -.. automodule:: display +.. automodule:: leds :members: diff --git a/epicardium/epicardium.h b/epicardium/epicardium.h index 5a816a4da6d20923bd894bcc3c744d97a1698cf3..2c65e376d4f3741592d34e1e64f57cd3c9714db2 100644 --- a/epicardium/epicardium.h +++ b/epicardium/epicardium.h @@ -5,10 +5,12 @@ #include <errno.h> #ifndef __SPHINX_DOC -/* stddef.h is not recognized by hawkmoth for some odd reason */ +/* Some headers are not recognized by hawkmoth for some odd reason */ #include <stddef.h> +#include <stdbool.h> #else typedef unsigned int size_t; +typedef _Bool bool; #endif /* __SPHINX_DOC */ /* @@ -225,54 +227,62 @@ API_ISR(EPIC_INT_CTRL_C, epic_isr_ctrl_c); /** * Set one of card10's RGB LEDs to a certain color in RGB format. * - * This function is rather slow when setting multiple LEDs, use leds_set_all or leds_prep + leds_update instead. + * This function is rather slow when setting multiple LEDs, use + * :c:func:`leds_set_all` or :c:func:`leds_prep` + :c:func:`leds_update` + * instead. * - * :param int led: Which LED to set. 0-10 are the LEDs on the top and 11-14 are the 4 "ambient" LEDs. + * :param int led: Which LED to set. 0-10 are the LEDs on the top and 11-14 + * are the 4 "ambient" LEDs. * :param uint8_t r: Red component of the color. * :param uint8_t g: Green component of the color. - * :param uint8_t b: Blue component of the color. + * :param uint8_t b: Blue component of the color. */ API(API_LEDS_SET, void epic_leds_set(int led, uint8_t r, uint8_t g, uint8_t b)); /** * Set one of card10's RGB LEDs to a certain color in HSV format. * - * This function is rather slow when setting multiple LEDs, use leds_set_all_hsv or leds_prep_hsv + leds_update instead. + * This function is rather slow when setting multiple LEDs, use + * :c:func:`leds_set_all_hsv` or :c:func:`leds_prep_hsv` + :c:func:`leds_update` + * instead. * * :param int led: Which LED to set. 0-10 are the LEDs on the top and 11-14 are the 4 "ambient" LEDs. * :param float h: Hue component of the color. (0 <= h < 360) * :param float s: Saturation component of the color. (0 <= s <= 1) * :param float v: Value/Brightness component of the color. (0 <= v <= 0) - */ + */ API(API_LEDS_SET_HSV, void epic_leds_set_hsv(int led, float h, float s, float v)); /** * Set multiple of card10's RGB LEDs to a certain color in RGB format. * - * The first $len led are set, the remaining ones are not modified. + * The first ``len`` leds are set, the remaining ones are not modified. * - * :param uint8_t[len][r,g,b] *pattern: Array with RGB Values with 0 <= len <= 15. 0-10 are the LEDs on the top and 11-14 are the 4 "ambient" LEDs. - * :param uint8_t len: Length of 1st dimension of *pattern, see above. - */ + * :param uint8_t[len][r,g,b] pattern: Array with RGB Values with 0 <= len <= + * 15. 0-10 are the LEDs on the top and 11-14 are the 4 "ambient" LEDs. + * :param uint8_t len: Length of 1st dimension of ``pattern``, see above. + */ API(API_LEDS_SET_ALL, void epic_leds_set_all(uint8_t *pattern, uint8_t len)); /** * Set multiple of card10's RGB LEDs to a certain color in HSV format. * - * The first $len led are set, the remaining ones are not modified. - * - * :param uint8_t[len][h,s,v] *pattern: Array of format with HSV Values with 0 <= len <= 15. 0-10 are the LEDs on the top and 11-14 are the 4 "ambient" LEDs. (0 <= h < 360, 0 <= s <= 1, 0 <= v <= 1) + * The first ``len`` led are set, the remaining ones are not modified. * - * :param uint8_t len: Length of 1st dimension of *pattern, see above. - */ + * :param uint8_t[len][h,s,v] pattern: Array of format with HSV Values with 0 + * <= len <= 15. 0-10 are the LEDs on the top and 11-14 are the 4 "ambient" + * LEDs. (0 <= h < 360, 0 <= s <= 1, 0 <= v <= 1) + * :param uint8_t len: Length of 1st dimension of ``pattern``, see above. + */ API(API_LEDS_SET_ALL_HSV, void epic_leds_set_all_hsv(float *pattern, uint8_t len)); /** * Prepare one of card10's RGB LEDs to be set to a certain color in RGB format. * - * Use leds_update() to apply changes. + * Use :c:func:`leds_update` to apply changes. * - * :param int led: Which LED to set. 0-10 are the LEDs on the top and 11-14 are the 4 "ambient" LEDs. + * :param int led: Which LED to set. 0-10 are the LEDs on the top and 11-14 + * are the 4 "ambient" LEDs. * :param uint8_t r: Red component of the color. * :param uint8_t g: Green component of the color. * :param uint8_t b: Blue component of the color. @@ -282,19 +292,22 @@ API(API_LEDS_PREP, void epic_leds_prep(int led, uint8_t r, uint8_t g, uint8_t b) /** * Prepare one of card10's RGB LEDs to be set to a certain color in HSV format. * - * Use leds_update() to apply changes. + * Use :c:func:`leds_update` to apply changes. * - * :param int led: Which LED to set. 0-10 are the LEDs on the top and 11-14 are the 4 "ambient" LEDs. + * :param int led: Which LED to set. 0-10 are the LEDs on the top and 11-14 + * are the 4 "ambient" LEDs. * :param uint8_t h: Hue component of the color. (float, 0 <= h < 360) * :param uint8_t s: Saturation component of the color. (float, 0 <= s <= 1) * :param uint8_t v: Value/Brightness component of the color. (float, 0 <= v <= 0) - */ + */ API(API_LEDS_PREP_HSV, void epic_leds_prep_hsv(int led, float h, float s, float v)); /** * Set global brightness for top RGB LEDs. * - * Aside from PWM, the RGB LEDs' overall brightness can be controlled with a current limiter independently to achieve a higher resolution at low brightness which can be set with this function. + * Aside from PWM, the RGB LEDs' overall brightness can be controlled with a + * current limiter independently to achieve a higher resolution at low + * brightness which can be set with this function. * * :param uint8_t value: Global brightness of top LEDs. (1 <= value <= 8, default = 1) */ @@ -303,7 +316,9 @@ API(API_LEDS_DIM_BOTTOM, void epic_leds_dim_bottom(uint8_t value)); /** * Set global brightness for bottom RGB LEDs. * - * Aside from PWM, the RGB LEDs' overall brightness can be controlled with a current limiter independently to achieve a higher resolution at low brightness which can be set with this function. + * Aside from PWM, the RGB LEDs' overall brightness can be controlled with a + * current limiter independently to achieve a higher resolution at low + * brightness which can be set with this function. * * :param uint8_t value: Global brightness of bottom LEDs. (1 <= value <= 8, default = 8) */ @@ -312,43 +327,66 @@ API(API_LEDS_DIM_TOP, void epic_leds_dim_top(uint8_t value)); /** * Enables or disables powersave mode. * - * Even when set to zero, the RGB LEDs still individually consume ~1mA. Powersave intelligently switches the supply power in groups. This introduces delays in the magnitude of ~10us, so it can be disabled for high speed applications such as POV. + * Even when set to zero, the RGB LEDs still individually consume ~1mA. + * Powersave intelligently switches the supply power in groups. This introduces + * delays in the magnitude of ~10µs, so it can be disabled for high speed + * applications such as POV. * - * :param bool eco: Activates powersave if true, disables it when false. (default = True) + * :param bool eco: Activates powersave if true, disables it when false. (default = True) */ -API(API_LEDS_SET_POWERSAVE, void epic_leds_set_powersave(_Bool eco)); +API(API_LEDS_SET_POWERSAVE, void epic_leds_set_powersave(bool eco)); /** - * Updates the RGB LEDs with changes that have been set with leds_prep() or leds_prep(). + * Updates the RGB LEDs with changes that have been set with :c:func:`leds_prep` + * or :c:func:`leds_prep_hsv`. * - * The LEDs can be only updated in bulk, so using this approach instead of leds_set() or leds_set_hsv() significantly reduces the load on the corresponding hardware bus. + * The LEDs can be only updated in bulk, so using this approach instead of + * :c:func:`leds_set` or :c:func:`leds_set_hsv` significantly reduces the load + * on the corresponding hardware bus. */ API(API_LEDS_UPDATE, void epic_leds_update(void)); /** - * Set the brightness of the rocket LEDs. + * Set the brightness of one of the rocket LEDs. * - *:param int led: Which LED to set. 0->Blue, 1->Yellow, 2->Green. - *:param uint8_t value: Brightness of LED + * :param int led: Which LED to set. + * + * +-------+--------+----------+ + * | ID | Color | Location | + * +=======+========+==========+ + * | ``0`` | Blue | Left | + * +-------+--------+----------+ + * | ``1`` | Yellow | Top | + * +-------+--------+----------+ + * | ``2`` | Green | Right | + * +-------+--------+----------+ + * :param uint8_t value: Brightness of LED (only two brightness levels are + * supported right now). */ API(API_LEDS_SET_ROCKET, void epic_leds_set_rocket(int led, uint8_t value)); /** * Turn on the bright side LED which can serve as a flashlight if worn on the left wrist or as a rad tattoo illuminator if worn on the right wrist. * - *:param bool power: Side LED on iff true. + *:param bool power: Side LED on if true. */ -API(API_LEDS_SET_FLASHLIGHT, void epic_set_flashlight(_Bool power)); +API(API_LEDS_SET_FLASHLIGHT, void epic_set_flashlight(bool power)); /** - * Set up gamma lookup table for individual rgb channel + * Set gamma lookup table for individual rgb channels. * - * Since the RGB LEDs' subcolor LEDs have different peak brightness and the linear scaling introduced by PWM is not desireable for color accurate work, custom lookup tables for each individual color channel can be loaded into the epicardium's memory with this function. + * Since the RGB LEDs' subcolor LEDs have different peak brightness and the + * linear scaling introduced by PWM is not desireable for color accurate work, + * custom lookup tables for each individual color channel can be loaded into the + * Epicardium's memory with this function. * - *:param uint8_t rgb_channel: Color whose gamma table is to be updated, 0->Red, 1->Green, 2->Blue. - *:param uint8_t[256] *gamma_table: Gamma lookup table. (default = 4th order power function rounded up) + * :param uint8_t rgb_channel: Color whose gamma table is to be updated, 0->Red, 1->Green, 2->Blue. + * :param uint8_t[256] gamma_table: Gamma lookup table. (default = 4th order power function rounded up) */ -API(API_LEDS_SET_GAMMA_TABLE, void epic_leds_set_gamma_table(uint8_t rgb_channel, uint8_t *gamma_table)); +API(API_LEDS_SET_GAMMA_TABLE, void epic_leds_set_gamma_table( + uint8_t rgb_channel, + uint8_t *gamma_table +)); /** * Sensor Data Streams diff --git a/pycardium/modules/py/leds.py b/pycardium/modules/py/leds.py index 15e52c26b5193c79e8832518dce49c0d355b7e19..05038e848abaae8f559021bfe74944988b4b0fb5 100644 --- a/pycardium/modules/py/leds.py +++ b/pycardium/modules/py/leds.py @@ -4,14 +4,22 @@ import math def update(): """ - Updates the RGB LEDs with changes that have been set with prep() or prep_hsv(). The LEDs can be only updated in bulk, so using this approach instead of set() or set_hsv() significantly reduces the load on the corresponding hardware bus. + Updates the RGB LEDs. + + This will apply changes that have been set with :func:`leds.prep` or + :func:`leds.prep_hsv`. The LEDs can be only updated in bulk, so using this + approach instead of :func:`leds.set` or :func:`leds.set_hsv` significantly + reduces the load on the corresponding hardware bus. """ sys_leds.update() def clear(): """ - Turns all LEDs off. Does NOT reactivate powersave if it has been deactivated, in which case ~15mA will be wasted. + Turns all LEDs off. + + Does **not** reactivate powersave if it has been deactivated, in which case + ~15mA will be wasted. """ values = [[0, 0, 0] for x in range(15)] sys_leds.set_all(values) @@ -19,9 +27,12 @@ def clear(): def flashlight(on): """ - Turn on the bright side LED which can serve as a flashlight if worn on the left wrist or as a rad tattoo illuminator if worn on the right wrist. + Turn on the bright side LED. + + This LED can serve as a flashlight if worn on the left wrist or as a rad + tattoo illuminator if worn on the right wrist. - :param on: Side LED on iff true. + :param bool on: Side LED on if true. """ sys_leds.set_flashlight(on) @@ -29,8 +40,8 @@ def flashlight(on): def dim_top(value): """ Set global brightness for top RGB LEDs. - - :param value: Brightness. Default = 1, range = 1...8 + + :param int value: Brightness. Default = 1, range = 1...8 """ sys_leds.dim_top(value) @@ -38,8 +49,8 @@ def dim_top(value): def dim_bottom(value): """ Set global brightness for bottom RGB LEDs. - - :param value: Brightness. Default = 8, range = 1...8 + + :param int value: Brightness. Default = 8, range = 1...8 """ sys_leds.dim_bottom(value) @@ -47,55 +58,90 @@ def dim_bottom(value): def rocket(led, value): """ Set brightness of one of the rocket LEDs. - - :param led: Choose your rocket! 0->Blue, 1->Yellow, 2->Green + + :param int led: Choose your rocket! + + +-------+--------+----------+ + | ID | Color | Location | + +=======+========+==========+ + | ``0`` | Blue | Left | + +-------+--------+----------+ + | ``1`` | Yellow | Top | + +-------+--------+----------+ + | ``2`` | Green | Right | + +-------+--------+----------+ + :param int value: Brightness of LED (only two brightness levels are + supported right now). """ sys_leds.set_rocket(led, value) def prep(led, color): """ - Prepare a RGB LED to be set to a RGB value. Changes are applied upon calling update(). This is faster than individual set() or set_hsv() calls in case of multiple changes. + Prepare am RGB LED to be set to an RGB value. + + Changes are applied upon calling :func:`leds.update`. This is faster than + individual :func:`leds.set` or :func:`leds.set_hsv` calls in case of + multiple changes. - :param led: Which LED to prepare. 0-10 are the LEDs on the top and 11-14 are the 4 "ambient" LEDs - :param color: RGB triplet + :param int led: Which LED to prepare. 0-10 are the LEDs on the top and + 11-14 are the 4 "ambient" LEDs + :param [r,g,b] color: RGB triplet """ sys_leds.prep(led, color) def prep_hsv(led, color): """ - Prepare a RGB LED to be set to a HSV value. Changes are applied upon calling update(). This is faster than individual set() or set_hsv() calls in case of multiple changes. + Prepare an RGB LED to be set to an HSV value. - :param led: Which LED to prepare. 0-10 are the LEDs on the top and 11-14 are the 4 "ambient" LEDs - :param color: HSV triplet + Changes are applied upon calling :func:`leds.update`. This is faster than + individual :func:`leds.set` or :func:`leds.set_hsv` calls in case of + multiple changes. + + :param int led: Which LED to prepare. 0-10 are the LEDs on the top and + 11-14 are the 4 "ambient" LEDs + :param [h,s,v] color: HSV triplet """ sys_leds.prep_hsv(led, color) def set(led, color): """ - Set a RGB LED to a RGB value. + Set an RGB LED to an RGB value. - :param led: Which LED to prepare. 0-10 are the LEDs on the top and 11-14 are the 4 "ambient" LEDs - :param color: RGB triplet + :param int led: Which LED to set. 0-10 are the LEDs on the top and 11-14 + are the 4 "ambient" LEDs + :param [r,g,b] color: RGB triplet """ sys_leds.set(led, color) def set_hsv(led, color): """ - Prepare a RGB LED to be set to a RGB value. Changes are applied upon calling update() + Prepare an RGB LED to be set to an HSV value. - :param led: Which LED to prepare. 0-10 are the LEDs on the top and 11-14 are the 4 "ambient" LEDs - :param color: RGB triplet + :param int led: Which LED to set. 0-10 are the LEDs on the top and 11-14 + are the 4 "ambient" LEDs + :param [h,s,v] color: HSV triplet """ sys_leds.set_hsv(led, color) def set_all(colors): """ - Set multiple RGB LEDs to RGB values. Filling starts at LED0 ascending. + Set multiple RGB LEDs to RGB values. + + Filling starts at LED0 ascending. + + **Example**: + + .. code-block:: python + + import leds, color + + # 1st red, 2nd green & 3rd blue: + leds.set_all([color.RED, color.GREEN, color.BLUE]) :param colors: List of RGB triplets """ @@ -104,7 +150,9 @@ def set_all(colors): def set_all_hsv(colors): """ - Set multiple RGB LEDs to HSV values. Filling starts at LED0 ascending. + Set multiple RGB LEDs to HSV values. + + Filling starts at LED0 ascending. :param colors: List of HSV triplets """ @@ -116,15 +164,18 @@ def gay(value=0.5): Gamma Adjust Yassistant. Prints a rainbow. Recommended calibration prodecure: - + .. code-block:: python - import leds - leds.gay(1) - gamma_rgb(channel=?, gain=?) //adjust gain for uniform brightness - leds.gay(0.5) - gamma_rgb(channel=?, power=?) //adjust power~4 for uniform brightness - + import leds + + leds.gay(1) + # adjust gain for uniform brightness + leds.gamma_rgb(channel=..., gain=...) + + leds.gay(0.5) + # adjust power~4 for uniform brightness + leds.gamma_rgb(channel=..., power=...) :param value: Brightness. Default = 0.5 """ @@ -134,9 +185,14 @@ def gay(value=0.5): def powersave(eco=True): """ - Enables or disables powersave mode. Even when set to zero, the RGB LEDs still individually consume ~1mA. Powersave intelligently switches the supply power in groups. This introduces delays in the magnitude of ~10us, so it can be disabled for high speed applications such as POV. + Enable or disable powersave mode. + + Even when set to zero, the RGB LEDs still individually consume ~1mA. + Powersave intelligently switches the supply power in groups. This + introduces delays in the magnitude of ~10us, so it can be disabled for high + speed applications such as POV. - :param eco: Activates powersave if true, disables it when false. (default = True) + :param bool eco: Activates powersave if ``True``, disables it when ``False``. """ sys_leds.set_powersave(eco) @@ -145,7 +201,7 @@ def gamma(power=4.0): """ Applies same power function gamma correction to all RGB channels. - :param power: Exponent of power function. Default = 4.0 + :param float power: Exponent of power function. """ table = [int(math.ceil(math.pow((x / 255.0), power) * 255)) for x in range(256)] for i in range(3): @@ -157,9 +213,10 @@ def gamma_rgb(channel, power=4.0, gain=1.0): """ Applies power function gamma correction with optional amplification to a single RGB channel. - :param channel: RGB channel to be adjusted. 0->Red, 1->Green, 2->Blue. - :param power: Exponent of power function. Default 4.0 - :param gain: Amplification of channel. Values above 1.0 might cause overflow. Default = 1.0 + :param int channel: RGB channel to be adjusted. 0->Red, 1->Green, 2->Blue. + :param float power: Exponent of power function. + :param float gain: Amplification of channel. Values above 1.0 might cause + overflow. """ table = [ int(math.ceil(math.pow((x / 255.0), power) * gain * 255)) for x in range(256)