From 24ea5579d58ae2d7a7909c473155521b5f1ef2c7 Mon Sep 17 00:00:00 2001 From: Rami Ali Date: Fri, 1 Sep 2017 16:21:05 +1000 Subject: [PATCH 01/34] www-emu/mp_unicorn.js: Fix repeatedly running bad scripts. --- www-emu/mp_unicorn.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/www-emu/mp_unicorn.js b/www-emu/mp_unicorn.js index 29fb5dd..d241d27 100644 --- a/www-emu/mp_unicorn.js +++ b/www-emu/mp_unicorn.js @@ -188,13 +188,14 @@ function execute() { } catch (er) { console.log(er, '\n'); - return; + return 1; } cycles++; addr = emu.reg_read_i32(uc.ARM_REG_PC); if (!waiting) { requestAnimationFrame(execute); } + return 0; } function inject(data) { @@ -235,7 +236,9 @@ run_button.addEventListener("click", function() { inject(String.fromCharCode(1)); inject(String.fromCharCode(4)); while (!waiting) { - execute(); + if (execute()) { + return; + } } term.reset(); term.focus(); From e99c1cff691fce1c8ab71743542c554940faab18 Mon Sep 17 00:00:00 2001 From: Rami Ali Date: Fri, 1 Sep 2017 16:46:26 +1000 Subject: [PATCH 02/34] www-emu/mp_unicorn.js: Fix early script termination due to badly ordered concat. --- www-emu/mp_unicorn.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/www-emu/mp_unicorn.js b/www-emu/mp_unicorn.js index d241d27..5ec6615 100644 --- a/www-emu/mp_unicorn.js +++ b/www-emu/mp_unicorn.js @@ -63,7 +63,6 @@ function hook_read(handle, type, addr_lo, addr_hi, size, value_lo, value_hi, us } else if (addr_lo == GPIO_Y_IDR) { emu.mem_write(GPIO_IDR, int_to_bytes(0)); } else if (addr_lo == SERVO_1_ANGLE) { - console.log(servo_angle); emu.mem_write(SERVO_1_ANGLE, int_to_bytes(servo_angle)); } else if (addr_lo >= ADC_X_IDR && addr_lo < ADC_X_IDR + 0x30) { } else if (addr_lo >= ADC_Y_IDR && addr_lo < ADC_Y_IDR + 0x30) { @@ -205,7 +204,7 @@ function inject(data) { if (keypress[0] == ichr[0]) { emu.mem_write(pending, exception); } else { - next_char = next_char.concat(keypress); + next_char = keypress.concat(next_char); } execute(); } From fe73917029815d1aa6d711c208cac995b78b2fad Mon Sep 17 00:00:00 2001 From: Rami Ali Date: Fri, 1 Sep 2017 17:17:30 +1000 Subject: [PATCH 03/34] www-emu/mp_unicorn.js: Reduce CYCLE_LIMIT. --- www-emu/mp_unicorn.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www-emu/mp_unicorn.js b/www-emu/mp_unicorn.js index 5ec6615..fb5935a 100644 --- a/www-emu/mp_unicorn.js +++ b/www-emu/mp_unicorn.js @@ -25,7 +25,7 @@ var ADC_Y_IDR = 0x40000250; var RTC_TICKS_MS = 0x40000300; var RTC_TICKS_US = 0x40000304; -var CYCLE_LIMIT = 390000; +var CYCLE_LIMIT = 50000; var prev_binary = ""; var user_button_state = 0; var epoch; From 72a5336a5bd8d9913393bb50d1aeace8ee4d5653 Mon Sep 17 00:00:00 2001 From: Rami Ali Date: Fri, 1 Sep 2017 18:14:23 +1000 Subject: [PATCH 04/34] www-emu/mp_unicorn.js: Change ADC value range to 0 to 255. --- www-emu/mp_unicorn.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www-emu/mp_unicorn.js b/www-emu/mp_unicorn.js index fb5935a..e73ffd1 100644 --- a/www-emu/mp_unicorn.js +++ b/www-emu/mp_unicorn.js @@ -67,7 +67,7 @@ function hook_read(handle, type, addr_lo, addr_hi, size, value_lo, value_hi, us } else if (addr_lo >= ADC_X_IDR && addr_lo < ADC_X_IDR + 0x30) { } else if (addr_lo >= ADC_Y_IDR && addr_lo < ADC_Y_IDR + 0x30) { if (addr_lo == ADC_Y_IDR + (3 * 4)) { //Pin Y4 connected to ADC slider - emu.mem_write(addr_lo, int_to_bytes(adc_slider.value)); + emu.mem_write(addr_lo, int_to_bytes((adc_slider.value * 255) / 100)); } } else if (addr_lo == RTC_TICKS_MS) { emu.mem_write(RTC_TICKS_MS, int_to_bytes(parseInt(window.performance.now() - epoch, 10))); From 3c5346f739d3ebda8b7a080c4ce175e2ba40055d Mon Sep 17 00:00:00 2001 From: Rami Ali Date: Fri, 1 Sep 2017 18:47:50 +1000 Subject: [PATCH 05/34] unicorn/machine_pin.c: Add call and constants to Pins. --- unicorn/machine_pin.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/unicorn/machine_pin.c b/unicorn/machine_pin.c index 063b8b9..9d3be9b 100644 --- a/unicorn/machine_pin.c +++ b/unicorn/machine_pin.c @@ -105,12 +105,13 @@ STATIC mp_obj_t machine_pin_on(mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_pin_on_obj, machine_pin_on); -STATIC mp_obj_t machine_pin_value(mp_uint_t nargs, const mp_obj_t *args) { - machine_pin_obj_t *self = args[0]; - if (nargs <= 1) { - return MP_OBJ_NEW_SMALL_INT(self->port->IDR & (1 << self->pin)); +mp_obj_t machine_pin_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { + mp_arg_check_num(n_args, n_kw, 0, 1, false); + machine_pin_obj_t *self = self_in; + if (n_args <= 0) { + return MP_OBJ_NEW_SMALL_INT((self->port->IDR & (1 << self->pin)) ? 1 : 0); } else { - if (mp_obj_get_int(args[1]) == 0) { + if (mp_obj_get_int(args[0]) == 0) { self->port->ODR &= ~(1 << self->pin); } else { self->port->ODR |= (1 << self->pin); @@ -118,12 +119,22 @@ STATIC mp_obj_t machine_pin_value(mp_uint_t nargs, const mp_obj_t *args) { return mp_const_none; } } + +STATIC mp_obj_t machine_pin_value(mp_uint_t n_args, const mp_obj_t *args) { + return machine_pin_call(args[0], n_args - 1, 0, args + 1); +} STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_pin_value_obj, 1, 2, machine_pin_value); STATIC const mp_rom_map_elem_t machine_pin_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_on), MP_ROM_PTR(&machine_pin_on_obj) }, { MP_ROM_QSTR(MP_QSTR_off), MP_ROM_PTR(&machine_pin_off_obj) }, { MP_ROM_QSTR(MP_QSTR_value), MP_ROM_PTR(&machine_pin_value_obj) }, + + { MP_ROM_QSTR(MP_QSTR_IN), MP_ROM_INT(0) }, + { MP_ROM_QSTR(MP_QSTR_OUT), MP_ROM_INT(1) }, + { MP_ROM_QSTR(MP_QSTR_PULL_UP), MP_ROM_INT(0) }, + { MP_ROM_QSTR(MP_QSTR_PULL_DOWN), MP_ROM_INT(1) }, + { MP_ROM_QSTR(MP_QSTR_PULL_NONE), MP_ROM_INT(0) }, }; STATIC MP_DEFINE_CONST_DICT(machine_pin_locals_dict, machine_pin_locals_dict_table); @@ -133,5 +144,6 @@ const mp_obj_type_t machine_pin_type = { .name = MP_QSTR_PIN, .print = machine_pin_print, .make_new = machine_pin_make_new, + .call = machine_pin_call, .locals_dict = (mp_obj_dict_t*)&machine_pin_locals_dict, }; From 9a77da81c7eeb79378444bf794b142e8f6a52c8b Mon Sep 17 00:00:00 2001 From: Rami Ali Date: Fri, 1 Sep 2017 18:48:52 +1000 Subject: [PATCH 06/34] www-emu/mp_unicorn.js: Store pin values and return them correctly. --- www-emu/mp_unicorn.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/www-emu/mp_unicorn.js b/www-emu/mp_unicorn.js index e73ffd1..3fd8e3c 100644 --- a/www-emu/mp_unicorn.js +++ b/www-emu/mp_unicorn.js @@ -34,6 +34,9 @@ var servo_target = 0; var servo_speed = 1; var EPSILON = 0.5; +var pins_x = 0; +var pins_y = 0; + function int_to_bytes(n) { return new Uint8Array([n, n >> 8, n >> 16, n >> 24]); } @@ -59,9 +62,9 @@ function hook_read(handle, type, addr_lo, addr_hi, size, value_lo, value_hi, us } else if (addr_lo == GPIO_IDR) { emu.mem_write(GPIO_IDR, int_to_bytes(user_button_state)); } else if (addr_lo == GPIO_X_IDR) { - emu.mem_write(GPIO_IDR, int_to_bytes(0)); + emu.mem_write(GPIO_X_IDR, int_to_bytes(pins_x)); } else if (addr_lo == GPIO_Y_IDR) { - emu.mem_write(GPIO_IDR, int_to_bytes(0)); + emu.mem_write(GPIO_Y_IDR, int_to_bytes(pins_y)); } else if (addr_lo == SERVO_1_ANGLE) { emu.mem_write(SERVO_1_ANGLE, int_to_bytes(servo_angle)); } else if (addr_lo >= ADC_X_IDR && addr_lo < ADC_X_IDR + 0x30) { @@ -106,11 +109,13 @@ function hook_write(handle, type, addr_lo, addr_hi, size, value_lo, value_hi, u idle = true; } } else if (addr_lo == GPIO_ODR) { + pins_x = value_lo; document.getElementById("red_led").style.display = ((value_lo & (1 << 0)) ? "inline" : "none"); document.getElementById("green_led").style.display = ((value_lo & (1 << 1)) ? "inline" : "none"); document.getElementById("yellow_led").style.display = ((value_lo & (1 << 2)) ? "inline" : "none"); document.getElementById("blue_led").style.display = ((value_lo & (1 << 3)) ? "inline" : "none"); } else if (addr_lo == GPIO_Y_ODR) { + pins_y = value_lo; document.getElementById("pin_led_on").style.display = ((value_lo & (1 << 12)) ? "inline" : "none"); } else if (addr_lo == SERVO_1_ANGLE) { servo_target = value_lo; From 3da7bb7fb609dd2ea653bb8ca7d4dea91fe8bb04 Mon Sep 17 00:00:00 2001 From: Rami Ali Date: Fri, 1 Sep 2017 18:51:52 +1000 Subject: [PATCH 07/34] www-emu/pyboard_demos.py: Add demos for Pin LED, ADC, Servo and Mandelbrot. --- www-emu/pyboard_demos.py | 63 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/www-emu/pyboard_demos.py b/www-emu/pyboard_demos.py index 16408f1..8666595 100644 --- a/www-emu/pyboard_demos.py +++ b/www-emu/pyboard_demos.py @@ -68,3 +68,66 @@ def asm_add(r0, r1): print(math.sin(12345) ** 2 + math.cos(12345) ** 2) print(math.cosh(1) ** 2 - math.sinh(1) ** 2) print(cmath.polar(1 + 1j)) +##### +# Pin LED +# Using a Pin with micropython +# Make sure you have the LED checkbox marked! + +import machine + +# The LED is connected to our virtual pin Y12 +y12 = machine.Pin('Y12') + +y12(0 if y12() else 1) +##### +# ADC +# Using the ADC (Analogue to Digital Converter) +# Make sure you have the ADC checkbox marked! + +import machine +import pyb + +# The slider is connected to pin Y4, try adjusting it +y4 = machine.Pin('Y4') + +adc = pyb.ADC(y4) + +print(adc.read()) +##### +# Using the Servo +# Make sure you have the Servo checkbox marked! + +import machine +import pyb + +# The pyboard has four simple servo connections +servo = pyb.Servo(1) + +servo.angle(90, 5000) +##### +# Mandelbrot Set +# A python Mandelbrot set courtesy of +# http://warp.povusers.org/MandScripts/python.html +# Try your own Python3 scripts on MicroPython! + +minX = -2.0 +maxX = 1.0 +width = 60 +height = 28 +aspectRatio = 2 + +chars = ' .,-:;i+hHM$*#@ ' + +yScale = (maxX-minX)*(float(height)/width)*aspectRatio + +for y in range(height): + line = '' + for x in range(width): + c = complex(minX+x*(maxX-minX)/width, y*yScale/height-yScale/2) + z = c + for char in chars: + if abs(z) > 2: + break + z = z*z+c + line += char + print(line) From feed9295a038e4fd611c968b933e0cfe75678bb5 Mon Sep 17 00:00:00 2001 From: Rami Ali Date: Fri, 1 Sep 2017 18:57:20 +1000 Subject: [PATCH 08/34] www-emu/mp_unicorn.js: Fix missing GPIO_X_ODR in hook write. --- www-emu/mp_unicorn.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/www-emu/mp_unicorn.js b/www-emu/mp_unicorn.js index 3fd8e3c..75715c3 100644 --- a/www-emu/mp_unicorn.js +++ b/www-emu/mp_unicorn.js @@ -109,11 +109,12 @@ function hook_write(handle, type, addr_lo, addr_hi, size, value_lo, value_hi, u idle = true; } } else if (addr_lo == GPIO_ODR) { - pins_x = value_lo; document.getElementById("red_led").style.display = ((value_lo & (1 << 0)) ? "inline" : "none"); document.getElementById("green_led").style.display = ((value_lo & (1 << 1)) ? "inline" : "none"); document.getElementById("yellow_led").style.display = ((value_lo & (1 << 2)) ? "inline" : "none"); document.getElementById("blue_led").style.display = ((value_lo & (1 << 3)) ? "inline" : "none"); + } else if (addr_lo == GPIO_X_ODR) { + pins_x = value_lo; } else if (addr_lo == GPIO_Y_ODR) { pins_y = value_lo; document.getElementById("pin_led_on").style.display = ((value_lo & (1 << 12)) ? "inline" : "none"); From eb34fe979ea4585bfccae4046904f127009cb727 Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 8 Sep 2017 14:02:53 +1000 Subject: [PATCH 09/34] micropython: Update to latest upstream version. --- micropython | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/micropython b/micropython index b53a635..cc7fece 160000 --- a/micropython +++ b/micropython @@ -1 +1 @@ -Subproject commit b53a63517a71278d0f73f98f4f5ce1b15b14370e +Subproject commit cc7fece309b0ce6d361cade8690b6c3a162d7378 From fe8917b7ad019019b4c6cc7a5e4aa022c1ef4de1 Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 8 Sep 2017 14:03:03 +1000 Subject: [PATCH 10/34] unicorn: Remove include of unnecessary stmhal/extint.h files. --- unicorn/pyb_adc.c | 1 - unicorn/pyb_servo.c | 1 - unicorn/pyb_switch.c | 1 - 3 files changed, 3 deletions(-) diff --git a/unicorn/pyb_adc.c b/unicorn/pyb_adc.c index 9f74715..b24f355 100644 --- a/unicorn/pyb_adc.c +++ b/unicorn/pyb_adc.c @@ -27,7 +27,6 @@ #include #include "py/runtime.h" -#include "stmhal/extint.h" #include "modpyb.h" #include "modmachine.h" #include "unicorn_mcu.h" diff --git a/unicorn/pyb_servo.c b/unicorn/pyb_servo.c index 5e28715..abe2931 100644 --- a/unicorn/pyb_servo.c +++ b/unicorn/pyb_servo.c @@ -27,7 +27,6 @@ #include #include "py/runtime.h" -#include "stmhal/extint.h" #include "modpyb.h" #include "unicorn_mcu.h" diff --git a/unicorn/pyb_switch.c b/unicorn/pyb_switch.c index 3429276..8cf45ea 100644 --- a/unicorn/pyb_switch.c +++ b/unicorn/pyb_switch.c @@ -27,7 +27,6 @@ #include #include "py/runtime.h" -#include "stmhal/extint.h" #include "modpyb.h" #include "unicorn_mcu.h" From 9fbe498ac9d295780d361f6f6b48b65511d974c3 Mon Sep 17 00:00:00 2001 From: Rami Ali Date: Fri, 8 Sep 2017 14:25:02 +1000 Subject: [PATCH 11/34] README.md: Add build instructions to README. --- README.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/README.md b/README.md index 3d59c58..d40cd90 100644 --- a/README.md +++ b/README.md @@ -9,3 +9,33 @@ of Unicorn, and allows the virtual microcontroller to run in the browser. This then gives a full MicroPython port running simulated-bare-metal in a web browser. For a running demo please visit https://micropython.org/unicorn + +Build Instructions +------------------ + +``` +$ git submodule update --init +``` + +Firmware binaries can be customized in the unicorn directory. + +``` +$ cd unicorn +$ make CONFIG=pyboard +``` + +The web page may be built using + +``` +$ cd www-emu +$ make +``` + +In order to build without using gzip (For example when testing with `$ python -m http.server`) + +``` +$ cd www-emu +$ make nogzip +``` + +There is a critical bug in unicorn-engine which is addressed [here](https://github.com/unicorn-engine/unicorn/pull/880). In order for full functionality apply the patch to a unicorn submodule within a unicorn.js repository and build normally. From a4bbadf55879455266993606105eaaed419c669b Mon Sep 17 00:00:00 2001 From: Rami Ali Date: Fri, 8 Sep 2017 14:26:55 +1000 Subject: [PATCH 12/34] www-emu/Makefile: Change Makefile to copy across all available binaries. --- www-emu/Makefile | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/www-emu/Makefile b/www-emu/Makefile index 94e8065..e4a0050 100644 --- a/www-emu/Makefile +++ b/www-emu/Makefile @@ -2,10 +2,6 @@ BUILD = build UNICORN_BUILDS = ../unicorn/build_ IMAGES = images -MINIMAL = minimal -FEATURES = features -PYBOARD = pyboard - DEMO_GEN = demo_gen.py INDEX = index.html @@ -44,9 +40,7 @@ copy: cp $(MP_UNICORN_JS) $(BUILD) cp $(MP_UNICORN_CSS) $(BUILD) cp -r $(IMAGES) $(BUILD) - -cp $(UNICORN_BUILDS)$(MINIMAL)/$(FIRMWARE)$(MINIMAL).bin $(BUILD) - -cp $(UNICORN_BUILDS)$(FEATURES)/$(FIRMWARE)$(FEATURES).bin $(BUILD) - -cp $(UNICORN_BUILDS)$(PYBOARD)/$(FIRMWARE)$(PYBOARD).bin $(BUILD) + -cp $(UNICORN_BUILDS)*/$(FIRMWARE)*.bin $(BUILD) python $(DEMO_GEN) mv $(DEMO_SCRIPTS) $(BUILD) From c5260ec07e8789fd9e04914fab9ea6598e6fdff3 Mon Sep 17 00:00:00 2001 From: Rami Ali Date: Fri, 8 Sep 2017 14:29:09 +1000 Subject: [PATCH 13/34] www-emu/index.html: Add web page title. --- www-emu/index.html | 1 + 1 file changed, 1 insertion(+) diff --git a/www-emu/index.html b/www-emu/index.html index 0e81dcf..3853d74 100644 --- a/www-emu/index.html +++ b/www-emu/index.html @@ -1,6 +1,7 @@ + MicroPython on Unicorn From 55f377e5e7f2963e68f3578306459559edd5f9e0 Mon Sep 17 00:00:00 2001 From: Rami Ali Date: Fri, 8 Sep 2017 17:44:41 +1000 Subject: [PATCH 14/34] unicorn: Add further builtins to pyboard and activate basic libraries. --- unicorn/mpconfigport.h | 8 ++++---- unicorn/mpconfigport_pyboard.h | 11 +++++++++++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/unicorn/mpconfigport.h b/unicorn/mpconfigport.h index c9f5b73..c2cd4b3 100644 --- a/unicorn/mpconfigport.h +++ b/unicorn/mpconfigport.h @@ -17,10 +17,10 @@ #define MICROPY_ENABLE_SOURCE_LINE (1) #define MICROPY_ENABLE_DOC_STRING (0) #define MICROPY_PY_MICROPYTHON_MEM_INFO (1) -#define MICROPY_PY___FILE__ (0) -#define MICROPY_PY_IO (0) -#define MICROPY_PY_STRUCT (0) -#define MICROPY_PY_SYS (0) +#define MICROPY_PY___FILE__ (1) +#define MICROPY_PY_IO (1) +#define MICROPY_PY_STRUCT (1) +#define MICROPY_PY_SYS (1) #define MICROPY_MODULE_FROZEN_MPY (0) #define MICROPY_CPYTHON_COMPAT (0) diff --git a/unicorn/mpconfigport_pyboard.h b/unicorn/mpconfigport_pyboard.h index fc22851..3476422 100644 --- a/unicorn/mpconfigport_pyboard.h +++ b/unicorn/mpconfigport_pyboard.h @@ -15,9 +15,20 @@ #define MICROPY_PY_BUILTINS_SLICE (1) #define MICROPY_PY_BUILTINS_PROPERTY (1) #define MICROPY_PY_BUILTINS_MIN_MAX (1) +#define MICROPY_PY_BUILTINS_INPUT (1) +#define MICROPY_PY_BUILTINS_POW3 (1) +#define MICROPY_PY_FUNCTION_ATTRS (1) +#define MICROPY_PY_BUILTINS_STR_UNICODE (1) +#define MICROPY_PY_BUILTINS_STR_CENTER (1) +#define MICROPY_PY_BUILTINS_STR_PARTITION (1) +#define MICROPY_PY_BUILTINS_STR_SPLITLINES (1) +#define MICROPY_PY_BUILTINS_SLICE_ATTRS (1) +#define MICROPY_PY_ALL_SPECIAL_METHODS (1) #define MICROPY_PY_BUILTINS_HELP (1) #define MICROPY_PY_BUILTINS_HELP_TEXT unicorn_help_text #define MICROPY_PY_BUILTINS_HELP_MODULES (1) +#define MICROPY_PY_BUILTINS_COMPILE (1) +#define MICROPY_PY_BUILTINS_EXECFILE (1) #define MICROPY_PY_GC (1) #define MICROPY_PY_ARRAY (1) #define MICROPY_PY_ATTRTUPLE (1) From 97f21a501b27ae884bc02adb440f48892335b303 Mon Sep 17 00:00:00 2001 From: Rami Ali Date: Fri, 8 Sep 2017 17:51:35 +1000 Subject: [PATCH 15/34] Implement ticks_cpu() and TICK_INSN_RATIO. --- unicorn/mphalport.c | 4 ++++ unicorn/mphalport.h | 2 +- unicorn/unicorn_mcu.h | 1 + www-emu/mp_unicorn.js | 10 ++++++++-- 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/unicorn/mphalport.c b/unicorn/mphalport.c index 6181faa..32725d5 100644 --- a/unicorn/mphalport.c +++ b/unicorn/mphalport.c @@ -54,3 +54,7 @@ mp_uint_t mp_hal_ticks_us(void) { mp_uint_t mp_hal_ticks_ms(void) { return RTC->TICKS_MS; } + +mp_uint_t mp_hal_ticks_cpu(void) { + return UNICORN_CONTROLLER->INSNS; +} diff --git a/unicorn/mphalport.h b/unicorn/mphalport.h index 0e27a2d..8f33bb1 100644 --- a/unicorn/mphalport.h +++ b/unicorn/mphalport.h @@ -2,5 +2,5 @@ void mp_hal_delay_ms(mp_uint_t ms); void mp_hal_delay_us(mp_uint_t us); mp_uint_t mp_hal_ticks_ms(void); mp_uint_t mp_hal_ticks_us(void); -static inline mp_uint_t mp_hal_ticks_cpu(void) { return 0; } +mp_uint_t mp_hal_ticks_cpu(void); void mp_hal_set_interrupt_char(int c); diff --git a/unicorn/unicorn_mcu.h b/unicorn/unicorn_mcu.h index 6d95559..f750986 100644 --- a/unicorn/unicorn_mcu.h +++ b/unicorn/unicorn_mcu.h @@ -34,6 +34,7 @@ typedef struct _unicorn_controller_t { volatile uint32_t RAM_SIZE; volatile uint32_t STACK_SIZE; volatile uint32_t IDLE; + volatile uint32_t INSNS; } unicorn_controller_t; #define UNICORN_CONTROLLER ((unicorn_controller_t*)0x40000100) diff --git a/www-emu/mp_unicorn.js b/www-emu/mp_unicorn.js index 75715c3..6b8d8ae 100644 --- a/www-emu/mp_unicorn.js +++ b/www-emu/mp_unicorn.js @@ -12,6 +12,7 @@ var UNICORN_CONTROLLER_INTR_CHAR = 0x40000108; var UNICORN_CONTROLLER_RAM_SIZE = 0x4000010c; var UNICORN_CONTROLLER_STACK_SIZE = 0x40000110; var UNICORN_CONTROLLER_IDLE = 0x40000114; +var UNICORN_CONTROLLER_INSNS = 0x40000118; var GPIO_ODR = 0x40000200; var GPIO_IDR = 0x40000204; var GPIO_X_ODR = 0x40000208; @@ -33,6 +34,7 @@ var servo_angle = 0; var servo_target = 0; var servo_speed = 1; var EPSILON = 0.5; +var TICK_INSN_RATIO = 2.5; // The approximate number of clock ticks per instruction found through experimentation var pins_x = 0; var pins_y = 0; @@ -59,6 +61,8 @@ function hook_read(handle, type, addr_lo, addr_hi, size, value_lo, value_hi, us emu.mem_write(UNICORN_CONTROLLER_RAM_SIZE, int_to_bytes(ram_size)); } else if (addr_lo == UNICORN_CONTROLLER_STACK_SIZE) { emu.mem_write(UNICORN_CONTROLLER_STACK_SIZE, int_to_bytes(stack_size)); + } else if (addr_lo == UNICORN_CONTROLLER_INSNS) { + emu.mem_write(UNICORN_CONTROLLER_INSNS, int_to_bytes(insns)); } else if (addr_lo == GPIO_IDR) { emu.mem_write(GPIO_IDR, int_to_bytes(user_button_state)); } else if (addr_lo == GPIO_X_IDR) { @@ -167,6 +171,7 @@ function continue_start() { next_char = []; timestamp = new Date(); cycles = 0; + insns = 0; idle = false; waiting = false; block_output = 0; @@ -195,9 +200,10 @@ function execute() { console.log(er, '\n'); return 1; } - cycles++; addr = emu.reg_read_i32(uc.ARM_REG_PC); if (!waiting) { + cycles++; + insns += CYCLE_LIMIT * TICK_INSN_RATIO; requestAnimationFrame(execute); } return 0; @@ -318,7 +324,7 @@ gauge = setInterval(function() { if (!window.cycles) { speed = 0; } else { - speed = (cycles * CYCLE_LIMIT / 1000000) / ((new_timestamp - timestamp) / 1000); + speed = (cycles * CYCLE_LIMIT * TICK_INSN_RATIO / 1000000) / ((new_timestamp - timestamp) / 1000); } document.getElementById("clock_speed").innerHTML = speed.toFixed(2); timestamp = new_timestamp; From 108ce36c1dd8c2ccaa32d74df93915b3ec10c7e5 Mon Sep 17 00:00:00 2001 From: Rami Ali Date: Fri, 8 Sep 2017 18:25:51 +1000 Subject: [PATCH 16/34] www-emu/pyboard_demos.py: Fix typo in Servo demo. --- www-emu/pyboard_demos.py | 1 + 1 file changed, 1 insertion(+) diff --git a/www-emu/pyboard_demos.py b/www-emu/pyboard_demos.py index 8666595..a8cbb14 100644 --- a/www-emu/pyboard_demos.py +++ b/www-emu/pyboard_demos.py @@ -94,6 +94,7 @@ def asm_add(r0, r1): print(adc.read()) ##### +# Servo # Using the Servo # Make sure you have the Servo checkbox marked! From 9ab7f189357cf042d40cd2362c203a5b78669f33 Mon Sep 17 00:00:00 2001 From: Rami Ali Date: Fri, 8 Sep 2017 18:28:39 +1000 Subject: [PATCH 17/34] www-emu/demo_gen.py: Add basic information in default demo. --- www-emu/demo_gen.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www-emu/demo_gen.py b/www-emu/demo_gen.py index fee4274..ae91481 100644 --- a/www-emu/demo_gen.py +++ b/www-emu/demo_gen.py @@ -5,7 +5,7 @@ for filename in os.listdir(): if filename[-9:] == '_demos.py': infile = open(filename, 'r') - outfile.write('var ' + filename[:-9] + '_demos = new Map([["Choose a demo...", "# Write a script, paste some code or try a demo!\\n"], ') + outfile.write('var ' + filename[:-9] + '_demos = new Map([["Choose a demo...", "# Welcome to MicroPython on Unicorn!\\n\\n# The terminal beside this is no ordinary REPL.\\n# It utilizes the Unicorn CPU emulator converted\\n# to Javascript by Unicorn.js in order to run MicroPython\\n# \\\"bare metal\\\" on an ARM CPU emulation.\\n\\n# MicroPython on Unicorn is completely open source so \\n# make sure to report bugs to the issue tracker!.\\n\\n# Source: https://github.com/micropython/micropython-unicorn\\n\\n# The user and reset buttons along with the LEDs and pins\\n# on the pyboard below are fully functional. Unfortunately\\n# that\'s not quite the case for the clock speed approximation\\n# when delayed.\\n\\n# Try to write a script, paste some code or run a demo!\\n"], ') for demo in infile.read().split('#####\n'): outfile.write('["' + demo.split('\n')[0][2:] + '", "') for line in demo.split('\n')[1:-1]: From f663b708db7b08b314515e9b98183d1fa3c512ef Mon Sep 17 00:00:00 2001 From: Damien George Date: Sun, 10 Sep 2017 17:32:21 +1000 Subject: [PATCH 18/34] unicorn: Rename "PIN" to "Pin" to reflect pyboard more accurately. --- unicorn/machine_pin.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/unicorn/machine_pin.c b/unicorn/machine_pin.c index 9d3be9b..5106e89 100644 --- a/unicorn/machine_pin.c +++ b/unicorn/machine_pin.c @@ -77,7 +77,7 @@ machine_pin_obj_t *machine_pin_get(mp_obj_t *obj_in) { void machine_pin_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { machine_pin_obj_t *self = self_in; - mp_printf(print, "PIN(%q)", self->name); + mp_printf(print, "Pin(%q)", self->name); } STATIC mp_obj_t machine_pin_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { @@ -141,7 +141,7 @@ STATIC MP_DEFINE_CONST_DICT(machine_pin_locals_dict, machine_pin_locals_dict_tab const mp_obj_type_t machine_pin_type = { { &mp_type_type }, - .name = MP_QSTR_PIN, + .name = MP_QSTR_Pin, .print = machine_pin_print, .make_new = machine_pin_make_new, .call = machine_pin_call, From 757d6d5db3b97493567c25db51670b3019af76ef Mon Sep 17 00:00:00 2001 From: Rami Ali Date: Tue, 12 Sep 2017 16:15:16 +1000 Subject: [PATCH 19/34] www-emu: Format and style web page. --- www-emu/demo_gen.py | 2 +- www-emu/features_demos.py | 6 +- www-emu/index.html | 51 +++++++++------- www-emu/minimal_demos.py | 2 +- www-emu/mp_unicorn.css | 120 +++++++++++++++++++++++++++++++++++--- www-emu/pyboard_demos.py | 20 +++---- 6 files changed, 155 insertions(+), 46 deletions(-) diff --git a/www-emu/demo_gen.py b/www-emu/demo_gen.py index ae91481..6b8644e 100644 --- a/www-emu/demo_gen.py +++ b/www-emu/demo_gen.py @@ -5,7 +5,7 @@ for filename in os.listdir(): if filename[-9:] == '_demos.py': infile = open(filename, 'r') - outfile.write('var ' + filename[:-9] + '_demos = new Map([["Choose a demo...", "# Welcome to MicroPython on Unicorn!\\n\\n# The terminal beside this is no ordinary REPL.\\n# It utilizes the Unicorn CPU emulator converted\\n# to Javascript by Unicorn.js in order to run MicroPython\\n# \\\"bare metal\\\" on an ARM CPU emulation.\\n\\n# MicroPython on Unicorn is completely open source so \\n# make sure to report bugs to the issue tracker!.\\n\\n# Source: https://github.com/micropython/micropython-unicorn\\n\\n# The user and reset buttons along with the LEDs and pins\\n# on the pyboard below are fully functional. Unfortunately\\n# that\'s not quite the case for the clock speed approximation\\n# when delayed.\\n\\n# Try to write a script, paste some code or run a demo!\\n"], ') + outfile.write('var ' + filename[:-9] + '_demos = new Map([["CHOOSE A DEMO...", "# Welcome to MicroPython on Unicorn!\\n\\n# The terminal beside this is no ordinary REPL.\\n# It utilizes the Unicorn CPU emulator converted\\n# to Javascript by Unicorn.js in order to run MicroPython\\n# \\\"bare metal\\\" on an ARM CPU emulation.\\n\\n# MicroPython on Unicorn is completely open source so \\n# make sure to report bugs to the issue tracker!.\\n\\n# Source: https://github.com/micropython/micropython-unicorn\\n\\n# The user and reset buttons along with the LEDs and pins\\n# on the pyboard below are fully functional. Unfortunately\\n# that\'s not quite the case for the clock speed approximation\\n# when delayed.\\n\\n# Try to write a script, paste some code or run a demo!\\n"], ') for demo in infile.read().split('#####\n'): outfile.write('["' + demo.split('\n')[0][2:] + '", "') for line in demo.split('\n')[1:-1]: diff --git a/www-emu/features_demos.py b/www-emu/features_demos.py index 7910944..4a4581a 100644 --- a/www-emu/features_demos.py +++ b/www-emu/features_demos.py @@ -1,12 +1,12 @@ -# Hello World! +# HELLO WORLD! # hello world! print('hello world') ##### -# Big Integer +# BIG INTEGER # bignum print(1 << 1000) ##### -# Assembly +# ASSEMBLY # inline assembler @micropython.asm_thumb def asm_add(r0, r1): diff --git a/www-emu/index.html b/www-emu/index.html index 3853d74..9148e74 100644 --- a/www-emu/index.html +++ b/www-emu/index.html @@ -49,43 +49,50 @@
-

Clock Speed MHz

- Binary: - + + + + RAM :   + - Stack Size: - + STACK :   + - -

-
-
-
- -
-

- - + +

+
+

CLOCK SPEED MHz

+
+
+

PERIPHERALS :

+
LED
SERVO
ADC
+
+
+
+
+ +
+
+

+ + +

diff --git a/www-emu/minimal_demos.py b/www-emu/minimal_demos.py index 6f6037f..ff06414 100644 --- a/www-emu/minimal_demos.py +++ b/www-emu/minimal_demos.py @@ -1,3 +1,3 @@ -# Hello World! +# HELLO WORLD! # hello world! print('hello world') diff --git a/www-emu/mp_unicorn.css b/www-emu/mp_unicorn.css index 4f6429b..2a7ff08 100644 --- a/www-emu/mp_unicorn.css +++ b/www-emu/mp_unicorn.css @@ -2,21 +2,18 @@ body { font-size: 11pt; font-family: 'Open Sans'; margin: 0 0 0 0; + line-height: 200%; } p { - margin: 0.5em auto; + display: inline-block; + margin: 0; } a, ins{ text-decoration: none; } -input { - position: relative; - z-index: 3; -} - #wrap { width: 96vw; margin: 2vw auto; @@ -33,7 +30,7 @@ input { width: 48vw; } -#editor_div { +#editor_wrap { height: 50vh; } @@ -43,6 +40,7 @@ input { } #terminal { + line-height: 100%; height: 50vh; padding: 0; } @@ -94,8 +92,8 @@ input { #adc_slider { position: absolute; - bottom: 22.13vh; - right: 62.45vh; + bottom: 22.30vh; + right: 62.15vh; width: 15vh; } @@ -129,3 +127,107 @@ input { padding-top: 10px; font-size: 12px; font-weight: bold; } + +button, select { + position: relative; + z-index: 3; + line-height: normal; + height: 27px; + -moz-appearance: none; + -webkit-appearance: none; + cursor: pointer; + color: white; + font-family: 'Montserrat', sans-serif; + font-size: 12px; + padding: 5px 10px; + border: 0; + outline: 0; + margin: 10px 10px 0px 0px; +} + +button:hover, select:hover { + filter: brightness(150%); +} + +.red-element { + background-color: #ff6464; +} + +.green-element { + background-color: #61ed61; +} + +.blue-element { + background-color: #649fff; +} + +input { + position: relative; + z-index: 3; + cursor: pointer; +} + +input[type=checkbox] { + -moz-appearance: none; + -webkit-appearance: none; + background-color: #ffffff; + padding: 4px; + border-style: solid; + border-width: 2px; + border-color: #ffd064; + outline: 0; + margin-right: 4px; + display: inline-block; + position: relative; +} + +input[type=checkbox]:checked { + background-color: #ffd064; + padding: 6px; + border: 0; +} + +input[type=range] { + -webkit-appearance: none; + -moz-appearance: none; + background: transparent; + outline: 0; + border: 0; + margin: 0; + padding: 0; +} + +input[type=range]::-webkit-slider-thumb { + -webkit-appearance: none; + height: 3vh; + width: 1vh; + border-radius: 0; + outline: 0; + border: 0; + background: #ff64ff; + margin-top: -1.1vh; +} + +input[type=range]::-webkit-slider-runnable-track { + width: 100%; + height: 0.7vh; + margin-top: -2.70vh; + background: #ff64ff; +} + +input[type=range]::-moz-range-thumb { + -moz-appearance: none; + height: 3vh; + width: 1vh; + border-radius: 0; + outline: 0; + border: 0; + background: #ff64ff; +} + +input[type=range]::-moz-range-track { + -moz-appearance: none; + width: 100%; + height: 0.7vh; + background: #ff64ff; +} diff --git a/www-emu/pyboard_demos.py b/www-emu/pyboard_demos.py index a8cbb14..737dba9 100644 --- a/www-emu/pyboard_demos.py +++ b/www-emu/pyboard_demos.py @@ -1,14 +1,14 @@ -# Hello World! +# HELLO WORLD! # hello world! print('hello world') ##### -# Big Integer +# BIG INTEGER # bignum print(1 << 1000) ##### -# Assembly +# ASSEMBLY # inline assembler @micropython.asm_thumb @@ -16,7 +16,7 @@ def asm_add(r0, r1): add(r0, r0, r1) print(asm_add(1, 2)) ##### -# Switch +# SWITCH # push the USR button on the pyboard to flash the LEDs! # try using the reset button on the pyboard to quit this script! # switch callback not yet supported. @@ -32,7 +32,7 @@ def asm_add(r0, r1): time.sleep_ms(50) ##### -# LEDs +# LEDS # four LEDS numbered 1 to 4 import time @@ -42,7 +42,7 @@ def asm_add(r0, r1): pyb.LED((i%4) + 1).toggle() time.sleep_ms(100) ##### -# Time +# TIME # the time module is utime, a specialized MicroPython library # sleep will break the clock speed # dates not yet supported @@ -57,7 +57,7 @@ def asm_add(r0, r1): time.sleep_us(1000000) ##### -# Math +# MATH # a subset of the Python Math library import math @@ -69,7 +69,7 @@ def asm_add(r0, r1): print(math.cosh(1) ** 2 - math.sinh(1) ** 2) print(cmath.polar(1 + 1j)) ##### -# Pin LED +# PIN LED # Using a Pin with micropython # Make sure you have the LED checkbox marked! @@ -94,7 +94,7 @@ def asm_add(r0, r1): print(adc.read()) ##### -# Servo +# SERVO # Using the Servo # Make sure you have the Servo checkbox marked! @@ -106,7 +106,7 @@ def asm_add(r0, r1): servo.angle(90, 5000) ##### -# Mandelbrot Set +# MANDELBROT SET # A python Mandelbrot set courtesy of # http://warp.povusers.org/MandScripts/python.html # Try your own Python3 scripts on MicroPython! From f091f94492bb683c2a45b66251d4bce577422e42 Mon Sep 17 00:00:00 2001 From: Rami Ali Date: Fri, 22 Sep 2017 15:16:12 +1000 Subject: [PATCH 20/34] unicorn: Add I2C to machine. --- unicorn/machine_pin.c | 15 +++++++++++---- unicorn/modmachine.c | 7 ++++++- unicorn/modmachine.h | 5 +++++ unicorn/mpconfigport_pyboard.h | 2 ++ unicorn/mphalport.h | 15 +++++++++++++++ 5 files changed, 39 insertions(+), 5 deletions(-) diff --git a/unicorn/machine_pin.c b/unicorn/machine_pin.c index 5106e89..044f6ba 100644 --- a/unicorn/machine_pin.c +++ b/unicorn/machine_pin.c @@ -75,6 +75,15 @@ machine_pin_obj_t *machine_pin_get(mp_obj_t *obj_in) { mp_raise_TypeError("expecting a Pin"); } +void pin_set(mp_obj_t self_in, int value) { + machine_pin_obj_t *self = self_in; + if (value) { + self->port->ODR |= (1 << self->pin); + } else { + self->port->ODR &= ~(1 << self->pin); + } +} + void machine_pin_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { machine_pin_obj_t *self = self_in; mp_printf(print, "Pin(%q)", self->name); @@ -92,15 +101,13 @@ STATIC mp_obj_t machine_pin_make_new(const mp_obj_type_t *type, size_t n_args, s } STATIC mp_obj_t machine_pin_off(mp_obj_t self_in) { - machine_pin_obj_t *self = self_in; - self->port->ODR &= ~(1 << self->pin); + pin_set(self_in, 0); return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_pin_off_obj, machine_pin_off); STATIC mp_obj_t machine_pin_on(mp_obj_t self_in) { - machine_pin_obj_t *self = self_in; - self->port->ODR |= (1 << self->pin); + pin_set(self_in, 1); return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_pin_on_obj, machine_pin_on); diff --git a/unicorn/modmachine.c b/unicorn/modmachine.c index 8fbc64b..a755ee5 100644 --- a/unicorn/modmachine.c +++ b/unicorn/modmachine.c @@ -27,8 +27,10 @@ #include #include "py/obj.h" -#include "extmod/machine_mem.h" +#include "mphalport.h" #include "modmachine.h" +#include "extmod/machine_mem.h" +#include "extmod/machine_i2c.h" #if MICROPY_PY_MACHINE @@ -40,6 +42,9 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_mem32), MP_ROM_PTR(&machine_mem32_obj) }, { MP_ROM_QSTR(MP_QSTR_Pin), MP_ROM_PTR(&machine_pin_type) }, + #if MICROPY_PY_MACHINE_I2C + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&machine_i2c_type) }, + #endif }; STATIC MP_DEFINE_CONST_DICT(machine_module_globals, machine_module_globals_table); diff --git a/unicorn/modmachine.h b/unicorn/modmachine.h index 070af82..9a9cc3f 100644 --- a/unicorn/modmachine.h +++ b/unicorn/modmachine.h @@ -23,6 +23,8 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ +#ifndef MICROPY_INCLUDED_MODMACHINE_H +#define MICROPY_INCLUDED_MODMACHINE_H #include "unicorn_mcu.h" @@ -36,3 +38,6 @@ typedef struct _machine_pin_obj_t { extern const mp_obj_type_t machine_pin_type; machine_pin_obj_t *machine_pin_get(mp_obj_t *obj_in); +void pin_set(mp_obj_t self_in, int value); + +#endif diff --git a/unicorn/mpconfigport_pyboard.h b/unicorn/mpconfigport_pyboard.h index 3476422..c412d78 100644 --- a/unicorn/mpconfigport_pyboard.h +++ b/unicorn/mpconfigport_pyboard.h @@ -36,7 +36,9 @@ #define MICROPY_PY_MATH (1) #define MICROPY_PY_MATH_SPECIAL_FUNCTIONS (1) #define MICROPY_PY_CMATH (1) +#define MICROPY_PY_FRAMEBUF (1) #define MICROPY_PY_MACHINE (1) +#define MICROPY_PY_MACHINE_I2C (1) #define MICROPY_PY_UTIME_MP_HAL (1) #define MICROPY_MODULE_WEAK_LINKS (1) #define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_MPZ) diff --git a/unicorn/mphalport.h b/unicorn/mphalport.h index 8f33bb1..82c63b0 100644 --- a/unicorn/mphalport.h +++ b/unicorn/mphalport.h @@ -1,6 +1,21 @@ +#include "py/obj.h" +#include "modmachine.h" + void mp_hal_delay_ms(mp_uint_t ms); void mp_hal_delay_us(mp_uint_t us); mp_uint_t mp_hal_ticks_ms(void); mp_uint_t mp_hal_ticks_us(void); mp_uint_t mp_hal_ticks_cpu(void); void mp_hal_set_interrupt_char(int c); + +#define mp_hal_pin_obj_t const machine_pin_obj_t* +#define mp_hal_pin_od_low(p) pin_set((mp_obj_t)p, 0) +#define mp_hal_pin_od_high(p) pin_set((mp_obj_t)p, 1) +#define mp_hal_get_pin_obj(o) machine_pin_get(o) +#define mp_hal_pin_read(p) (((p)->port->IDR & (1 << (p)->pin)) ? 1 : 0) +#define mp_hal_pin_open_drain(p) mp_hal_pin_config((p), 0, 0, 0) + + +static inline void mp_hal_pin_config(mp_hal_pin_obj_t pin, uint32_t mode, uint32_t pull, uint32_t alt) { } + +static inline void mp_hal_delay_us_fast(uint32_t us) { return; } From be37608e0f6fa863d0da60eca69c3beaf1075020 Mon Sep 17 00:00:00 2001 From: Rami Ali Date: Fri, 22 Sep 2017 16:01:00 +1000 Subject: [PATCH 21/34] www-emu: Add I2C and LCD. --- www-emu/index.html | 18 +++++- www-emu/mp_unicorn.css | 16 +++++ www-emu/mp_unicorn.js | 131 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 162 insertions(+), 3 deletions(-) diff --git a/www-emu/index.html b/www-emu/index.html index 9148e74..cd2645c 100644 --- a/www-emu/index.html +++ b/www-emu/index.html @@ -78,9 +78,18 @@

PERIPHERALS :


- LED
- SERVO
- ADC
+ + + + + + + + + + + +
LED
I2C LCD
SERVO
ADC
@@ -111,6 +120,9 @@
+
+ +
diff --git a/www-emu/mp_unicorn.css b/www-emu/mp_unicorn.css index 2a7ff08..69dadd9 100644 --- a/www-emu/mp_unicorn.css +++ b/www-emu/mp_unicorn.css @@ -53,6 +53,10 @@ a, ins{ float: left; } +#checkbox_table { + width: 120%; +} + #PYB { position: absolute; right: 0; @@ -97,6 +101,18 @@ a, ins{ width: 15vh; } +#lcd_unicorn { + position: absolute; + right: 56.15vh; + bottom: 2vh; + width: 256px; + height: 128px; + background: #354359; + border: 3px; + border-color: #171d26; + border-style: solid; +} + .nav { display: block; } diff --git a/www-emu/mp_unicorn.js b/www-emu/mp_unicorn.js index 6b8d8ae..9f445bb 100644 --- a/www-emu/mp_unicorn.js +++ b/www-emu/mp_unicorn.js @@ -33,12 +33,127 @@ var epoch; var servo_angle = 0; var servo_target = 0; var servo_speed = 1; +var LCD_WIDTH = 64; +var LCD_HEIGHT = 32; var EPSILON = 0.5; var TICK_INSN_RATIO = 2.5; // The approximate number of clock ticks per instruction found through experimentation var pins_x = 0; var pins_y = 0; +class I2C { + constructor(address, scl, sda) { + this.address = address; + this.scl_gpio = scl[0] + this.scl_pin = scl[1] + this.sda_gpio = sda[0] + this.sda_pin = sda[1] + + this.active = true; + this.selected = false; + this.rw = 0; + this.data = 0; + this.recv = 0; + this.send = -1; + this.buffer = [] + } + + write(val) { + var scl = this.scl_gpio(this.scl_pin) + var nscl = extract_pin(val, this.scl_pin); + var sda = this.sda_gpio(this.sda_pin) + var nsda = extract_pin(val, this.sda_pin); + if (nsda != sda) { + if (scl) { + if (!nsda) { + this.active = true; + this.selected = false; + this.recv = 0; + this.data = 0; + this.buffer = []; + } else { + this.active = false; + if (this.selected) { + this.process(); + } + } + } + } + if (nscl != scl && this.active) { + if (nscl) { + if (this.recv < 8) { + this.data = (this.data << 1) + sda; + this.recv++; + } else { + if (this.selected) { + this.buffer.push(this.data); + this.send = 0; + this.data = 0; + this.recv = 0; + } else if ((this.data >> 1) == this.address) { + this.selected = true; + this.rw = this.data & 1; + this.send = 0; + this.data = 0; + this.recv = 0; + } else { + this.active = false; + } + } + } else if (!nscl) { + this.send = -1; + } + } + } + + read(GPIO, pins) { + if (this.sda_gpio.name != GPIO || this.send == -1) { + return pins; + } + pins = pins & ~(1 << this.sda_pin) | (this.send << this.sda_pin); + return pins; + } + + process() { + } +} + +class LCD extends I2C { + process() { + var ctx = lcd_unicorn.getContext('2d'); + ctx.fillStyle = 'rgb(255, 255, 255)'; + for (var j = 0; j < LCD_HEIGHT; j++) { + for (var i = 0; i < LCD_WIDTH / 8; i++) { + if (this.buffer.length == 0) { + return; + } + var bite = this.buffer.shift(); + for (var k = 7; k >= 0; k--) { + if (bite >> k & 1) { + ctx.fillRect(i * 4 * 8 + ((7 - k) * 4), j * 4, 4, 4); + } else { + ctx.clearRect(i * 4 * 8 + ((7 - k) * 4), j * 4, 4, 4); + } + } + } + } + } +} + +var i2c_devices = new Map([[8, new LCD(8, [X, 9], [X, 10])]]) + +function extract_pin(pins, n) { + return ((pins & (1 << n)) ? 1 : 0); +} + +function X(n) { + return extract_pin(pins_x, n); +} + +function Y(n) { + return extract_pin(pins_y, n); +} + function int_to_bytes(n) { return new Uint8Array([n, n >> 8, n >> 16, n >> 24]); } @@ -66,9 +181,17 @@ function hook_read(handle, type, addr_lo, addr_hi, size, value_lo, value_hi, us } else if (addr_lo == GPIO_IDR) { emu.mem_write(GPIO_IDR, int_to_bytes(user_button_state)); } else if (addr_lo == GPIO_X_IDR) { + for (var key of i2c_devices.keys()) { + pins_x = i2c_devices.get(key).read('X', pins_x); + } emu.mem_write(GPIO_X_IDR, int_to_bytes(pins_x)); + emu.mem_write(GPIO_X_ODR, int_to_bytes(pins_x)); } else if (addr_lo == GPIO_Y_IDR) { + for (var key of i2c_devices.keys()) { + pins_y = i2c_devices.get(key).read('Y', pins_y); + } emu.mem_write(GPIO_Y_IDR, int_to_bytes(pins_y)); + emu.mem_write(GPIO_Y_ODR, int_to_bytes(pins_y)); } else if (addr_lo == SERVO_1_ANGLE) { emu.mem_write(SERVO_1_ANGLE, int_to_bytes(servo_angle)); } else if (addr_lo >= ADC_X_IDR && addr_lo < ADC_X_IDR + 0x30) { @@ -118,9 +241,17 @@ function hook_write(handle, type, addr_lo, addr_hi, size, value_lo, value_hi, u document.getElementById("yellow_led").style.display = ((value_lo & (1 << 2)) ? "inline" : "none"); document.getElementById("blue_led").style.display = ((value_lo & (1 << 3)) ? "inline" : "none"); } else if (addr_lo == GPIO_X_ODR) { + for (var key of i2c_devices.keys()) { + i2c_devices.get(key).write(value_lo); + } pins_x = value_lo; + emu.mem_write(GPIO_X_IDR, int_to_bytes(pins_x)); } else if (addr_lo == GPIO_Y_ODR) { + for (var key of i2c_devices.keys()) { + i2c_devices.get(key).write(value_lo); + } pins_y = value_lo; + emu.mem_write(GPIO_X_IDR, int_to_bytes(pins_y)); document.getElementById("pin_led_on").style.display = ((value_lo & (1 << 12)) ? "inline" : "none"); } else if (addr_lo == SERVO_1_ANGLE) { servo_target = value_lo; From 4c3b6f19c025e370e14ccad5228983a35c8492e8 Mon Sep 17 00:00:00 2001 From: Rami Ali Date: Fri, 22 Sep 2017 16:01:35 +1000 Subject: [PATCH 22/34] www-emu/index.html: Fix CodeMirror tabs to spaces. --- www-emu/index.html | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/www-emu/index.html b/www-emu/index.html index cd2645c..25bc83f 100644 --- a/www-emu/index.html +++ b/www-emu/index.html @@ -143,7 +143,13 @@ var editor = CodeMirror.fromTextArea(document.getElementById('editor'), { indentUnit: 4, lineNumbers: true, - mode: "python" + mode: "python", + extraKeys: { + Tab: function(cm) { + var spaces = Array(cm.getOption("indentUnit") + 1).join(" "); + cm.replaceSelection(spaces); + } + } }); $('#button_layer').mapster({ fillColor: 'ff0000', From 38837060dddc510fb75a0d6f4b5f56a4f193b459 Mon Sep 17 00:00:00 2001 From: Rami Ali Date: Fri, 22 Sep 2017 16:48:52 +1000 Subject: [PATCH 23/34] www-emu/pyboard_demos.py: Add I2C LCD demo. --- www-emu/pyboard_demos.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/www-emu/pyboard_demos.py b/www-emu/pyboard_demos.py index 737dba9..7355947 100644 --- a/www-emu/pyboard_demos.py +++ b/www-emu/pyboard_demos.py @@ -106,6 +106,34 @@ def asm_add(r0, r1): servo.angle(90, 5000) ##### +# I2C LCD +# A fully simulated I2C bus and LCD Display +# The framebuf class simplifies graphics in MicroPython +# Make sure you have the I2C LCD checkbox marked! + +import machine +import framebuf + +scl = machine.Pin('X9') +sda = machine.Pin('X10') +i2c = machine.I2C(scl=scl, sda=sda) + +fbuf = framebuf.FrameBuffer(bytearray(64 * 32 // 8), 64, 32, framebuf.MONO_HLSB) + +logo = framebuf.FrameBuffer(bytearray(17 * 17 // 8), 17, 17, framebuf.MONO_HLSB) + +logo.fill(0) +logo.fill_rect(1, 1, 15, 15, 1) +logo.vline(4, 4, 12, 0) +logo.vline(8, 1, 12, 0) +logo.vline(12, 4, 12, 0) +logo.vline(14, 13, 2, 0) + +fbuf.fill(0) +fbuf.blit(logo, 23, 7) + +i2c.writeto(8, fbuf) +##### # MANDELBROT SET # A python Mandelbrot set courtesy of # http://warp.povusers.org/MandScripts/python.html From a59e937f8f7caeff956197fd3444c086c394eb84 Mon Sep 17 00:00:00 2001 From: Rami Ali Date: Fri, 22 Sep 2017 16:49:26 +1000 Subject: [PATCH 24/34] www-emu: Add I2C LCD wires. --- www-emu/images/PYB_I2C_LCD.png | Bin 0 -> 3764 bytes www-emu/index.html | 1 + 2 files changed, 1 insertion(+) create mode 100644 www-emu/images/PYB_I2C_LCD.png diff --git a/www-emu/images/PYB_I2C_LCD.png b/www-emu/images/PYB_I2C_LCD.png new file mode 100644 index 0000000000000000000000000000000000000000..a3dc6393ee572ea9e6b73a5fe28e70082eafdd20 GIT binary patch literal 3764 zcmeAS@N?(olHy`uVBq!ia0y~yV7QL70(Y)*K0-AbW|YuPggQPBAtu@y6M~)z3bc8| z(dgw{EvA2K99ctR3~ZC1Y_JaPw@T+Ut@_T*smTa5Vib&qz-S1JhQMeDjE2DA2!RjV z%jPlM=nAfn-NSSxT_XRTB+y-52@9BJ7rfF-vJT0a@h(paD74Agukl0GMp+Nd-bL0x z{!Gbb4jHx8Vz(Qw{;1iJ3luqVOoR2%t0QF(x;;zS85k5M%lk95Y<=+-D8(?vxq$u9 zq}!k>P^0q!-;t->Gm6ZKz>@A<_6BQ z`$X?9OnQI*vM)$U*)h!xlI#~{SDAE!V*_ZxC>RZa(GVC7fzc44T?qW?j{ln#qMj~( Q`4`9%Pgg&ebxsLQ0L$IUJOBUy literal 0 HcmV?d00001 diff --git a/www-emu/index.html b/www-emu/index.html index 25bc83f..19eab45 100644 --- a/www-emu/index.html +++ b/www-emu/index.html @@ -121,6 +121,7 @@
+
From e778d3c9faf41b7187c039af0b717d6e30663c67 Mon Sep 17 00:00:00 2001 From: Rami Ali Date: Fri, 13 Oct 2017 15:03:22 +1100 Subject: [PATCH 25/34] unicorn: Add hard i2c support in firmware. --- unicorn/Makefile | 1 + unicorn/machine_i2c.c | 117 +++++++++++++++++++++++++++++++++ unicorn/modmachine.h | 2 + unicorn/mpconfigport_pyboard.h | 2 + unicorn/unicorn_mcu.h | 7 ++ 5 files changed, 129 insertions(+) create mode 100644 unicorn/machine_i2c.c diff --git a/unicorn/Makefile b/unicorn/Makefile index ec0ba6d..1e572ad 100644 --- a/unicorn/Makefile +++ b/unicorn/Makefile @@ -47,6 +47,7 @@ SRC_C = \ modutime.c \ modmachine.c \ machine_pin.c \ + machine_i2c.c \ modpyb.c \ pyb_led.c \ pyb_switch.c \ diff --git a/unicorn/machine_i2c.c b/unicorn/machine_i2c.c new file mode 100644 index 0000000..9cb2790 --- /dev/null +++ b/unicorn/machine_i2c.c @@ -0,0 +1,117 @@ +#include +#include + +#include "py/runtime.h" +#include "py/mphal.h" +#include "py/mperrno.h" +#include "extmod/machine_i2c.h" +#include "unicorn_mcu.h" + +typedef struct _machine_hard_i2c_obj_t { + mp_obj_base_t base; +} machine_hard_i2c_obj_t; + +STATIC const machine_hard_i2c_obj_t machine_hard_i2c_obj[] = { + {{&machine_hard_i2c_type}}, +}; + +void machine_hard_i2c_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + mp_printf(print, "I2C(1, freq=unicorn, timeout=unicorn)"); +} + +mp_obj_t machine_hard_i2c_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + enum { ARG_id, ARG_scl, ARG_sda, ARG_freq, ARG_timeout }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_id, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_scl, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_sda, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_freq, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 400000} }, + { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1000} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + // work out i2c bus + int i2c_id = 0; + if (MP_OBJ_IS_STR(args[ARG_id].u_obj)) { + const char *port = mp_obj_str_get_str(args[ARG_id].u_obj); + if (0) { + #ifdef MICROPY_HW_I2C1_NAME + } else if (strcmp(port, "X") == 0) { + i2c_id = 1; + #endif + } else { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, + "I2C(%s) doesn't exist", port)); + } + } else { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, + "I2C(%d) doesn't exist", i2c_id)); + } + + // get static peripheral object + machine_hard_i2c_obj_t *self = (machine_hard_i2c_obj_t*)&machine_hard_i2c_obj[i2c_id - 1]; + + // here we would check the scl/sda pins and configure them, but it's not implemented + if (args[ARG_scl].u_obj != MP_OBJ_NULL || args[ARG_sda].u_obj != MP_OBJ_NULL) { + mp_raise_ValueError("explicit choice of scl/sda is not implemented"); + } + + // initialise the I2C peripheral + //machine_hard_i2c_init(self, args[ARG_freq].u_int, args[ARG_timeout].u_int); + + return MP_OBJ_FROM_PTR(self); +} + +int machine_hard_i2c_readfrom(mp_obj_base_t *self_in, uint16_t addr, uint8_t *dest, size_t len, bool stop) { + printf("READFROM\n"); + return 0; +} + +int machine_hard_i2c_writeto(mp_obj_base_t *self_in, uint16_t addr, const uint8_t *src, size_t len, bool stop) { + + I2C->COMMAND = 0; + + I2C->DATA = addr << 1; + + int ret = I2C->DATA; + if (ret < 0) { + return ret; + } else if (ret != 0) { + return -MP_ENODEV; + } + + int num_acks = 0; + + while (len > 0U) { + I2C->DATA = *src++; + len--; + ret = I2C->DATA; + if (ret < 0) { + return ret; + } else if (ret != 0) { + break; + } + ++num_acks; + } + + if (stop) { + I2C->COMMAND = 1; + } + + return num_acks; +} + +STATIC const mp_machine_i2c_p_t machine_hard_i2c_p = { + .readfrom = machine_hard_i2c_readfrom, + .writeto = machine_hard_i2c_writeto, +}; + +const mp_obj_type_t machine_hard_i2c_type = { + { &mp_type_type }, + .name = MP_QSTR_I2C, + .print = machine_hard_i2c_print, + .make_new = machine_hard_i2c_make_new, + .protocol = &machine_hard_i2c_p, + .locals_dict = (mp_obj_dict_t*)&mp_machine_soft_i2c_locals_dict, +}; diff --git a/unicorn/modmachine.h b/unicorn/modmachine.h index 9a9cc3f..4c338be 100644 --- a/unicorn/modmachine.h +++ b/unicorn/modmachine.h @@ -40,4 +40,6 @@ extern const mp_obj_type_t machine_pin_type; machine_pin_obj_t *machine_pin_get(mp_obj_t *obj_in); void pin_set(mp_obj_t self_in, int value); +extern const mp_obj_type_t machine_hard_i2c_type; + #endif diff --git a/unicorn/mpconfigport_pyboard.h b/unicorn/mpconfigport_pyboard.h index c412d78..1e8ea71 100644 --- a/unicorn/mpconfigport_pyboard.h +++ b/unicorn/mpconfigport_pyboard.h @@ -39,6 +39,8 @@ #define MICROPY_PY_FRAMEBUF (1) #define MICROPY_PY_MACHINE (1) #define MICROPY_PY_MACHINE_I2C (1) +#define MICROPY_PY_MACHINE_I2C_MAKE_NEW machine_hard_i2c_make_new +#define MICROPY_HW_I2C1_NAME "X" #define MICROPY_PY_UTIME_MP_HAL (1) #define MICROPY_MODULE_WEAK_LINKS (1) #define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_MPZ) diff --git a/unicorn/unicorn_mcu.h b/unicorn/unicorn_mcu.h index f750986..6c72b09 100644 --- a/unicorn/unicorn_mcu.h +++ b/unicorn/unicorn_mcu.h @@ -69,4 +69,11 @@ typedef struct _rtc_t { #define RTC ((rtc_t*)0x40000300) +typedef struct _i2c_t { + volatile uint32_t DATA; + volatile uint32_t COMMAND; // (0) Start bit, (1) Stop bit +} i2c_t; + +#define I2C ((i2c_t*)0x40000400) + #endif From bc1225d141110c51552b5321676285dc0770f596 Mon Sep 17 00:00:00 2001 From: Rami Ali Date: Fri, 13 Oct 2017 15:03:32 +1100 Subject: [PATCH 26/34] www-emu: Add hard i2c support to javascript. --- www-emu/mp_unicorn.js | 69 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 58 insertions(+), 11 deletions(-) diff --git a/www-emu/mp_unicorn.js b/www-emu/mp_unicorn.js index 9f445bb..644648a 100644 --- a/www-emu/mp_unicorn.js +++ b/www-emu/mp_unicorn.js @@ -25,6 +25,8 @@ var ADC_X_IDR = 0x40000220; var ADC_Y_IDR = 0x40000250; var RTC_TICKS_MS = 0x40000300; var RTC_TICKS_US = 0x40000304; +var I2C_DATA = 0x40000400; +var I2C_COMMAND = 0x40000404; var CYCLE_LIMIT = 50000; var prev_binary = ""; @@ -37,6 +39,8 @@ var LCD_WIDTH = 64; var LCD_HEIGHT = 32; var EPSILON = 0.5; var TICK_INSN_RATIO = 2.5; // The approximate number of clock ticks per instruction found through experimentation +var HARD_I2C_SCL_X = 9 +var HARD_I2C_SDA_X = 10 var pins_x = 0; var pins_y = 0; @@ -65,16 +69,17 @@ class I2C { var nsda = extract_pin(val, this.sda_pin); if (nsda != sda) { if (scl) { - if (!nsda) { + if (!nsda) { // Start bit this.active = true; this.selected = false; this.recv = 0; this.data = 0; this.buffer = []; - } else { + } else { // Stop bit this.active = false; if (this.selected) { this.process(); + this.selected = false; } } } @@ -85,7 +90,7 @@ class I2C { this.data = (this.data << 1) + sda; this.recv++; } else { - if (this.selected) { + if (this.selected) { // Receive data this.buffer.push(this.data); this.send = 0; this.data = 0; @@ -110,7 +115,7 @@ class I2C { if (this.sda_gpio.name != GPIO || this.send == -1) { return pins; } - pins = pins & ~(1 << this.sda_pin) | (this.send << this.sda_pin); + pins = set_pin(pins, this.sda_pin, this.send); return pins; } @@ -140,7 +145,30 @@ class LCD extends I2C { } } -var i2c_devices = new Map([[8, new LCD(8, [X, 9], [X, 10])]]) +var i2c_devices = new Map([[8, new LCD(8, [X, HARD_I2C_SCL_X], [X, HARD_I2C_SDA_X])]]) + +function write_to_i2c_devices(pins) { + // No X Y split? + for (var key of i2c_devices.keys()) { + i2c_devices.get(key).write(pins); + } +} + +function set_pin(pins, pin_no, val) { + if (val) { + return pins | (1 << pin_no); + } else { + return pins & ~(1 << pin_no); + } +} + +function hard_i2c_write(scl, sda) { + var pins = pins_x; + pins = set_pin(pins, HARD_I2C_SCL_X, scl); + pins = set_pin(pins, HARD_I2C_SDA_X, sda); + write_to_i2c_devices(pins); + pins_x = pins; +} function extract_pin(pins, n) { return ((pins & (1 << n)) ? 1 : 0); @@ -203,6 +231,12 @@ function hook_read(handle, type, addr_lo, addr_hi, size, value_lo, value_hi, us emu.mem_write(RTC_TICKS_MS, int_to_bytes(parseInt(window.performance.now() - epoch, 10))); } else if (addr_lo == RTC_TICKS_US) { emu.mem_write(RTC_TICKS_US, int_to_bytes(parseInt((window.performance.now() - epoch) * 1000, 10))); + } else if (addr_lo == I2C_DATA) { + for (var key of i2c_devices.keys()) { + pins_x = i2c_devices.get(key).read('X', pins_x); + } + emu.mem_write(I2C_DATA, int_to_bytes(X(HARD_I2C_SDA_X))); + hard_i2c_write(0, X(HARD_I2C_SDA_X)); } return; } @@ -241,15 +275,11 @@ function hook_write(handle, type, addr_lo, addr_hi, size, value_lo, value_hi, u document.getElementById("yellow_led").style.display = ((value_lo & (1 << 2)) ? "inline" : "none"); document.getElementById("blue_led").style.display = ((value_lo & (1 << 3)) ? "inline" : "none"); } else if (addr_lo == GPIO_X_ODR) { - for (var key of i2c_devices.keys()) { - i2c_devices.get(key).write(value_lo); - } + write_to_i2c_devices(value_lo); pins_x = value_lo; emu.mem_write(GPIO_X_IDR, int_to_bytes(pins_x)); } else if (addr_lo == GPIO_Y_ODR) { - for (var key of i2c_devices.keys()) { - i2c_devices.get(key).write(value_lo); - } + write_to_i2c_devices(value_lo); pins_y = value_lo; emu.mem_write(GPIO_X_IDR, int_to_bytes(pins_y)); document.getElementById("pin_led_on").style.display = ((value_lo & (1 << 12)) ? "inline" : "none"); @@ -258,6 +288,23 @@ function hook_write(handle, type, addr_lo, addr_hi, size, value_lo, value_hi, u rotate_servo(); } else if (addr_lo == SERVO_1_TIME) { servo_speed = (Math.abs(servo_angle - servo_target) / (value_lo / 1000)) / 60; + } else if (addr_lo == I2C_DATA) { + for (var i = 7; i >= 0; i--) { + var j = (value_lo >> i) & 1; + for (var k = 0; k < 3; k++) { + hard_i2c_write(k % 2, j); + } + } + hard_i2c_write(0, 1); + hard_i2c_write(1, 1); + } else if (addr_lo == I2C_COMMAND) { + if (value_lo == 0) { + hard_i2c_write(1, 1); + hard_i2c_write(1, 0); + } else if (value_lo == 1) { + hard_i2c_write(1, 0); + hard_i2c_write(1, 1); + } } prev_val = value_lo; return; From 097465a55d2ddefc6c20204264781caf9ea0b3db Mon Sep 17 00:00:00 2001 From: Rami Ali Date: Fri, 13 Oct 2017 15:08:43 +1100 Subject: [PATCH 27/34] www-emu/mp_unicorn.js: Clean code using etract_pin. --- www-emu/mp_unicorn.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/www-emu/mp_unicorn.js b/www-emu/mp_unicorn.js index 644648a..5aa1625 100644 --- a/www-emu/mp_unicorn.js +++ b/www-emu/mp_unicorn.js @@ -270,10 +270,10 @@ function hook_write(handle, type, addr_lo, addr_hi, size, value_lo, value_hi, u idle = true; } } else if (addr_lo == GPIO_ODR) { - document.getElementById("red_led").style.display = ((value_lo & (1 << 0)) ? "inline" : "none"); - document.getElementById("green_led").style.display = ((value_lo & (1 << 1)) ? "inline" : "none"); - document.getElementById("yellow_led").style.display = ((value_lo & (1 << 2)) ? "inline" : "none"); - document.getElementById("blue_led").style.display = ((value_lo & (1 << 3)) ? "inline" : "none"); + document.getElementById("red_led").style.display = extract_pin(value_lo, 0) ? "inline" : "none"; + document.getElementById("green_led").style.display = extract_pin(value_lo, 1) ? "inline" : "none"; + document.getElementById("yellow_led").style.display = extract_pin(value_lo, 2) ? "inline" : "none"; + document.getElementById("blue_led").style.display = extract_pin(value_lo, 3) ? "inline" : "none"; } else if (addr_lo == GPIO_X_ODR) { write_to_i2c_devices(value_lo); pins_x = value_lo; @@ -282,7 +282,7 @@ function hook_write(handle, type, addr_lo, addr_hi, size, value_lo, value_hi, u write_to_i2c_devices(value_lo); pins_y = value_lo; emu.mem_write(GPIO_X_IDR, int_to_bytes(pins_y)); - document.getElementById("pin_led_on").style.display = ((value_lo & (1 << 12)) ? "inline" : "none"); + document.getElementById("pin_led_on").style.display = extract_pin(value_lo, 12) ? "inline" : "none"; } else if (addr_lo == SERVO_1_ANGLE) { servo_target = value_lo; rotate_servo(); From 51599f3ba9bb47166d06989bbfb51a6a09e1d3d5 Mon Sep 17 00:00:00 2001 From: Rami Ali Date: Fri, 13 Oct 2017 16:11:34 +1100 Subject: [PATCH 28/34] www-emu: Implement automatic peripheral switching with demos. --- www-emu/mp_unicorn.js | 12 +++++++++++- www-emu/pyboard_demos.py | 4 ++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/www-emu/mp_unicorn.js b/www-emu/mp_unicorn.js index 5aa1625..d180a5f 100644 --- a/www-emu/mp_unicorn.js +++ b/www-emu/mp_unicorn.js @@ -450,7 +450,17 @@ function set_demos() { } demos.addEventListener("change", function() { - editor.setValue(demos.value); + checkboxes = document.getElementsByClassName('components'); + for (var i = 0; i < checkboxes.length; i++) { + var check = new Event('change'); + checkboxes[i].checked = (demos.value.search(checkboxes[i].value) != -1) ? true : false; + checkboxes[i].dispatchEvent(check); + } + if (demos.value.search("# PERIPHERALS: ") != -1) { + editor.setValue(demos.value.slice(demos.value.search("\n") + 1)); + } else { + editor.setValue(demos.value); + } }); function set_LEDs() { diff --git a/www-emu/pyboard_demos.py b/www-emu/pyboard_demos.py index 7355947..af9d446 100644 --- a/www-emu/pyboard_demos.py +++ b/www-emu/pyboard_demos.py @@ -70,6 +70,7 @@ def asm_add(r0, r1): print(cmath.polar(1 + 1j)) ##### # PIN LED +# PERIPHERALS: pin_led # Using a Pin with micropython # Make sure you have the LED checkbox marked! @@ -81,6 +82,7 @@ def asm_add(r0, r1): y12(0 if y12() else 1) ##### # ADC +# PERIPHERALS: pin_adc # Using the ADC (Analogue to Digital Converter) # Make sure you have the ADC checkbox marked! @@ -95,6 +97,7 @@ def asm_add(r0, r1): print(adc.read()) ##### # SERVO +# PERIPHERALS: pin_servo # Using the Servo # Make sure you have the Servo checkbox marked! @@ -107,6 +110,7 @@ def asm_add(r0, r1): servo.angle(90, 5000) ##### # I2C LCD +# PERIPHERALS: i2c_lcd # A fully simulated I2C bus and LCD Display # The framebuf class simplifies graphics in MicroPython # Make sure you have the I2C LCD checkbox marked! From 2383fd7f2eaffa18f689cf9d77bd981978f7fc05 Mon Sep 17 00:00:00 2001 From: Rami Ali Date: Fri, 13 Oct 2017 18:49:11 +1100 Subject: [PATCH 29/34] www-emu/pyboard_demos.py: Add Pong demo. --- www-emu/pyboard_demos.py | 88 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/www-emu/pyboard_demos.py b/www-emu/pyboard_demos.py index af9d446..7597187 100644 --- a/www-emu/pyboard_demos.py +++ b/www-emu/pyboard_demos.py @@ -113,6 +113,7 @@ def asm_add(r0, r1): # PERIPHERALS: i2c_lcd # A fully simulated I2C bus and LCD Display # The framebuf class simplifies graphics in MicroPython +# Use the hardware i2c in example Pong for faster performance # Make sure you have the I2C LCD checkbox marked! import machine @@ -164,3 +165,90 @@ def asm_add(r0, r1): z = z*z+c line += char print(line) +##### +# Pong +# PERIPHERALS: i2c_lcd pin_adc +# Pong! +# Using emulated hardware i2c, we can push enough frames for +# rough animations. Performance for this project is reduced +# using chromium. + +import machine +import framebuf +import time +import pyb + +SCREEN_WIDTH = 64 +SCREEN_HEIGHT = 32 + +game_over = False +score = 0 + +class Entity: + def __init__(self, x, y, w, h, vx, vy): + self.x = x; + self.y = y; + self.w = w; + self.h = h; + self.vx = vx; + self.vy = vy; + + def draw(self, fbuf): + fbuf.fill_rect(int(self.x), int(self.y), self.w, self.h, 1) + +class Ball(Entity): + def update(self, dt, player): + self.x += self.vx * dt; + if (self.x <= 0): + self.x = 0 + self.vx = -self.vx + if (self.x >= SCREEN_WIDTH - self.w): + self.x = SCREEN_WIDTH - self.w + self.vx = -self.vx + self.y += self.vy * dt; + if (self.y <= 0): + self.y = 0 + self.vy = -self.vy + if (self.y >= SCREEN_HEIGHT - self.h - player.h): + if (self.x >= player.x and self.x <= player.x + player.w): + self.y = SCREEN_HEIGHT - self.h - player.h + self.vy = -self.vy + global score + score += 1 + if score % 2 == 0: + self.vx += (self.vx/abs(self.vx)) * 1 + if score % 3 == 0: + self.vy += (self.vy/abs(self.vy)) * 1 + else: + global game_over + game_over = True + +class Player(Entity): + pass + +ball = Ball(32, 16, 1, 1, 2, -2) +player = Player(30, 31, 10, 1, 0, 0) + +y4 = machine.Pin('Y4') +adc = pyb.ADC(y4) +i2c = machine.I2C('X') +fbuf = framebuf.FrameBuffer(bytearray(64 * 32 // 8), 64, 32, framebuf.MONO_HLSB) +tick = time.ticks_ms() + +while not game_over: + ntick = time.ticks_ms() + ball.update(time.ticks_diff(ntick, tick) // 100, player) + tick = ntick + player.x = adc.read() * 58 / 255 + fbuf.fill(0) + ball.draw(fbuf) + player.draw(fbuf) + i2c.writeto(8, fbuf) + time.sleep_ms(20) + +fbuf.fill(0) +fbuf.text('GAME', 15, 8) +fbuf.text('OVER', 15, 18) +i2c.writeto(8, fbuf) + +print('Score: ', score) From a18f01cfabddf13feec746e02145c25b0cb86ac9 Mon Sep 17 00:00:00 2001 From: Rami Ali Date: Tue, 14 Nov 2017 10:59:27 +1100 Subject: [PATCH 30/34] www-emu/pyboard_demos.py: Adjust pong delay for faster computers. --- www-emu/pyboard_demos.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www-emu/pyboard_demos.py b/www-emu/pyboard_demos.py index 7597187..be93d66 100644 --- a/www-emu/pyboard_demos.py +++ b/www-emu/pyboard_demos.py @@ -244,7 +244,7 @@ class Player(Entity): ball.draw(fbuf) player.draw(fbuf) i2c.writeto(8, fbuf) - time.sleep_ms(20) + time.sleep_ms(50) # Adjust this for performance boosts fbuf.fill(0) fbuf.text('GAME', 15, 8) From cd2f742057c3805b4faac2563c187e24deee6c2d Mon Sep 17 00:00:00 2001 From: Rami Ali Date: Tue, 14 Nov 2017 11:03:37 +1100 Subject: [PATCH 31/34] www-emu/mp_unicorn.css: Remove button border radius. --- www-emu/mp_unicorn.css | 1 + 1 file changed, 1 insertion(+) diff --git a/www-emu/mp_unicorn.css b/www-emu/mp_unicorn.css index 69dadd9..15eef0b 100644 --- a/www-emu/mp_unicorn.css +++ b/www-emu/mp_unicorn.css @@ -157,6 +157,7 @@ button, select { font-size: 12px; padding: 5px 10px; border: 0; + border-radius: 0; outline: 0; margin: 10px 10px 0px 0px; } From 545e880568441b39bffc5e4b2c1229783bc62a1d Mon Sep 17 00:00:00 2001 From: Damien George Date: Mon, 31 Oct 2022 13:05:14 +1100 Subject: [PATCH 32/34] micropython: Update to v1.19.1. Signed-off-by: Damien George --- micropython | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/micropython b/micropython index cc7fece..9b48634 160000 --- a/micropython +++ b/micropython @@ -1 +1 @@ -Subproject commit cc7fece309b0ce6d361cade8690b6c3a162d7378 +Subproject commit 9b486340da22931cde82872f79e1c34db959548b From 537518db953f42e3a12104c28c611de0d2d0695f Mon Sep 17 00:00:00 2001 From: Damien George Date: Mon, 31 Oct 2022 13:05:55 +1100 Subject: [PATCH 33/34] unicorn: Update to build against MicroPython v1.19.1. Signed-off-by: Damien George --- unicorn/Makefile | 12 +++++---- unicorn/help.c | 2 +- unicorn/machine_i2c.c | 44 +++++++++++++++++++-------------- unicorn/main.c | 10 ++++---- unicorn/modmachine.c | 4 ++- unicorn/modmachine.h | 2 +- unicorn/modpyb.c | 2 ++ unicorn/modutime.c | 8 +++++- unicorn/mpconfigport.h | 3 +++ unicorn/mpconfigport_features.h | 5 ---- unicorn/mpconfigport_pyboard.h | 14 +---------- unicorn/mphalport.c | 5 ++-- unicorn/mphalport.h | 2 ++ 13 files changed, 60 insertions(+), 53 deletions(-) diff --git a/unicorn/Makefile b/unicorn/Makefile index 1e572ad..29fe8b7 100644 --- a/unicorn/Makefile +++ b/unicorn/Makefile @@ -53,10 +53,13 @@ SRC_C = \ pyb_switch.c \ pyb_servo.c \ pyb_adc.c \ - lib/utils/stdout_helpers.c \ - lib/utils/interrupt_char.c \ - lib/utils/pyexec.c \ - lib/libc/string0.c \ + shared/libc/string0.c \ + shared/readline/readline.c \ + shared/runtime/interrupt_char.c \ + shared/runtime/pyexec.c \ + shared/runtime/stdout_helpers.c \ + +SRC_C += \ lib/libm/math.c \ lib/libm/fmodf.c \ lib/libm/nearbyintf.c \ @@ -83,7 +86,6 @@ SRC_C = \ lib/libm/asinfacosf.c \ lib/libm/atanf.c \ lib/libm/atan2f.c \ - lib/mp-readline/readline.c \ # List of sources for qstr extraction SRC_QSTR += $(SRC_C) diff --git a/unicorn/help.c b/unicorn/help.c index 04528ac..962b8b5 100644 --- a/unicorn/help.c +++ b/unicorn/help.c @@ -26,7 +26,7 @@ #include "py/builtin.h" -const char *unicorn_help_text = +const char unicorn_help_text[] = "Welcome to MicroPython running under Unicorn!\n" "\n" "Control commands:\n" diff --git a/unicorn/machine_i2c.c b/unicorn/machine_i2c.c index 9cb2790..4b6b116 100644 --- a/unicorn/machine_i2c.c +++ b/unicorn/machine_i2c.c @@ -7,19 +7,19 @@ #include "extmod/machine_i2c.h" #include "unicorn_mcu.h" -typedef struct _machine_hard_i2c_obj_t { +typedef struct _machine_i2c_obj_t { mp_obj_base_t base; -} machine_hard_i2c_obj_t; +} machine_i2c_obj_t; -STATIC const machine_hard_i2c_obj_t machine_hard_i2c_obj[] = { - {{&machine_hard_i2c_type}}, +STATIC const machine_i2c_obj_t machine_i2c_obj[] = { + {{&machine_i2c_type}}, }; -void machine_hard_i2c_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { +STATIC void machine_i2c_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { mp_printf(print, "I2C(1, freq=unicorn, timeout=unicorn)"); } -mp_obj_t machine_hard_i2c_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { +STATIC mp_obj_t machine_i2c_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_id, ARG_scl, ARG_sda, ARG_freq, ARG_timeout }; static const mp_arg_t allowed_args[] = { { MP_QSTR_id, MP_ARG_REQUIRED | MP_ARG_OBJ }, @@ -50,7 +50,7 @@ mp_obj_t machine_hard_i2c_make_new(const mp_obj_type_t *type, size_t n_args, siz } // get static peripheral object - machine_hard_i2c_obj_t *self = (machine_hard_i2c_obj_t*)&machine_hard_i2c_obj[i2c_id - 1]; + machine_i2c_obj_t *self = (machine_i2c_obj_t*)&machine_i2c_obj[i2c_id - 1]; // here we would check the scl/sda pins and configure them, but it's not implemented if (args[ARG_scl].u_obj != MP_OBJ_NULL || args[ARG_sda].u_obj != MP_OBJ_NULL) { @@ -58,17 +58,17 @@ mp_obj_t machine_hard_i2c_make_new(const mp_obj_type_t *type, size_t n_args, siz } // initialise the I2C peripheral - //machine_hard_i2c_init(self, args[ARG_freq].u_int, args[ARG_timeout].u_int); + //machine_i2c_init(self, args[ARG_freq].u_int, args[ARG_timeout].u_int); return MP_OBJ_FROM_PTR(self); } -int machine_hard_i2c_readfrom(mp_obj_base_t *self_in, uint16_t addr, uint8_t *dest, size_t len, bool stop) { +STATIC int machine_i2c_readfrom(mp_obj_base_t *self_in, uint16_t addr, uint8_t *dest, size_t len, bool stop) { printf("READFROM\n"); return 0; } -int machine_hard_i2c_writeto(mp_obj_base_t *self_in, uint16_t addr, const uint8_t *src, size_t len, bool stop) { +STATIC int machine_i2c_writeto(mp_obj_base_t *self_in, uint16_t addr, const uint8_t *src, size_t len, bool stop) { I2C->COMMAND = 0; @@ -102,16 +102,24 @@ int machine_hard_i2c_writeto(mp_obj_base_t *self_in, uint16_t addr, const uint8_ return num_acks; } -STATIC const mp_machine_i2c_p_t machine_hard_i2c_p = { - .readfrom = machine_hard_i2c_readfrom, - .writeto = machine_hard_i2c_writeto, +STATIC int machine_i2c_transfer_single(mp_obj_base_t *self_in, uint16_t addr, size_t len, uint8_t *buf, unsigned int flags) { + if (flags & MP_MACHINE_I2C_FLAG_READ) { + return machine_i2c_readfrom(self_in, addr, buf, len, flags & MP_MACHINE_I2C_FLAG_STOP); + } else { + return machine_i2c_writeto(self_in, addr, buf, len, flags & MP_MACHINE_I2C_FLAG_STOP); + } +} + +STATIC const mp_machine_i2c_p_t machine_i2c_p = { + .transfer = mp_machine_i2c_transfer_adaptor, + .transfer_single = machine_i2c_transfer_single, }; -const mp_obj_type_t machine_hard_i2c_type = { +const mp_obj_type_t machine_i2c_type = { { &mp_type_type }, .name = MP_QSTR_I2C, - .print = machine_hard_i2c_print, - .make_new = machine_hard_i2c_make_new, - .protocol = &machine_hard_i2c_p, - .locals_dict = (mp_obj_dict_t*)&mp_machine_soft_i2c_locals_dict, + .print = machine_i2c_print, + .make_new = machine_i2c_make_new, + .protocol = &machine_i2c_p, + .locals_dict = (mp_obj_dict_t*)&mp_machine_i2c_locals_dict, }; diff --git a/unicorn/main.c b/unicorn/main.c index 3fcdc68..eafe6a5 100644 --- a/unicorn/main.c +++ b/unicorn/main.c @@ -28,15 +28,15 @@ #include #include -#include "py/nlr.h" +#include "py/builtin.h" #include "py/compile.h" #include "py/runtime.h" #include "py/stackctrl.h" #include "py/repl.h" #include "py/gc.h" #include "py/mperrno.h" -#include "lib/utils/interrupt_char.h" -#include "lib/utils/pyexec.h" +#include "shared/runtime/interrupt_char.h" +#include "shared/runtime/pyexec.h" #include "unicorn_mcu.h" void do_str(const char *src, mp_parse_input_kind_t input_kind) { @@ -44,7 +44,7 @@ void do_str(const char *src, mp_parse_input_kind_t input_kind) { if (nlr_push(&nlr) == 0) { mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0); mp_parse_tree_t parse_tree = mp_parse(lex, input_kind); - mp_obj_t module_fun = mp_compile(&parse_tree, MP_QSTR__lt_stdin_gt_, MP_EMIT_OPT_NONE, false); + mp_obj_t module_fun = mp_compile(&parse_tree, MP_QSTR__lt_stdin_gt_, false); mp_call_function_0(module_fun); nlr_pop(); } else { @@ -140,7 +140,7 @@ void Reset_Handler(void) { *dest++ = 0; } - UNICORN_CONTROLLER->PENDING = (uint32_t) &MP_STATE_VM(mp_pending_exception); + UNICORN_CONTROLLER->PENDING = (uint32_t) &MP_STATE_MAIN_THREAD(mp_pending_exception); UNICORN_CONTROLLER->EXCEPTION = (uint32_t) &MP_STATE_VM(mp_kbd_exception); UNICORN_CONTROLLER->INTR_CHAR = (uint32_t) &mp_interrupt_char; diff --git a/unicorn/modmachine.c b/unicorn/modmachine.c index a755ee5..07919c5 100644 --- a/unicorn/modmachine.c +++ b/unicorn/modmachine.c @@ -27,7 +27,6 @@ #include #include "py/obj.h" -#include "mphalport.h" #include "modmachine.h" #include "extmod/machine_mem.h" #include "extmod/machine_i2c.h" @@ -43,6 +42,7 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_Pin), MP_ROM_PTR(&machine_pin_type) }, #if MICROPY_PY_MACHINE_I2C + { MP_ROM_QSTR(MP_QSTR_SoftI2C), MP_ROM_PTR(&mp_machine_soft_i2c_type) }, { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&machine_i2c_type) }, #endif }; @@ -53,4 +53,6 @@ const mp_obj_module_t mp_module_machine = { .globals = (mp_obj_dict_t*)&machine_module_globals, }; +MP_REGISTER_MODULE(MP_QSTR_machine, mp_module_machine); + #endif // MICROPY_PY_MACHINE diff --git a/unicorn/modmachine.h b/unicorn/modmachine.h index 4c338be..62f90bf 100644 --- a/unicorn/modmachine.h +++ b/unicorn/modmachine.h @@ -40,6 +40,6 @@ extern const mp_obj_type_t machine_pin_type; machine_pin_obj_t *machine_pin_get(mp_obj_t *obj_in); void pin_set(mp_obj_t self_in, int value); -extern const mp_obj_type_t machine_hard_i2c_type; +extern const mp_obj_type_t machine_i2c_type; #endif diff --git a/unicorn/modpyb.c b/unicorn/modpyb.c index 2312152..4daa6f7 100644 --- a/unicorn/modpyb.c +++ b/unicorn/modpyb.c @@ -42,3 +42,5 @@ const mp_obj_module_t pyb_module = { .base = { &mp_type_module }, .globals = (mp_obj_dict_t*)&pyb_module_globals, }; + +MP_REGISTER_MODULE(MP_QSTR_pyb, pyb_module); diff --git a/unicorn/modutime.c b/unicorn/modutime.c index 1cad089..fd0156c 100644 --- a/unicorn/modutime.c +++ b/unicorn/modutime.c @@ -30,10 +30,12 @@ #include "py/nlr.h" #include "py/smallint.h" #include "py/obj.h" -#include "lib/timeutils/timeutils.h" +#include "shared/timeutils/timeutils.h" #include "extmod/utime_mphal.h" #include "unicorn_mcu.h" +#if MICROPY_PY_UTIME_MP_HAL + STATIC const mp_rom_map_elem_t time_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_utime) }, @@ -53,3 +55,7 @@ const mp_obj_module_t mp_module_utime = { .base = { &mp_type_module }, .globals = (mp_obj_dict_t*)&time_module_globals, }; + +MP_REGISTER_MODULE(MP_QSTR_utime, mp_module_utime); + +#endif // MICROPY_PY_UTIME_MP_HAL diff --git a/unicorn/mpconfigport.h b/unicorn/mpconfigport.h index c2cd4b3..2e4c23f 100644 --- a/unicorn/mpconfigport.h +++ b/unicorn/mpconfigport.h @@ -47,6 +47,9 @@ typedef long mp_off_t; #define MICROPY_PORT_BUILTINS \ { MP_OBJ_NEW_QSTR(MP_QSTR_open), (mp_obj_t)&mp_builtin_open_obj }, +// We need an implementation of the log2 function which is not a macro +#define MP_NEED_LOG2 (1) + // We need to provide a declaration/definition of alloca() #include diff --git a/unicorn/mpconfigport_features.h b/unicorn/mpconfigport_features.h index f4ecbce..526ebc8 100644 --- a/unicorn/mpconfigport_features.h +++ b/unicorn/mpconfigport_features.h @@ -27,9 +27,4 @@ #define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_MPZ) #define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_FLOAT) -extern const struct _mp_obj_module_t mp_module_machine; - -#define MICROPY_PORT_BUILTIN_MODULES \ - { MP_ROM_QSTR(MP_QSTR_machine), MP_ROM_PTR(&mp_module_machine) }, \ - #include "mpconfigport.h" diff --git a/unicorn/mpconfigport_pyboard.h b/unicorn/mpconfigport_pyboard.h index 1e8ea71..e125fc9 100644 --- a/unicorn/mpconfigport_pyboard.h +++ b/unicorn/mpconfigport_pyboard.h @@ -39,23 +39,11 @@ #define MICROPY_PY_FRAMEBUF (1) #define MICROPY_PY_MACHINE (1) #define MICROPY_PY_MACHINE_I2C (1) -#define MICROPY_PY_MACHINE_I2C_MAKE_NEW machine_hard_i2c_make_new +#define MICROPY_PY_MACHINE_SOFTI2C (1) #define MICROPY_HW_I2C1_NAME "X" #define MICROPY_PY_UTIME_MP_HAL (1) #define MICROPY_MODULE_WEAK_LINKS (1) #define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_MPZ) #define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_FLOAT) -extern const struct _mp_obj_module_t mp_module_utime; -extern const struct _mp_obj_module_t mp_module_machine; -extern const struct _mp_obj_module_t pyb_module; - -#define MICROPY_PORT_BUILTIN_MODULES \ - { MP_ROM_QSTR(MP_QSTR_utime), MP_ROM_PTR(&mp_module_utime) }, \ - { MP_ROM_QSTR(MP_QSTR_machine), MP_ROM_PTR(&mp_module_machine) }, \ - { MP_ROM_QSTR(MP_QSTR_pyb), MP_ROM_PTR(&pyb_module) }, \ - -#define MICROPY_PORT_BUILTIN_MODULE_WEAK_LINKS \ - { MP_OBJ_NEW_QSTR(MP_QSTR_time), (mp_obj_t)&mp_module_utime }, \ - #include "mpconfigport.h" diff --git a/unicorn/mphalport.c b/unicorn/mphalport.c index 32725d5..32c7ff3 100644 --- a/unicorn/mphalport.c +++ b/unicorn/mphalport.c @@ -33,9 +33,8 @@ void mp_hal_delay_ms(mp_uint_t ms) { uint32_t start = mp_hal_ticks_ms(); - extern void mp_handle_pending(void); while (mp_hal_ticks_ms() - start < ms) { - mp_handle_pending(); + mp_handle_pending(true); UNICORN_CONTROLLER->IDLE = 1; } } @@ -43,7 +42,7 @@ void mp_hal_delay_ms(mp_uint_t ms) { void mp_hal_delay_us(mp_uint_t us) { uint32_t start = mp_hal_ticks_us(); while (mp_hal_ticks_us() - start < us) { - mp_handle_pending(); + mp_handle_pending(true); } } diff --git a/unicorn/mphalport.h b/unicorn/mphalport.h index 82c63b0..658fe5b 100644 --- a/unicorn/mphalport.h +++ b/unicorn/mphalport.h @@ -8,7 +8,9 @@ mp_uint_t mp_hal_ticks_us(void); mp_uint_t mp_hal_ticks_cpu(void); void mp_hal_set_interrupt_char(int c); +#define MP_HAL_PIN_FMT "%q" #define mp_hal_pin_obj_t const machine_pin_obj_t* +#define mp_hal_pin_name(p) ((p)->name) #define mp_hal_pin_od_low(p) pin_set((mp_obj_t)p, 0) #define mp_hal_pin_od_high(p) pin_set((mp_obj_t)p, 1) #define mp_hal_get_pin_obj(o) machine_pin_get(o) From 8286116877bc644502c48697171b45dcd8d5022a Mon Sep 17 00:00:00 2001 From: Damien George Date: Mon, 31 Oct 2022 13:29:08 +1100 Subject: [PATCH 34/34] www-unicorn/pyboard_demos.py: Use I2C('X') for LCD I2C demo. Signed-off-by: Damien George --- www-emu/pyboard_demos.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/www-emu/pyboard_demos.py b/www-emu/pyboard_demos.py index be93d66..44f2fd2 100644 --- a/www-emu/pyboard_demos.py +++ b/www-emu/pyboard_demos.py @@ -119,9 +119,7 @@ def asm_add(r0, r1): import machine import framebuf -scl = machine.Pin('X9') -sda = machine.Pin('X10') -i2c = machine.I2C(scl=scl, sda=sda) +i2c = machine.I2C('X') fbuf = framebuf.FrameBuffer(bytearray(64 * 32 // 8), 64, 32, framebuf.MONO_HLSB)