Port of MicroPython to the mbed platform. See micropython-repl for an interactive program.

Dependents:   micropython-repl

This a port of MicroPython to the mbed Classic platform.

This provides an interpreter running on the board's USB serial connection.

Getting Started

Import the micropython-repl program into your IDE workspace on developer.mbed.org. Compile and download to your board. Connect to the USB serial port in your usual manner. You should get a startup message similar to the following:

  MicroPython v1.7-155-gdddcdd8 on 2016-04-23; K64F with ARM
  Type "help()" for more information.
  >>>

Then you can start using micropython. For example:

  >>> from mbed import DigitalOut
  >>> from pins import LED1
  >>> led = DigitalOut(LED1)
  >>> led.write(1)

Requirements

You need approximately 100K of flash memory, so this will be no good for boards with smaller amounts of storage.

Caveats

This can be considered an alpha release of the port; things may not work; APIs may change in later releases. It is NOT an official part part the micropython project, so if anything doesn't work, blame me. If it does work, most of the credit is due to micropython.

  • Only a few of the mbed classes are available in micropython so far, and not all methods of those that are.
  • Only a few boards have their full range of pin names available; for others, only a few standard ones (USBTX, USBRX, LED1) are implemented.
  • The garbage collector is not yet implemented. The interpreter will gradually consume memory and then fail.
  • Exceptions from the mbed classes are not yet handled.
  • Asynchronous processing (e.g. events on inputs) is not supported.

Credits

  • Damien P. George and other contributors who created micropython.
  • Colin Hogben, author of this port.
Committer:
Colin Hogben
Date:
Wed Apr 27 22:11:29 2016 +0100
Revision:
10:33521d742af1
Parent:
0:5868e8752d44
Update README and version

Who changed what in which revision?

UserRevisionLine numberNew contents of line
pythontech 0:5868e8752d44 1 /*
pythontech 0:5868e8752d44 2 * This file is part of the Micro Python project, http://micropython.org/
pythontech 0:5868e8752d44 3 *
pythontech 0:5868e8752d44 4 * The MIT License (MIT)
pythontech 0:5868e8752d44 5 *
pythontech 0:5868e8752d44 6 * Copyright (c) 2013, 2014 Damien P. George
pythontech 0:5868e8752d44 7 *
pythontech 0:5868e8752d44 8 * Permission is hereby granted, free of charge, to any person obtaining a copy
pythontech 0:5868e8752d44 9 * of this software and associated documentation files (the "Software"), to deal
pythontech 0:5868e8752d44 10 * in the Software without restriction, including without limitation the rights
pythontech 0:5868e8752d44 11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
pythontech 0:5868e8752d44 12 * copies of the Software, and to permit persons to whom the Software is
pythontech 0:5868e8752d44 13 * furnished to do so, subject to the following conditions:
pythontech 0:5868e8752d44 14 *
pythontech 0:5868e8752d44 15 * The above copyright notice and this permission notice shall be included in
pythontech 0:5868e8752d44 16 * all copies or substantial portions of the Software.
pythontech 0:5868e8752d44 17 *
pythontech 0:5868e8752d44 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
pythontech 0:5868e8752d44 19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
pythontech 0:5868e8752d44 20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
pythontech 0:5868e8752d44 21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
pythontech 0:5868e8752d44 22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
pythontech 0:5868e8752d44 23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
pythontech 0:5868e8752d44 24 * THE SOFTWARE.
pythontech 0:5868e8752d44 25 */
pythontech 0:5868e8752d44 26
pythontech 0:5868e8752d44 27 #include <stdlib.h>
pythontech 0:5868e8752d44 28 #include <stdio.h>
pythontech 0:5868e8752d44 29 #include <assert.h>
pythontech 0:5868e8752d44 30
pythontech 0:5868e8752d44 31 #include "py/nlr.h"
pythontech 0:5868e8752d44 32 #include "py/obj.h"
pythontech 0:5868e8752d44 33 #include "py/parsenum.h"
pythontech 0:5868e8752d44 34 #include "py/runtime0.h"
pythontech 0:5868e8752d44 35 #include "py/runtime.h"
pythontech 0:5868e8752d44 36
pythontech 0:5868e8752d44 37 #if MICROPY_PY_BUILTINS_COMPLEX
pythontech 0:5868e8752d44 38
pythontech 0:5868e8752d44 39 #include <math.h>
pythontech 0:5868e8752d44 40 #include "py/formatfloat.h"
pythontech 0:5868e8752d44 41
pythontech 0:5868e8752d44 42 typedef struct _mp_obj_complex_t {
pythontech 0:5868e8752d44 43 mp_obj_base_t base;
pythontech 0:5868e8752d44 44 mp_float_t real;
pythontech 0:5868e8752d44 45 mp_float_t imag;
pythontech 0:5868e8752d44 46 } mp_obj_complex_t;
pythontech 0:5868e8752d44 47
pythontech 0:5868e8752d44 48 STATIC void complex_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind) {
pythontech 0:5868e8752d44 49 (void)kind;
pythontech 0:5868e8752d44 50 mp_obj_complex_t *o = MP_OBJ_TO_PTR(o_in);
pythontech 0:5868e8752d44 51 #if MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_FLOAT
pythontech 0:5868e8752d44 52 char buf[16];
pythontech 0:5868e8752d44 53 const int precision = 7;
pythontech 0:5868e8752d44 54 #else
pythontech 0:5868e8752d44 55 char buf[32];
pythontech 0:5868e8752d44 56 const int precision = 16;
pythontech 0:5868e8752d44 57 #endif
pythontech 0:5868e8752d44 58 if (o->real == 0) {
pythontech 0:5868e8752d44 59 mp_format_float(o->imag, buf, sizeof(buf), 'g', precision, '\0');
pythontech 0:5868e8752d44 60 mp_printf(print, "%sj", buf);
pythontech 0:5868e8752d44 61 } else {
pythontech 0:5868e8752d44 62 mp_format_float(o->real, buf, sizeof(buf), 'g', precision, '\0');
pythontech 0:5868e8752d44 63 mp_printf(print, "(%s", buf);
pythontech 0:5868e8752d44 64 if (o->imag >= 0 || isnan(o->imag)) {
pythontech 0:5868e8752d44 65 mp_print_str(print, "+");
pythontech 0:5868e8752d44 66 }
pythontech 0:5868e8752d44 67 mp_format_float(o->imag, buf, sizeof(buf), 'g', precision, '\0');
pythontech 0:5868e8752d44 68 mp_printf(print, "%sj)", buf);
pythontech 0:5868e8752d44 69 }
pythontech 0:5868e8752d44 70 }
pythontech 0:5868e8752d44 71
pythontech 0:5868e8752d44 72 STATIC mp_obj_t complex_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
pythontech 0:5868e8752d44 73 (void)type_in;
pythontech 0:5868e8752d44 74 mp_arg_check_num(n_args, n_kw, 0, 2, false);
pythontech 0:5868e8752d44 75
pythontech 0:5868e8752d44 76 switch (n_args) {
pythontech 0:5868e8752d44 77 case 0:
pythontech 0:5868e8752d44 78 return mp_obj_new_complex(0, 0);
pythontech 0:5868e8752d44 79
pythontech 0:5868e8752d44 80 case 1:
pythontech 0:5868e8752d44 81 if (MP_OBJ_IS_STR(args[0])) {
pythontech 0:5868e8752d44 82 // a string, parse it
pythontech 0:5868e8752d44 83 mp_uint_t l;
pythontech 0:5868e8752d44 84 const char *s = mp_obj_str_get_data(args[0], &l);
pythontech 0:5868e8752d44 85 return mp_parse_num_decimal(s, l, true, true, NULL);
pythontech 0:5868e8752d44 86 } else if (MP_OBJ_IS_TYPE(args[0], &mp_type_complex)) {
pythontech 0:5868e8752d44 87 // a complex, just return it
pythontech 0:5868e8752d44 88 return args[0];
pythontech 0:5868e8752d44 89 } else {
pythontech 0:5868e8752d44 90 // something else, try to cast it to a complex
pythontech 0:5868e8752d44 91 return mp_obj_new_complex(mp_obj_get_float(args[0]), 0);
pythontech 0:5868e8752d44 92 }
pythontech 0:5868e8752d44 93
pythontech 0:5868e8752d44 94 case 2:
pythontech 0:5868e8752d44 95 default: {
pythontech 0:5868e8752d44 96 mp_float_t real, imag;
pythontech 0:5868e8752d44 97 if (MP_OBJ_IS_TYPE(args[0], &mp_type_complex)) {
pythontech 0:5868e8752d44 98 mp_obj_complex_get(args[0], &real, &imag);
pythontech 0:5868e8752d44 99 } else {
pythontech 0:5868e8752d44 100 real = mp_obj_get_float(args[0]);
pythontech 0:5868e8752d44 101 imag = 0;
pythontech 0:5868e8752d44 102 }
pythontech 0:5868e8752d44 103 if (MP_OBJ_IS_TYPE(args[1], &mp_type_complex)) {
pythontech 0:5868e8752d44 104 mp_float_t real2, imag2;
pythontech 0:5868e8752d44 105 mp_obj_complex_get(args[1], &real2, &imag2);
pythontech 0:5868e8752d44 106 real -= imag2;
pythontech 0:5868e8752d44 107 imag += real2;
pythontech 0:5868e8752d44 108 } else {
pythontech 0:5868e8752d44 109 imag += mp_obj_get_float(args[1]);
pythontech 0:5868e8752d44 110 }
pythontech 0:5868e8752d44 111 return mp_obj_new_complex(real, imag);
pythontech 0:5868e8752d44 112 }
pythontech 0:5868e8752d44 113 }
pythontech 0:5868e8752d44 114 }
pythontech 0:5868e8752d44 115
pythontech 0:5868e8752d44 116 STATIC mp_obj_t complex_unary_op(mp_uint_t op, mp_obj_t o_in) {
pythontech 0:5868e8752d44 117 mp_obj_complex_t *o = MP_OBJ_TO_PTR(o_in);
pythontech 0:5868e8752d44 118 switch (op) {
pythontech 0:5868e8752d44 119 case MP_UNARY_OP_BOOL: return mp_obj_new_bool(o->real != 0 || o->imag != 0);
pythontech 0:5868e8752d44 120 case MP_UNARY_OP_POSITIVE: return o_in;
pythontech 0:5868e8752d44 121 case MP_UNARY_OP_NEGATIVE: return mp_obj_new_complex(-o->real, -o->imag);
pythontech 0:5868e8752d44 122 default: return MP_OBJ_NULL; // op not supported
pythontech 0:5868e8752d44 123 }
pythontech 0:5868e8752d44 124 }
pythontech 0:5868e8752d44 125
pythontech 0:5868e8752d44 126 STATIC mp_obj_t complex_binary_op(mp_uint_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
pythontech 0:5868e8752d44 127 mp_obj_complex_t *lhs = MP_OBJ_TO_PTR(lhs_in);
pythontech 0:5868e8752d44 128 return mp_obj_complex_binary_op(op, lhs->real, lhs->imag, rhs_in);
pythontech 0:5868e8752d44 129 }
pythontech 0:5868e8752d44 130
pythontech 0:5868e8752d44 131 STATIC void complex_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
pythontech 0:5868e8752d44 132 if (dest[0] != MP_OBJ_NULL) {
pythontech 0:5868e8752d44 133 // not load attribute
pythontech 0:5868e8752d44 134 return;
pythontech 0:5868e8752d44 135 }
pythontech 0:5868e8752d44 136 mp_obj_complex_t *self = MP_OBJ_TO_PTR(self_in);
pythontech 0:5868e8752d44 137 if (attr == MP_QSTR_real) {
pythontech 0:5868e8752d44 138 dest[0] = mp_obj_new_float(self->real);
pythontech 0:5868e8752d44 139 } else if (attr == MP_QSTR_imag) {
pythontech 0:5868e8752d44 140 dest[0] = mp_obj_new_float(self->imag);
pythontech 0:5868e8752d44 141 }
pythontech 0:5868e8752d44 142 }
pythontech 0:5868e8752d44 143
pythontech 0:5868e8752d44 144 const mp_obj_type_t mp_type_complex = {
pythontech 0:5868e8752d44 145 { &mp_type_type },
pythontech 0:5868e8752d44 146 .name = MP_QSTR_complex,
pythontech 0:5868e8752d44 147 .print = complex_print,
pythontech 0:5868e8752d44 148 .make_new = complex_make_new,
pythontech 0:5868e8752d44 149 .unary_op = complex_unary_op,
pythontech 0:5868e8752d44 150 .binary_op = complex_binary_op,
pythontech 0:5868e8752d44 151 .attr = complex_attr,
pythontech 0:5868e8752d44 152 };
pythontech 0:5868e8752d44 153
pythontech 0:5868e8752d44 154 mp_obj_t mp_obj_new_complex(mp_float_t real, mp_float_t imag) {
pythontech 0:5868e8752d44 155 mp_obj_complex_t *o = m_new_obj(mp_obj_complex_t);
pythontech 0:5868e8752d44 156 o->base.type = &mp_type_complex;
pythontech 0:5868e8752d44 157 o->real = real;
pythontech 0:5868e8752d44 158 o->imag = imag;
pythontech 0:5868e8752d44 159 return MP_OBJ_FROM_PTR(o);
pythontech 0:5868e8752d44 160 }
pythontech 0:5868e8752d44 161
pythontech 0:5868e8752d44 162 void mp_obj_complex_get(mp_obj_t self_in, mp_float_t *real, mp_float_t *imag) {
pythontech 0:5868e8752d44 163 assert(MP_OBJ_IS_TYPE(self_in, &mp_type_complex));
pythontech 0:5868e8752d44 164 mp_obj_complex_t *self = MP_OBJ_TO_PTR(self_in);
pythontech 0:5868e8752d44 165 *real = self->real;
pythontech 0:5868e8752d44 166 *imag = self->imag;
pythontech 0:5868e8752d44 167 }
pythontech 0:5868e8752d44 168
pythontech 0:5868e8752d44 169 mp_obj_t mp_obj_complex_binary_op(mp_uint_t op, mp_float_t lhs_real, mp_float_t lhs_imag, mp_obj_t rhs_in) {
pythontech 0:5868e8752d44 170 mp_float_t rhs_real, rhs_imag;
pythontech 0:5868e8752d44 171 mp_obj_get_complex(rhs_in, &rhs_real, &rhs_imag); // can be any type, this function will convert to float (if possible)
pythontech 0:5868e8752d44 172 switch (op) {
pythontech 0:5868e8752d44 173 case MP_BINARY_OP_ADD:
pythontech 0:5868e8752d44 174 case MP_BINARY_OP_INPLACE_ADD:
pythontech 0:5868e8752d44 175 lhs_real += rhs_real;
pythontech 0:5868e8752d44 176 lhs_imag += rhs_imag;
pythontech 0:5868e8752d44 177 break;
pythontech 0:5868e8752d44 178 case MP_BINARY_OP_SUBTRACT:
pythontech 0:5868e8752d44 179 case MP_BINARY_OP_INPLACE_SUBTRACT:
pythontech 0:5868e8752d44 180 lhs_real -= rhs_real;
pythontech 0:5868e8752d44 181 lhs_imag -= rhs_imag;
pythontech 0:5868e8752d44 182 break;
pythontech 0:5868e8752d44 183 case MP_BINARY_OP_MULTIPLY:
pythontech 0:5868e8752d44 184 case MP_BINARY_OP_INPLACE_MULTIPLY: {
pythontech 0:5868e8752d44 185 mp_float_t real;
pythontech 0:5868e8752d44 186 multiply:
pythontech 0:5868e8752d44 187 real = lhs_real * rhs_real - lhs_imag * rhs_imag;
pythontech 0:5868e8752d44 188 lhs_imag = lhs_real * rhs_imag + lhs_imag * rhs_real;
pythontech 0:5868e8752d44 189 lhs_real = real;
pythontech 0:5868e8752d44 190 break;
pythontech 0:5868e8752d44 191 }
pythontech 0:5868e8752d44 192 case MP_BINARY_OP_FLOOR_DIVIDE:
pythontech 0:5868e8752d44 193 case MP_BINARY_OP_INPLACE_FLOOR_DIVIDE:
pythontech 0:5868e8752d44 194 nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "can't do truncated division of a complex number"));
pythontech 0:5868e8752d44 195
pythontech 0:5868e8752d44 196 case MP_BINARY_OP_TRUE_DIVIDE:
pythontech 0:5868e8752d44 197 case MP_BINARY_OP_INPLACE_TRUE_DIVIDE:
pythontech 0:5868e8752d44 198 if (rhs_imag == 0) {
pythontech 0:5868e8752d44 199 if (rhs_real == 0) {
pythontech 0:5868e8752d44 200 nlr_raise(mp_obj_new_exception_msg(&mp_type_ZeroDivisionError, "complex division by zero"));
pythontech 0:5868e8752d44 201 }
pythontech 0:5868e8752d44 202 lhs_real /= rhs_real;
pythontech 0:5868e8752d44 203 lhs_imag /= rhs_real;
pythontech 0:5868e8752d44 204 } else if (rhs_real == 0) {
pythontech 0:5868e8752d44 205 mp_float_t real = lhs_imag / rhs_imag;
pythontech 0:5868e8752d44 206 lhs_imag = -lhs_real / rhs_imag;
pythontech 0:5868e8752d44 207 lhs_real = real;
pythontech 0:5868e8752d44 208 } else {
pythontech 0:5868e8752d44 209 mp_float_t rhs_len_sq = rhs_real*rhs_real + rhs_imag*rhs_imag;
pythontech 0:5868e8752d44 210 rhs_real /= rhs_len_sq;
pythontech 0:5868e8752d44 211 rhs_imag /= -rhs_len_sq;
pythontech 0:5868e8752d44 212 goto multiply;
pythontech 0:5868e8752d44 213 }
pythontech 0:5868e8752d44 214 break;
pythontech 0:5868e8752d44 215
pythontech 0:5868e8752d44 216 case MP_BINARY_OP_POWER:
pythontech 0:5868e8752d44 217 case MP_BINARY_OP_INPLACE_POWER: {
pythontech 0:5868e8752d44 218 // z1**z2 = exp(z2*ln(z1))
pythontech 0:5868e8752d44 219 // = exp(z2*(ln(|z1|)+i*arg(z1)))
pythontech 0:5868e8752d44 220 // = exp( (x2*ln1 - y2*arg1) + i*(y2*ln1 + x2*arg1) )
pythontech 0:5868e8752d44 221 // = exp(x3 + i*y3)
pythontech 0:5868e8752d44 222 // = exp(x3)*(cos(y3) + i*sin(y3))
pythontech 0:5868e8752d44 223 mp_float_t abs1 = MICROPY_FLOAT_C_FUN(sqrt)(lhs_real*lhs_real + lhs_imag*lhs_imag);
pythontech 0:5868e8752d44 224 if (abs1 == 0) {
pythontech 0:5868e8752d44 225 if (rhs_imag == 0) {
pythontech 0:5868e8752d44 226 lhs_real = 1;
pythontech 0:5868e8752d44 227 rhs_real = 0;
pythontech 0:5868e8752d44 228 } else {
pythontech 0:5868e8752d44 229 nlr_raise(mp_obj_new_exception_msg(&mp_type_ZeroDivisionError, "0.0 to a complex power"));
pythontech 0:5868e8752d44 230 }
pythontech 0:5868e8752d44 231 } else {
pythontech 0:5868e8752d44 232 mp_float_t ln1 = MICROPY_FLOAT_C_FUN(log)(abs1);
pythontech 0:5868e8752d44 233 mp_float_t arg1 = MICROPY_FLOAT_C_FUN(atan2)(lhs_imag, lhs_real);
pythontech 0:5868e8752d44 234 mp_float_t x3 = rhs_real * ln1 - rhs_imag * arg1;
pythontech 0:5868e8752d44 235 mp_float_t y3 = rhs_imag * ln1 + rhs_real * arg1;
pythontech 0:5868e8752d44 236 mp_float_t exp_x3 = MICROPY_FLOAT_C_FUN(exp)(x3);
pythontech 0:5868e8752d44 237 lhs_real = exp_x3 * MICROPY_FLOAT_C_FUN(cos)(y3);
pythontech 0:5868e8752d44 238 lhs_imag = exp_x3 * MICROPY_FLOAT_C_FUN(sin)(y3);
pythontech 0:5868e8752d44 239 }
pythontech 0:5868e8752d44 240 break;
pythontech 0:5868e8752d44 241 }
pythontech 0:5868e8752d44 242
pythontech 0:5868e8752d44 243 case MP_BINARY_OP_EQUAL: return mp_obj_new_bool(lhs_real == rhs_real && lhs_imag == rhs_imag);
pythontech 0:5868e8752d44 244
pythontech 0:5868e8752d44 245 default:
pythontech 0:5868e8752d44 246 return MP_OBJ_NULL; // op not supported
pythontech 0:5868e8752d44 247 }
pythontech 0:5868e8752d44 248 return mp_obj_new_complex(lhs_real, lhs_imag);
pythontech 0:5868e8752d44 249 }
pythontech 0:5868e8752d44 250
pythontech 0:5868e8752d44 251 #endif