Skip to content

Commit

Permalink
Merge pull request #232 from brilliantlabsAR/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
siliconwitch authored Jun 15, 2023
2 parents f019e7b + 6358c20 commit 66d4863
Show file tree
Hide file tree
Showing 10 changed files with 170 additions and 19 deletions.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ SRC_C += modules/device.c
SRC_C += modules/display.c
SRC_C += modules/fpga.c
SRC_C += modules/led.c
SRC_C += modules/rtt.c
SRC_C += modules/storage.c
SRC_C += modules/touch.c
SRC_C += modules/update.c
Expand Down
22 changes: 16 additions & 6 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#include "py/builtin.h"
#include "py/compile.h"
#include "py/gc.h"
#include "py/mphal.h"
#include "py/mperrno.h"
#include "py/repl.h"
#include "py/runtime.h"
Expand Down Expand Up @@ -457,9 +458,15 @@ void SD_EVT_IRQHandler(void)
break;
}

// Catch the safe mode signal
if (ble_evt->evt.gatts_evt.params.write.data[i] == 0x1C)
{
monocle_enter_safe_mode();
}

// Catch keyboard interrupts
if (ble_evt->evt.gatts_evt.params.write.data[i] ==
mp_interrupt_char)
else if (ble_evt->evt.gatts_evt.params.write.data[i] ==
mp_interrupt_char)
{
mp_sched_keyboard_interrupt();
}
Expand Down Expand Up @@ -674,7 +681,7 @@ int main(void)
ble_cfg_t cfg;
cfg.conn_cfg.conn_cfg_tag = 1;
cfg.conn_cfg.params.gap_conn_cfg.conn_count = 1;
cfg.conn_cfg.params.gap_conn_cfg.event_length = 3;
cfg.conn_cfg.params.gap_conn_cfg.event_length = 300;
app_err(sd_ble_cfg_set(BLE_CONN_CFG_GAP, &cfg, ram_start));

// Set BLE role to peripheral only
Expand Down Expand Up @@ -728,7 +735,7 @@ int main(void)
ble_gap_conn_params_t gap_conn_params = {0};
gap_conn_params.min_conn_interval = (15 * 1000) / 1250;
gap_conn_params.max_conn_interval = (15 * 1000) / 1250;
gap_conn_params.slave_latency = 3;
gap_conn_params.slave_latency = 0;
gap_conn_params.conn_sup_timeout = (2000 * 1000) / 10000;
app_err(sd_ble_gap_ppcp_set(&gap_conn_params));

Expand Down Expand Up @@ -892,8 +899,9 @@ int main(void)
pyexec_frozen_module("_mountfs.py", false);
pyexec_frozen_module("_splashscreen.py", false);

// Run the user's main file if it exists
pyexec_file_if_exists("main.py");
// If safe mode is not enabled, run the user's main.py file
monocle_started_in_safe_mode() ? NRFX_LOG("Starting in safe mode")
: pyexec_file_if_exists("main.py");

// Stay in the friendly or raw REPL until a reset is called
for (;;)
Expand All @@ -917,6 +925,8 @@ int main(void)
// On exit, clean up before reset
gc_sweep_all();
mp_deinit();

mp_hal_stdout_tx_str("MPY: soft reboot\r\n");
}
}

Expand Down
2 changes: 1 addition & 1 deletion micropython
Submodule micropython updated 83 files
+60 −0 extmod/btstack/btstack.cmake
+2 −2 extmod/btstack/modbluetooth_btstack.c
+1 −0 extmod/extmod.cmake
+1 −1 lib/btstack
+1 −1 lib/cyw43-driver
+1 −1 lib/pico-sdk
+1 −1 lib/stm32lib
+2 −5 ports/esp32/CMakeLists.txt
+4 −0 ports/esp32/boards/sdkconfig.base
+7 −2 ports/esp32/esp32_ulp.c
+44 −39 ports/esp32/main/CMakeLists.txt
+5 −5 ports/esp32/modespnow.c
+4 −0 ports/esp32/modules/inisetup.py
+4 −0 ports/esp8266/modules/inisetup.py
+57 −20 ports/rp2/CMakeLists.txt
+2 −1 ports/rp2/boards/PICO_W/board.json
+3 −0 ports/rp2/boards/PICO_W/manifest.py
+9 −0 ports/rp2/boards/PICO_W/mpconfigboard.cmake
+9 −0 ports/rp2/btstack_inc/btstack_config.h
+9 −1 ports/rp2/cyw43_configport.h
+1 −1 ports/rp2/main.c
+18 −11 ports/rp2/mpbthciport.c
+1 −1 ports/rp2/mpbthciport.h
+157 −0 ports/rp2/mpbtstackport.c
+6 −0 ports/rp2/mpconfigport.h
+1 −1 ports/rp2/mpnetworkport.c
+11 −2 ports/stm32/Makefile
+15 −7 ports/stm32/adc.c
+1 −1 ports/stm32/adc.h
+45 −0 ports/stm32/boards/STM32H573I_DK/bdev.c
+113 −0 ports/stm32/boards/STM32H573I_DK/mpconfigboard.h
+15 −0 ports/stm32/boards/STM32H573I_DK/mpconfigboard.mk
+149 −0 ports/stm32/boards/STM32H573I_DK/pins.csv
+19 −0 ports/stm32/boards/STM32H573I_DK/stm32h5xx_hal_conf.h
+142 −0 ports/stm32/boards/stm32h573_af.csv
+34 −0 ports/stm32/boards/stm32h573xi.ld
+108 −0 ports/stm32/boards/stm32h5xx_hal_conf_base.h
+4 −4 ports/stm32/dac.c
+107 −8 ports/stm32/dma.c
+1 −1 ports/stm32/dma.h
+30 −11 ports/stm32/extint.c
+5 −0 ports/stm32/extint.h
+28 −5 ports/stm32/flash.c
+1 −1 ports/stm32/i2cslave.h
+17 −15 ports/stm32/machine_adc.c
+1 −1 ports/stm32/machine_uart.c
+34 −19 ports/stm32/main.c
+5 −1 ports/stm32/make-stmconst.py
+2 −0 ports/stm32/mboot/Makefile
+30 −1 ports/stm32/mboot/main.c
+2 −0 ports/stm32/mboot/mphalport.h
+20 −14 ports/stm32/modmachine.c
+13 −1 ports/stm32/mpconfigboard_common.h
+5 −1 ports/stm32/mphalport.c
+4 −0 ports/stm32/mphalport.h
+30 −0 ports/stm32/mpu.h
+343 −0 ports/stm32/octospi.c
+33 −0 ports/stm32/octospi.h
+28 −5 ports/stm32/powerctrl.c
+101 −1 ports/stm32/powerctrlboot.c
+1 −0 ports/stm32/rng.c
+27 −9 ports/stm32/rtc.c
+23 −4 ports/stm32/spi.c
+2 −0 ports/stm32/stm32.mk
+25 −4 ports/stm32/stm32_it.c
+56 −4 ports/stm32/timer.c
+7 −7 ports/stm32/uart.c
+1 −1 ports/stm32/usb.c
+2 −2 ports/stm32/usbd_cdc_interface.c
+20 −17 ports/stm32/usbd_conf.c
+0 −2 py/builtin.h
+18 −6 py/lexer.c
+5 −2 py/makemoduledefs.py
+1 −1 py/mkrules.mk
+1 −1 py/modsys.c
+8 −7 py/nlraarch64.c
+0 −6 py/objmodule.c
+6 −0 py/objmodule.h
+1 −1 py/parsenum.c
+19 −0 tests/basics/string_fstring.py
+4 −14 tests/cpydiff/core_fstring_repr.py
+4 −3 tools/ci.sh
+2 −2 tools/mpremote/mpremote/commands.py
37 changes: 37 additions & 0 deletions modules/_mountramfs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import os, device

class RAMBlockDev:
def __init__(self, block_size, num_blocks):
self.block_size = block_size
self.data = bytearray(block_size * num_blocks)

def readblocks(self, block_num, buf, offset=0):
addr = block_num * self.block_size + offset
for i in range(len(buf)):
buf[i] = self.data[addr + i]

def writeblocks(self, block_num, buf, offset=None):
if offset is None:
# do erase, then write
for i in range(len(buf) // self.block_size):
self.ioctl(6, block_num + i)
offset = 0
addr = block_num * self.block_size + offset
for i in range(len(buf)):
self.data[addr + i] = buf[i]

def ioctl(self, op, arg):
if op == 4: # block count
return len(self.data) // self.block_size
if op == 5: # block size
return self.block_size
if op == 6: # block erase
return 0

bdev = RAMBlockDev(512, 32)
os.VfsLfs2.mkfs(bdev)
os.mount(bdev, "/")

del os
del device
del bdev
3 changes: 3 additions & 0 deletions modules/microphone.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ def __read_raw(samples=-1):
def read(samples=-1):
byte_data = __read_raw(samples)

if byte_data == None:
return None

int16_list = []

for i in range(len(byte_data) / 2):
Expand Down
49 changes: 49 additions & 0 deletions modules/rtt.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* This file is part of the MicroPython for Monocle project:
* https://github.com/brilliantlabsAR/monocle-micropython
*
* Authored by: Josuah Demangeon ([email protected])
* Raj Nakarja / Brilliant Labs Ltd. ([email protected])
*
* ISC Licence
*
* Copyright © 2023 Brilliant Labs Ltd.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/

#include "monocle.h"
#include "nrf_gpio.h"
#include "nrfx_log.h"
#include "py/runtime.h"
#include "py/objstr.h"

STATIC mp_obj_t rtt_print(mp_obj_t arg1)
{
const char *str = mp_obj_str_get_data(arg1, NULL);

NRFX_LOG("%s", str);
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(rtt_print_obj, rtt_print);

STATIC const mp_rom_map_elem_t rtt_module_globals_table[] = {
{MP_ROM_QSTR(MP_QSTR_print), MP_ROM_PTR(&rtt_print_obj)},
};
STATIC MP_DEFINE_CONST_DICT(rtt_module_globals, rtt_module_globals_table);

const mp_obj_module_t rtt_module = {
.base = {&mp_type_module},
.globals = (mp_obj_dict_t *)&rtt_module_globals,
};
MP_REGISTER_MODULE(MP_QSTR__rtt, rtt_module);
26 changes: 24 additions & 2 deletions monocle-core/monocle-critical.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ bool prevent_sleep_flag = false;

bool force_sleep_flag = false;

// Magic number which doesn't interfere with the bootloader flag bits
static const uint32_t safe_mode_flag = 0x06;

static void power_all_rails(bool enable)
{
if (enable)
Expand Down Expand Up @@ -319,12 +322,31 @@ void monocle_critical_startup(void)
void monocle_enter_bootloader(void)
{
// Set the persistent memory flag telling the bootloader to go into DFU mode
sd_power_gpregret_set(0, 0xB1);
app_err(sd_power_gpregret_set(0, 0xB1));

// Resets the CPU, giving control to the bootloader
NVIC_SystemReset();
}

void monocle_enter_safe_mode(void)
{
// Set the persistent memory flag for safe mode
app_err(sd_power_gpregret_set(0, safe_mode_flag));

// Reset the CPU, giving control to the bootloader
NVIC_SystemReset();
}

bool monocle_started_in_safe_mode(void)
{
uint32_t register_value;
app_err(sd_power_gpregret_get(0, &register_value));

// Clear magic number once read
app_err(sd_power_gpregret_clr(0, safe_mode_flag));

return register_value & safe_mode_flag;
}

void monocle_fpga_reset(bool reboot)
{
// CAUTION: READ DATASHEET CAREFULLY BEFORE CHANGING THESE
Expand Down
12 changes: 12 additions & 0 deletions monocle-core/monocle.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,18 @@ void monocle_critical_startup(void);

void monocle_enter_bootloader(void);

/**
* @brief Reboots Monocle with the safe mode flag enabled.
*/

void monocle_enter_safe_mode(void);

/**
* @brief Checks if the safe mode flag is set or not.
*/

bool monocle_started_in_safe_mode(void);

/**
* @brief Resets the FPGA, and either holds it in reset, or reboots.
*/
Expand Down
2 changes: 1 addition & 1 deletion monocle-core/monocle.ld
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ bl_flash_start = 0x78000;
bl_flash_size = 512K - bl_flash_start; /* Bootloader is at the end of the flash */

/* This must be updated whenever softdevice settings are changed */
sd_ram_end = 0x2A60;
sd_ram_end = 0x2D88;

ENTRY(Reset_Handler)

Expand Down
35 changes: 26 additions & 9 deletions tools/serial_console.py
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#!/usr/bin/env python3
"""
UART Service
-------------
Expand All @@ -7,6 +8,9 @@

import asyncio
import sys
import os
import tty
import termios
from itertools import count, takewhile
from typing import Iterator

Expand Down Expand Up @@ -34,27 +38,32 @@ async def uart_terminal():
remote device. Any data received from the device is printed to stdout.
"""

# opens sandard output in binary mode
stdout = os.fdopen(1, 'wb')

def match_nus_uuid(device: BLEDevice, adv: AdvertisementData):
# This assumes that the device includes the UART service UUID in the
# advertising data. This test may need to be adjusted depending on the
# actual advertising data supplied by the device.
print(f"uuids={adv.service_uuids}")
sys.stderr.write(f"uuids={adv.service_uuids}\n")
return UART_SERVICE_UUID.lower() in adv.service_uuids

device = await BleakScanner.find_device_by_filter(match_nus_uuid)

if device is None:
print("no matching device found, you may need to edit match_nus_uuid().")
sys.stderr.write("no matching device found\n")
sys.exit(1)

def handle_disconnect(_: BleakClient):
print("Device was disconnected.")
sys.stderr.write("\r\nDevice was disconnected.\r\n")

# cancelling all tasks effectively ends the program
for task in asyncio.all_tasks():
task.cancel()

def handle_rx(_: BleakGATTCharacteristic, data: bytearray):
print(data.decode(), end="")
stdout.write(data)
stdout.flush()

async with BleakClient(device, disconnected_callback=handle_disconnect) as client:
await client.start_notify(UART_TX_CHAR_UUID, handle_rx)
Expand All @@ -63,29 +72,37 @@ def handle_rx(_: BleakGATTCharacteristic, data: bytearray):
nus = client.services.get_service(UART_SERVICE_UUID)
rx_char = nus.get_characteristic(UART_RX_CHAR_UUID)

# set the terminal to raw I/O: no buffering
if sys.stdin.isatty():
tty.setraw(0)

while True:
# This waits until you type a line and press ENTER.
# A real terminal program might put stdin in raw mode so that things
# like CTRL+C get passed to the remote device.
data = await loop.run_in_executor(None, sys.stdin.buffer.readline)
data = await loop.run_in_executor(None, sys.stdin.buffer.read, 1)

# data will be empty on EOF (e.g. CTRL+D on *nix)
if not data:
break

# some devices, like devices running MicroPython, expect Windows
# line endings (uncomment line below if needed)
data = data.replace(b"\n", b"\r\n")

# Writing without response requires that the data can fit in a
# single BLE packet. We can use the max_write_without_response_size
# property to split the data into chunks that will fit.
for s in sliced(data, rx_char.max_write_without_response_size):
await client.write_gatt_char(rx_char, s)

if __name__ == "__main__":
# save the terminal I/O state
if sys.stdin.isatty():
saved_term = termios.tcgetattr(0)

try:
asyncio.run(uart_terminal())
except asyncio.CancelledError:
# task is cancelled on disconnect, so we ignore this error
pass

# restore terminal I/O state
if sys.stdin.isatty():
termios.tcsetattr(0, termios.TCSANOW, saved_term)

0 comments on commit 66d4863

Please sign in to comment.