Commits (54)
......@@ -6,6 +6,47 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## [Unreleased]
## [v1.11] - 2019-09-24 - [Karotte]
[Karotte]: https://card10.badge.events.ccc.de/release/card10-v1.11-Karotte.zip
### Added
- **Support for sleep-mode instead of full power-off. This means the RTC now
retains its state!**
- For debugger users: A GDB macro `task_backtrace` which allows to view
backtraces of tasks which are currently swapped out. Use like
```text
(gdb) task_backtrace serial_task_id
...
(gdb) task_backtrace dispatcher_task_id
...
(gdb) task_backtrace ble_task_id
```
- BHI160 magnetometer sensor
- ESB API in Pycardium.
- Monotonic clock API
- New FOSS font ...
### Changed
- `Display.print()` uses a transparent background when printing with `bg == fg`.
- Try different crc16 module during build because different environments might
have different ones installed.
- Improved ECG app, it can now blink on pulse and more!
- Improved BHI160 and BME680 apps.
### Fixed
- Fixed a regression which made it impossible to turn off the flashlight.
- Fixed CRT for l0dables not allowing to overwrite interrupt handlers.
- Fixed ECG App not closing the sensor on `KeyboardInterrupt`.
- Fixed a bug which made the power-button unresponsive when pressed during boot
(Interrupts were getting ignored).
- Fixed `simple_menu.Menu.exit()` not actually working.
- Added a few missing locks in `leds` module.
- Added a workaround for BHI160 axis mapping not being applied in some cases.
- Added a critical-section in BLE stack initialization to prevent weird lock-ups.
- Fixed vibra module crashing when calling `vibra.vibrate()` while already running.
- Fixed sensor-sample overflow leading to I2C bus lockup.
## [v1.10] - 2019-09-05 21:42 - [JerusalemArtichoke]
[JerusalemArtichoke]: https://card10.badge.events.ccc.de/release/card10-v1.10-JerusalemArtichoke.zip
......@@ -240,7 +281,8 @@ fbf7c8c0 fix(menu.py) Refactored menu.py based on !138
## [v1.0] - 2019-08-21 00:50
Initial release.
[Unreleased]: https://git.card10.badge.events.ccc.de/card10/firmware/compare/v1.10...master
[Unreleased]: https://git.card10.badge.events.ccc.de/card10/firmware/compare/v1.11...master
[v1.11]: https://git.card10.badge.events.ccc.de/card10/firmware/compare/v1.10...v1.11
[v1.10]: https://git.card10.badge.events.ccc.de/card10/firmware/compare/v1.9...v1.10
[v1.9]: https://git.card10.badge.events.ccc.de/card10/firmware/compare/v1.8...v1.9
[v1.8]: https://git.card10.badge.events.ccc.de/card10/firmware/compare/v1.7...v1.8
......
......@@ -105,7 +105,7 @@ Rockets characteristic
The Rockets characteristic makes it possible to address every three rockets.
Just write there three byte array, one for evey rocket.
On read you get the current value of all three rockets.
Range is between 0 and 31 (``0x1f`) if send higher value it will set to max of 31.
Range is between 0 and 31 (``0x1f``) if send higher value it will set to max of 31.
Dataformat:
......
......@@ -144,6 +144,15 @@ In order to do a rebuild you can issue a clean command to ninja via
Otherwise, rerunning ``./bootstrap.sh`` will also clean the build-directory.
.. note::
**macOS**: If ``strip`` fails to work on the freshly compiled ``mpy-cross``:
"strip: object: (...)/lib/micropython/micropython/mpy-cross/mpy-cross
malformed object (unknown load command 9)", you a likely not using the
`strip` that matches to your ``clang``. Do ``which strip && which clang``,
and if the paths don't match, clean up your PATHs, or as a quick hack,
create a symlink for strip.
.. note::
If you try to flash pycardium_epicardium.bin (renamed to card10.bin)
......
......@@ -14,24 +14,38 @@ Epicardium
Epicardium is based on `FreeRTOS <https://www.freertos.org/>`_. There are a
number of tasks that will have been keeping card10 running. These are:
* **Dispatcher**: The dispatcher task handles API calls from core 1.
* **PMIC**: The power manager task checks the battery level and other interesting
statistics that can be gathered from our power manager IC (MAX77650).
* **Serial**: Handles serial communication via *UART*, *CDC ACM* and possibly
Bluetooth.
* **BHI160**: Housekeeping task for interaction with the `BHI160`_.
+-------------------+-------------------------------+----------+-------------------------------------------+
| Name | ID Global | Priority | Description |
+===================+===============================+==========+===========================================+
| `vPmicTask`_ | ``pmic_task_id`` (static) | +4 | Power Management (and Reset Button) |
+-------------------+-------------------------------+----------+-------------------------------------------+
| `vLifecycleTask`_ | ``lifecycle_task`` (static) | +3 | Control of the payload running on core 1. |
+-------------------+-------------------------------+----------+-------------------------------------------+
| `vBleTask`_ | ``ble_task_id`` (static) | +3 | Bluetooth Low Energy Stack |
+-------------------+-------------------------------+----------+-------------------------------------------+
| `vSerialTask`_ | ``serial_task_id`` | +3 | Serial Output via UART/CDC-ACM/BLE |
+-------------------+-------------------------------+----------+-------------------------------------------+
| `vApiDispatcher`_ | ``dispatcher_task_id`` | +2 | Epicardium API dispatcher |
+-------------------+-------------------------------+----------+-------------------------------------------+
| `vLedTask`_ | -/- | +1 | LED Animations |
+-------------------+-------------------------------+----------+-------------------------------------------+
| `vMAX30001Task`_ | ``max30001_task_id`` (static) | +1 | `MAX30001`_ ECG driver |
+-------------------+-------------------------------+----------+-------------------------------------------+
| `vBhi160Task`_ | ``bhi160_task_id`` (static) | +1 | `BHI160`_ sensor fusion driver |
+-------------------+-------------------------------+----------+-------------------------------------------+
.. _vPmicTask: https://git.card10.badge.events.ccc.de/card10/firmware/blob/master/epicardium/modules/pmic.c#L281
.. _vLifecycleTask: https://git.card10.badge.events.ccc.de/card10/firmware/blob/master/epicardium/modules/lifecycle.c#L361
.. _vBleTask: https://git.card10.badge.events.ccc.de/card10/firmware/blob/master/epicardium/ble/ble.c#L237
.. _vSerialTask: https://git.card10.badge.events.ccc.de/card10/firmware/blob/master/epicardium/modules/serial.c#L289
.. _vApiDispatcher: https://git.card10.badge.events.ccc.de/card10/firmware/blob/master/epicardium/modules/dispatcher.c#L25
.. _vLedTask: https://git.card10.badge.events.ccc.de/card10/firmware/blob/master/epicardium/modules/personal_state.c#L58
.. _vMAX30001Task: https://git.card10.badge.events.ccc.de/card10/firmware/blob/master/epicardium/modules/max30001.c#L378
.. _vBhi160Task: https://git.card10.badge.events.ccc.de/card10/firmware/blob/master/epicardium/modules/bhi.c#L419
.. _MAX30001: https://www.maximintegrated.com/en/products/analog/data-converters/analog-front-end-ics/MAX30001.html
.. _BHI160: https://www.bosch-sensortec.com/bst/products/all_products/bhi160
.. todo::
The following tasks have not yet been implemented/are currently in the works:
- **Bluetooth**: The bluetooth stack (`#23`_)
- **Payload Controller**: Control what is running on core 1
.. _#23: https://git.card10.badge.events.ccc.de/card10/firmware/issues/23
Epicardium API
--------------
Epicardium exposes lots of functionality via the *Epicardium API*. The
......@@ -48,13 +62,15 @@ Pycardium, take a look at the :ref:`pycardium_guide` guide.
L0dables
--------
Next to Pycardium, other bare-metal code can also run on core 1. For example,
a Rustcardium or C-cardium. These l0dables must be compiled using our special
a `Rustcardium`_ or C-cardium. These l0dables must be compiled using our special
linker script and should link against the api-caller library so they can
interface with the :ref:`epicardium_api`.
Note: this feature is disabled by default and has to be enabled at build time.
To do this, run ``bootstrap.sh`` with the option ``-Djailbreak_card10=true``
and rebuild the firmware as described in :ref:`how_to_build`.
.. _Rustcardium: https://git.card10.badge.events.ccc.de/astro/rust-card10
.. todo::
Provide more details how this works
......
......@@ -100,3 +100,31 @@ Supports the BHI160 sensor on the card10 for accelerometer, gyroscope...
Close the connection to the sensor
.. class:: bhi160.BHI160Magnetometer
Magnetometer of the BHI160
Parameters:
sample_rate: int, optional
Sample rate (default is 4)
dynamic_range: int, optional
Dynamic range (default is 1)
callback: callable, optional
Call this callback when enough data is collected (default is None)
.. todo:: The callback functionality is untested, so do not be confused if it does not work.
sample_buffer_len: int, optional
Length of sample buffer (default is 200)
.. versionadded:: 1.11
.. py:method:: read():
Read sensor values
:returns: Collected sensor values as list
.. py:method:: close():
Close the connection to the sensor
......@@ -72,3 +72,30 @@ Card10-Specific
Please only call this function if absolutely necessary. In most cases
you'll want to just :py:func:`os.exit` instead.
.. py:function:: usbconfig(config_type)
Change active USB configuration. By default, card10 boots with
:py:data:`os.USB_SERIAL` active.
This will deactivate the currently active USB configuration. This means
that, if you activate :py:data:`os.USB_FLASH` while :py:data:`os.USB_SERIAL`
was active, the USB serial will be disconnected.
:param config_type: Selects which config to activate. Possible
values are :py:data:`os.USB_SERIAL`, :py:data:`os.USB_FLASH`,
or :py:data:`os.USB_NONE`.
.. versionadded:: 1.11
.. py:data:: USB_NONE
No USB device active.
.. py:data:: USB_SERIAL
CDC-ACM serial device active.
.. py:data:: USB_FLASH
Mass-Storage device active.
......@@ -49,10 +49,19 @@ and power it on::
leds.set_rocket(0, 31)
.. note::
If you're using iOS/Mac then you can connect to your serial console using:
.. code-block:: shell-session
screen /dev/tty.usbmodem* 115200
You can now see in your console what buttons you have pressed and your
console outputs/logs. With ``CTRL+C`` you exit the console.
REPL modes
^^^^^^^^^^
MicroPython supports a different REPL modes over the serial console. The modes
can be changed on every new line.
......@@ -77,5 +86,3 @@ or give you tracebacks if an error occured.
You can use **pycard10** (tools/pycard10.py) to execute python files from your
PC directly on the card10.
......@@ -33,6 +33,18 @@ alarm.
Return the current timestamp in milliseconds since 2000-01-01 00:00 in
the local timezone.
.. py:function:: monotonic()
Return a monotonically increasing timestamp.
.. versionadded:: 1.11
.. py:function:: monotonic_ms()
Return a monotonically increasing timestamp in milliseconds.
.. versionadded:: 1.11
.. py:function:: set_time(secs)
Sets the time to ``secs`` seconds since 2000-01-01 00:00 in the local
......
#!/usr/bin/env python3
import sys
import crc16
try:
import crc16
crcfun = crc16.crc16xmodem
except ImportError:
try:
import crcmod
crcfun = crcmod.predefined.mkCrcFun("xmodem")
except ImportError:
try:
import crcelk
crcfun = crcelk.CRC_XMODEM.calc_bytes
except ImportError:
raise Exception(
"Could not find a CRC implementation. Tried: crc16, crcmod, crcelk."
)
def main():
data = open(sys.argv[1], 'rb').read()
crc = crc16.crc16xmodem(data)
data = open(sys.argv[1], "rb").read()
crc = crcfun(data)
# print(crc)
padded = data + bytes([crc >> 8, crc & 0xFF])
crc = crc16.crc16xmodem(padded)
crc = crcfun(padded)
# print(crc)
open(sys.argv[1], 'wb').write(padded)
open(sys.argv[1], "wb").write(padded)
if __name__ == "__main__":
......
......@@ -244,10 +244,18 @@ void vBleTask(void *pvParameters)
vTaskDelay(pdMS_TO_TICKS(500));
WsfInit();
taskENTER_CRITICAL();
/* Critical section to prevent a loop in iq_capture2 / meas_freq in
* /home/maxim/Documents/src/BLE/mcbusw/Hardware/Micro/ME14/Firmware/trunk/NDALibraries/BTLE/phy/dbb/prot/ble/pan2g5/afe/max32665/board_config.c:275
* if BHI160 and -Ddebug_prints=true is enabled*/
StackInit();
taskEXIT_CRITICAL();
BbBleDrvSetTxPower(0);
setAddress();
/* We are going to execute FreeRTOS functions from callbacks
* coming from these interrupts. Their priority needs to be
* reduced to allow this. */
NVIC_SetPriority(BTLE_SFD_TO_IRQn, 2);
NVIC_SetPriority(BTLE_TX_DONE_IRQn, 2);
NVIC_SetPriority(BTLE_RX_RCVD_IRQn, 2);
......
......@@ -776,25 +776,20 @@ static uint8_t writeCard10CB(
}
// leds above
case CARD10_LEDS_ABOVE_VAL_HDL:
APP_TRACE_INFO0("ble-card10: update LEDs above");
for (ui16 = 0; ui16 < 11; ui16++) {
epic_leds_set(
ui16,
pValue[ui16 * 3],
pValue[ui16 * 3 + 1],
pValue[ui16 * 3 + 2]
);
APP_TRACE_INFO4(
"ble-card10: set led %ld above to #%02x%02x%02x\n",
epic_leds_prep(
ui16,
pValue[ui16 * 3],
pValue[ui16 * 3 + 1],
pValue[ui16 * 3 + 2]
);
}
epic_leds_update();
return ATT_SUCCESS;
default:
APP_TRACE_INFO1(
"ble-card10: unsupported characteristic: %c\n", handle
);
APP_TRACE_INFO1("ble-card10: unsupported handle: %x\n", handle);
return ATT_ERR_HANDLE;
}
}
......
......@@ -396,9 +396,7 @@ static uint8_t writeCallback(
connId, handle, operation, offset, len, pValue, pAttr
);
default:
LOG_ERR("filetrans",
"unsupported characteristic: %c\n",
handle);
LOG_ERR("filetrans", "unsupported handle: %x\n", handle);
return ATT_ERR_HANDLE;
}
}
......
......@@ -81,6 +81,8 @@ typedef _Bool bool;
#define API_RTC_SCHEDULE_ALARM 0x51
#define API_RTC_SET_MILLISECONDS 0x52
#define API_RTC_GET_MILLISECONDS 0x53
#define API_RTC_GET_MONOTONIC_SECONDS 0x54
#define API_RTC_GET_MONOTONIC_MILLISECONDS 0x55
#define API_LEDS_SET 0x60
#define API_LEDS_SET_HSV 0x61
......@@ -188,17 +190,19 @@ API(API_INTERRUPT_DISABLE, int epic_interrupt_disable(api_int_id_t int_id));
#define EPIC_INT_UART_RX 2
/** RTC Alarm interrupt. See :c:func:`epic_isr_rtc_alarm`. */
#define EPIC_INT_RTC_ALARM 3
/** BHI180 Accelerometer. See :c:func:`epic_isr_bhi160_accelerometer`. */
/** BHI160 Accelerometer. See :c:func:`epic_isr_bhi160_accelerometer`. */
#define EPIC_INT_BHI160_ACCELEROMETER 4
/** BHI180 Orientation Sensor. See :c:func:`epic_isr_bhi160_orientation`. */
/** BHI160 Orientation Sensor. See :c:func:`epic_isr_bhi160_orientation`. */
#define EPIC_INT_BHI160_ORIENTATION 5
/** BHI180 Gyroscope. See :c:func:`epic_isr_bhi160_gyroscope`. */
/** BHI160 Gyroscope. See :c:func:`epic_isr_bhi160_gyroscope`. */
#define EPIC_INT_BHI160_GYROSCOPE 6
/** MAX30001 ECG. See :c:func:`epic_isr_max30001_ecg`. */
#define EPIC_INT_MAX30001_ECG 7
/** BHI160 Magnetometer. See :c:func:`epic_isr_bhi160_magnetometer`. */
#define EPIC_INT_BHI160_MAGNETOMETER 8
/* Number of defined interrupts. */
#define EPIC_INT_NUM 8
#define EPIC_INT_NUM 9
/* clang-format on */
/*
......@@ -1045,7 +1049,12 @@ enum bhi160_sensor_type {
* - Dynamic range: g's (1x Earth Gravity, ~9.81m*s^-2)
*/
BHI160_ACCELEROMETER = 0,
/** Magnetometer (**Unimplemented**) */
/**
* Magnetometer
*
* - Data type: :c:type:`bhi160_data_vector`
* - Dynamic range: -1000 to 1000 microtesla
*/
BHI160_MAGNETOMETER = 1,
/** Orientation */
BHI160_ORIENTATION = 2,
......@@ -1177,6 +1186,14 @@ API(API_BHI160_DISABLE_ALL, void epic_bhi160_disable_all_sensors());
*/
API_ISR(EPIC_INT_BHI160_ACCELEROMETER, epic_isr_bhi160_accelerometer);
/**
* **Interrupt Service Routine** for :c:data:`EPIC_INT_BHI160_MAGNETOMETER`
*
* :c:func:`epic_isr_bhi160_magnetometer` is called whenever the BHI160
* magnetometer has new data available.
*/
API_ISR(EPIC_INT_BHI160_MAGNETOMETER, epic_isr_bhi160_magnetometer);
/**
* **Interrupt Service Routine** for :c:data:`EPIC_INT_BHI160_ORIENTATION`
*
......@@ -1347,7 +1364,7 @@ enum disp_font_name {
* :param posy: y position to print to. 0 <= y <= 80
* :param pString: string to print
* :param fg: foreground color in rgb565
* :param bg: background color in rgb565
* :param bg: background color in rgb565, no background is drawn if bg==fg
* :return: ``0`` on success or a negative value in case of an error:
*
* - ``-EBUSY``: Display was already locked from another task.
......@@ -1718,6 +1735,28 @@ API(API_FILE_MKDIR, int epic_file_mkdir(const char *dirname));
* ===
*/
/**
* Get the monotonic time in seconds.
*
* :return: monotonic time in seconds
*
* .. versionadded:: 1.11
*/
API(API_RTC_GET_MONOTONIC_SECONDS,
uint32_t epic_rtc_get_monotonic_seconds(void)
);
/**
* Get the monotonic time in ms.
*
* :return: monotonic time in milliseconds
*
* .. versionadded:: 1.11
*/
API(API_RTC_GET_MONOTONIC_MILLISECONDS,
uint64_t epic_rtc_get_monotonic_milliseconds(void)
);
/**
* Read the current RTC value.
*
......
......@@ -33,7 +33,7 @@ int main(void)
const char *version_buf = CARD10_VERSION;
mxc_delay(500000);
epic_disp_clear(0x0000);
if (strcmp(CARD10_VERSION, "v1.10") == 0) {
if (strcmp(CARD10_VERSION, "v1.11") == 0) {
gfx_copy_region_raw(
&display_screen, 0, 0, 160, 80, 2, version_splash
);
......@@ -119,7 +119,7 @@ int main(void)
(const char *)"BLE",
configMINIMAL_STACK_SIZE * 10,
NULL,
tskIDLE_PRIORITY + 1,
tskIDLE_PRIORITY + 3,
NULL) != pdPASS) {
LOG_CRIT("startup", "Failed to create %s task!", "BLE");
abort();
......
......@@ -91,6 +91,8 @@ static bhy_virtual_sensor_t bhi160_lookup_vs_id(enum bhi160_sensor_type type)
switch (type) {
case BHI160_ACCELEROMETER:
return VS_ID_ACCELEROMETER;
case BHI160_MAGNETOMETER:
return VS_ID_MAGNETOMETER;
case BHI160_ORIENTATION:
return VS_ID_ORIENTATION;
case BHI160_GYROSCOPE:
......@@ -108,6 +110,8 @@ static int bhi160_lookup_sd(enum bhi160_sensor_type type)
switch (type) {
case BHI160_ACCELEROMETER:
return SD_BHI160_ACCELEROMETER;
case BHI160_MAGNETOMETER:
return SD_BHI160_MAGNETOMETER;
case BHI160_ORIENTATION:
return SD_BHI160_ORIENTATION;
case BHI160_GYROSCOPE:
......@@ -267,11 +271,13 @@ bhi160_handle_packet(bhy_data_type_t data_type, bhy_data_generic_t *sensor_data)
sensor_data->data_scalar_u16.data;
break;
case VS_ID_ACCELEROMETER_WAKEUP:
case VS_ID_MAGNETOMETER_WAKEUP:
case VS_ID_ORIENTATION_WAKEUP:
case VS_ID_GYROSCOPE_WAKEUP:
wakeup = true;
/* fall through */
case VS_ID_ACCELEROMETER:
case VS_ID_MAGNETOMETER:
case VS_ID_ORIENTATION:
case VS_ID_GYROSCOPE:
switch (sensor_id) {
......@@ -280,6 +286,11 @@ bhi160_handle_packet(bhy_data_type_t data_type, bhy_data_generic_t *sensor_data)
sensor_type = BHI160_ACCELEROMETER;
epic_int = EPIC_INT_BHI160_ACCELEROMETER;
break;
case VS_ID_MAGNETOMETER_WAKEUP:
case VS_ID_MAGNETOMETER:
sensor_type = BHI160_MAGNETOMETER;
epic_int = EPIC_INT_BHI160_MAGNETOMETER;
break;
case VS_ID_ORIENTATION_WAKEUP:
case VS_ID_ORIENTATION:
sensor_type = BHI160_ORIENTATION;
......@@ -301,11 +312,15 @@ bhi160_handle_packet(bhy_data_type_t data_type, bhy_data_generic_t *sensor_data)
data_vector.y = sensor_data->data_vector.y;
data_vector.z = sensor_data->data_vector.z;
data_vector.status = sensor_data->data_vector.status;
xQueueSend(
/* Discard overflow. See discussion in !316. */
if (xQueueSend(
bhi160_streams[sensor_type].queue,
&data_vector,
BHI160_MUTEX_WAIT_MS
);
0) != pdTRUE) {
LOG_WARN("bhi160", "queue full for %d", sensor_type);
}
if (wakeup) {
api_interrupt_trigger(epic_int);
}
......@@ -460,6 +475,11 @@ void vBhi160Task(void *pvParameters)
}
/* Remap axes to match card10 layout */
/* Due to a known issue (#133) the first call to
* bhy_mapping_matrix_set might fail. */
bhy_mapping_matrix_set(
PHYSICAL_SENSOR_INDEX_ACC, bhi160_mapping_matrix
);
bhy_mapping_matrix_set(
PHYSICAL_SENSOR_INDEX_ACC, bhi160_mapping_matrix
);
......
......@@ -54,6 +54,13 @@ int hardware_early_init(void)
*/
GPIO_Init();
/* Set the power hold pin, so the PMIC does not turn off again */
const gpio_cfg_t pwr_hold_pin = {
PORT_0, PIN_30, GPIO_FUNC_OUT, GPIO_PAD_NONE
};
GPIO_Config(&pwr_hold_pin);
GPIO_OutSet(&pwr_hold_pin);
/*
* PMIC (MAX77650)
*/
......
......@@ -95,21 +95,41 @@ void epic_leds_set_all_hsv(float *pattern_ptr, uint8_t len)
void epic_leds_dim_top(uint8_t value)
{
leds_set_dim_top(value);
if (personal_state_enabled() == 0)
if (personal_state_enabled() == 0) {
while (hwlock_acquire(HWLOCK_I2C, pdMS_TO_TICKS(1)) < 0) {
vTaskDelay(pdMS_TO_TICKS(1));
}
leds_update();
hwlock_release(HWLOCK_I2C);
}
}
void epic_leds_dim_bottom(uint8_t value)
{
leds_set_dim_bottom(value);
if (personal_state_enabled() == 0)
if (personal_state_enabled() == 0) {
while (hwlock_acquire(HWLOCK_I2C, pdMS_TO_TICKS(1)) < 0) {
vTaskDelay(pdMS_TO_TICKS(1));
}
leds_update();
hwlock_release(HWLOCK_I2C);
}
}
void epic_leds_set_rocket(int led, uint8_t value)
{
while (hwlock_acquire(HWLOCK_I2C, pdMS_TO_TICKS(1)) < 0) {
vTaskDelay(pdMS_TO_TICKS(1));
}
value = value > 31 ? 31 : value;
pmic_set_led(led, value);
hwlock_release(HWLOCK_I2C);
}
int epic_leds_get_rocket(int led)
......@@ -126,7 +146,13 @@ int epic_leds_get_rocket(int led)
void epic_set_flashlight(bool power)
{
while (hwlock_acquire(HWLOCK_I2C, pdMS_TO_TICKS(1)) < 0) {
vTaskDelay(pdMS_TO_TICKS(1));
}
leds_flashlight(power);
hwlock_release(HWLOCK_I2C);
}
void epic_leds_update(void)
......@@ -136,7 +162,13 @@ void epic_leds_update(void)
void epic_leds_set_powersave(bool eco)
{
while (hwlock_acquire(HWLOCK_I2C, pdMS_TO_TICKS(1)) < 0) {
vTaskDelay(pdMS_TO_TICKS(1));
}
leds_powersave(eco);
hwlock_release(HWLOCK_I2C);
}
void epic_leds_set_gamma_table(uint8_t rgb_channel, uint8_t gamma_table[256])
......
......@@ -155,13 +155,10 @@ static void max30001_handle_samples(int16_t *sensor_data, int16_t n)
while (n--) {
uint16_t data = -*sensor_data++;
if (xQueueSend(
max30001_stream.queue,
&data,
MAX30001_MUTEX_WAIT_MS) != pdTRUE) {
LOG_WARN(
"max30001",
"queue full"); // TODO; handle queue full
/* Discard overflow. See discussion in !316. */
if (xQueueSend(max30001_stream.queue, &data, 0) != pdTRUE) {
LOG_WARN("max30001", "queue full");
}
}
api_interrupt_trigger(EPIC_INT_MAX30001_ECG);
......
......@@ -17,6 +17,7 @@ module_sources = files(
'pmic.c',
'rtc.c',
'serial.c',
'sleep.c',
'stream.c',
'trng.c',
'vibra.c',
......
......@@ -29,6 +29,7 @@ void return_to_menu(void);
void serial_init();
void vSerialTask(void *pvParameters);
void serial_enqueue_char(char chr);
void serial_flush(void);
extern TaskHandle_t serial_task_id;
// For the eSetBit xTaskNotify task semaphore trigger
......@@ -111,4 +112,7 @@ void max30001_mutex_init(void);
#define MAX30001_MUTEX_WAIT_MS 50
extern gpio_cfg_t gpio_configs[];
/* ---------- Sleep -------------------------------------------------------- */
void sleep_deepsleep(void);
#endif /* MODULES_H */