Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision

Target

Select target project
  • card10/firmware
  • annejan/firmware
  • astro/firmware
  • fpletz/firmware
  • gerd/firmware
  • fleur/firmware
  • swym/firmware
  • l/firmware
  • uberardy/firmware
  • wink/firmware
  • madonius/firmware
  • mot/firmware
  • filid/firmware
  • q3k/firmware
  • hauke/firmware
  • Woazboat/firmware
  • pink/firmware
  • mossmann/firmware
  • omniskop/firmware
  • zenox/firmware
  • trilader/firmware
  • Danukeru/firmware
  • shoragan/firmware
  • zlatko/firmware
  • sistason/firmware
  • datenwolf/firmware
  • bene/firmware
  • amedee/firmware
  • martinling/firmware
  • griffon/firmware
  • chris007/firmware
  • adisbladis/firmware
  • dbrgn/firmware
  • jelly/firmware
  • rnestler/firmware
  • mh/firmware
  • ln/firmware
  • penguineer/firmware
  • monkeydom/firmware
  • jens/firmware
  • jnaulty/firmware
  • jeffmakes/firmware
  • marekventur/firmware
  • pete/firmware
  • h2obrain/firmware
  • DooMMasteR/firmware
  • jackie/firmware
  • prof_r/firmware
  • Draradech/firmware
  • Kartoffel/firmware
  • hinerk/firmware
  • abbradar/firmware
  • JustTB/firmware
  • LuKaRo/firmware
  • iggy/firmware
  • ente/firmware
  • flgr/firmware
  • Lorphos/firmware
  • matejo/firmware
  • ceddral7/firmware
  • danb/firmware
  • joshi/firmware
  • melle/firmware
  • fitch/firmware
  • deurknop/firmware
  • sargon/firmware
  • markus/firmware
  • kloenk/firmware
  • lucaswerkmeister/firmware
  • derf/firmware
  • meh/firmware
  • dx/card10-firmware
  • torben/firmware
  • yuvadm/firmware
  • AndyBS/firmware
  • klausdieter1/firmware
  • katzenparadoxon/firmware
  • xiretza/firmware
  • ole/firmware
  • techy/firmware
  • thor77/firmware
  • TilCreator/firmware
  • fuchsi/firmware
  • dos/firmware
  • yrlf/firmware
  • PetePriority/firmware
  • SuperVirus/firmware
  • sur5r/firmware
  • tazz/firmware
  • Alienmaster/firmware
  • flo_h/firmware
  • baldo/firmware
  • mmu_man/firmware
  • Foaly/firmware
  • sodoku/firmware
  • Guinness/firmware
  • ssp/firmware
  • led02/firmware
  • Stormwind/firmware
  • arist/firmware
  • coon/firmware
  • mdik/firmware
  • pippin/firmware
  • royrobotiks/firmware
  • zigot83/firmware
  • mo_k/firmware
106 results
Select Git revision
Show changes
Showing
with 342 additions and 67 deletions
``png`` - PNG Decoder
=====================
The ``png`` module provides functions to decode PNG files into raw pixel data
which can be displayed using the card10's display or its LEDs.
.. automodule:: png
:members:
...@@ -25,4 +25,6 @@ displaying menus. You can use it like this: ...@@ -25,4 +25,6 @@ displaying menus. You can use it like this:
.. autoclass:: simple_menu.Menu .. autoclass:: simple_menu.Menu
:members: :members:
.. autodata:: simple_menu.TIMEOUT
.. autofunction:: simple_menu.button_events .. autofunction:: simple_menu.button_events
MicroPython Standard Library MicroPython Standard Library
============================ ============================
Pycardium contains some modules from the MicroPython standard library. These Pycardium contains some modules from the MicroPython standard library.
are:
Some modules below use a standard Python name, but prefixed with “u”,
e.g. ujson instead of json. This is to signify that such a module is a
micro-library, i.e. implements only a subset of CPython module
functionality. Please refer to the official `MicroPython docs`_ for an
explanation why.
All u-name modules can also be imported using their non-u-name. E.g.
``import utime`` and import ``import time`` will both work.
.. _MicroPython docs: http://docs.micropython.org/en/latest/library/index.html#python-standard-libraries-and-micro-libraries
.. py:module:: framebuf
``framebuf``
------------
Refer to the official `MicroPython docs for framebuf`_.
.. _MicroPython docs for framebuf: https://docs.micropython.org/en/latest/library/framebuf.html
.. py:module:: ubinascii .. py:module:: ubinascii
...@@ -201,6 +219,8 @@ Struct module. ...@@ -201,6 +219,8 @@ Struct module.
UUID(bytes='\x12\x34\x56\x78' * 4) UUID(bytes='\x12\x34\x56\x78' * 4)
UUID(int=0x12345678123456781234567812345678) UUID(int=0x12345678123456781234567812345678)
.. versionadded:: 1.10
.. py:attribute:: bytes .. py:attribute:: bytes
UUID as ``bytes()`` object UUID as ``bytes()`` object
...@@ -217,11 +237,8 @@ Struct module. ...@@ -217,11 +237,8 @@ Struct module.
UUID version accordiung to RFC 4122 UUID version accordiung to RFC 4122
.. py:function:: uuid4(): .. py:function:: uuid4()
Generate a new UUID version 4 (random UUID). Generate a new UUID version 4 (random UUID).
.. todo:: .. versionadded:: 1.10
This function is not yet usable because we don't have
:py:func:`os.urandom` yet.
...@@ -8,6 +8,9 @@ CPython but wouldn't fit anywhere else in our implementation. Most ...@@ -8,6 +8,9 @@ CPython but wouldn't fit anywhere else in our implementation. Most
prominently, this is the :py:func:`utime.alarm` function for setting an RTC prominently, this is the :py:func:`utime.alarm` function for setting an RTC
alarm. alarm.
Like all other u-name modules, ``utime`` can also imported using the standard
``import time`` statement.
.. |time| replace:: ``time`` .. |time| replace:: ``time``
.. _time: https://docs.python.org/3/library/time.html .. _time: https://docs.python.org/3/library/time.html
...@@ -33,6 +36,48 @@ alarm. ...@@ -33,6 +36,48 @@ alarm.
Return the current timestamp in milliseconds since 2000-01-01 00:00 in Return the current timestamp in milliseconds since 2000-01-01 00:00 in
the local timezone. 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:: ticks_ms()
Return processor ticks (converted to milliseconds) since Pycardium startup.
This function should be the preferred method for timing and profiling
because it does not need an API call and thus is very fast.
.. versionadded:: 1.13
.. py:function:: ticks_us()
Return processor ticks (converted to microseconds) since Pycardium startup.
This function should be the preferred method for timing and profiling
because it does not need an API call and thus is very fast.
.. versionadded:: 1.13
.. py:function:: unix_time()
Return the current unix time as seconds since the epoch.
.. versionadded:: 1.12
.. py:function:: unix_time_ms()
Return the current unix time as milliseconds since the epoch.
.. versionadded:: 1.12
.. py:function:: set_time(secs) .. py:function:: set_time(secs)
Sets the time to ``secs`` seconds since 2000-01-01 00:00 in the local Sets the time to ``secs`` seconds since 2000-01-01 00:00 in the local
...@@ -42,6 +87,13 @@ alarm. ...@@ -42,6 +87,13 @@ alarm.
:py:func:`utime.set_time` previously applied a wrong timezone offset, :py:func:`utime.set_time` previously applied a wrong timezone offset,
thus leading to wrong results. thus leading to wrong results.
.. py:function:: set_time_ms(msecs)
Set the time to ``msecs`` seconds since 2000-01-01 00:00 in the local
timezone.
.. versionadded:: 1.12
.. py:function:: set_unix_time(secs) .. py:function:: set_unix_time(secs)
Sets the time to ``secs`` seconds since 1970-01-01 00:00 UTC. Sets the time to ``secs`` seconds since 1970-01-01 00:00 UTC.
...@@ -49,6 +101,12 @@ alarm. ...@@ -49,6 +101,12 @@ alarm.
by running ``date +%s`` in a command line or ``int(time.time())`` by running ``date +%s`` in a command line or ``int(time.time())``
in Python. in Python.
.. py:function:: set_unix_time_ms(msecs)
Set the time to ``msecs`` milliseconds since the unix epoch.
.. versionadded:: 1.12
.. py:function:: localtime([secs]) .. py:function:: localtime([secs])
Return the current time as a timestruct tuple. If ``secs`` is given, return Return the current time as a timestruct tuple. If ``secs`` is given, return
...@@ -80,13 +138,13 @@ alarm. ...@@ -80,13 +138,13 @@ alarm.
.. code-block:: python .. code-block:: python
import utime import time
def minute_timer(x): def minute_timer(x):
current = utime.time() current = time.time()
print("Current: " + str(current)) print("Current: " + str(current))
alarm = (current // 60 + 1) * 60 alarm = (current // 60 + 1) * 60
utime.alarm(alarm, minute_timer) time.alarm(alarm, minute_timer)
minute_timer(None) minute_timer(None)
...@@ -95,13 +153,13 @@ alarm. ...@@ -95,13 +153,13 @@ alarm.
.. code-block:: python .. code-block:: python
import interrupt, utime import interrupt, time
def 5_second_timer(x): def 5_second_timer(x):
current = utime.time() current = time.time()
print("Current: " + str(current)) print("Current: " + str(current))
alarm = (current // 10) * 10 + 5 alarm = (current // 10) * 10 + 5
utime.alarm(alarm) time.alarm(alarm)
# This time, we need to register and enable the callback manually # This time, we need to register and enable the callback manually
interrupt.set_callback(interrupt.RTC_ALARM, 5_second_timer) interrupt.set_callback(interrupt.RTC_ALARM, 5_second_timer)
......
.. py:module:: ws2812
``ws2812`` - Neopixel LEDs
==========================
The ``ws2812`` module controls LEDs of the WS2812 type. Just as the ``leds`` module, it exposes a function :py:func:`ws2812.set_all`, which works a similar fashion.
.. versionadded:: 1.10
.. py:function:: set_all(pin, colors)
Set multiple of the LEDs to RGB values.
Filling starts at the LED connected to the specified gpio pin.
:param int pin: ID of the pin to use for sending the data.
:param colors: List of RGB triplets.
**Example**
.. code-block:: python
import color, time, ws2812, gpio
gpio.set_mode(gpio.WRISTBAND_2, gpio.mode.OUTPUT)
i = 0
while True:
col1 = color.from_hsv(i % 360, 1.0, 0.1)
col2 = color.from_hsv((i + 20) % 360, 1.0, 0.1)
col3 = color.from_hsv((i + 40) % 360, 1.0, 0.1)
ws2812.set_all(gpio.WRISTBAND_2, [col1, col2, col3])
i += 1
time.sleep_ms(10)
.. versionadded:: 1.10
Documentation/static/bhi160-coordinates.png

324 KiB

.. _usb_file_transfer:
USB File Transfer
=================
The card10 badge bootloader offers a USB Mass Storage mode to access its 8MB external flash.
This flash contains a FAT32 filesystem and files on it will be visible to software running on the badge.
Getting to the USB mode
-----------------------
To get to the USB mode, you will need to boot the badge while keeping the bottom-right button pressed.
.. image:: static/bootloader-buttons.png
1. If the badge is on, hold the top-left (power) button until the sleep screen appears, then release.
2. Start holding the bottom-right button.
3. Quickly press and release the top-left (power) button to turn the badge on.
4. Your badge should now be in file transfer mode, and you can then release the bottom-right button.
If you succesfully got into USB File Transfer mode, the screen will display its version and notify about the USB mode by displaying ``USB activated. Ready.``. If you connect the badge via USB to your computer, it should now detect 8MB of flash storage that you can mount in the same way as a pendrive.
This pendrive can contain multiple files with different functions, some of them outlined here:
============== ========
File name Function
============== ========
``card10.bin`` Firmware update file for the badge. If this file is present, the bootloader will perform an internal update to boot from this firmware file, then it will be deleted.
``main.py`` This file contains the default `application` to be run on power on.
``menu.py`` This file contains the default `menu` to be run when the power button is short-pressed.
``*.py`` These are application files written in (Micro)Python that can be run from the menu.
``*.elf`` These are :ref:`l0dables` that can be run from the menu.
============== ========
Updating files and rebooting
----------------------------
No matter which file you are writing, the bootloader will display a red ``Writing`` status message while write operations are pending. Please wait until it displays ``Ready`` again before resetting the badge by pressing the power button again.
...@@ -6,31 +6,17 @@ ...@@ -6,31 +6,17 @@
#include "gfx.h" #include "gfx.h"
#include "display.h" #include "display.h"
/*
* "Decompress" splash-screen image. The algorithm works as follows:
*
* Each byte encodes up to 127 pixels in either white or black. The most
* significant bit determines the color, the remaining 7 bits determine the
* amount.
*/
static void bootloader_display_splash(void) static void bootloader_display_splash(void)
{ {
int idx = 0; gfx_copy_region_rle_mono(
&display_screen,
Color white = gfx_color(&display_screen, WHITE); 0,
Color black = gfx_color(&display_screen, BLACK); 0,
for (int i = 0; i < sizeof(splash); i++) { 160,
Color color = (splash[i] & 0x80) ? white : black; 80,
uint8_t length = splash[i] & 0x7f; sizeof(splash),
(const void *)(splash)
for (int j = 0; j < length; j++) { );
uint16_t x = idx % 160;
uint16_t y = idx / 160;
gfx_setpixel(&display_screen, x, y, color);
idx++;
}
}
gfx_update(&display_screen); gfx_update(&display_screen);
} }
......
...@@ -6,8 +6,12 @@ BIN1="$2" ...@@ -6,8 +6,12 @@ BIN1="$2"
BIN2="$3" BIN2="$3"
BINOUT="$4" BINOUT="$4"
dd if=/dev/zero ibs=1k count=448 2>/dev/null | LANG=C LC_CTYPE=C LC_ALL=C LC_COLLATE=C tr "\000" "\377" > "$BINOUT" if [ "$(stat -c "%s" "${BIN1}")" -gt 589824 ]; then
dd if="$BIN1" of="$BINOUT" conv=notrunc 2>/dev/null echo "$0: ${BIN1} is too big to fit!" >&2
dd if="$BIN2" >> "$BINOUT" 2>/dev/null exit 1
fi
objcopy -I binary -O binary --pad-to=589824 --gap-fill=255 "${BIN1}" "$BINOUT"
cat "$BIN2" >>"$BINOUT"
"$PYTHON" "$(dirname "$0")/crc_patch.py" "$BINOUT" "$PYTHON" "$(dirname "$0")/crc_patch.py" "$BINOUT"
#!/usr/bin/env python3 #!/usr/bin/env python3
import sys import sys
import warnings
warnings.simplefilter("ignore")
try:
import crc16 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(): def main():
data = open(sys.argv[1], 'rb').read() data = open(sys.argv[1], "rb").read()
crc = crc16.crc16xmodem(data) crc = crcfun(data)
# print(crc) # print(crc)
padded = data + bytes([crc >> 8, crc & 0xFF]) padded = data + bytes([crc >> 8, crc & 0xFF])
crc = crc16.crc16xmodem(padded) crc = crcfun(padded)
# print(crc) # print(crc)
open(sys.argv[1], 'wb').write(padded) open(sys.argv[1], "wb").write(padded)
if __name__ == "__main__": if __name__ == "__main__":
......
...@@ -4,7 +4,9 @@ set -xe ...@@ -4,7 +4,9 @@ set -xe
cd "$(dirname "$0")" cd "$(dirname "$0")"
test -d build/ && rm -r build/ test -d build/ && rm -r build/
git submodule update --init ./lib/micropython # Get external libs (MicroPython, tiny-AES-c, SHA256)
git submodule deinit --all
git submodule update --init ./lib
meson --cross-file card10-cross.ini build/ "$@" meson --cross-file card10-cross.ini build/ "$@"
set +x set +x
......
...@@ -6,7 +6,7 @@ strip = 'arm-none-eabi-strip' ...@@ -6,7 +6,7 @@ strip = 'arm-none-eabi-strip'
[properties] [properties]
c_args = ['-mthumb', '-mcpu=cortex-m4', '-mfloat-abi=softfp', '-mfpu=fpv4-sp-d16', '-Wa,-mimplicit-it=thumb', '-ffunction-sections', '-fdata-sections', '-fsingle-precision-constant', '-fno-isolate-erroneous-paths-dereference'] c_args = ['-mthumb', '-mcpu=cortex-m4', '-mfloat-abi=softfp', '-mfpu=fpv4-sp-d16', '-Wa,-mimplicit-it=thumb', '-ffunction-sections', '-fdata-sections', '-fsingle-precision-constant', '-fno-isolate-erroneous-paths-dereference']
c_link_args = ['-mthumb', '-mcpu=cortex-m4', '-mfloat-abi=softfp', '-mfpu=fpv4-sp-d16', '-Wl,--start-group', '-lc', '-lnosys', '-Wl,--end-group', '--specs=nano.specs'] c_link_args = ['-mthumb', '-mcpu=cortex-m4', '-mfloat-abi=softfp', '-mfpu=fpv4-sp-d16', '-Wl,--start-group', '-lc', '-lnosys', '-Wl,--end-group', '--specs=nano.specs', '-Wl,-wrap,BbBleDrvRand']
target_defs = ['-DTARGET=32665', '-DTARGET_REV=0x4131', '-DBOARD_CARD10=1'] target_defs = ['-DTARGET=32665', '-DTARGET_REV=0x4131', '-DBOARD_CARD10=1']
......
...@@ -18,6 +18,7 @@ in stdenv.mkDerivation rec { ...@@ -18,6 +18,7 @@ in stdenv.mkDerivation rec {
bash bash
crc16 crc16
gcc-arm-embedded gcc-arm-embedded
git
meson meson
ninja ninja
py py
......
import ws2812, gpio, bluetooth, time, display
from micropython import const
_IRQ_GATTS_WRITE = const(3)
WS2812_SERVICE_UUID = \
bluetooth.UUID("23238000-2342-2342-2342-234223422342")
SET_ALL = (
bluetooth.UUID("23238001-2342-2342-2342-234223422342"),
bluetooth.FLAG_WRITE
)
WS2812_SERVICE = (
WS2812_SERVICE_UUID,
(SET_ALL,)
)
def irq(event, data):
if event == _IRQ_GATTS_WRITE:
conn_handle, value_handle = data
value = ble.gatts_read(value_handle)
ws2812.set_all(gpio.WRISTBAND_3, [value] * 3)
if __name__ == "__main__":
display.open().backlight(0)
gpio.set_mode(gpio.WRISTBAND_3, gpio.mode.OUTPUT)
ble = bluetooth.BLE()
ble.active(True)
ble.irq(irq)
ble.gatts_register_services((WS2812_SERVICE,))
print("Waiting for connection!")
while True:
time.sleep(1)
#!/usr/bin/env python3
import bluepy
import time
import colorsys
# Change this to the MAC of your card10
p = bluepy.btle.Peripheral("CA:4D:10:01:ff:64")
c = p.getCharacteristics(
uuid='23238001-2342-2342-2342-234223422342')[0]
hue = 0
while 1:
r,g,b = colorsys.hsv_to_rgb(hue, 1, 0.1)
c.write(b"%c%c%c" %
(int(r*255), int(g*255), int(b*255)), True)
time.sleep(.1)
hue += 0.1
FROM ubuntu
RUN apt-get update && apt-get -y install gcc-arm-none-eabi binutils-arm-none-eabi libnewlib-arm-none-eabi python3 python3-pip ninja-build git
RUN pip3 install meson crc16 pillow
VOLUME /firmware
WORKDIR /firmware
CMD ./bootstrap.sh && ninja -C build && chown -R --reference=/firmware build
FROM ubuntu:bionic FROM ubuntu:focal
RUN set -e -x ;\ RUN set -e -x ;\
export DEBIAN_FRONTEND=noninteractive ;\ export DEBIAN_FRONTEND=noninteractive ;\
...@@ -10,7 +10,7 @@ RUN set -e -x ;\ ...@@ -10,7 +10,7 @@ RUN set -e -x ;\
llvm \ llvm \
python3-pip ;\ python3-pip ;\
pip3 install \ pip3 install \
clang \ clang==10.0.1 \
sphinx \ sphinx \
sphinx_rtd_theme ;\ sphinx_rtd_theme ;\
rm -rf /var/lib/apt/lists rm -rf /var/lib/apt/lists
......
#ifndef FREERTOS_CONFIG_H #ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H #define FREERTOS_CONFIG_H
#define MXC_ASSERT_ENABLE
#include "mxc_assert.h"
#include "max32665.h" #include "max32665.h"
#include <assert.h>
/* CMSIS keeps a global updated with current system clock in Hz */ /* CMSIS keeps a global updated with current system clock in Hz */
#define configCPU_CLOCK_HZ ((unsigned long)96000000) #define configCPU_CLOCK_HZ ((unsigned long)96000000)
...@@ -51,8 +50,11 @@ ...@@ -51,8 +50,11 @@
#define INCLUDE_vTaskSuspend 1 #define INCLUDE_vTaskSuspend 1
#define INCLUDE_vTaskDelay 1 #define INCLUDE_vTaskDelay 1
#define INCLUDE_vTaskDelete 1
#define INCLUDE_uxTaskGetStackHighWaterMark 1 #define INCLUDE_uxTaskGetStackHighWaterMark 1
#define INCLUDE_xTimerPendFunctionCall 1 #define INCLUDE_xTimerPendFunctionCall 1
#define INCLUDE_xSemaphoreGetMutexHolder 1
/* Allow static allocation of data structures */ /* Allow static allocation of data structures */
#define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_STATIC_ALLOCATION 1
...@@ -69,7 +71,7 @@ ...@@ -69,7 +71,7 @@
#define xPortSysTickHandler SysTick_Handler #define xPortSysTickHandler SysTick_Handler
/* Assert */ /* Assert */
#define configASSERT(x) MXC_ASSERT(x) #define configASSERT(x) assert(x)
/* Tickless idle hooks */ /* Tickless idle hooks */
typedef uint32_t TickType_t; typedef uint32_t TickType_t;
......
...@@ -5,8 +5,17 @@ ...@@ -5,8 +5,17 @@
#define MXC_ASSERT_ENABLE #define MXC_ASSERT_ENABLE
#include "mxc_assert.h" #include "mxc_assert.h"
static uint32_t irq_save = 0;
void *_api_call_start(api_id_t id, uintptr_t size) void *_api_call_start(api_id_t id, uintptr_t size)
{ {
/*
* Disable all maskable interrupts here, to be turned on again at the
* end of _api_call_transact().
*/
irq_save = __get_PRIMASK();
__set_PRIMASK(1);
while (SEMA_GetSema(_API_SEMAPHORE) == E_BUSY) { while (SEMA_GetSema(_API_SEMAPHORE) == E_BUSY) {
} }
...@@ -51,6 +60,12 @@ void *_api_call_transact(void *buffer) ...@@ -51,6 +60,12 @@ void *_api_call_transact(void *buffer)
API_CALL_MEM->call_flag = _API_FLAG_IDLE; API_CALL_MEM->call_flag = _API_FLAG_IDLE;
SEMA_FreeSema(_API_SEMAPHORE); SEMA_FreeSema(_API_SEMAPHORE);
/*
* Re-enable interrupts (if previously enabled) after completing the API
* call.
*/
__set_PRIMASK(irq_save);
return API_CALL_MEM->buffer; return API_CALL_MEM->buffer;
} }
...@@ -109,7 +124,7 @@ int api_fetch_args(char *buf, size_t cnt) ...@@ -109,7 +124,7 @@ int api_fetch_args(char *buf, size_t cnt)
return 0; return 0;
} }
int i; size_t i;
for (i = 0; i < cnt && API_CALL_MEM->buffer[i + 0x20] != '\0'; i++) { for (i = 0; i < cnt && API_CALL_MEM->buffer[i + 0x20] != '\0'; i++) {
buf[i] = API_CALL_MEM->buffer[i + 0x20]; buf[i] = API_CALL_MEM->buffer[i + 0x20];
} }
......
#include "epicardium.h" #include "epicardium.h"
#include "api/dispatcher.h" #include "api/dispatcher.h"
#include "api/interrupt-sender.h"
#include "modules/log.h"
#include "card10.h" #include "card10.h"
...@@ -10,6 +8,7 @@ ...@@ -10,6 +8,7 @@
#include "tmr.h" #include "tmr.h"
static void __core1_init(void); static void __core1_init(void);
extern void interrupt_trigger_sync(api_int_id_t id);
struct core1_info { struct core1_info {
/* Location of core1's interrupt vector table */ /* Location of core1's interrupt vector table */
...@@ -76,6 +75,11 @@ void __core1_init(void) ...@@ -76,6 +75,11 @@ void __core1_init(void)
*/ */
TMR_IntClear(MXC_TMR5); TMR_IntClear(MXC_TMR5);
/*
* Disable the SysTick
*/
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk;
/* /*
* Reset Interrupts * Reset Interrupts
* *
...@@ -201,14 +205,19 @@ void core1_boot(void) ...@@ -201,14 +205,19 @@ void core1_boot(void)
void core1_trigger_reset(void) void core1_trigger_reset(void)
{ {
/* Signal core 1 that we intend to load a new payload. */ /*
api_interrupt_trigger(EPIC_INT_RESET); * Signal core 1 that we intend to load a new payload.
*
* This needs to be synchroneous because otherwise we will deadlock
* (Lifecycle task busy-spins and interrupt can never get dispatched).
*/
interrupt_trigger_sync(EPIC_INT_RESET);
} }
void core1_wait_ready(void) bool core1_is_ready(void)
{ {
/* Wait for the core to accept */ bool ready;
while (1) {
while (SEMA_GetSema(_CONTROL_SEMAPHORE) == E_BUSY) { while (SEMA_GetSema(_CONTROL_SEMAPHORE) == E_BUSY) {
} }
...@@ -216,12 +225,21 @@ void core1_wait_ready(void) ...@@ -216,12 +225,21 @@ void core1_wait_ready(void)
* core 1 will set the ready flag once it is spinning in the * core 1 will set the ready flag once it is spinning in the
* above loop, waiting for a new IVT. * above loop, waiting for a new IVT.
*/ */
if (core1_info.ready) { ready = core1_info.ready;
break;
}
SEMA_FreeSema(_CONTROL_SEMAPHORE); SEMA_FreeSema(_CONTROL_SEMAPHORE);
return ready;
}
void core1_wait_ready(void)
{
/* Wait for the core to accept */
while (1) {
if (core1_is_ready()) {
break;
}
for (int i = 0; i < 10000; i++) { for (int i = 0; i < 10000; i++) {
} }
} }
...@@ -235,6 +253,9 @@ void core1_wait_ready(void) ...@@ -235,6 +253,9 @@ void core1_wait_ready(void)
void core1_load(void *ivt, char *args) void core1_load(void *ivt, char *args)
{ {
while (SEMA_GetSema(_CONTROL_SEMAPHORE) == E_BUSY) {
}
/* If the core is currently in an API call, reset it. */ /* If the core is currently in an API call, reset it. */
API_CALL_MEM->call_flag = _API_FLAG_IDLE; API_CALL_MEM->call_flag = _API_FLAG_IDLE;
API_CALL_MEM->id = 0; API_CALL_MEM->id = 0;
......