summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--.gitignore3
-rw-r--r--README.md3
-rw-r--r--logo/micropythonpowered-art.pngbin0 -> 30494 bytes
-rw-r--r--logo/upython-with-micro.jpgbin0 -> 79102 bytes
-rw-r--r--logo/upython-with-micro.pngbin0 -> 576190 bytes
-rw-r--r--logo/vector-logo-2.pngbin90783 -> 92679 bytes
-rw-r--r--logo/vector-logo-3.pngbin0 -> 114034 bytes
-rw-r--r--logo/vector-logo-inkscape_master.svg2105
-rw-r--r--py/builtin.c124
-rw-r--r--py/builtin.h39
-rw-r--r--py/builtineval.c50
-rw-r--r--py/builtinimport.c11
-rw-r--r--py/compile.c10
-rw-r--r--py/emitpass1.c5
-rw-r--r--py/gc.c7
-rw-r--r--py/grammar.h2
-rw-r--r--py/lexer.c28
-rw-r--r--py/lexer.h37
-rw-r--r--py/map.c67
-rw-r--r--py/map.h10
-rw-r--r--py/misc.h9
-rw-r--r--py/mpconfig.h17
-rw-r--r--py/mpqstrraw.h11
-rw-r--r--py/obj.c43
-rw-r--r--py/obj.h33
-rw-r--r--py/objbool.c2
-rw-r--r--py/objcomplex.c2
-rw-r--r--py/objdict.c26
-rw-r--r--py/objenumerate.c53
-rw-r--r--py/objexcept.c123
-rw-r--r--py/objfilter.c58
-rw-r--r--py/objfloat.c2
-rw-r--r--py/objfun.c80
-rw-r--r--py/objgenerator.c2
-rw-r--r--py/objint.c56
-rw-r--r--py/objint.h9
-rw-r--r--py/objlist.c73
-rw-r--r--py/objmap.c60
-rw-r--r--py/objmodule.c2
-rw-r--r--py/objnone.c2
-rw-r--r--py/objset.c401
-rw-r--r--py/objslice.c4
-rw-r--r--py/objstr.c71
-rw-r--r--py/objtuple.c31
-rw-r--r--py/objtuple.h7
-rw-r--r--py/objtype.c4
-rw-r--r--py/objzip.c57
-rw-r--r--py/parse.c72
-rw-r--r--py/parse.h3
-rw-r--r--py/py.mk5
-rw-r--r--py/runtime.c126
-rw-r--r--py/runtime.h6
-rw-r--r--py/stream.c86
-rw-r--r--py/stream.h2
-rw-r--r--py/strtonum.c2
-rw-r--r--py/strtonum.h1
-rw-r--r--py/vm.c15
-rw-r--r--py/vstr.c45
-rw-r--r--stm/Makefile13
-rw-r--r--stm/adc.c304
-rw-r--r--stm/adc.h1
-rw-r--r--stm/audio.c6
-rw-r--r--stm/lcd.c14
-rw-r--r--stm/lib/stm32f4xx_adc.c1746
-rw-r--r--stm/lib/stm32f4xx_adc.h656
-rw-r--r--stm/lib/usb_bsp.c89
-rw-r--r--stm/lib/usb_conf.h59
-rw-r--r--stm/lib/usb_core.c2
-rw-r--r--stm/main.c106
-rw-r--r--stm/printf.c21
-rw-r--r--stm/pybwlan.c10
-rw-r--r--stm/std.h2
-rw-r--r--stm/stm32fxxx_it.c4
-rw-r--r--stm/string0.c28
-rw-r--r--stm/timer.c10
-rw-r--r--stm/usart.c30
-rw-r--r--stm/usart.h17
-rw-r--r--stm/usb.c29
-rw-r--r--stm/usb.h3
-rw-r--r--teensy/Makefile29
-rwxr-xr-xteensy/add-memzip.sh27
-rw-r--r--teensy/lexermemzip.c18
-rw-r--r--teensy/lexermemzip.h2
-rw-r--r--teensy/main.c133
-rw-r--r--teensy/memzip.c37
-rw-r--r--teensy/memzip.h73
-rw-r--r--teensy/memzip_files/boot.py1
-rw-r--r--teensy/memzip_files/src/main.py11
-rw-r--r--teensy/memzip_files/src/test.py1
-rw-r--r--teensy/memzip_files/test.py1
-rw-r--r--teensy/mk20dx256.ld6
-rwxr-xr-xtests/basics/run-tests3
-rw-r--r--tests/basics/tests/containment.py23
-rw-r--r--tests/basics/tests/enumerate.py6
-rw-r--r--tests/basics/tests/eval1.py13
-rw-r--r--tests/basics/tests/exception1.py9
-rw-r--r--tests/basics/tests/filter.py2
-rw-r--r--tests/basics/tests/int-small.py26
-rw-r--r--tests/basics/tests/is-isnot.py14
-rw-r--r--tests/basics/tests/list_compare.py50
-rw-r--r--tests/basics/tests/map.py4
-rw-r--r--tests/basics/tests/set_add.py5
-rw-r--r--tests/basics/tests/set_binop.py30
-rw-r--r--tests/basics/tests/set_clear.py3
-rw-r--r--tests/basics/tests/set_copy.py8
-rw-r--r--tests/basics/tests/set_difference.py21
-rw-r--r--tests/basics/tests/set_discard.py3
-rw-r--r--tests/basics/tests/set_intersection.py12
-rw-r--r--tests/basics/tests/set_isdisjoint.py6
-rw-r--r--tests/basics/tests/set_isfooset.py5
-rw-r--r--tests/basics/tests/set_iter.py5
-rw-r--r--tests/basics/tests/set_pop.py9
-rw-r--r--tests/basics/tests/set_remove.py9
-rw-r--r--tests/basics/tests/set_symmetric_difference.py7
-rw-r--r--tests/basics/tests/set_union.py1
-rw-r--r--tests/basics/tests/set_update.py12
-rw-r--r--tests/basics/tests/sorted.py2
-rw-r--r--tests/basics/tests/string_find.py11
-rw-r--r--tests/basics/tests/zip.py2
-rw-r--r--unix-cpy/Makefile9
-rw-r--r--unix-cpy/main.c17
-rw-r--r--unix/Makefile11
-rw-r--r--unix/file.c4
-rw-r--r--unix/main.c14
124 files changed, 7307 insertions, 640 deletions
diff --git a/.gitignore b/.gitignore
index 95be7bf651..6224e57cdb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,3 +19,6 @@
######################
*.swp
+# Build directory
+######################
+build/
diff --git a/README.md b/README.md
index dda8970f0c..d723818fe3 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,8 @@
The Micro Python project
========================
+<p align="center">
+ <img src="https://raw2.github.com/micropython/micropython/master/logo/upython-with-micro.jpg" alt="MicroPython Logo"/>
+</p>
This is the Micro Python project, which aims to put an implementation
of Python 3.x on a microcontroller.
diff --git a/logo/micropythonpowered-art.png b/logo/micropythonpowered-art.png
new file mode 100644
index 0000000000..9045bb0a43
--- /dev/null
+++ b/logo/micropythonpowered-art.png
Binary files differ
diff --git a/logo/upython-with-micro.jpg b/logo/upython-with-micro.jpg
new file mode 100644
index 0000000000..4984d8e2f2
--- /dev/null
+++ b/logo/upython-with-micro.jpg
Binary files differ
diff --git a/logo/upython-with-micro.png b/logo/upython-with-micro.png
new file mode 100644
index 0000000000..2b3431cbdd
--- /dev/null
+++ b/logo/upython-with-micro.png
Binary files differ
diff --git a/logo/vector-logo-2.png b/logo/vector-logo-2.png
index 3ad2383ff5..72ce88e1d5 100644
--- a/logo/vector-logo-2.png
+++ b/logo/vector-logo-2.png
Binary files differ
diff --git a/logo/vector-logo-3.png b/logo/vector-logo-3.png
new file mode 100644
index 0000000000..ba75b05624
--- /dev/null
+++ b/logo/vector-logo-3.png
Binary files differ
diff --git a/logo/vector-logo-inkscape_master.svg b/logo/vector-logo-inkscape_master.svg
index 19415d41b7..ddcf741178 100644
--- a/logo/vector-logo-inkscape_master.svg
+++ b/logo/vector-logo-inkscape_master.svg
@@ -15,8 +15,8 @@
height="779.328"
id="svg2"
inkscape:version="0.48.4 r9939"
- sodipodi:docname="vector-logo-inkscape_master.svg"
- inkscape:export-filename="R:\Mark_Sector\!!Projects-2\microPython\Logo\vector-logo-4.png"
+ sodipodi:docname="vector-logo-inkscape_master-2.svg"
+ inkscape:export-filename="C:\Users\user3\Documents\GitHub\micropython\logo\vector-logo-2.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90">
<sodipodi:namedview
@@ -28,20 +28,110 @@
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
- inkscape:window-width="1609"
+ inkscape:window-width="1414"
inkscape:window-height="1086"
id="namedview127"
showgrid="false"
- inkscape:zoom="1.1668212"
- inkscape:cx="347.36024"
- inkscape:cy="357.11268"
+ inkscape:zoom="0.80389336"
+ inkscape:cx="-0.14388424"
+ inkscape:cy="205.20636"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="0"
- inkscape:current-layer="layer6" />
+ inkscape:current-layer="layer3" />
<defs
id="defs4">
<linearGradient
+ id="linearGradient5215">
+ <stop
+ style="stop-color:#f1f1f1;stop-opacity:1;"
+ offset="0"
+ id="stop5217" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0.4054054;"
+ offset="1"
+ id="stop5219" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient5205">
+ <stop
+ style="stop-color:#d8d8d8;stop-opacity:1;"
+ offset="0"
+ id="stop5207" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop5209" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4753">
+ <stop
+ id="stop4755"
+ offset="0"
+ style="stop-color:#101010;stop-opacity:1;" />
+ <stop
+ style="stop-color:#acacac;stop-opacity:1;"
+ offset="0.47657159"
+ id="stop4761" />
+ <stop
+ style="stop-color:#acacac;stop-opacity:1;"
+ offset="0.60369939"
+ id="stop4759" />
+ <stop
+ id="stop4757"
+ offset="1"
+ style="stop-color:#3e3e3e;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4249">
+ <stop
+ style="stop-color:#afafaf;stop-opacity:1;"
+ offset="0"
+ id="stop4251" />
+ <stop
+ style="stop-color:#0b0b0b;stop-opacity:1;"
+ offset="1"
+ id="stop4253" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4233">
+ <stop
+ style="stop-color:#6f6f6f;stop-opacity:1;"
+ offset="0"
+ id="stop4235" />
+ <stop
+ id="stop4247"
+ offset="0.0808401"
+ style="stop-color:#ffffff;stop-opacity:1" />
+ <stop
+ id="stop4245"
+ offset="0.125"
+ style="stop-color:#616161;stop-opacity:1;" />
+ <stop
+ id="stop4243"
+ offset="0.25"
+ style="stop-color:#535353;stop-opacity:1;" />
+ <stop
+ id="stop4241"
+ offset="0.5"
+ style="stop-color:#373737;stop-opacity:1;" />
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="1"
+ id="stop4237" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4029">
+ <stop
+ style="stop-color:#3e3e3e;stop-opacity:1;"
+ offset="0"
+ id="stop4031" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop4033" />
+ </linearGradient>
+ <linearGradient
id="linearGradient4981">
<stop
style="stop-color:#370000;stop-opacity:1;"
@@ -364,6 +454,1786 @@
x2="273.90927"
y2="601.64478"
gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4029"
+ id="linearGradient4035"
+ x1="50.162903"
+ y1="641.96503"
+ x2="305.03671"
+ y2="733.44366"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249"
+ id="linearGradient4255"
+ x1="48.514041"
+ y1="697.80837"
+ x2="326.39456"
+ y2="697.80837"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249-2"
+ id="linearGradient4332-7"
+ gradientUnits="userSpaceOnUse"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981" />
+ <linearGradient
+ id="linearGradient4249-2">
+ <stop
+ style="stop-color:#afafaf;stop-opacity:1;"
+ offset="0"
+ id="stop4251-2" />
+ <stop
+ style="stop-color:#0b0b0b;stop-opacity:1;"
+ offset="1"
+ id="stop4253-9" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249-9"
+ id="linearGradient4332-1"
+ gradientUnits="userSpaceOnUse"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981" />
+ <linearGradient
+ id="linearGradient4249-9">
+ <stop
+ style="stop-color:#afafaf;stop-opacity:1;"
+ offset="0"
+ id="stop4251-6" />
+ <stop
+ style="stop-color:#0b0b0b;stop-opacity:1;"
+ offset="1"
+ id="stop4253-98" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249-4"
+ id="linearGradient4332-5"
+ gradientUnits="userSpaceOnUse"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981" />
+ <linearGradient
+ id="linearGradient4249-4">
+ <stop
+ style="stop-color:#afafaf;stop-opacity:1;"
+ offset="0"
+ id="stop4251-9" />
+ <stop
+ style="stop-color:#0b0b0b;stop-opacity:1;"
+ offset="1"
+ id="stop4253-1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249-3"
+ id="linearGradient4332-8"
+ gradientUnits="userSpaceOnUse"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981" />
+ <linearGradient
+ id="linearGradient4249-3">
+ <stop
+ style="stop-color:#afafaf;stop-opacity:1;"
+ offset="0"
+ id="stop4251-93" />
+ <stop
+ style="stop-color:#0b0b0b;stop-opacity:1;"
+ offset="1"
+ id="stop4253-96" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249-7"
+ id="linearGradient4332-9"
+ gradientUnits="userSpaceOnUse"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981" />
+ <linearGradient
+ id="linearGradient4249-7">
+ <stop
+ style="stop-color:#afafaf;stop-opacity:1;"
+ offset="0"
+ id="stop4251-69" />
+ <stop
+ style="stop-color:#0b0b0b;stop-opacity:1;"
+ offset="1"
+ id="stop4253-3" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249-6"
+ id="linearGradient4332-6"
+ gradientUnits="userSpaceOnUse"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981" />
+ <linearGradient
+ id="linearGradient4249-6">
+ <stop
+ style="stop-color:#afafaf;stop-opacity:1;"
+ offset="0"
+ id="stop4251-5" />
+ <stop
+ style="stop-color:#0b0b0b;stop-opacity:1;"
+ offset="1"
+ id="stop4253-8" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249-63"
+ id="linearGradient4332-61"
+ gradientUnits="userSpaceOnUse"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981" />
+ <linearGradient
+ id="linearGradient4249-63">
+ <stop
+ style="stop-color:#afafaf;stop-opacity:1;"
+ offset="0"
+ id="stop4251-3" />
+ <stop
+ style="stop-color:#0b0b0b;stop-opacity:1;"
+ offset="1"
+ id="stop4253-5" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249-5"
+ id="linearGradient4332-82"
+ gradientUnits="userSpaceOnUse"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981" />
+ <linearGradient
+ id="linearGradient4249-5">
+ <stop
+ style="stop-color:#afafaf;stop-opacity:1;"
+ offset="0"
+ id="stop4251-36" />
+ <stop
+ style="stop-color:#0b0b0b;stop-opacity:1;"
+ offset="1"
+ id="stop4253-18" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249-62"
+ id="linearGradient4332-4"
+ gradientUnits="userSpaceOnUse"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981" />
+ <linearGradient
+ id="linearGradient4249-62">
+ <stop
+ style="stop-color:#afafaf;stop-opacity:1;"
+ offset="0"
+ id="stop4251-91" />
+ <stop
+ style="stop-color:#0b0b0b;stop-opacity:1;"
+ offset="1"
+ id="stop4253-50" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249-29"
+ id="linearGradient4332-49"
+ gradientUnits="userSpaceOnUse"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981" />
+ <linearGradient
+ id="linearGradient4249-29">
+ <stop
+ style="stop-color:#afafaf;stop-opacity:1;"
+ offset="0"
+ id="stop4251-34" />
+ <stop
+ style="stop-color:#0b0b0b;stop-opacity:1;"
+ offset="1"
+ id="stop4253-4" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249-42"
+ id="linearGradient4332-63"
+ gradientUnits="userSpaceOnUse"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981" />
+ <linearGradient
+ id="linearGradient4249-42">
+ <stop
+ style="stop-color:#afafaf;stop-opacity:1;"
+ offset="0"
+ id="stop4251-8" />
+ <stop
+ style="stop-color:#0b0b0b;stop-opacity:1;"
+ offset="1"
+ id="stop4253-87" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249-57"
+ id="linearGradient4332-2"
+ gradientUnits="userSpaceOnUse"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981" />
+ <linearGradient
+ id="linearGradient4249-57">
+ <stop
+ style="stop-color:#afafaf;stop-opacity:1;"
+ offset="0"
+ id="stop4251-4" />
+ <stop
+ style="stop-color:#0b0b0b;stop-opacity:1;"
+ offset="1"
+ id="stop4253-44" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249-0"
+ id="linearGradient4332-93"
+ gradientUnits="userSpaceOnUse"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981" />
+ <linearGradient
+ id="linearGradient4249-0">
+ <stop
+ style="stop-color:#afafaf;stop-opacity:1;"
+ offset="0"
+ id="stop4251-7" />
+ <stop
+ style="stop-color:#0b0b0b;stop-opacity:1;"
+ offset="1"
+ id="stop4253-7" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249-38"
+ id="linearGradient4332-0"
+ gradientUnits="userSpaceOnUse"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981" />
+ <linearGradient
+ id="linearGradient4249-38">
+ <stop
+ style="stop-color:#afafaf;stop-opacity:1;"
+ offset="0"
+ id="stop4251-25" />
+ <stop
+ style="stop-color:#0b0b0b;stop-opacity:1;"
+ offset="1"
+ id="stop4253-2" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249-53"
+ id="linearGradient4332-97"
+ gradientUnits="userSpaceOnUse"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981" />
+ <linearGradient
+ id="linearGradient4249-53">
+ <stop
+ style="stop-color:#afafaf;stop-opacity:1;"
+ offset="0"
+ id="stop4251-43" />
+ <stop
+ style="stop-color:#0b0b0b;stop-opacity:1;"
+ offset="1"
+ id="stop4253-21" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249"
+ id="linearGradient4627"
+ gradientUnits="userSpaceOnUse"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249-2"
+ id="linearGradient4629"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(16.462108,6.0241868)"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249-9"
+ id="linearGradient4631"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(32.653947,11.977068)"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249-4"
+ id="linearGradient4633"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(49.0839,18.168066)"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249-3"
+ id="linearGradient4635"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(65.513853,24.359063)"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249-7"
+ id="linearGradient4637"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(81.467577,30.311944)"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249-6"
+ id="linearGradient4639"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(97.89753,36.02671)"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249-63"
+ id="linearGradient4641"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(115.04183,41.741477)"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249-5"
+ id="linearGradient4643"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(130.99555,47.694359)"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249-62"
+ id="linearGradient4645"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(147.66362,53.647241)"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249-29"
+ id="linearGradient4647"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(164.09357,59.838237)"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249-42"
+ id="linearGradient4649"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(180.52353,65.314889)"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249-57"
+ id="linearGradient4651"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(196.71536,71.744001)"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249-0"
+ id="linearGradient4653"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(212.66909,77.934999)"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249-38"
+ id="linearGradient4655"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(229.57527,82.935419)"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249-53"
+ id="linearGradient4657"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(246.00523,89.126416)"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4029"
+ id="linearGradient4692"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.11034178,-0.45120379)"
+ x1="50.162903"
+ y1="641.96503"
+ x2="305.03671"
+ y2="733.44366" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4029"
+ id="linearGradient4695"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.11034178,-0.45120379)"
+ x1="50.162903"
+ y1="641.96503"
+ x2="305.03671"
+ y2="733.44366" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4029"
+ id="linearGradient4698"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.11034178,-0.45120379)"
+ x1="50.162903"
+ y1="641.96503"
+ x2="305.03671"
+ y2="733.44366" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4029"
+ id="linearGradient4701"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.11034178,-0.45120379)"
+ x1="50.162903"
+ y1="641.96503"
+ x2="305.03671"
+ y2="733.44366" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4029"
+ id="linearGradient4704"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.11034178,-0.45120379)"
+ x1="50.162903"
+ y1="641.96503"
+ x2="305.03671"
+ y2="733.44366" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4029"
+ id="linearGradient4707"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.11034178,-0.45120379)"
+ x1="50.162903"
+ y1="641.96503"
+ x2="305.03671"
+ y2="733.44366" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4029"
+ id="linearGradient4710"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.11034178,-0.45120379)"
+ x1="50.162903"
+ y1="641.96503"
+ x2="305.03671"
+ y2="733.44366" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4029"
+ id="linearGradient4713"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.11034178,-0.45120379)"
+ x1="50.162903"
+ y1="641.96503"
+ x2="305.03671"
+ y2="733.44366" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4029"
+ id="linearGradient4716"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.11034178,-0.45120379)"
+ x1="50.162903"
+ y1="641.96503"
+ x2="305.03671"
+ y2="733.44366" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4029"
+ id="linearGradient4719"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.11034178,-0.45120379)"
+ x1="50.162903"
+ y1="641.96503"
+ x2="305.03671"
+ y2="733.44366" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4029"
+ id="linearGradient4722"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.11034178,-0.45120379)"
+ x1="50.162903"
+ y1="641.96503"
+ x2="305.03671"
+ y2="733.44366" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4029"
+ id="linearGradient4725"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.11034178,-0.45120379)"
+ x1="50.162903"
+ y1="641.96503"
+ x2="305.03671"
+ y2="733.44366" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4029"
+ id="linearGradient4728"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.11034178,-0.45120379)"
+ x1="50.162903"
+ y1="641.96503"
+ x2="305.03671"
+ y2="733.44366" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4029"
+ id="linearGradient4731"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.11034178,-0.45120379)"
+ x1="50.162903"
+ y1="641.96503"
+ x2="305.03671"
+ y2="733.44366" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4029"
+ id="linearGradient4734"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.11034178,-0.45120379)"
+ x1="50.162903"
+ y1="641.96503"
+ x2="305.03671"
+ y2="733.44366" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4753"
+ id="linearGradient4737"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.11034178,-0.45120379)"
+ x1="462.33984"
+ y1="762.51996"
+ x2="447.14349"
+ y2="713.91241" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4029-2"
+ id="linearGradient4704-3"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-94.138416,56.066335)"
+ x1="50.162903"
+ y1="641.96503"
+ x2="305.03671"
+ y2="733.44366" />
+ <linearGradient
+ id="linearGradient4029-2">
+ <stop
+ style="stop-color:#3e3e3e;stop-opacity:1;"
+ offset="0"
+ id="stop4031-1" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop4033-0" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4753-0"
+ id="linearGradient4737-4"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.11034178,-0.45120379)"
+ x1="462.33984"
+ y1="762.51996"
+ x2="447.14349"
+ y2="713.91241" />
+ <linearGradient
+ id="linearGradient4753-0">
+ <stop
+ id="stop4755-7"
+ offset="0"
+ style="stop-color:#101010;stop-opacity:1;" />
+ <stop
+ style="stop-color:#acacac;stop-opacity:1;"
+ offset="0.47657159"
+ id="stop4761-5" />
+ <stop
+ style="stop-color:#acacac;stop-opacity:1;"
+ offset="0.60369939"
+ id="stop4759-9" />
+ <stop
+ id="stop4757-0"
+ offset="1"
+ style="stop-color:#3e3e3e;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ y2="713.91241"
+ x2="447.14349"
+ y1="762.51996"
+ x1="462.33984"
+ gradientTransform="translate(-94.138416,56.066335)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient4785"
+ xlink:href="#linearGradient4753-0"
+ inkscape:collect="always" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4753-09"
+ id="linearGradient4737-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.11034178,-0.45120379)"
+ x1="462.33984"
+ y1="762.51996"
+ x2="447.14349"
+ y2="713.91241" />
+ <linearGradient
+ id="linearGradient4753-09">
+ <stop
+ id="stop4755-8"
+ offset="0"
+ style="stop-color:#101010;stop-opacity:1;" />
+ <stop
+ style="stop-color:#acacac;stop-opacity:1;"
+ offset="0.47657159"
+ id="stop4761-9" />
+ <stop
+ style="stop-color:#acacac;stop-opacity:1;"
+ offset="0.60369939"
+ id="stop4759-1" />
+ <stop
+ id="stop4757-7"
+ offset="1"
+ style="stop-color:#3e3e3e;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ y2="713.91241"
+ x2="447.14349"
+ y1="762.51996"
+ x1="462.33984"
+ gradientTransform="translate(16.293772,-6.7832111)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient4835"
+ xlink:href="#linearGradient4753-09"
+ inkscape:collect="always" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4753-07"
+ id="linearGradient4737-3"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.11034178,-0.45120379)"
+ x1="462.33984"
+ y1="762.51996"
+ x2="447.14349"
+ y2="713.91241" />
+ <linearGradient
+ id="linearGradient4753-07">
+ <stop
+ id="stop4755-6"
+ offset="0"
+ style="stop-color:#101010;stop-opacity:1;" />
+ <stop
+ style="stop-color:#acacac;stop-opacity:1;"
+ offset="0.47657159"
+ id="stop4761-6" />
+ <stop
+ style="stop-color:#acacac;stop-opacity:1;"
+ offset="0.60369939"
+ id="stop4759-0" />
+ <stop
+ id="stop4757-2"
+ offset="1"
+ style="stop-color:#3e3e3e;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ y2="713.91241"
+ x2="447.14349"
+ y1="762.51996"
+ x1="462.33984"
+ gradientTransform="translate(32.866764,-12.497978)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient4835-8"
+ xlink:href="#linearGradient4753-07"
+ inkscape:collect="always" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4753-9"
+ id="linearGradient4737-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.11034178,-0.45120379)"
+ x1="462.33984"
+ y1="762.51996"
+ x2="447.14349"
+ y2="713.91241" />
+ <linearGradient
+ id="linearGradient4753-9">
+ <stop
+ id="stop4755-9"
+ offset="0"
+ style="stop-color:#101010;stop-opacity:1;" />
+ <stop
+ style="stop-color:#acacac;stop-opacity:1;"
+ offset="0.47657159"
+ id="stop4761-94" />
+ <stop
+ style="stop-color:#acacac;stop-opacity:1;"
+ offset="0.60369939"
+ id="stop4759-2" />
+ <stop
+ id="stop4757-08"
+ offset="1"
+ style="stop-color:#3e3e3e;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ y2="713.91241"
+ x2="447.14349"
+ y1="762.51996"
+ x1="462.33984"
+ gradientTransform="translate(49.296717,-18.212744)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient4835-7"
+ xlink:href="#linearGradient4753-9"
+ inkscape:collect="always" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4753-3"
+ id="linearGradient4737-7"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.11034178,-0.45120379)"
+ x1="462.33984"
+ y1="762.51996"
+ x2="447.14349"
+ y2="713.91241" />
+ <linearGradient
+ id="linearGradient4753-3">
+ <stop
+ id="stop4755-0"
+ offset="0"
+ style="stop-color:#101010;stop-opacity:1;" />
+ <stop
+ style="stop-color:#acacac;stop-opacity:1;"
+ offset="0.47657159"
+ id="stop4761-7" />
+ <stop
+ style="stop-color:#acacac;stop-opacity:1;"
+ offset="0.60369939"
+ id="stop4759-6" />
+ <stop
+ id="stop4757-4"
+ offset="1"
+ style="stop-color:#3e3e3e;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ y2="713.91241"
+ x2="447.14349"
+ y1="762.51996"
+ x1="462.33984"
+ gradientTransform="translate(65.72667,-24.403741)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient4835-2"
+ xlink:href="#linearGradient4753-3"
+ inkscape:collect="always" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4753-1"
+ id="linearGradient4737-9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.11034178,-0.45120379)"
+ x1="462.33984"
+ y1="762.51996"
+ x2="447.14349"
+ y2="713.91241" />
+ <linearGradient
+ id="linearGradient4753-1">
+ <stop
+ id="stop4755-60"
+ offset="0"
+ style="stop-color:#101010;stop-opacity:1;" />
+ <stop
+ style="stop-color:#acacac;stop-opacity:1;"
+ offset="0.47657159"
+ id="stop4761-3" />
+ <stop
+ style="stop-color:#acacac;stop-opacity:1;"
+ offset="0.60369939"
+ id="stop4759-3" />
+ <stop
+ id="stop4757-6"
+ offset="1"
+ style="stop-color:#3e3e3e;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ y2="713.91241"
+ x2="447.14349"
+ y1="762.51996"
+ x1="462.33984"
+ gradientTransform="translate(82.156624,-30.356622)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient4835-22"
+ xlink:href="#linearGradient4753-1"
+ inkscape:collect="always" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4753-6"
+ id="linearGradient4737-32"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.11034178,-0.45120379)"
+ x1="462.33984"
+ y1="762.51996"
+ x2="447.14349"
+ y2="713.91241" />
+ <linearGradient
+ id="linearGradient4753-6">
+ <stop
+ id="stop4755-05"
+ offset="0"
+ style="stop-color:#101010;stop-opacity:1;" />
+ <stop
+ style="stop-color:#acacac;stop-opacity:1;"
+ offset="0.47657159"
+ id="stop4761-4" />
+ <stop
+ style="stop-color:#acacac;stop-opacity:1;"
+ offset="0.60369939"
+ id="stop4759-96" />
+ <stop
+ id="stop4757-082"
+ offset="1"
+ style="stop-color:#3e3e3e;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ y2="713.91241"
+ x2="447.14349"
+ y1="762.51996"
+ x1="462.33984"
+ gradientTransform="translate(98.586578,-36.309505)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient4835-74"
+ xlink:href="#linearGradient4753-6"
+ inkscape:collect="always" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4753-01"
+ id="linearGradient4737-76"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.11034178,-0.45120379)"
+ x1="462.33984"
+ y1="762.51996"
+ x2="447.14349"
+ y2="713.91241" />
+ <linearGradient
+ id="linearGradient4753-01">
+ <stop
+ id="stop4755-2"
+ offset="0"
+ style="stop-color:#101010;stop-opacity:1;" />
+ <stop
+ style="stop-color:#acacac;stop-opacity:1;"
+ offset="0.47657159"
+ id="stop4761-93" />
+ <stop
+ style="stop-color:#acacac;stop-opacity:1;"
+ offset="0.60369939"
+ id="stop4759-8" />
+ <stop
+ id="stop4757-5"
+ offset="1"
+ style="stop-color:#3e3e3e;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ y2="713.91241"
+ x2="447.14349"
+ y1="762.51996"
+ x1="462.33984"
+ gradientTransform="translate(115.01653,-42.262386)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient4835-1"
+ xlink:href="#linearGradient4753-01"
+ inkscape:collect="always" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4753-68"
+ id="linearGradient4737-6"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.11034178,-0.45120379)"
+ x1="462.33984"
+ y1="762.51996"
+ x2="447.14349"
+ y2="713.91241" />
+ <linearGradient
+ id="linearGradient4753-68">
+ <stop
+ id="stop4755-89"
+ offset="0"
+ style="stop-color:#101010;stop-opacity:1;" />
+ <stop
+ style="stop-color:#acacac;stop-opacity:1;"
+ offset="0.47657159"
+ id="stop4761-8" />
+ <stop
+ style="stop-color:#acacac;stop-opacity:1;"
+ offset="0.60369939"
+ id="stop4759-7" />
+ <stop
+ id="stop4757-07"
+ offset="1"
+ style="stop-color:#3e3e3e;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ y2="713.91241"
+ x2="447.14349"
+ y1="762.51996"
+ x1="462.33984"
+ gradientTransform="translate(131.20837,-48.215268)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient4835-9"
+ xlink:href="#linearGradient4753-68"
+ inkscape:collect="always" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4753-39"
+ id="linearGradient4737-86"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.11034178,-0.45120379)"
+ x1="462.33984"
+ y1="762.51996"
+ x2="447.14349"
+ y2="713.91241" />
+ <linearGradient
+ id="linearGradient4753-39">
+ <stop
+ id="stop4755-4"
+ offset="0"
+ style="stop-color:#101010;stop-opacity:1;" />
+ <stop
+ style="stop-color:#acacac;stop-opacity:1;"
+ offset="0.47657159"
+ id="stop4761-53" />
+ <stop
+ style="stop-color:#acacac;stop-opacity:1;"
+ offset="0.60369939"
+ id="stop4759-82" />
+ <stop
+ id="stop4757-3"
+ offset="1"
+ style="stop-color:#3e3e3e;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ y2="713.91241"
+ x2="447.14349"
+ y1="762.51996"
+ x1="462.33984"
+ gradientTransform="translate(147.40021,-54.16815)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient4835-94"
+ xlink:href="#linearGradient4753-39"
+ inkscape:collect="always" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4753-32"
+ id="linearGradient4737-1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.11034178,-0.45120379)"
+ x1="462.33984"
+ y1="762.51996"
+ x2="447.14349"
+ y2="713.91241" />
+ <linearGradient
+ id="linearGradient4753-32">
+ <stop
+ id="stop4755-81"
+ offset="0"
+ style="stop-color:#101010;stop-opacity:1;" />
+ <stop
+ style="stop-color:#acacac;stop-opacity:1;"
+ offset="0.47657159"
+ id="stop4761-64" />
+ <stop
+ style="stop-color:#acacac;stop-opacity:1;"
+ offset="0.60369939"
+ id="stop4759-67" />
+ <stop
+ id="stop4757-79"
+ offset="1"
+ style="stop-color:#3e3e3e;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ y2="713.91241"
+ x2="447.14349"
+ y1="762.51996"
+ x1="462.33984"
+ gradientTransform="translate(164.06828,-60.359147)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient4835-6"
+ xlink:href="#linearGradient4753-32"
+ inkscape:collect="always" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4753-2"
+ id="linearGradient4737-19"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.11034178,-0.45120379)"
+ x1="462.33984"
+ y1="762.51996"
+ x2="447.14349"
+ y2="713.91241" />
+ <linearGradient
+ id="linearGradient4753-2">
+ <stop
+ id="stop4755-63"
+ offset="0"
+ style="stop-color:#101010;stop-opacity:1;" />
+ <stop
+ style="stop-color:#acacac;stop-opacity:1;"
+ offset="0.47657159"
+ id="stop4761-1" />
+ <stop
+ style="stop-color:#acacac;stop-opacity:1;"
+ offset="0.60369939"
+ id="stop4759-5" />
+ <stop
+ id="stop4757-9"
+ offset="1"
+ style="stop-color:#3e3e3e;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ y2="713.91241"
+ x2="447.14349"
+ y1="762.51996"
+ x1="462.33984"
+ gradientTransform="translate(180.49823,-66.073913)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient4835-70"
+ xlink:href="#linearGradient4753-2"
+ inkscape:collect="always" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4753-7"
+ id="linearGradient4737-61"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.11034178,-0.45120379)"
+ x1="462.33984"
+ y1="762.51996"
+ x2="447.14349"
+ y2="713.91241" />
+ <linearGradient
+ id="linearGradient4753-7">
+ <stop
+ id="stop4755-62"
+ offset="0"
+ style="stop-color:#101010;stop-opacity:1;" />
+ <stop
+ style="stop-color:#acacac;stop-opacity:1;"
+ offset="0.47657159"
+ id="stop4761-534" />
+ <stop
+ style="stop-color:#acacac;stop-opacity:1;"
+ offset="0.60369939"
+ id="stop4759-07" />
+ <stop
+ id="stop4757-55"
+ offset="1"
+ style="stop-color:#3e3e3e;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ y2="713.91241"
+ x2="447.14349"
+ y1="762.51996"
+ x1="462.33984"
+ gradientTransform="translate(196.45195,-72.264911)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient4835-3"
+ xlink:href="#linearGradient4753-7"
+ inkscape:collect="always" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4753-017"
+ id="linearGradient4737-88"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.11034178,-0.45120379)"
+ x1="462.33984"
+ y1="762.51996"
+ x2="447.14349"
+ y2="713.91241" />
+ <linearGradient
+ id="linearGradient4753-017">
+ <stop
+ id="stop4755-5"
+ offset="0"
+ style="stop-color:#101010;stop-opacity:1;" />
+ <stop
+ style="stop-color:#acacac;stop-opacity:1;"
+ offset="0.47657159"
+ id="stop4761-0" />
+ <stop
+ style="stop-color:#acacac;stop-opacity:1;"
+ offset="0.60369939"
+ id="stop4759-59" />
+ <stop
+ id="stop4757-09"
+ offset="1"
+ style="stop-color:#3e3e3e;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ y2="713.91241"
+ x2="447.14349"
+ y1="762.51996"
+ x1="462.33984"
+ gradientTransform="translate(213.12002,-77.979677)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient4835-35"
+ xlink:href="#linearGradient4753-017"
+ inkscape:collect="always" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4753-67"
+ id="linearGradient4737-72"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.11034178,-0.45120379)"
+ x1="462.33984"
+ y1="762.51996"
+ x2="447.14349"
+ y2="713.91241" />
+ <linearGradient
+ id="linearGradient4753-67">
+ <stop
+ id="stop4755-22"
+ offset="0"
+ style="stop-color:#101010;stop-opacity:1;" />
+ <stop
+ style="stop-color:#acacac;stop-opacity:1;"
+ offset="0.47657159"
+ id="stop4761-01" />
+ <stop
+ style="stop-color:#acacac;stop-opacity:1;"
+ offset="0.60369939"
+ id="stop4759-17" />
+ <stop
+ id="stop4757-59"
+ offset="1"
+ style="stop-color:#3e3e3e;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ y2="713.91241"
+ x2="447.14349"
+ y1="762.51996"
+ x1="462.33984"
+ gradientTransform="translate(229.54998,-83.932557)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient4835-18"
+ xlink:href="#linearGradient4753-67"
+ inkscape:collect="always" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4753-99"
+ id="linearGradient4737-866"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.11034178,-0.45120379)"
+ x1="462.33984"
+ y1="762.51996"
+ x2="447.14349"
+ y2="713.91241" />
+ <linearGradient
+ id="linearGradient4753-99">
+ <stop
+ id="stop4755-26"
+ offset="0"
+ style="stop-color:#101010;stop-opacity:1;" />
+ <stop
+ style="stop-color:#acacac;stop-opacity:1;"
+ offset="0.47657159"
+ id="stop4761-65" />
+ <stop
+ style="stop-color:#acacac;stop-opacity:1;"
+ offset="0.60369939"
+ id="stop4759-84" />
+ <stop
+ id="stop4757-03"
+ offset="1"
+ style="stop-color:#3e3e3e;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ y2="713.91241"
+ x2="447.14349"
+ y1="762.51996"
+ x1="462.33984"
+ gradientTransform="translate(245.97993,-89.885443)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient4835-78"
+ xlink:href="#linearGradient4753-99"
+ inkscape:collect="always" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4753"
+ id="linearGradient5170"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0.11034178,-0.45120379)"
+ x1="462.33984"
+ y1="762.51996"
+ x2="447.14349"
+ y2="713.91241" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4753-09"
+ id="linearGradient5172"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(16.293772,-6.7832111)"
+ x1="462.33984"
+ y1="762.51996"
+ x2="447.14349"
+ y2="713.91241" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4753-07"
+ id="linearGradient5174"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(32.866764,-12.497978)"
+ x1="462.33984"
+ y1="762.51996"
+ x2="447.14349"
+ y2="713.91241" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4753-9"
+ id="linearGradient5176"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(49.296717,-18.212744)"
+ x1="462.33984"
+ y1="762.51996"
+ x2="447.14349"
+ y2="713.91241" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4753-3"
+ id="linearGradient5178"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(65.72667,-24.403741)"
+ x1="462.33984"
+ y1="762.51996"
+ x2="447.14349"
+ y2="713.91241" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4753-1"
+ id="linearGradient5180"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(82.156624,-30.356622)"
+ x1="462.33984"
+ y1="762.51996"
+ x2="447.14349"
+ y2="713.91241" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4753-6"
+ id="linearGradient5182"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(98.586578,-36.309505)"
+ x1="462.33984"
+ y1="762.51996"
+ x2="447.14349"
+ y2="713.91241" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4753-01"
+ id="linearGradient5184"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(115.01653,-42.262386)"
+ x1="462.33984"
+ y1="762.51996"
+ x2="447.14349"
+ y2="713.91241" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4753-68"
+ id="linearGradient5186"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(131.20837,-48.215268)"
+ x1="462.33984"
+ y1="762.51996"
+ x2="447.14349"
+ y2="713.91241" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4753-39"
+ id="linearGradient5188"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(147.40021,-54.16815)"
+ x1="462.33984"
+ y1="762.51996"
+ x2="447.14349"
+ y2="713.91241" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4753-32"
+ id="linearGradient5190"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(164.06828,-60.359147)"
+ x1="462.33984"
+ y1="762.51996"
+ x2="447.14349"
+ y2="713.91241" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4753-2"
+ id="linearGradient5192"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(180.49823,-66.073913)"
+ x1="462.33984"
+ y1="762.51996"
+ x2="447.14349"
+ y2="713.91241" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4753-7"
+ id="linearGradient5194"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(196.45195,-72.264911)"
+ x1="462.33984"
+ y1="762.51996"
+ x2="447.14349"
+ y2="713.91241" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4753-017"
+ id="linearGradient5196"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(213.12002,-77.979677)"
+ x1="462.33984"
+ y1="762.51996"
+ x2="447.14349"
+ y2="713.91241" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4753-67"
+ id="linearGradient5198"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(229.54998,-83.932557)"
+ x1="462.33984"
+ y1="762.51996"
+ x2="447.14349"
+ y2="713.91241" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4753-99"
+ id="linearGradient5200"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(245.97993,-89.885443)"
+ x1="462.33984"
+ y1="762.51996"
+ x2="447.14349"
+ y2="713.91241" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5205"
+ id="linearGradient5211"
+ x1="192.18854"
+ y1="640.29102"
+ x2="183.33424"
+ y2="664.34637"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5215"
+ id="linearGradient5221"
+ x1="550.91754"
+ y1="631.59814"
+ x2="562.11096"
+ y2="661.61688"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249-53"
+ id="linearGradient5224"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(262.50578,95.187841)"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249-38"
+ id="linearGradient5227"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(246.07582,88.996844)"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249-0"
+ id="linearGradient5230"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(229.16964,83.996424)"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249-57"
+ id="linearGradient5233"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(213.21591,77.805426)"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249-42"
+ id="linearGradient5236"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(197.02408,71.376314)"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249-29"
+ id="linearGradient5239"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(180.59412,65.899662)"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249-62"
+ id="linearGradient5242"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(164.16417,59.708666)"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249-5"
+ id="linearGradient5245"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(147.4961,53.755784)"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249-63"
+ id="linearGradient5248"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(131.54238,47.802902)"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249-6"
+ id="linearGradient5251"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(114.39808,42.088135)"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249-7"
+ id="linearGradient5254"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(97.968123,36.373369)"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249-3"
+ id="linearGradient5257"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(82.014399,30.420488)"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249-4"
+ id="linearGradient5260"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(65.584446,24.229491)"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249-9"
+ id="linearGradient5263"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(49.154493,18.038493)"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249-2"
+ id="linearGradient5266"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(32.962654,12.085612)"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249"
+ id="linearGradient5269"
+ gradientUnits="userSpaceOnUse"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981"
+ gradientTransform="translate(16.500546,6.0614254)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249"
+ id="linearGradient5321"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(16.500546,6.0614254)"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249-2"
+ id="linearGradient5323"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(32.962654,12.085612)"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249-9"
+ id="linearGradient5325"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(49.154493,18.038493)"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249-4"
+ id="linearGradient5327"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(65.584446,24.229491)"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249-3"
+ id="linearGradient5329"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(82.014399,30.420488)"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249-7"
+ id="linearGradient5331"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(97.968123,36.373369)"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249-6"
+ id="linearGradient5333"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(114.39808,42.088135)"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249-63"
+ id="linearGradient5335"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(131.54238,47.802902)"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249-5"
+ id="linearGradient5337"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(147.4961,53.755784)"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249-62"
+ id="linearGradient5339"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(164.16417,59.708666)"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249-29"
+ id="linearGradient5341"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(180.59412,65.899662)"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249-42"
+ id="linearGradient5343"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(197.02408,71.376314)"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249-57"
+ id="linearGradient5345"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(213.21591,77.805426)"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249-0"
+ id="linearGradient5347"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(229.16964,83.996424)"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249-38"
+ id="linearGradient5349"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(246.07582,88.996844)"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4249-53"
+ id="linearGradient5351"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(262.50578,95.187841)"
+ x1="56.430466"
+ y1="632.71771"
+ x2="67.791367"
+ y2="650.30981" />
</defs>
<metadata
id="metadata7">
@@ -373,7 +2243,7 @@
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title />
+ <dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
@@ -693,6 +2563,12 @@
d="m 197.35296,637.05028 26.22631,-36.06117 193.41902,1.96697 -36.06117,45.24038 -89.82511,-9.83486 7.21224,-15.08013 -43.27341,3.93395 z"
id="path5039"
inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffffff;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
+ d="m 344.52579,102.27483 15.42653,-40.280383 23.99682,-15.426528 17.14059,9.427323 3.42812,11.998411 28.28197,-6.856235 14.56949,21.425734 0.85703,38.566318 -13.71247,30.85306 -21.42573,9.42732 -20.5687,-12.85544 -20.56871,8.57029 -24.98883,-23.71207 z"
+ id="path3253"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccccccccccc" />
</g>
<g
inkscape:groupmode="layer"
@@ -730,176 +2606,191 @@
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccccccccccccccscccccccccccccccscsccsscccsccccscsccscccccsscssscsssscsscscssscssssscssscscccsssscscccccsccssccssssscccccccccccccccccccccccsccssscsscccsssccsscsccscccccccsscssccssccsssccssccccccsssscsssscssssccscscsccscscscsccsscsccscccccccccccccccccccccccccccssccssccscssccssscccccccccccccscsssscssssscsscsssssssscsccssccscccccsssssssssccscc" />
<path
- d="m 751.29906,574.49054 0,56.09559 -368.04049,133.95574 -368.040477,-133.95574 0,-56.61975 368.347517,133.55687 z"
+ d="m 749.69878,574.66835 0,56.09559 -366.44021,133.77793 -367.263011,-133.80025 0,-56.61975 367.570051,133.40138 z"
id="path3354-4"
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccc" />
<g
- transform="translate(0.11034178,-0.45120379)"
- id="g5049-2"
- style="stroke:#3e3e3e;stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline">
+ id="g5271"
+ transform="translate(-18.659191,-7.4636765)">
<path
inkscape:connector-curvature="0"
- style="fill:none;stroke:#3e3e3e;stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- id="path3290-8"
- d="m 321.48422,721.5392 -22.36609,12.913 0,30.0333" />
+ style="fill:none;stroke:url(#linearGradient5321);stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3292-8"
+ d="m 92.180672,637.64386 -22.366085,12.91307 0,30.03328" />
<path
inkscape:connector-curvature="0"
- style="fill:none;stroke:#3e3e3e;stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- id="path3292-8"
- d="m 75.569784,632.03363 -22.366085,12.91307 0,30.03328" />
+ style="fill:none;stroke:url(#linearGradient5323);stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ id="path3292-8-4"
+ d="m 108.64278,643.66805 -22.366085,12.91307 0,30.03328" />
<path
inkscape:connector-curvature="0"
- style="fill:none;stroke:#3e3e3e;stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- id="path3294-1"
- d="m 305.08992,715.57213 -22.36608,12.91307 0,30.0333" />
+ style="fill:none;stroke:url(#linearGradient5325);stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ id="path3292-8-5"
+ d="m 124.83462,649.62094 -22.36609,12.91306 0,30.03328" />
<path
inkscape:connector-curvature="0"
- style="fill:none;stroke:#3e3e3e;stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- id="path3296-8"
- d="m 288.69563,709.6051 -22.36609,12.9131 0,30.0332" />
+ style="fill:none;stroke:url(#linearGradient5327);stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ id="path3292-8-0"
+ d="m 141.26457,655.81193 -22.36608,12.91307 0,30.03328" />
<path
inkscape:connector-curvature="0"
- style="fill:none;stroke:#3e3e3e;stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- id="path3298-6"
- d="m 272.30133,703.63806 -22.36608,12.91304 0,30.0333" />
+ style="fill:none;stroke:url(#linearGradient5329);stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ id="path3292-8-9"
+ d="m 157.69453,662.00293 -22.36608,12.91307 0,30.03328" />
<path
inkscape:connector-curvature="0"
- style="fill:none;stroke:#3e3e3e;stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- id="path3300-0"
- d="m 255.90704,697.67102 -22.36609,12.91307 0,30.03331" />
+ style="fill:none;stroke:url(#linearGradient5331);stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ id="path3292-8-7"
+ d="m 173.64825,667.9558 -22.36608,12.91307 0,30.03328" />
<path
inkscape:connector-curvature="0"
- style="fill:none;stroke:#3e3e3e;stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- id="path3302-2"
- d="m 239.51274,691.70399 -22.36608,12.91306 0,30.03325" />
+ style="fill:none;stroke:url(#linearGradient5333);stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ id="path3292-8-41"
+ d="m 190.07821,673.67057 -22.36608,12.91307 0,30.03328" />
<path
inkscape:connector-curvature="0"
- style="fill:none;stroke:#3e3e3e;stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- id="path3304-4"
- d="m 223.11845,685.73695 -22.36609,12.91307 0,30.03328" />
+ style="fill:none;stroke:url(#linearGradient5335);stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ id="path3292-8-2"
+ d="m 207.22251,679.38534 -22.36609,12.91307 0,30.03328" />
<path
inkscape:connector-curvature="0"
- style="fill:none;stroke:#3e3e3e;stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- id="path3306-9"
- d="m 206.72415,679.76992 -22.36609,12.91306 0,30.03332" />
+ style="fill:none;stroke:url(#linearGradient5337);stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ id="path3292-8-21"
+ d="m 223.17623,685.33822 -22.36609,12.91306 0,30.03328" />
<path
inkscape:connector-curvature="0"
- style="fill:none;stroke:#3e3e3e;stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- id="path3308-0"
- d="m 190.32985,673.80288 -22.36608,12.91307 0,30.03325" />
+ style="fill:none;stroke:url(#linearGradient5339);stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ id="path3292-8-6"
+ d="m 239.8443,691.2911 -22.36609,12.91307 0,30.03328" />
<path
inkscape:connector-curvature="0"
- style="fill:none;stroke:#3e3e3e;stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- id="path3310-2"
- d="m 173.93556,667.83585 -22.36609,12.91306 0,30.03328" />
+ style="fill:none;stroke:url(#linearGradient5341);stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ id="path3292-8-59"
+ d="m 256.27425,697.4821 -22.36609,12.91307 0,30.03328" />
<path
inkscape:connector-curvature="0"
- style="fill:none;stroke:#3e3e3e;stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- id="path3312-2"
- d="m 157.54126,661.86881 -22.36608,12.91307 0,30.03328" />
+ style="fill:none;stroke:url(#linearGradient5343);stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ id="path3292-8-1"
+ d="m 272.70421,702.95875 -22.36609,12.91307 0,30.03328" />
<path
inkscape:connector-curvature="0"
- style="fill:none;stroke:#3e3e3e;stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- id="path3314-1"
- d="m 141.14697,655.90177 -22.36609,12.91307 0,30.03328" />
+ style="fill:none;stroke:url(#linearGradient5345);stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ id="path3292-8-42"
+ d="m 288.89604,709.38786 -22.36609,12.91307 0,30.03328" />
<path
inkscape:connector-curvature="0"
- style="fill:none;stroke:#3e3e3e;stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- id="path3316-5"
- d="m 124.75267,649.93474 -22.36608,12.91306 0,30.03329" />
+ style="fill:none;stroke:url(#linearGradient5347);stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ id="path3292-8-73"
+ d="m 304.84977,715.57886 -22.36609,12.91307 0,30.03328" />
<path
inkscape:connector-curvature="0"
- style="fill:none;stroke:#3e3e3e;stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- id="path3318-4"
- d="m 108.35837,643.9677 -22.36608,12.91307 0,30.03328" />
+ style="fill:none;stroke:url(#linearGradient5349);stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ id="path3292-8-72"
+ d="m 321.75595,720.57928 -22.36609,12.91307 0,30.03328" />
<path
inkscape:connector-curvature="0"
- style="fill:none;stroke:#3e3e3e;stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- id="path3320-4"
- d="m 91.96408,638.00067 -22.366085,12.91306 0,30.03328" />
+ style="fill:none;stroke:url(#linearGradient5351);stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ id="path3292-8-3"
+ d="m 338.18591,726.77028 -22.36609,12.91307 0,30.03328" />
+ </g>
+ <g
+ id="g5152"
+ transform="translate(16.429953,-5.9528819)">
<path
inkscape:connector-curvature="0"
- style="fill:none;stroke:#3e3e3e;stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ style="fill:none;stroke:url(#linearGradient5170);stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
id="path3322-4"
- d="m 443.61027,721.5392 22.36608,12.913 0,30.0333" />
+ d="m 443.72061,721.088 22.36608,12.913 0,30.0333" />
<path
inkscape:connector-curvature="0"
- style="fill:none;stroke:#3e3e3e;stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- id="path3324-2"
- d="m 476.39886,709.6051 22.36608,12.9131 0,30.0332" />
+ style="fill:none;stroke:url(#linearGradient5172);stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ id="path3322-4-3"
+ d="m 459.90404,714.75598 22.36608,12.913 0,30.0333" />
<path
inkscape:connector-curvature="0"
- style="fill:none;stroke:#3e3e3e;stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- id="path3326-5"
- d="m 460.00456,715.57213 22.36609,12.91307 0,30.0333" />
+ style="fill:none;stroke:url(#linearGradient5174);stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ id="path3322-4-9"
+ d="m 476.47704,709.04122 22.36608,12.913 0,30.0333" />
<path
inkscape:connector-curvature="0"
- style="fill:none;stroke:#3e3e3e;stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- id="path3328-0"
- d="m 525.58175,691.70399 22.36608,12.91306 0,30.03325" />
+ style="fill:none;stroke:url(#linearGradient5176);stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ id="path3322-4-8"
+ d="m 492.90699,703.32646 22.36607,12.913 0,30.0333" />
<path
inkscape:connector-curvature="0"
- style="fill:none;stroke:#3e3e3e;stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- id="path3330-4"
- d="m 509.18745,697.67102 22.36609,12.91307 0,30.03331" />
+ style="fill:none;stroke:url(#linearGradient5178);stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ id="path3322-4-1"
+ d="m 509.33694,697.13546 22.36608,12.913 0,30.0333" />
<path
inkscape:connector-curvature="0"
- style="fill:none;stroke:#3e3e3e;stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- id="path3332-2"
- d="m 492.79316,703.63806 22.36608,12.91304 0,30.0333" />
+ style="fill:none;stroke:url(#linearGradient5180);stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ id="path3322-4-14"
+ d="m 525.76689,691.18258 22.36608,12.913 0,30.0333" />
<path
inkscape:connector-curvature="0"
- style="fill:none;stroke:#3e3e3e;stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- id="path3334-1"
- d="m 558.37034,679.76992 22.36608,12.91306 0,30.03332" />
+ style="fill:none;stroke:url(#linearGradient5182);stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ id="path3322-4-0"
+ d="m 542.19685,685.22969 22.36608,12.913 0,30.0333" />
<path
inkscape:connector-curvature="0"
- style="fill:none;stroke:#3e3e3e;stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- id="path3336-2"
- d="m 541.97604,685.73695 22.36609,12.91307 0,30.03328" />
+ style="fill:none;stroke:url(#linearGradient5184);stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ id="path3322-4-5"
+ d="m 558.6268,679.27682 22.36608,12.913 0,30.0333" />
<path
inkscape:connector-curvature="0"
- style="fill:none;stroke:#3e3e3e;stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- id="path3338-7"
- d="m 607.55322,661.86881 22.36609,12.91307 0,30.03328" />
+ style="fill:none;stroke:url(#linearGradient5186);stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ id="path3322-4-15"
+ d="m 574.81864,673.32393 22.36608,12.913 0,30.0333" />
<path
inkscape:connector-curvature="0"
- style="fill:none;stroke:#3e3e3e;stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- id="path3340-7"
- d="m 574.76463,673.80288 22.36609,12.91307 0,30.03325" />
+ style="fill:none;stroke:url(#linearGradient5188);stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ id="path3322-4-85"
+ d="m 591.01048,667.37105 22.36608,12.913 0,30.0333" />
<path
inkscape:connector-curvature="0"
- style="fill:none;stroke:#3e3e3e;stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- id="path3342-9"
- d="m 591.15893,667.83585 22.36609,12.91306 0,30.03328" />
+ style="fill:none;stroke:url(#linearGradient5190);stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ id="path3322-4-4"
+ d="m 607.67855,661.18005 22.36608,12.913 0,30.0333" />
<path
inkscape:connector-curvature="0"
- style="fill:none;stroke:#3e3e3e;stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- id="path3344-5"
- d="m 689.5247,632.03363 22.36609,12.91307 0,30.03328" />
+ style="fill:none;stroke:url(#linearGradient5192);stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ id="path3322-4-2"
+ d="m 624.1085,655.46528 22.36608,12.913 0,30.0333" />
<path
inkscape:connector-curvature="0"
- style="fill:none;stroke:#3e3e3e;stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- id="path3346-5"
- d="m 623.94752,655.90177 22.36609,12.91307 0,30.03328" />
+ style="fill:none;stroke:url(#linearGradient5194);stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ id="path3322-4-18"
+ d="m 640.06222,649.27429 22.36608,12.913 0,30.0333" />
<path
inkscape:connector-curvature="0"
- style="fill:none;stroke:#3e3e3e;stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- id="path3348-4"
- d="m 640.34182,649.93474 22.36608,12.91306 0,30.03329" />
+ style="fill:none;stroke:url(#linearGradient5196);stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ id="path3322-4-42"
+ d="m 656.73029,643.55953 22.36608,12.913 0,30.0333" />
<path
inkscape:connector-curvature="0"
- style="fill:none;stroke:#3e3e3e;stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- id="path3350-0"
- d="m 656.73611,643.9677 22.36609,12.91307 0,30.03328" />
+ style="fill:none;stroke:url(#linearGradient5198);stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ id="path3322-4-17"
+ d="m 673.16025,637.60664 22.36608,12.913 0,30.0333" />
<path
inkscape:connector-curvature="0"
- style="fill:none;stroke:#3e3e3e;stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- id="path3352-3"
- d="m 673.13041,638.00067 22.36608,12.91306 0,30.03328" />
+ style="fill:none;stroke:url(#linearGradient5200);stroke-width:9.60000038;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+ id="path3322-4-31"
+ d="m 689.5902,631.65376 22.36608,12.913 0,30.0333" />
</g>
+ <path
+ style="fill:url(#linearGradient5211);fill-opacity:1;stroke:none;display:inline"
+ d="m 13.872826,595.95429 c 0.387521,-16.26739 -3.132044,-24.34489 11.843623,-17.81444 67.361595,23.56741 305.258621,108.07438 347.099071,124.14652 6.9538,4.2814 16.05227,4.7547 12.47851,7.2194 -0.0902,3.98398 -2.69274,4.02033 -4.62883,4.99233 -1.93608,0.97199 -2.92965,-0.15731 -5.87591,0.39099 -1.28974,3.03308 -1.90493,21.91052 -1.90493,21.91052 0,0 -3.99564,-7.30146 -4.7623,-11.12968 -0.76666,-3.82822 -3.77724,-3.13603 -9.18147,-5.22972 C 289.67149,695.89705 13.872826,595.95429 13.872826,595.95429 z"
+ id="path5202"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccscczcc" />
+ <path
+ style="fill:url(#linearGradient5221);fill-opacity:1;stroke:none"
+ d="m 749.01081,575.84113 c 0.30103,-3.12022 -1.0367,-3.0558 -13.718,-9.28068 -46.08067,16.93915 -285.08057,107.25201 -352.73995,131.17677 -26.94394,-4.90548 4.70243,5.27427 9.2182,8.05818 4.51572,2.78391 16.61463,-1.25017 26.77523,-5.28719 53.11696,-19.719 286.75703,-106.37669 330.46452,-124.66708 z"
+ id="path5213"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccc" />
</g>
<g
inkscape:groupmode="layer"
diff --git a/py/builtin.c b/py/builtin.c
index 078f4b49c3..04bb2681db 100644
--- a/py/builtin.c
+++ b/py/builtin.c
@@ -18,7 +18,7 @@
// args[0] is function from class body
// args[1] is class name
// args[2:] are base objects
-mp_obj_t mp_builtin___build_class__(int n_args, const mp_obj_t *args) {
+static mp_obj_t mp_builtin___build_class__(int n_args, const mp_obj_t *args) {
assert(2 <= n_args);
// we differ from CPython: we set the new __locals__ object here
@@ -62,14 +62,16 @@ mp_obj_t mp_builtin___build_class__(int n_args, const mp_obj_t *args) {
MP_DEFINE_CONST_FUN_OBJ_VAR(mp_builtin___build_class___obj, 2, mp_builtin___build_class__);
-mp_obj_t mp_builtin___repl_print__(mp_obj_t o) {
+static mp_obj_t mp_builtin___repl_print__(mp_obj_t o) {
if (o != mp_const_none) {
- mp_obj_print(o);
+ mp_obj_print(o, PRINT_REPR);
printf("\n");
}
return mp_const_none;
}
+MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin___repl_print___obj, mp_builtin___repl_print__);
+
mp_obj_t mp_builtin_abs(mp_obj_t o_in) {
if (MP_OBJ_IS_SMALL_INT(o_in)) {
mp_small_int_t val = MP_OBJ_SMALL_INT_VALUE(o_in);
@@ -97,7 +99,9 @@ mp_obj_t mp_builtin_abs(mp_obj_t o_in) {
}
}
-mp_obj_t mp_builtin_all(mp_obj_t o_in) {
+MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_abs_obj, mp_builtin_abs);
+
+static mp_obj_t mp_builtin_all(mp_obj_t o_in) {
mp_obj_t iterable = rt_getiter(o_in);
mp_obj_t item;
while ((item = rt_iternext(iterable)) != mp_const_stop_iteration) {
@@ -108,7 +112,9 @@ mp_obj_t mp_builtin_all(mp_obj_t o_in) {
return mp_const_true;
}
-mp_obj_t mp_builtin_any(mp_obj_t o_in) {
+MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_all_obj, mp_builtin_all);
+
+static mp_obj_t mp_builtin_any(mp_obj_t o_in) {
mp_obj_t iterable = rt_getiter(o_in);
mp_obj_t item;
while ((item = rt_iternext(iterable)) != mp_const_stop_iteration) {
@@ -119,7 +125,9 @@ mp_obj_t mp_builtin_any(mp_obj_t o_in) {
return mp_const_false;
}
-mp_obj_t mp_builtin_callable(mp_obj_t o_in) {
+MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_any_obj, mp_builtin_any);
+
+static mp_obj_t mp_builtin_callable(mp_obj_t o_in) {
if (mp_obj_is_callable(o_in)) {
return mp_const_true;
} else {
@@ -127,19 +135,21 @@ mp_obj_t mp_builtin_callable(mp_obj_t o_in) {
}
}
-mp_obj_t mp_builtin_chr(mp_obj_t o_in) {
+MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_callable_obj, mp_builtin_callable);
+
+static mp_obj_t mp_builtin_chr(mp_obj_t o_in) {
int ord = mp_obj_get_int(o_in);
if (0 <= ord && ord <= 0x10ffff) {
- char *str = m_new(char, 2);
- str[0] = ord;
- str[1] = '\0';
- return mp_obj_new_str(qstr_from_str_take(str, 2));
+ char str[2] = {ord, '\0'};
+ return mp_obj_new_str(qstr_from_strn_copy(str, 1));
} else {
nlr_jump(mp_obj_new_exception_msg(MP_QSTR_ValueError, "chr() arg not in range(0x110000)"));
}
}
-mp_obj_t mp_builtin_divmod(mp_obj_t o1_in, mp_obj_t o2_in) {
+MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_chr_obj, mp_builtin_chr);
+
+static mp_obj_t mp_builtin_divmod(mp_obj_t o1_in, mp_obj_t o2_in) {
if (MP_OBJ_IS_SMALL_INT(o1_in) && MP_OBJ_IS_SMALL_INT(o2_in)) {
mp_small_int_t i1 = MP_OBJ_SMALL_INT_VALUE(o1_in);
mp_small_int_t i2 = MP_OBJ_SMALL_INT_VALUE(o2_in);
@@ -152,6 +162,8 @@ mp_obj_t mp_builtin_divmod(mp_obj_t o1_in, mp_obj_t o2_in) {
}
}
+MP_DEFINE_CONST_FUN_OBJ_2(mp_builtin_divmod_obj, mp_builtin_divmod);
+
static mp_obj_t mp_builtin_hash(mp_obj_t o_in) {
// TODO hash will generally overflow small integer; can we safely truncate it?
return mp_obj_new_int(mp_obj_hash(o_in));
@@ -165,7 +177,7 @@ static mp_obj_t mp_builtin_iter(mp_obj_t o_in) {
MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_iter_obj, mp_builtin_iter);
-mp_obj_t mp_builtin_len(mp_obj_t o_in) {
+static mp_obj_t mp_builtin_len(mp_obj_t o_in) {
mp_obj_t len = mp_obj_len_maybe(o_in);
if (len == NULL) {
nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "object of type '%s' has no len()", mp_obj_get_type_str(o_in)));
@@ -174,7 +186,9 @@ mp_obj_t mp_builtin_len(mp_obj_t o_in) {
}
}
-mp_obj_t mp_builtin_max(int n_args, const mp_obj_t *args) {
+MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_len_obj, mp_builtin_len);
+
+static mp_obj_t mp_builtin_max(int n_args, const mp_obj_t *args) {
if (n_args == 1) {
// given an iterable
mp_obj_t iterable = rt_getiter(args[0]);
@@ -201,7 +215,9 @@ mp_obj_t mp_builtin_max(int n_args, const mp_obj_t *args) {
}
}
-mp_obj_t mp_builtin_min(int n_args, const mp_obj_t *args) {
+MP_DEFINE_CONST_FUN_OBJ_VAR(mp_builtin_max_obj, 1, mp_builtin_max);
+
+static mp_obj_t mp_builtin_min(int n_args, const mp_obj_t *args) {
if (n_args == 1) {
// given an iterable
mp_obj_t iterable = rt_getiter(args[0]);
@@ -228,6 +244,8 @@ mp_obj_t mp_builtin_min(int n_args, const mp_obj_t *args) {
}
}
+MP_DEFINE_CONST_FUN_OBJ_VAR(mp_builtin_min_obj, 1, mp_builtin_min);
+
static mp_obj_t mp_builtin_next(mp_obj_t o) {
mp_obj_t ret = rt_iternext(o);
if (ret == mp_const_stop_iteration) {
@@ -239,7 +257,7 @@ static mp_obj_t mp_builtin_next(mp_obj_t o) {
MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_next_obj, mp_builtin_next);
-mp_obj_t mp_builtin_ord(mp_obj_t o_in) {
+static mp_obj_t mp_builtin_ord(mp_obj_t o_in) {
const char *str = qstr_str(mp_obj_get_qstr(o_in));
if (strlen(str) == 1) {
return mp_obj_new_int(str[0]);
@@ -248,46 +266,56 @@ mp_obj_t mp_builtin_ord(mp_obj_t o_in) {
}
}
-mp_obj_t mp_builtin_pow(int n_args, const mp_obj_t *args) {
+MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_ord_obj, mp_builtin_ord);
+
+static mp_obj_t mp_builtin_pow(int n_args, const mp_obj_t *args) {
+ assert(2 <= n_args && n_args <= 3);
switch (n_args) {
case 2: return rt_binary_op(RT_BINARY_OP_POWER, args[0], args[1]);
- case 3: return rt_binary_op(RT_BINARY_OP_MODULO, rt_binary_op(RT_BINARY_OP_POWER, args[0], args[1]), args[2]); // TODO optimise...
- default: nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "pow expected at most 3 arguments, got %d", n_args));
+ default: return rt_binary_op(RT_BINARY_OP_MODULO, rt_binary_op(RT_BINARY_OP_POWER, args[0], args[1]), args[2]); // TODO optimise...
}
}
-mp_obj_t mp_builtin_print(int n_args, const mp_obj_t *args) {
+MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_pow_obj, 2, 3, mp_builtin_pow);
+
+static mp_obj_t mp_builtin_print(int n_args, const mp_obj_t *args) {
for (int i = 0; i < n_args; i++) {
if (i > 0) {
printf(" ");
}
- if (MP_OBJ_IS_TYPE(args[i], &str_type)) {
- // special case, print string raw
- printf("%s", qstr_str(mp_obj_str_get(args[i])));
- } else {
- // print the object Python style
- mp_obj_print(args[i]);
- }
+ mp_obj_print(args[i], PRINT_STR);
}
printf("\n");
return mp_const_none;
}
-mp_obj_t mp_builtin_range(int n_args, const mp_obj_t *args) {
+MP_DEFINE_CONST_FUN_OBJ_VAR(mp_builtin_print_obj, 0, mp_builtin_print);
+
+static mp_obj_t mp_builtin_range(int n_args, const mp_obj_t *args) {
+ assert(1 <= n_args && n_args <= 3);
switch (n_args) {
case 1: return mp_obj_new_range(0, mp_obj_get_int(args[0]), 1);
case 2: return mp_obj_new_range(mp_obj_get_int(args[0]), mp_obj_get_int(args[1]), 1);
- case 3: return mp_obj_new_range(mp_obj_get_int(args[0]), mp_obj_get_int(args[1]), mp_obj_get_int(args[2]));
- default: nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "range expected at most 3 arguments, got %d", n_args));
+ default: return mp_obj_new_range(mp_obj_get_int(args[0]), mp_obj_get_int(args[1]), mp_obj_get_int(args[2]));
}
}
-mp_obj_t mp_builtin_sum(int n_args, const mp_obj_t *args) {
+MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_range_obj, 1, 3, mp_builtin_range);
+
+static mp_obj_t mp_builtin_repr(mp_obj_t o_in) {
+ vstr_t *vstr = vstr_new();
+ mp_obj_print_helper((void (*)(void *env, const char *fmt, ...))vstr_printf, vstr, o_in, PRINT_REPR);
+ return mp_obj_new_str(qstr_from_str_take(vstr->buf, vstr->alloc));
+}
+
+MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_repr_obj, mp_builtin_repr);
+
+static mp_obj_t mp_builtin_sum(int n_args, const mp_obj_t *args) {
+ assert(1 <= n_args && n_args <= 2);
mp_obj_t value;
switch (n_args) {
case 1: value = mp_obj_new_int(0); break;
- case 2: value = args[1]; break;
- default: nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "sum expected at most 2 arguments, got %d", n_args));
+ default: value = args[1]; break;
}
mp_obj_t iterable = rt_getiter(args[0]);
mp_obj_t item;
@@ -296,3 +324,33 @@ mp_obj_t mp_builtin_sum(int n_args, const mp_obj_t *args) {
}
return value;
}
+
+MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_sum_obj, 1, 2, mp_builtin_sum);
+
+static mp_obj_t mp_builtin_sorted(mp_obj_t args, mp_map_t *kwargs) {
+ mp_obj_t *args_items = NULL;
+ uint args_len = 0;
+
+ assert(MP_OBJ_IS_TYPE(args, &tuple_type));
+ mp_obj_tuple_get(args, &args_len, &args_items);
+ assert(args_len >= 1);
+ if (args_len > 1) {
+ nlr_jump(mp_obj_new_exception_msg(MP_QSTR_TypeError,
+ "must use keyword argument for key function"));
+ }
+ mp_obj_t self = list_type.make_new((mp_obj_t)&list_type, 1, args_items);
+ mp_obj_t new_args = rt_build_tuple(1, &self);
+ mp_obj_list_sort(new_args, kwargs);
+
+ return self;
+}
+
+MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_sorted_obj, 1, mp_builtin_sorted);
+
+static mp_obj_t mp_builtin_str(mp_obj_t o_in) {
+ vstr_t *vstr = vstr_new();
+ mp_obj_print_helper((void (*)(void*, const char*, ...))vstr_printf, vstr, o_in, PRINT_STR);
+ return mp_obj_new_str(qstr_from_str_take(vstr->buf, vstr->alloc));
+}
+
+MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_str_obj, mp_builtin_str);
diff --git a/py/builtin.h b/py/builtin.h
index db7d517a06..f4038b47b4 100644
--- a/py/builtin.h
+++ b/py/builtin.h
@@ -1,25 +1,28 @@
-// TODO convert all these to objects using MP_DECLARE and MP_DEFINE
+mp_obj_t mp_builtin___import__(int n_args, mp_obj_t *args);
MP_DECLARE_CONST_FUN_OBJ(mp_builtin___build_class___obj);
-mp_obj_t mp_builtin___import__(int n, mp_obj_t *args);
-mp_obj_t mp_builtin___repl_print__(mp_obj_t o);
-mp_obj_t mp_builtin_abs(mp_obj_t o_in);
-mp_obj_t mp_builtin_all(mp_obj_t o_in);
-mp_obj_t mp_builtin_any(mp_obj_t o_in);
-mp_obj_t mp_builtin_callable(mp_obj_t o_in);
-mp_obj_t mp_builtin_chr(mp_obj_t o_in);
-mp_obj_t mp_builtin_divmod(mp_obj_t o1_in, mp_obj_t o2_in);
+MP_DECLARE_CONST_FUN_OBJ(mp_builtin___repl_print___obj);
+MP_DECLARE_CONST_FUN_OBJ(mp_builtin_abs_obj);
+MP_DECLARE_CONST_FUN_OBJ(mp_builtin_all_obj);
+MP_DECLARE_CONST_FUN_OBJ(mp_builtin_any_obj);
+MP_DECLARE_CONST_FUN_OBJ(mp_builtin_callable_obj);
+MP_DECLARE_CONST_FUN_OBJ(mp_builtin_chr_obj);
+MP_DECLARE_CONST_FUN_OBJ(mp_builtin_divmod_obj);
+MP_DECLARE_CONST_FUN_OBJ(mp_builtin_eval_obj);
MP_DECLARE_CONST_FUN_OBJ(mp_builtin_hash_obj);
MP_DECLARE_CONST_FUN_OBJ(mp_builtin_isinstance_obj);
MP_DECLARE_CONST_FUN_OBJ(mp_builtin_issubclass_obj);
MP_DECLARE_CONST_FUN_OBJ(mp_builtin_iter_obj);
-mp_obj_t mp_builtin_len(mp_obj_t o_in);
-mp_obj_t mp_builtin_list(int n_args, const mp_obj_t *args);
-mp_obj_t mp_builtin_max(int n_args, const mp_obj_t *args);
-mp_obj_t mp_builtin_min(int n_args, const mp_obj_t *args);
+MP_DECLARE_CONST_FUN_OBJ(mp_builtin_len_obj);
+MP_DECLARE_CONST_FUN_OBJ(mp_builtin_list_obj);
+MP_DECLARE_CONST_FUN_OBJ(mp_builtin_max_obj);
+MP_DECLARE_CONST_FUN_OBJ(mp_builtin_min_obj);
MP_DECLARE_CONST_FUN_OBJ(mp_builtin_next_obj);
-mp_obj_t mp_builtin_ord(mp_obj_t o_in);
-mp_obj_t mp_builtin_pow(int n_args, const mp_obj_t *args);
-mp_obj_t mp_builtin_print(int n_args, const mp_obj_t *args);
-mp_obj_t mp_builtin_range(int n_args, const mp_obj_t *args);
-mp_obj_t mp_builtin_sum(int n_args, const mp_obj_t *args);
+MP_DECLARE_CONST_FUN_OBJ(mp_builtin_ord_obj);
+MP_DECLARE_CONST_FUN_OBJ(mp_builtin_pow_obj);
+MP_DECLARE_CONST_FUN_OBJ(mp_builtin_print_obj);
+MP_DECLARE_CONST_FUN_OBJ(mp_builtin_range_obj);
+MP_DECLARE_CONST_FUN_OBJ(mp_builtin_repr_obj);
+MP_DECLARE_CONST_FUN_OBJ(mp_builtin_sorted_obj);
+MP_DECLARE_CONST_FUN_OBJ(mp_builtin_sum_obj);
+MP_DECLARE_CONST_FUN_OBJ(mp_builtin_str_obj);
diff --git a/py/builtineval.c b/py/builtineval.c
new file mode 100644
index 0000000000..a8a7a476a3
--- /dev/null
+++ b/py/builtineval.c
@@ -0,0 +1,50 @@
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <assert.h>
+
+#include "nlr.h"
+#include "misc.h"
+#include "mpconfig.h"
+#include "lexer.h"
+#include "lexerunix.h"
+#include "parse.h"
+#include "obj.h"
+#include "compile.h"
+#include "runtime0.h"
+#include "runtime.h"
+#include "map.h"
+#include "builtin.h"
+
+static mp_obj_t mp_builtin_eval(mp_obj_t o_in) {
+ const char *str = qstr_str(mp_obj_get_qstr(o_in));
+
+ // create the lexer
+ mp_lexer_t *lex = mp_lexer_new_from_str_len("<string>", str, strlen(str), 0);
+
+ // parse the string
+ qstr parse_exc_id;
+ const char *parse_exc_msg;
+ mp_parse_node_t pn = mp_parse(lex, MP_PARSE_EVAL_INPUT, &parse_exc_id, &parse_exc_msg);
+ mp_lexer_free(lex);
+
+ if (pn == MP_PARSE_NODE_NULL) {
+ // parse error; raise exception
+ nlr_jump(mp_obj_new_exception_msg(parse_exc_id, parse_exc_msg));
+ }
+
+ // compile the string
+ mp_obj_t module_fun = mp_compile(pn, false);
+
+ if (module_fun == mp_const_none) {
+ // TODO handle compile error correctly
+ return mp_const_none;
+ }
+
+ // complied successfully, execute it
+ return rt_call_function_0(module_fun);
+}
+
+MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_eval_obj, mp_builtin_eval);
diff --git a/py/builtinimport.c b/py/builtinimport.c
index 90a0fc3394..2eca36fbc6 100644
--- a/py/builtinimport.c
+++ b/py/builtinimport.c
@@ -18,7 +18,7 @@
#include "map.h"
#include "builtin.h"
-mp_obj_t mp_builtin___import__(int n, mp_obj_t *args) {
+mp_obj_t mp_builtin___import__(int n_args, mp_obj_t *args) {
/*
printf("import:\n");
for (int i = 0; i < n; i++) {
@@ -48,16 +48,19 @@ mp_obj_t mp_builtin___import__(int n, mp_obj_t *args) {
rt_globals_set(mp_obj_module_get_globals(module_obj));
// parse the imported script
- mp_parse_node_t pn = mp_parse(lex, MP_PARSE_FILE_INPUT);
+ qstr parse_exc_id;
+ const char *parse_exc_msg;
+ mp_parse_node_t pn = mp_parse(lex, MP_PARSE_FILE_INPUT, &parse_exc_id, &parse_exc_msg);
mp_lexer_free(lex);
if (pn == MP_PARSE_NODE_NULL) {
- // TODO handle parse error correctly
+ // parse error; clean up and raise exception
rt_locals_set(old_locals);
rt_globals_set(old_globals);
- return mp_const_none;
+ nlr_jump(mp_obj_new_exception_msg(parse_exc_id, parse_exc_msg));
}
+ // compile the imported script
mp_obj_t module_fun = mp_compile(pn, false);
if (module_fun == mp_const_none) {
diff --git a/py/compile.c b/py/compile.c
index 2e22d64262..b24e94a8dc 100644
--- a/py/compile.c
+++ b/py/compile.c
@@ -1316,7 +1316,7 @@ void compile_nonlocal_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
void compile_assert_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
int l_end = comp_next_label(comp);
c_if_cond(comp, pns->nodes[0], true, l_end);
- EMIT(load_id, MP_QSTR_AssertionError);
+ EMIT(load_global, MP_QSTR_AssertionError); // we load_global instead of load_id, to be consistent with CPython
if (!MP_PARSE_NODE_IS_NULL(pns->nodes[1])) {
// assertion message
compile_node(comp, pns->nodes[1]);
@@ -2708,7 +2708,12 @@ void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
#endif
// compile
- if (scope->kind == SCOPE_MODULE) {
+ if (MP_PARSE_NODE_IS_STRUCT_KIND(scope->pn, PN_eval_input)) {
+ assert(scope->kind == SCOPE_MODULE);
+ mp_parse_node_struct_t *pns = (mp_parse_node_struct_t*)scope->pn;
+ compile_node(comp, pns->nodes[0]); // compile the expression
+ EMIT(return_value);
+ } else if (scope->kind == SCOPE_MODULE) {
if (!comp->is_repl) {
check_for_doc_string(comp, scope->pn);
}
@@ -2833,7 +2838,6 @@ void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
}
EMIT(end_pass);
-
}
void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
diff --git a/py/emitpass1.c b/py/emitpass1.c
index 2f0ecac86d..60fdd0b825 100644
--- a/py/emitpass1.c
+++ b/py/emitpass1.c
@@ -45,10 +45,7 @@ static void emit_pass1_load_id(emit_t *emit, qstr qstr) {
bool added;
id_info_t *id = scope_find_or_add_id(emit->scope, qstr, &added);
if (added) {
- if (qstr == MP_QSTR_AssertionError) {
- // TODO how much of a hack is this?
- id->kind = ID_INFO_KIND_GLOBAL_EXPLICIT;
- } else if (strcmp(qstr_str(qstr), "super") == 0 && emit->scope->kind == SCOPE_FUNCTION) {
+ if (strcmp(qstr_str(qstr), "super") == 0 && emit->scope->kind == SCOPE_FUNCTION) {
// special case, super is a global, and also counts as use of __class__
id->kind = ID_INFO_KIND_GLOBAL_EXPLICIT;
id_info_t *id2 = scope_find_local_in_parent(emit->scope, emit->qstr___class__);
diff --git a/py/gc.c b/py/gc.c
index 054a3cc315..70b071ebc8 100644
--- a/py/gc.c
+++ b/py/gc.c
@@ -8,15 +8,8 @@
#if MICROPY_ENABLE_GC
-// a machine word is big enough to hold a pointer
-/*
-#define BYTES_PER_WORD (8)
-typedef unsigned long machine_uint_t;
-*/
typedef unsigned char byte;
-#define BITS_PER_BYTE (8)
-#define BITS_PER_WORD (BITS_PER_BYTE * BYTES_PER_WORD)
#define WORDS_PER_BLOCK (4)
#define BYTES_PER_BLOCK (WORDS_PER_BLOCK * BYTES_PER_WORD)
#define STACK_SIZE (64) // tunable; minimum is 1
diff --git a/py/grammar.h b/py/grammar.h
index 4d53bd3fc4..32be6c66ca 100644
--- a/py/grammar.h
+++ b/py/grammar.h
@@ -15,6 +15,8 @@ DEF_RULE(single_input, nc, or(3), tok(NEWLINE), rule(simple_stmt), rule(compound
DEF_RULE(file_input, nc, and(1), opt_rule(file_input_2))
DEF_RULE(file_input_2, c(generic_all_nodes), one_or_more, rule(file_input_3))
DEF_RULE(file_input_3, nc, or(2), tok(NEWLINE), rule(stmt))
+DEF_RULE(eval_input, nc, and(2), rule(testlist), opt_rule(eval_input_2))
+DEF_RULE(eval_input_2, nc, and(1), tok(NEWLINE))
// decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE
// decorators: decorator+
diff --git a/py/lexer.c b/py/lexer.c
index d4205236c3..6feb231e0c 100644
--- a/py/lexer.c
+++ b/py/lexer.c
@@ -35,6 +35,7 @@ struct _mp_lexer_t {
mp_token_t tok_cur;
};
+// TODO replace with a call to a standard function
bool str_strn_equal(const char *str, const char *strn, int len) {
uint i = 0;
@@ -66,15 +67,6 @@ void mp_token_show(const mp_token_t *tok) {
printf("\n");
}
-void mp_token_show_error_prefix(const mp_token_t *tok) {
- printf("(%s:%d:%d) ", tok->src_name, tok->src_line, tok->src_column);
-}
-
-bool mp_token_show_error(const mp_token_t *tok, const char *msg) {
- printf("(%s:%d:%d) %s\n", tok->src_name, tok->src_line, tok->src_column, msg);
- return false;
-}
-
#define CUR_CHAR(lex) ((lex)->chr0)
static bool is_end(mp_lexer_t *lex) {
@@ -299,8 +291,15 @@ static void mp_lexer_next_token_into(mp_lexer_t *lex, mp_token_t *tok, bool firs
// backslash (outside string literals) must appear just before a physical newline
next_char(lex);
if (!is_physical_newline(lex)) {
- // TODO SyntaxError
- assert(0);
+ // SyntaxError: unexpected character after line continuation character
+ tok->src_name = lex->name;
+ tok->src_line = lex->line;
+ tok->src_column = lex->column;
+ tok->kind = MP_TOKEN_BAD_LINE_CONTINUATION;
+ vstr_reset(&lex->vstr);
+ tok->str = vstr_str(&lex->vstr);
+ tok->len = 0;
+ return;
} else {
next_char(lex);
}
@@ -607,7 +606,7 @@ mp_lexer_t *mp_lexer_new(const char *src_name, void *stream_data, mp_lexer_strea
lex->num_indent_level = 1;
lex->indent_level = m_new(uint16_t, lex->alloc_indent_level);
lex->indent_level[0] = 0;
- vstr_init(&lex->vstr);
+ vstr_init(&lex->vstr, 32);
// preload characters
lex->chr0 = stream_next_char(stream_data);
@@ -677,8 +676,9 @@ bool mp_lexer_opt_str(mp_lexer_t *lex, const char *str) {
}
*/
-bool mp_lexer_show_error(mp_lexer_t *lex, const char *msg) {
- return mp_token_show_error(&lex->tok_cur, msg);
+bool mp_lexer_show_error_pythonic_prefix(mp_lexer_t *lex) {
+ printf(" File \"%s\", line %d column %d\n", lex->tok_cur.src_name, lex->tok_cur.src_line, lex->tok_cur.src_column);
+ return false;
}
bool mp_lexer_show_error_pythonic(mp_lexer_t *lex, const char *msg) {
diff --git a/py/lexer.h b/py/lexer.h
index 9dfcb128c5..ea928c77f8 100644
--- a/py/lexer.h
+++ b/py/lexer.h
@@ -10,19 +10,20 @@ typedef enum _mp_token_kind_t {
MP_TOKEN_INVALID,
MP_TOKEN_DEDENT_MISMATCH,
MP_TOKEN_LONELY_STRING_OPEN,
+ MP_TOKEN_BAD_LINE_CONTINUATION,
- MP_TOKEN_NEWLINE, // 4
- MP_TOKEN_INDENT, // 5
- MP_TOKEN_DEDENT, // 6
+ MP_TOKEN_NEWLINE, // 5
+ MP_TOKEN_INDENT, // 6
+ MP_TOKEN_DEDENT, // 7
- MP_TOKEN_NAME, // 7
+ MP_TOKEN_NAME, // 8
MP_TOKEN_NUMBER,
MP_TOKEN_STRING,
MP_TOKEN_BYTES,
MP_TOKEN_ELLIPSIS,
- MP_TOKEN_KW_FALSE, // 12
+ MP_TOKEN_KW_FALSE, // 13
MP_TOKEN_KW_NONE,
MP_TOKEN_KW_TRUE,
MP_TOKEN_KW_AND,
@@ -31,7 +32,7 @@ typedef enum _mp_token_kind_t {
MP_TOKEN_KW_BREAK,
MP_TOKEN_KW_CLASS,
MP_TOKEN_KW_CONTINUE,
- MP_TOKEN_KW_DEF, // 21
+ MP_TOKEN_KW_DEF, // 22
MP_TOKEN_KW_DEL,
MP_TOKEN_KW_ELIF,
MP_TOKEN_KW_ELSE,
@@ -41,7 +42,7 @@ typedef enum _mp_token_kind_t {
MP_TOKEN_KW_FROM,
MP_TOKEN_KW_GLOBAL,
MP_TOKEN_KW_IF,
- MP_TOKEN_KW_IMPORT, // 31
+ MP_TOKEN_KW_IMPORT, // 32
MP_TOKEN_KW_IN,
MP_TOKEN_KW_IS,
MP_TOKEN_KW_LAMBDA,
@@ -51,12 +52,12 @@ typedef enum _mp_token_kind_t {
MP_TOKEN_KW_PASS,
MP_TOKEN_KW_RAISE,
MP_TOKEN_KW_RETURN,
- MP_TOKEN_KW_TRY, // 41
+ MP_TOKEN_KW_TRY, // 42
MP_TOKEN_KW_WHILE,
MP_TOKEN_KW_WITH,
MP_TOKEN_KW_YIELD,
- MP_TOKEN_OP_PLUS, // 45
+ MP_TOKEN_OP_PLUS, // 46
MP_TOKEN_OP_MINUS,
MP_TOKEN_OP_STAR,
MP_TOKEN_OP_DBL_STAR,
@@ -66,7 +67,7 @@ typedef enum _mp_token_kind_t {
MP_TOKEN_OP_LESS,
MP_TOKEN_OP_DBL_LESS,
MP_TOKEN_OP_MORE,
- MP_TOKEN_OP_DBL_MORE, // 55
+ MP_TOKEN_OP_DBL_MORE, // 56
MP_TOKEN_OP_AMPERSAND,
MP_TOKEN_OP_PIPE,
MP_TOKEN_OP_CARET,
@@ -76,7 +77,7 @@ typedef enum _mp_token_kind_t {
MP_TOKEN_OP_DBL_EQUAL,
MP_TOKEN_OP_NOT_EQUAL,
- MP_TOKEN_DEL_PAREN_OPEN, // 64
+ MP_TOKEN_DEL_PAREN_OPEN, // 65
MP_TOKEN_DEL_PAREN_CLOSE,
MP_TOKEN_DEL_BRACKET_OPEN,
MP_TOKEN_DEL_BRACKET_CLOSE,
@@ -86,7 +87,7 @@ typedef enum _mp_token_kind_t {
MP_TOKEN_DEL_COLON,
MP_TOKEN_DEL_PERIOD,
MP_TOKEN_DEL_SEMICOLON,
- MP_TOKEN_DEL_AT, // 74
+ MP_TOKEN_DEL_AT, // 75
MP_TOKEN_DEL_EQUAL,
MP_TOKEN_DEL_PLUS_EQUAL,
MP_TOKEN_DEL_MINUS_EQUAL,
@@ -96,7 +97,7 @@ typedef enum _mp_token_kind_t {
MP_TOKEN_DEL_PERCENT_EQUAL,
MP_TOKEN_DEL_AMPERSAND_EQUAL,
MP_TOKEN_DEL_PIPE_EQUAL,
- MP_TOKEN_DEL_CARET_EQUAL, // 84
+ MP_TOKEN_DEL_CARET_EQUAL, // 85
MP_TOKEN_DEL_DBL_MORE_EQUAL,
MP_TOKEN_DEL_DBL_LESS_EQUAL,
MP_TOKEN_DEL_DBL_STAR_EQUAL,
@@ -123,8 +124,6 @@ typedef void (*mp_lexer_stream_close_t)(void*);
typedef struct _mp_lexer_t mp_lexer_t;
void mp_token_show(const mp_token_t *tok);
-void mp_token_show_error_prefix(const mp_token_t *tok);
-bool mp_token_show_error(const mp_token_t *tok, const char *msg);
mp_lexer_t *mp_lexer_new(const char *src_name, void *stream_data, mp_lexer_stream_next_char_t stream_next_char, mp_lexer_stream_close_t stream_close);
mp_lexer_t *mp_lexer_new_from_str_len(const char *src_name, const char *str, uint len, uint free_len);
@@ -133,12 +132,8 @@ void mp_lexer_free(mp_lexer_t *lex);
void mp_lexer_to_next(mp_lexer_t *lex);
const mp_token_t *mp_lexer_cur(const mp_lexer_t *lex);
bool mp_lexer_is_kind(mp_lexer_t *lex, mp_token_kind_t kind);
-/* unused
-bool mp_lexer_is_str(mp_lexer_t *lex, const char *str);
-bool mp_lexer_opt_kind(mp_lexer_t *lex, mp_token_kind_t kind);
-bool mp_lexer_opt_str(mp_lexer_t *lex, const char *str);
-*/
-bool mp_lexer_show_error(mp_lexer_t *lex, const char *msg);
+
+bool mp_lexer_show_error_pythonic_prefix(mp_lexer_t *lex);
bool mp_lexer_show_error_pythonic(mp_lexer_t *lex, const char *msg);
// used to import a module; must be implemented for a specific port
diff --git a/py/map.c b/py/map.c
index e44cf33d26..1ce763ab0e 100644
--- a/py/map.c
+++ b/py/map.c
@@ -132,28 +132,45 @@ void mp_set_init(mp_set_t *set, int n) {
set->table = m_new0(mp_obj_t, set->alloc);
}
-mp_obj_t mp_set_lookup(mp_set_t *set, mp_obj_t index, bool add_if_not_found) {
- int hash = mp_obj_hash(index);
- assert(set->alloc); /* FIXME: if alloc is ever 0 when doing a lookup, this'll fail: */
- int pos = hash % set->alloc;
+static void mp_set_rehash(mp_set_t *set) {
+ int old_alloc = set->alloc;
+ mp_obj_t *old_table = set->table;
+ set->alloc = get_doubling_prime_greater_or_equal_to(set->alloc + 1);
+ set->used = 0;
+ set->table = m_new0(mp_obj_t, set->alloc);
+ for (int i = 0; i < old_alloc; i++) {
+ if (old_table[i] != NULL) {
+ mp_set_lookup(set, old_table[i], true);
+ }
+ }
+ m_del(mp_obj_t, old_table, old_alloc);
+}
+
+mp_obj_t mp_set_lookup(mp_set_t *set, mp_obj_t index, mp_map_lookup_kind_t lookup_kind) {
+ int hash;
+ int pos;
+ if (set->alloc == 0) {
+ if (lookup_kind & MP_MAP_LOOKUP_ADD_IF_NOT_FOUND) {
+ mp_set_rehash(set);
+ } else {
+ return NULL;
+ }
+ }
+ if (lookup_kind & MP_MAP_LOOKUP_FIRST) {
+ hash = 0;
+ pos = 0;
+ } else {
+ hash = mp_obj_hash(index);;
+ pos = hash % set->alloc;
+ }
for (;;) {
mp_obj_t elem = set->table[pos];
if (elem == MP_OBJ_NULL) {
// not in table
- if (add_if_not_found) {
+ if (lookup_kind & MP_MAP_LOOKUP_ADD_IF_NOT_FOUND) {
if (set->used + 1 >= set->alloc) {
// not enough room in table, rehash it
- int old_alloc = set->alloc;
- mp_obj_t *old_table = set->table;
- set->alloc = get_doubling_prime_greater_or_equal_to(set->alloc + 1);
- set->used = 0;
- set->table = m_new(mp_obj_t, set->alloc);
- for (int i = 0; i < old_alloc; i++) {
- if (old_table[i] != NULL) {
- mp_set_lookup(set, old_table[i], true);
- }
- }
- m_del(mp_obj_t, old_table, old_alloc);
+ mp_set_rehash(set);
// restart the search for the new element
pos = hash % set->alloc;
} else {
@@ -161,11 +178,17 @@ mp_obj_t mp_set_lookup(mp_set_t *set, mp_obj_t index, bool add_if_not_found) {
set->table[pos] = index;
return index;
}
+ } else if (lookup_kind & MP_MAP_LOOKUP_FIRST) {
+ pos++;
} else {
return MP_OBJ_NULL;
}
- } else if (mp_obj_equal(elem, index)) {
+ } else if (lookup_kind & MP_MAP_LOOKUP_FIRST || mp_obj_equal(elem, index)) {
// found it
+ if (lookup_kind & MP_MAP_LOOKUP_REMOVE_IF_FOUND) {
+ set->used--;
+ set->table[pos] = NULL;
+ }
return elem;
} else {
// not yet found, keep searching in this table
@@ -173,3 +196,13 @@ mp_obj_t mp_set_lookup(mp_set_t *set, mp_obj_t index, bool add_if_not_found) {
}
}
}
+
+void mp_set_clear(mp_set_t *set) {
+ set->used = 0;
+ machine_uint_t a = set->alloc;
+ set->alloc = 0;
+ set->table = m_renew(mp_obj_t, set->table, a, set->alloc);
+ for (uint i=0; i<set->alloc; i++) {
+ set->table[i] = NULL;
+ }
+}
diff --git a/py/map.h b/py/map.h
index 5ce4e835b6..2db0ac3ebc 100644
--- a/py/map.h
+++ b/py/map.h
@@ -19,9 +19,10 @@ typedef struct _mp_set_t {
} mp_set_t;
typedef enum _mp_map_lookup_kind_t {
- MP_MAP_LOOKUP,
- MP_MAP_LOOKUP_ADD_IF_NOT_FOUND,
- MP_MAP_LOOKUP_REMOVE_IF_FOUND,
+ MP_MAP_LOOKUP, // 0
+ MP_MAP_LOOKUP_ADD_IF_NOT_FOUND, // 1
+ MP_MAP_LOOKUP_REMOVE_IF_FOUND, // 2
+ MP_MAP_LOOKUP_FIRST = 4,
} mp_map_lookup_kind_t;
int get_doubling_prime_greater_or_equal_to(int x);
@@ -31,4 +32,5 @@ mp_map_elem_t* mp_map_lookup(mp_map_t *map, mp_obj_t index, mp_map_lookup_kind_t
void mp_map_clear(mp_map_t *map);
void mp_set_init(mp_set_t *set, int n);
-mp_obj_t mp_set_lookup(mp_set_t *set, mp_obj_t index, bool add_if_not_found);
+mp_obj_t mp_set_lookup(mp_set_t *set, mp_obj_t index, mp_map_lookup_kind_t lookup_kind);
+void mp_set_clear(mp_set_t *set);
diff --git a/py/misc.h b/py/misc.h
index 1bf4d8f291..5b012d03dc 100644
--- a/py/misc.h
+++ b/py/misc.h
@@ -21,6 +21,7 @@ typedef unsigned int uint;
#define m_renew(type, ptr, old_num, new_num) ((type*)(m_realloc((ptr), sizeof(type) * (old_num), sizeof(type) * (new_num))))
#define m_del(type, ptr, num) m_free(ptr, sizeof(type) * (num))
#define m_del_obj(type, ptr) (m_del(type, ptr, 1))
+#define m_del_var(obj_type, var_type, var_num, ptr) (m_free(ptr, sizeof(obj_type) + sizeof(var_type) * (var_num)))
void *m_malloc(int num_bytes);
void *m_malloc0(int num_bytes);
@@ -49,6 +50,8 @@ bool unichar_isdigit(unichar c);
#define streq(s1, s2) (strcmp((s1), (s2)) == 0)
*/
+long strtonum(const char *restrict s, int base);
+
/** variable string *********************************************/
typedef struct _vstr_t {
@@ -58,15 +61,19 @@ typedef struct _vstr_t {
bool had_error;
} vstr_t;
-void vstr_init(vstr_t *vstr);
+void vstr_init(vstr_t *vstr, int alloc);
void vstr_clear(vstr_t *vstr);
vstr_t *vstr_new(void);
+vstr_t *vstr_new_size(int alloc);
void vstr_free(vstr_t *vstr);
void vstr_reset(vstr_t *vstr);
bool vstr_had_error(vstr_t *vstr);
char *vstr_str(vstr_t *vstr);
int vstr_len(vstr_t *vstr);
void vstr_hint_size(vstr_t *vstr, int size);
+char *vstr_extend(vstr_t *vstr, int size);
+bool vstr_set_size(vstr_t *vstr, int size);
+bool vstr_shrink(vstr_t *vstr);
char *vstr_add_len(vstr_t *vstr, int len);
void vstr_add_byte(vstr_t *vstr, byte v);
void vstr_add_char(vstr_t *vstr, unichar chr);
diff --git a/py/mpconfig.h b/py/mpconfig.h
index 2017ba366a..5d8c57692e 100644
--- a/py/mpconfig.h
+++ b/py/mpconfig.h
@@ -62,6 +62,18 @@
#define MICROPY_ENABLE_LEXER_UNIX (0)
#endif
+// Long int implementation
+#define MICROPY_LONGINT_IMPL_NONE (0)
+#define MICROPY_LONGINT_IMPL_LONGLONG (1)
+
+#ifndef MICROPY_LONGINT_IMPL
+#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_NONE)
+#endif
+
+#if MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_LONGLONG
+typedef long long mp_longint_impl_t;
+#endif
+
// Whether to support float and complex types
#ifndef MICROPY_ENABLE_FLOAT
#define MICROPY_ENABLE_FLOAT (0)
@@ -76,6 +88,11 @@
/*****************************************************************************/
/* Miscellaneous settings */
+#define BITS_PER_BYTE (8)
+#define BITS_PER_WORD (BITS_PER_BYTE * BYTES_PER_WORD)
+// machine_int_t value with most significant bit set
+#define WORD_MSBIT_HIGH (((machine_uint_t)1) << (BYTES_PER_WORD * 8 - 1))
+
// printf format spec to use for machine_int_t and friends
#ifndef INT_FMT
#ifdef __LP64__
diff --git a/py/mpqstrraw.h b/py/mpqstrraw.h
index e4404a36f0..6674a2c398 100644
--- a/py/mpqstrraw.h
+++ b/py/mpqstrraw.h
@@ -24,13 +24,14 @@ Q(StopIteration)
Q(AssertionError)
Q(AttributeError)
+Q(IndentationError)
Q(IndexError)
Q(KeyError)
Q(NameError)
+Q(OSError)
Q(SyntaxError)
Q(TypeError)
Q(ValueError)
-Q(OSError)
Q(abs)
Q(all)
@@ -41,6 +42,9 @@ Q(chr)
Q(complex)
Q(dict)
Q(divmod)
+Q(enumerate)
+Q(eval)
+Q(filter)
Q(float)
Q(hash)
Q(int)
@@ -49,6 +53,7 @@ Q(issubclass)
Q(iter)
Q(len)
Q(list)
+Q(map)
Q(max)
Q(min)
Q(next)
@@ -56,10 +61,14 @@ Q(ord)
Q(pow)
Q(print)
Q(range)
+Q(repr)
Q(set)
+Q(sorted)
Q(sum)
+Q(str)
Q(tuple)
Q(type)
+Q(zip)
Q(append)
Q(pop)
diff --git a/py/obj.c b/py/obj.c
index 866b9aaefa..9ca3d5d16b 100644
--- a/py/obj.c
+++ b/py/obj.c
@@ -13,7 +13,6 @@
#include "runtime0.h"
#include "runtime.h"
#include "map.h"
-#include "strtonum.h"
mp_obj_t mp_obj_get_type(mp_obj_t o_in) {
if (MP_OBJ_IS_SMALL_INT(o_in)) {
@@ -42,21 +41,21 @@ void printf_wrapper(void *env, const char *fmt, ...) {
va_end(args);
}
-void mp_obj_print_helper(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in) {
+void mp_obj_print_helper(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in, mp_print_kind_t kind) {
if (MP_OBJ_IS_SMALL_INT(o_in)) {
print(env, "%d", (int)MP_OBJ_SMALL_INT_VALUE(o_in));
} else {
mp_obj_base_t *o = o_in;
if (o->type->print != NULL) {
- o->type->print(print, env, o_in);
+ o->type->print(print, env, o_in, kind);
} else {
print(env, "<%s>", o->type->name);
}
}
}
-void mp_obj_print(mp_obj_t o_in) {
- mp_obj_print_helper(printf_wrapper, NULL, o_in);
+void mp_obj_print(mp_obj_t o_in, mp_print_kind_t kind) {
+ mp_obj_print_helper(printf_wrapper, NULL, o_in, kind);
}
bool mp_obj_is_callable(mp_obj_t o_in) {
@@ -109,15 +108,28 @@ bool mp_obj_equal(mp_obj_t o1, mp_obj_t o2) {
return val == 0;
} else if (o2 == mp_const_true) {
return val == 1;
- } else {
- return false;
+ } else if (MP_OBJ_IS_TYPE(o2, &int_type)) {
+ // If o2 is long int, dispatch to its virtual methods
+ mp_obj_base_t *o = o2;
+ if (o->type->binary_op != NULL) {
+ mp_obj_t r = o->type->binary_op(RT_COMPARE_OP_EQUAL, o2, o1);
+ return r == mp_const_true ? true : false;
+ }
}
+ return false;
}
} else if (MP_OBJ_IS_QSTR(o1) || MP_OBJ_IS_QSTR(o2)) {
return false;
} else if (MP_OBJ_IS_TYPE(o1, &str_type) && MP_OBJ_IS_TYPE(o2, &str_type)) {
return mp_obj_str_get(o1) == mp_obj_str_get(o2);
} else {
+ mp_obj_base_t *o = o1;
+ if (o->type->binary_op != NULL) {
+ mp_obj_t r = o->type->binary_op(RT_COMPARE_OP_EQUAL, o1, o2);
+ if (r != MP_OBJ_NULL) {
+ return r == mp_const_true ? true : false;
+ }
+ }
// TODO: Debugging helper
printf("Equality for '%s' and '%s' types not yet implemented\n", mp_obj_get_type_str(o1), mp_obj_get_type_str(o2));
assert(0);
@@ -137,12 +149,6 @@ bool mp_obj_less(mp_obj_t o1, mp_obj_t o2) {
}
machine_int_t mp_obj_get_int(mp_obj_t arg) {
- return mp_obj_get_int_base(arg, 0);
-}
-
-machine_int_t mp_obj_get_int_base(mp_obj_t arg, mp_obj_t base_arg) {
- const char *value;
- int base;
if (arg == mp_const_false) {
return 0;
} else if (arg == mp_const_true) {
@@ -154,17 +160,6 @@ machine_int_t mp_obj_get_int_base(mp_obj_t arg, mp_obj_t base_arg) {
// TODO work out if this should be floor, ceil or trunc
return (machine_int_t)mp_obj_float_get(arg);
#endif
- } else if (MP_OBJ_IS_TYPE(arg, &str_type)) {
- if (base_arg == 0) {
- value = qstr_str(mp_obj_str_get(arg));
- return (machine_int_t)strtonum(value, 0);
- } else if (MP_OBJ_IS_SMALL_INT(base_arg)) {
- base = MP_OBJ_SMALL_INT_VALUE(base_arg);
- value = qstr_str(mp_obj_str_get(arg));
- return (machine_int_t)strtonum(value, base);
- } else {
- nlr_jump(mp_obj_new_exception_msg(MP_QSTR_TypeError, "an integer is required"));
- }
} else {
nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "can't convert %s to int", mp_obj_get_type_str(arg)));
}
diff --git a/py/obj.h b/py/obj.h
index 381fcc1f25..cbd12fe862 100644
--- a/py/obj.h
+++ b/py/obj.h
@@ -34,6 +34,8 @@ typedef struct _mp_obj_base_t mp_obj_base_t;
// - xxxx...xx10: a qstr, bits 2 and above are the value
// - xxxx...xx00: a pointer to an mp_obj_base_t
+// In SMALL_INT, next-to-highest bits is used as sign, so both must match for value in range
+#define MP_OBJ_FITS_SMALL_INT(n) ((((n) ^ ((n) << 1)) & WORD_MSBIT_HIGH) == 0)
#define MP_OBJ_IS_SMALL_INT(o) ((((mp_small_int_t)(o)) & 1) != 0)
#define MP_OBJ_IS_QSTR(o) ((((mp_small_int_t)(o)) & 3) == 2)
#define MP_OBJ_IS_OBJ(o) ((((mp_small_int_t)(o)) & 3) == 0)
@@ -57,7 +59,7 @@ typedef struct _mp_obj_base_t mp_obj_base_t;
#define MP_DEFINE_CONST_FUN_OBJ_3(obj_name, fun_name) MP_DEFINE_CONST_FUN_OBJ_VOID_PTR(obj_name, false, 3, 3, (mp_fun_3_t)fun_name)
#define MP_DEFINE_CONST_FUN_OBJ_VAR(obj_name, n_args_min, fun_name) MP_DEFINE_CONST_FUN_OBJ_VOID_PTR(obj_name, false, n_args_min, (~((machine_uint_t)0)), (mp_fun_var_t)fun_name)
#define MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(obj_name, n_args_min, n_args_max, fun_name) MP_DEFINE_CONST_FUN_OBJ_VOID_PTR(obj_name, false, n_args_min, n_args_max, (mp_fun_var_t)fun_name)
-#define MP_DEFINE_CONST_FUN_OBJ_KW(obj_name, fun_name) MP_DEFINE_CONST_FUN_OBJ_VOID_PTR(obj_name, true, 0, (~((machine_uint_t)0)), (mp_fun_kw_t)fun_name)
+#define MP_DEFINE_CONST_FUN_OBJ_KW(obj_name, n_args_min, fun_name) MP_DEFINE_CONST_FUN_OBJ_VOID_PTR(obj_name, true, n_args_min, (~((machine_uint_t)0)), (mp_fun_kw_t)fun_name)
// These macros are used to declare and define constant staticmethond and classmethod objects
// You can put "static" in front of the definitions to make them local
@@ -83,7 +85,11 @@ typedef mp_obj_t (*mp_fun_t)(void);
typedef mp_obj_t (*mp_fun_var_t)(int n, const mp_obj_t *);
typedef mp_obj_t (*mp_fun_kw_t)(mp_obj_t, struct _mp_map_t*);
-typedef void (*mp_print_fun_t)(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o);
+typedef enum {
+ PRINT_STR, PRINT_REPR
+} mp_print_kind_t;
+
+typedef void (*mp_print_fun_t)(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o, mp_print_kind_t kind);
typedef mp_obj_t (*mp_make_new_fun_t)(mp_obj_t type_in, int n_args, const mp_obj_t *args); // args are in reverse order in the array
typedef mp_obj_t (*mp_call_n_fun_t)(mp_obj_t fun, int n_args, const mp_obj_t *args); // args are in reverse order in the array
typedef mp_obj_t (*mp_call_n_kw_fun_t)(mp_obj_t fun, int n_args, int n_kw, const mp_obj_t *args); // args are in reverse order in the array
@@ -196,6 +202,8 @@ mp_obj_t mp_obj_new_none(void);
mp_obj_t mp_obj_new_bool(bool value);
mp_obj_t mp_obj_new_cell(mp_obj_t obj);
mp_obj_t mp_obj_new_int(machine_int_t value);
+mp_obj_t mp_obj_new_int_from_uint(machine_uint_t value);
+mp_obj_t mp_obj_new_int_from_long_str(const char *s);
mp_obj_t mp_obj_new_str(qstr qstr);
#if MICROPY_ENABLE_FLOAT
mp_obj_t mp_obj_new_float(mp_float_t val);
@@ -226,8 +234,8 @@ mp_obj_t mp_obj_new_module(qstr module_name);
mp_obj_t mp_obj_get_type(mp_obj_t o_in);
const char *mp_obj_get_type_str(mp_obj_t o_in);
-void mp_obj_print_helper(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in);
-void mp_obj_print(mp_obj_t o);
+void mp_obj_print_helper(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in, mp_print_kind_t kind);
+void mp_obj_print(mp_obj_t o, mp_print_kind_t kind);
bool mp_obj_is_callable(mp_obj_t o_in);
machine_int_t mp_obj_hash(mp_obj_t o_in);
@@ -235,7 +243,7 @@ bool mp_obj_equal(mp_obj_t o1, mp_obj_t o2);
bool mp_obj_less(mp_obj_t o1, mp_obj_t o2);
machine_int_t mp_obj_get_int(mp_obj_t arg);
-machine_int_t mp_obj_get_int_base(mp_obj_t arg, mp_obj_t base_arg);
+machine_int_t mp_obj_parse_int(mp_obj_t arg, mp_obj_t base_arg);
#if MICROPY_ENABLE_FLOAT
mp_float_t mp_obj_get_float(mp_obj_t self_in);
void mp_obj_get_complex(mp_obj_t self_in, mp_float_t *real, mp_float_t *imag);
@@ -282,12 +290,23 @@ mp_obj_t mp_obj_complex_binary_op(int op, mp_float_t lhs_real, mp_float_t lhs_im
// tuple
extern const mp_obj_type_t tuple_type;
void mp_obj_tuple_get(mp_obj_t self_in, uint *len, mp_obj_t **items);
+void mp_obj_tuple_del(mp_obj_t self_in);
// list
extern const mp_obj_type_t list_type;
mp_obj_t mp_obj_list_append(mp_obj_t self_in, mp_obj_t arg);
void mp_obj_list_get(mp_obj_t self_in, uint *len, mp_obj_t **items);
void mp_obj_list_store(mp_obj_t self_in, mp_obj_t index, mp_obj_t value);
+mp_obj_t mp_obj_list_sort(mp_obj_t args, struct _mp_map_t *kwargs);
+
+// map (the python builtin, not the dict implementation detail)
+extern const mp_obj_type_t map_type;
+
+// enumerate
+extern const mp_obj_type_t enumerate_type;
+
+// filter
+extern const mp_obj_type_t filter_type;
// dict
extern const mp_obj_type_t dict_type;
@@ -303,6 +322,10 @@ void mp_obj_set_store(mp_obj_t self_in, mp_obj_t item);
extern const mp_obj_type_t slice_type;
void mp_obj_slice_get(mp_obj_t self_in, machine_int_t *start, machine_int_t *stop, machine_int_t *step);
+// zip
+extern const mp_obj_type_t zip_type;
+
+
// functions
typedef struct _mp_obj_fun_native_t { // need this so we can define const objects (to go in ROM)
mp_obj_base_t base;
diff --git a/py/objbool.c b/py/objbool.c
index da9a678063..66f9e902a6 100644
--- a/py/objbool.c
+++ b/py/objbool.c
@@ -13,7 +13,7 @@ typedef struct _mp_obj_bool_t {
bool value;
} mp_obj_bool_t;
-static void bool_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) {
+static void bool_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
mp_obj_bool_t *self = self_in;
if (self->value) {
print(env, "True");
diff --git a/py/objcomplex.c b/py/objcomplex.c
index 1036bae420..bd103bbfab 100644
--- a/py/objcomplex.c
+++ b/py/objcomplex.c
@@ -21,7 +21,7 @@ typedef struct _mp_obj_complex_t {
mp_obj_t mp_obj_new_complex(mp_float_t real, mp_float_t imag);
-void complex_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in) {
+void complex_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in, mp_print_kind_t kind) {
mp_obj_complex_t *o = o_in;
if (o->real == 0) {
print(env, "%.8gj", o->imag);
diff --git a/py/objdict.c b/py/objdict.c
index 6dbb1f316b..da1b5b9f5b 100644
--- a/py/objdict.c
+++ b/py/objdict.c
@@ -20,7 +20,7 @@ typedef struct _mp_obj_dict_t {
static mp_obj_t mp_obj_new_dict_iterator(mp_obj_dict_t *dict, int cur);
static mp_map_elem_t *dict_it_iternext_elem(mp_obj_t self_in);
-static void dict_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) {
+static void dict_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
mp_obj_dict_t *self = self_in;
bool first = true;
print(env, "{");
@@ -31,9 +31,9 @@ static void dict_print(void (*print)(void *env, const char *fmt, ...), void *env
print(env, ", ");
}
first = false;
- mp_obj_print_helper(print, env, next->key);
+ mp_obj_print_helper(print, env, next->key, PRINT_REPR);
print(env, ": ");
- mp_obj_print_helper(print, env, next->value);
+ mp_obj_print_helper(print, env, next->value, PRINT_REPR);
}
print(env, "}");
}
@@ -57,6 +57,12 @@ static mp_obj_t dict_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
return elem->value;
}
}
+ case RT_COMPARE_OP_IN:
+ case RT_COMPARE_OP_NOT_IN:
+ {
+ mp_map_elem_t *elem = mp_map_lookup(&o->map, rhs_in, MP_MAP_LOOKUP);
+ return MP_BOOL((op == RT_COMPARE_OP_IN) ^ (elem == NULL));
+ }
default:
// op not supported
return NULL;
@@ -344,7 +350,7 @@ static mp_obj_t dict_view_getiter(mp_obj_t view_in) {
return o;
}
-static void dict_view_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) {
+static void dict_view_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
assert(MP_OBJ_IS_TYPE(self_in, &dict_view_type));
mp_obj_dict_view_t *self = self_in;
bool first = true;
@@ -357,15 +363,25 @@ static void dict_view_print(void (*print)(void *env, const char *fmt, ...), void
print(env, ", ");
}
first = false;
- mp_obj_print_helper(print, env, next);
+ mp_obj_print_helper(print, env, next, PRINT_REPR);
}
print(env, "])");
}
+static mp_obj_t dict_view_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
+ /* only supported for the 'keys' kind until sets and dicts are refactored */
+ mp_obj_dict_view_t *o = lhs_in;
+ if (o->kind != MP_DICT_VIEW_KEYS) return NULL;
+ if (op != RT_COMPARE_OP_IN && op != RT_COMPARE_OP_NOT_IN) return NULL;
+ return dict_binary_op(op, o->dict, rhs_in);
+}
+
+
static const mp_obj_type_t dict_view_type = {
{ &mp_const_type },
"dict_view",
.print = dict_view_print,
+ .binary_op = dict_view_binary_op,
.getiter = dict_view_getiter,
};
diff --git a/py/objenumerate.c b/py/objenumerate.c
new file mode 100644
index 0000000000..5bfd8a3370
--- /dev/null
+++ b/py/objenumerate.c
@@ -0,0 +1,53 @@
+#include <stdlib.h>
+#include <assert.h>
+
+#include "misc.h"
+#include "mpconfig.h"
+#include "obj.h"
+#include "runtime.h"
+
+typedef struct _mp_obj_enumerate_t {
+ mp_obj_base_t base;
+ mp_obj_t iter;
+ machine_int_t cur;
+} mp_obj_enumerate_t;
+
+static mp_obj_t enumerate_getiter(mp_obj_t self_in) {
+ return self_in;
+}
+
+static mp_obj_t enumerate_iternext(mp_obj_t self_in);
+
+/* TODO: enumerate is one of the ones that can take args or kwargs.
+ Sticking to args for now */
+static mp_obj_t enumerate_make_new(mp_obj_t type_in, int n_args, const mp_obj_t *args) {
+ /* NOTE: args are backwards */
+ assert(n_args > 0);
+ args += n_args - 1;
+ mp_obj_enumerate_t *o = m_new_obj(mp_obj_enumerate_t);
+ o->base.type = &enumerate_type;
+ o->iter = rt_getiter(args[0]);
+ o->cur = n_args > 1 ? mp_obj_get_int(args[-1]) : 0;
+
+ return o;
+}
+
+const mp_obj_type_t enumerate_type = {
+ { &mp_const_type },
+ "enumerate",
+ .make_new = enumerate_make_new,
+ .iternext = enumerate_iternext,
+ .getiter = enumerate_getiter,
+};
+
+static mp_obj_t enumerate_iternext(mp_obj_t self_in) {
+ assert(MP_OBJ_IS_TYPE(self_in, &enumerate_type));
+ mp_obj_enumerate_t *self = self_in;
+ mp_obj_t next = rt_iternext(self->iter);
+ if (next == mp_const_stop_iteration) {
+ return mp_const_stop_iteration;
+ } else {
+ mp_obj_t items[] = {MP_OBJ_NEW_SMALL_INT(self->cur++), next};
+ return mp_obj_new_tuple(2, items);
+ }
+}
diff --git a/py/objexcept.c b/py/objexcept.c
index 4708a27bfc..67e6d63155 100644
--- a/py/objexcept.c
+++ b/py/objexcept.c
@@ -8,105 +8,98 @@
#include "misc.h"
#include "mpconfig.h"
#include "obj.h"
+#include "objtuple.h"
+// This is unified class for C-level and Python-level exceptions
+// Python-level exception have empty ->msg and all arguments are in
+// args tuple. C-level excepttion likely have ->msg, and may as well
+// have args tuple (or otherwise have it as NULL).
typedef struct mp_obj_exception_t {
mp_obj_base_t base;
qstr id;
- int n_args;
- const void *args[];
+ qstr msg;
+ mp_obj_tuple_t args;
} mp_obj_exception_t;
-void exception_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in) {
+void exception_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in, mp_print_kind_t kind) {
mp_obj_exception_t *o = o_in;
- switch (o->n_args) {
- case 0:
+ if (o->msg != 0) {
+ print(env, "%s: %s", qstr_str(o->id), qstr_str(o->msg));
+ } else {
+ // Yes, that's how CPython has it
+ if (kind == PRINT_REPR) {
print(env, "%s", qstr_str(o->id));
- break;
- case 1:
- print(env, "%s: %s", qstr_str(o->id), (const char*)o->args[0]);
- break;
- case 2:
- print(env, "%s: ", qstr_str(o->id));
- print(env, (const char*)o->args[0], o->args[1]);
- break;
- default: // here we just assume at least 3 args, but only use first 3
- print(env, "%s: ", qstr_str(o->id));
- print(env, (const char*)o->args[0], o->args[1], o->args[2]);
- break;
+ }
+ if (kind == PRINT_STR) {
+ if (o->args.len == 0) {
+ print(env, "");
+ return;
+ } else if (o->args.len == 1) {
+ mp_obj_print_helper(print, env, o->args.items[0], PRINT_STR);
+ return;
+ }
+ }
+ tuple_print(print, env, &o->args, kind);
}
}
+// args in reversed order
+static mp_obj_t exception_call(mp_obj_t self_in, int n_args, const mp_obj_t *args) {
+ mp_obj_exception_t *base = self_in;
+ mp_obj_exception_t *o = m_new_obj_var(mp_obj_exception_t, mp_obj_t*, n_args);
+ o->base.type = &exception_type;
+ o->id = base->id;
+ o->msg = 0;
+ o->args.len = n_args;
+
+ // TODO: factor out as reusable copy_reversed()
+ int j = 0;
+ for (int i = n_args - 1; i >= 0; i--) {
+ o->args.items[i] = args[j++];
+ }
+ return o;
+}
+
const mp_obj_type_t exception_type = {
{ &mp_const_type },
"exception",
.print = exception_print,
+ .call_n = exception_call,
};
mp_obj_t mp_obj_new_exception(qstr id) {
- mp_obj_exception_t *o = m_new_obj(mp_obj_exception_t);
- o->base.type = &exception_type;
- o->id = id;
- o->n_args = 0;
- return o;
+ return mp_obj_new_exception_msg_varg(id, NULL);
}
mp_obj_t mp_obj_new_exception_msg(qstr id, const char *msg) {
- mp_obj_exception_t *o = m_new_obj_var(mp_obj_exception_t, void*, 1);
- o->base.type = &exception_type;
- o->id = id;
- o->n_args = 1;
- o->args[0] = msg;
- return o;
+ return mp_obj_new_exception_msg_varg(id, msg);
}
mp_obj_t mp_obj_new_exception_msg_1_arg(qstr id, const char *fmt, const char *a1) {
- mp_obj_exception_t *o = m_new_obj_var(mp_obj_exception_t, void*, 2);
- o->base.type = &exception_type;
- o->id = id;
- o->n_args = 2;
- o->args[0] = fmt;
- o->args[1] = a1;
- return o;
+ return mp_obj_new_exception_msg_varg(id, fmt, a1);
}
mp_obj_t mp_obj_new_exception_msg_2_args(qstr id, const char *fmt, const char *a1, const char *a2) {
- mp_obj_exception_t *o = m_new_obj_var(mp_obj_exception_t, void*, 3);
- o->base.type = &exception_type;
- o->id = id;
- o->n_args = 3;
- o->args[0] = fmt;
- o->args[1] = a1;
- o->args[2] = a2;
- return o;
+ return mp_obj_new_exception_msg_varg(id, fmt, a1, a2);
}
mp_obj_t mp_obj_new_exception_msg_varg(qstr id, const char *fmt, ...) {
- // count number of arguments by number of % signs, excluding %%
- int n_args = 1; // count fmt
- for (const char *s = fmt; *s; s++) {
- if (*s == '%') {
- if (s[1] == '%') {
- s += 1;
- } else {
- n_args += 1;
- }
- }
- }
-
// make exception object
- mp_obj_exception_t *o = m_new_obj_var(mp_obj_exception_t, void*, n_args);
+ mp_obj_exception_t *o = m_new_obj_var(mp_obj_exception_t, mp_obj_t*, 0);
o->base.type = &exception_type;
o->id = id;
- o->n_args = n_args;
- o->args[0] = fmt;
-
- // extract args and store them
- va_list ap;
- va_start(ap, fmt);
- for (int i = 1; i < n_args; i++) {
- o->args[i] = va_arg(ap, void*);
+ o->args.len = 0;
+ if (fmt == NULL) {
+ o->msg = 0;
+ } else {
+ // render exception message
+ vstr_t *vstr = vstr_new();
+ va_list ap;
+ va_start(ap, fmt);
+ vstr_vprintf(vstr, fmt, ap);
+ va_end(ap);
+ o->msg = qstr_from_str_take(vstr->buf, vstr->alloc);
}
- va_end(ap);
return o;
}
diff --git a/py/objfilter.c b/py/objfilter.c
new file mode 100644
index 0000000000..18225ac102
--- /dev/null
+++ b/py/objfilter.c
@@ -0,0 +1,58 @@
+#include <stdlib.h>
+#include <assert.h>
+
+#include "nlr.h"
+#include "misc.h"
+#include "mpconfig.h"
+#include "mpqstr.h"
+#include "obj.h"
+#include "runtime.h"
+
+typedef struct _mp_obj_filter_t {
+ mp_obj_base_t base;
+ mp_obj_t fun;
+ mp_obj_t iter;
+} mp_obj_filter_t;
+
+static mp_obj_t filter_make_new(mp_obj_t type_in, int n_args, const mp_obj_t *args) {
+ /* NOTE: args are backwards */
+ if (n_args != 2) {
+ nlr_jump(mp_obj_new_exception_msg(MP_QSTR_TypeError, "filter expected 2 arguments"));
+ }
+ assert(n_args == 2);
+ mp_obj_filter_t *o = m_new_obj(mp_obj_filter_t);
+ o->base.type = &filter_type;
+ o->fun = args[1];
+ o->iter = rt_getiter(args[0]);
+ return o;
+}
+
+static mp_obj_t filter_getiter(mp_obj_t self_in) {
+ return self_in;
+}
+
+static mp_obj_t filter_iternext(mp_obj_t self_in) {
+ assert(MP_OBJ_IS_TYPE(self_in, &filter_type));
+ mp_obj_filter_t *self = self_in;
+ mp_obj_t next;
+ while ((next = rt_iternext(self->iter)) != mp_const_stop_iteration) {
+ mp_obj_t val;
+ if (self->fun != mp_const_none) {
+ val = rt_call_function_n(self->fun, 1, &next);
+ } else {
+ val = next;
+ }
+ if (rt_is_true(val)) {
+ return next;
+ }
+ }
+ return mp_const_stop_iteration;
+}
+
+const mp_obj_type_t filter_type = {
+ { &mp_const_type },
+ "filter",
+ .make_new = filter_make_new,
+ .getiter = filter_getiter,
+ .iternext = filter_iternext,
+};
diff --git a/py/objfloat.c b/py/objfloat.c
index bb44ac9549..1ac8754e40 100644
--- a/py/objfloat.c
+++ b/py/objfloat.c
@@ -19,7 +19,7 @@ typedef struct _mp_obj_float_t {
mp_obj_t mp_obj_new_float(mp_float_t value);
-static void float_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in) {
+static void float_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in, mp_print_kind_t kind) {
mp_obj_float_t *o = o_in;
print(env, "%.8g", o->value);
}
diff --git a/py/objfun.c b/py/objfun.c
index afac3889fd..c624cf2d27 100644
--- a/py/objfun.c
+++ b/py/objfun.c
@@ -17,21 +17,44 @@
// mp_obj_fun_native_t defined in obj.h
+void check_nargs(mp_obj_fun_native_t *self, int n_args, int n_kw) {
+ if (n_kw && !self->is_kw) {
+ nlr_jump(mp_obj_new_exception_msg(MP_QSTR_TypeError,
+ "function does not take keyword arguments"));
+ }
+
+ if (self->n_args_min == self->n_args_max) {
+ if (n_args != self->n_args_min) {
+ nlr_jump(mp_obj_new_exception_msg_2_args(MP_QSTR_TypeError,
+ "function takes %d positional arguments but %d were given",
+ (const char*)(machine_int_t)self->n_args_min,
+ (const char*)(machine_int_t)n_args));
+ }
+ } else {
+ if (n_args < self->n_args_min) {
+ nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_TypeError,
+ "<fun name>() missing %d required positional arguments: <list of names of params>",
+ (const char*)(machine_int_t)(self->n_args_min - n_args)));
+ } else if (n_args > self->n_args_max) {
+ nlr_jump(mp_obj_new_exception_msg_2_args(MP_QSTR_TypeError,
+ "<fun name> expected at most %d arguments, got %d",
+ (void*)(machine_int_t)self->n_args_max, (void*)(machine_int_t)n_args));
+ }
+ }
+}
+
mp_obj_t fun_native_call_n_kw(mp_obj_t self_in, int n_args, int n_kw, const mp_obj_t *args);
// args are in reverse order in the array
mp_obj_t fun_native_call_n(mp_obj_t self_in, int n_args, const mp_obj_t *args) {
mp_obj_fun_native_t *self = self_in;
+ // check number of arguments
+ check_nargs(self, n_args, 0);
if (self->is_kw) {
return fun_native_call_n_kw(self_in, n_args, 0, args);
}
if (self->n_args_min == self->n_args_max) {
// function requires a fixed number of arguments
- // check number of arguments
- if (n_args != self->n_args_min) {
- nlr_jump(mp_obj_new_exception_msg_2_args(MP_QSTR_TypeError, "function takes %d positional arguments but %d were given", (const char*)(machine_int_t)self->n_args_min, (const char*)(machine_int_t)n_args));
- }
-
// dispatch function call
switch (self->n_args_min) {
case 0:
@@ -54,12 +77,6 @@ mp_obj_t fun_native_call_n(mp_obj_t self_in, int n_args, const mp_obj_t *args) {
} else {
// function takes a variable number of arguments
- if (n_args < self->n_args_min) {
- nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_TypeError, "<fun name>() missing %d required positional arguments: <list of names of params>", (const char*)(machine_int_t)(self->n_args_min - n_args)));
- } else if (n_args > self->n_args_max) {
- nlr_jump(mp_obj_new_exception_msg_2_args(MP_QSTR_TypeError, "<fun name> expected at most %d arguments, got %d", (void*)(machine_int_t)self->n_args_max, (void*)(machine_int_t)n_args));
- }
-
// TODO really the args need to be passed in as a Python tuple, as the form f(*[1,2]) can be used to pass var args
mp_obj_t *args_ordered = m_new(mp_obj_t, n_args);
for (int i = 0; i < n_args; i++) {
@@ -76,9 +93,7 @@ mp_obj_t fun_native_call_n(mp_obj_t self_in, int n_args, const mp_obj_t *args) {
mp_obj_t fun_native_call_n_kw(mp_obj_t self_in, int n_args, int n_kw, const mp_obj_t *args) {
mp_obj_fun_native_t *self = self_in;
- if (!self->is_kw) {
- nlr_jump(mp_obj_new_exception_msg(MP_QSTR_TypeError, "function does not take keyword arguments"));
- }
+ check_nargs(self, n_args, n_kw);
mp_obj_t *vargs = mp_obj_new_tuple_reverse(n_args, args + 2*n_kw);
mp_map_t *kw_args = mp_map_new(n_kw);
@@ -98,38 +113,13 @@ const mp_obj_type_t fun_native_type = {
.call_n_kw = fun_native_call_n_kw,
};
-mp_obj_t rt_make_function_0(mp_fun_0_t fun) {
- mp_obj_fun_native_t *o = m_new_obj(mp_obj_fun_native_t);
- o->base.type = &fun_native_type;
- o->n_args_min = 0;
- o->n_args_max = 0;
- o->fun = fun;
- return o;
-}
-
-mp_obj_t rt_make_function_1(mp_fun_1_t fun) {
- mp_obj_fun_native_t *o = m_new_obj(mp_obj_fun_native_t);
- o->base.type = &fun_native_type;
- o->n_args_min = 1;
- o->n_args_max = 1;
- o->fun = fun;
- return o;
-}
-
-mp_obj_t rt_make_function_2(mp_fun_2_t fun) {
- mp_obj_fun_native_t *o = m_new_obj(mp_obj_fun_native_t);
- o->base.type = &fun_native_type;
- o->n_args_min = 2;
- o->n_args_max = 2;
- o->fun = fun;
- return o;
-}
-
-mp_obj_t rt_make_function_3(mp_fun_3_t fun) {
+// fun must have the correct signature for n_args fixed arguments
+mp_obj_t rt_make_function_n(int n_args, void *fun) {
mp_obj_fun_native_t *o = m_new_obj(mp_obj_fun_native_t);
o->base.type = &fun_native_type;
- o->n_args_min = 3;
- o->n_args_max = 3;
+ o->is_kw = false;
+ o->n_args_min = n_args;
+ o->n_args_max = n_args;
o->fun = fun;
return o;
}
@@ -137,6 +127,7 @@ mp_obj_t rt_make_function_3(mp_fun_3_t fun) {
mp_obj_t rt_make_function_var(int n_args_min, mp_fun_var_t fun) {
mp_obj_fun_native_t *o = m_new_obj(mp_obj_fun_native_t);
o->base.type = &fun_native_type;
+ o->is_kw = false;
o->n_args_min = n_args_min;
o->n_args_max = ~((machine_uint_t)0);
o->fun = fun;
@@ -147,6 +138,7 @@ mp_obj_t rt_make_function_var(int n_args_min, mp_fun_var_t fun) {
mp_obj_t rt_make_function_var_between(int n_args_min, int n_args_max, mp_fun_var_t fun) {
mp_obj_fun_native_t *o = m_new_obj(mp_obj_fun_native_t);
o->base.type = &fun_native_type;
+ o->is_kw = false;
o->n_args_min = n_args_min;
o->n_args_max = n_args_max;
o->fun = fun;
diff --git a/py/objgenerator.c b/py/objgenerator.c
index 7eeb4ef80b..40f202df3c 100644
--- a/py/objgenerator.c
+++ b/py/objgenerator.c
@@ -61,7 +61,7 @@ typedef struct _mp_obj_gen_instance_t {
mp_obj_t state[];
} mp_obj_gen_instance_t;
-void gen_instance_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) {
+void gen_instance_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
print(env, "<generator object 'fun-name' at %p>", self_in);
}
diff --git a/py/objint.c b/py/objint.c
index bd0926840b..937bff7ae3 100644
--- a/py/objint.c
+++ b/py/objint.c
@@ -8,21 +8,27 @@
#include "mpconfig.h"
#include "mpqstr.h"
#include "obj.h"
+#include "objint.h"
-typedef struct _mp_obj_int_t {
- mp_obj_base_t base;
-} mp_obj_int_t;
-
+// This dispatcher function is expected to be independent of the implementation
+// of long int
static mp_obj_t int_make_new(mp_obj_t type_in, int n_args, const mp_obj_t *args) {
switch (n_args) {
case 0:
return MP_OBJ_NEW_SMALL_INT(0);
case 1:
- return MP_OBJ_NEW_SMALL_INT(mp_obj_get_int(args[0]));
+ if (MP_OBJ_IS_TYPE(args[0], &str_type)) {
+ // a string, parse it
+ return MP_OBJ_NEW_SMALL_INT(strtonum(qstr_str(mp_obj_get_qstr(args[0])), 0));
+ } else {
+ return MP_OBJ_NEW_SMALL_INT(mp_obj_get_int(args[0]));
+ }
case 2:
- return MP_OBJ_NEW_SMALL_INT(mp_obj_get_int_base(args[1], args[0]));
+ // should be a string, parse it
+ // TODO proper error checking of argument types
+ return MP_OBJ_NEW_SMALL_INT(strtonum(qstr_str(mp_obj_get_qstr(args[1])), mp_obj_get_int(args[0])));
default:
nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_TypeError, "int takes at most 2 arguments, %d given", (void*)(machine_int_t)n_args));
@@ -32,9 +38,45 @@ static mp_obj_t int_make_new(mp_obj_t type_in, int n_args, const mp_obj_t *args)
const mp_obj_type_t int_type = {
{ &mp_const_type },
"int",
+ .print = int_print,
.make_new = int_make_new,
+ .binary_op = int_binary_op,
};
+#if MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_NONE
+// This is called only for non-SMALL_INT
+void int_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
+}
+
+// This is called only for non-SMALL_INT
+mp_obj_t int_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
+ assert(0);
+ return mp_const_none;
+}
+
+// This is called only with strings whose value doesn't fit in SMALL_INT
+mp_obj_t mp_obj_new_int_from_long_str(const char *s) {
+ assert(0);
+ return mp_const_none;
+}
+
+mp_obj_t mp_obj_new_int_from_uint(machine_uint_t value) {
+ // SMALL_INT accepts only signed numbers, of one bit less size
+ // then word size, which totals 2 bits less for unsigned numbers.
+ if ((value & (WORD_MSBIT_HIGH | (WORD_MSBIT_HIGH >> 1))) == 0) {
+ return MP_OBJ_NEW_SMALL_INT(value);
+ }
+ // TODO: Raise exception
+ assert(0);
+ return mp_const_none;
+}
+
mp_obj_t mp_obj_new_int(machine_int_t value) {
- return MP_OBJ_NEW_SMALL_INT(value);
+ if (MP_OBJ_FITS_SMALL_INT(value)) {
+ return MP_OBJ_NEW_SMALL_INT(value);
+ }
+ // TODO: Raise exception
+ assert(0);
+ return mp_const_none;
}
+#endif
diff --git a/py/objint.h b/py/objint.h
new file mode 100644
index 0000000000..7d43971ec3
--- /dev/null
+++ b/py/objint.h
@@ -0,0 +1,9 @@
+typedef struct _mp_obj_int_t {
+ mp_obj_base_t base;
+#if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE
+ mp_longint_impl_t val;
+#endif
+} mp_obj_int_t;
+
+void int_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind);
+mp_obj_t int_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in);
diff --git a/py/objlist.c b/py/objlist.c
index c153d2222b..829677b43b 100644
--- a/py/objlist.c
+++ b/py/objlist.c
@@ -26,14 +26,14 @@ static mp_obj_t list_extend(mp_obj_t self_in, mp_obj_t arg_in);
/******************************************************************************/
/* list */
-static void list_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in) {
+static void list_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in, mp_print_kind_t kind) {
mp_obj_list_t *o = o_in;
print(env, "[");
for (int i = 0; i < o->len; i++) {
if (i > 0) {
print(env, ", ");
}
- mp_obj_print_helper(print, env, o->items[i]);
+ mp_obj_print_helper(print, env, o->items[i], PRINT_REPR);
}
print(env, "]");
}
@@ -62,6 +62,61 @@ static mp_obj_t list_make_new(mp_obj_t type_in, int n_args, const mp_obj_t *args
return NULL;
}
+// Don't pass RT_COMPARE_OP_NOT_EQUAL here
+static bool list_cmp_helper(int op, mp_obj_t self_in, mp_obj_t another_in) {
+ assert(MP_OBJ_IS_TYPE(self_in, &list_type));
+ if (!MP_OBJ_IS_TYPE(another_in, &list_type)) {
+ return false;
+ }
+ mp_obj_list_t *self = self_in;
+ mp_obj_list_t *another = another_in;
+ if (op == RT_COMPARE_OP_EQUAL && self->len != another->len) {
+ return false;
+ }
+
+ // Let's deal only with > & >=
+ if (op == RT_COMPARE_OP_LESS || op == RT_COMPARE_OP_LESS_EQUAL) {
+ mp_obj_t t = self;
+ self = another;
+ another = t;
+ if (op == RT_COMPARE_OP_LESS) {
+ op = RT_COMPARE_OP_MORE;
+ } else {
+ op = RT_COMPARE_OP_MORE_EQUAL;
+ }
+ }
+
+ int len = self->len < another->len ? self->len : another->len;
+ bool eq_status = true; // empty lists are equal
+ bool rel_status;
+ for (int i = 0; i < len; i++) {
+ eq_status = mp_obj_equal(self->items[i], another->items[i]);
+ if (op == RT_COMPARE_OP_EQUAL && !eq_status) {
+ return false;
+ }
+ rel_status = (rt_binary_op(op, self->items[i], another->items[i]) == mp_const_true);
+ if (!eq_status && !rel_status) {
+ return false;
+ }
+ }
+
+ // If we had tie in the last element...
+ if (eq_status) {
+ // ... and we have lists of different lengths...
+ if (self->len != another->len) {
+ if (self->len < another->len) {
+ // ... then longer list length wins (we deal only with >)
+ return false;
+ }
+ } else if (op == RT_COMPARE_OP_MORE) {
+ // Otherwise, if we have strict relation, equality means failure
+ return false;
+ }
+ }
+
+ return true;
+}
+
static mp_obj_t list_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) {
mp_obj_list_t *o = lhs;
switch (op) {
@@ -105,6 +160,15 @@ static mp_obj_t list_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) {
}
return s;
}
+ case RT_COMPARE_OP_EQUAL:
+ case RT_COMPARE_OP_LESS:
+ case RT_COMPARE_OP_LESS_EQUAL:
+ case RT_COMPARE_OP_MORE:
+ case RT_COMPARE_OP_MORE_EQUAL:
+ return MP_BOOL(list_cmp_helper(op, lhs, rhs));
+ case RT_COMPARE_OP_NOT_EQUAL:
+ return MP_BOOL(!list_cmp_helper(RT_COMPARE_OP_EQUAL, lhs, rhs));
+
default:
// op not supported
return NULL;
@@ -184,13 +248,14 @@ static void mp_quicksort(mp_obj_t *head, mp_obj_t *tail, mp_obj_t key_fn, bool r
}
}
-static mp_obj_t list_sort(mp_obj_t args, mp_map_t *kwargs) {
+mp_obj_t mp_obj_list_sort(mp_obj_t args, mp_map_t *kwargs) {
mp_obj_t *args_items = NULL;
uint args_len = 0;
assert(MP_OBJ_IS_TYPE(args, &tuple_type));
mp_obj_tuple_get(args, &args_len, &args_items);
assert(args_len >= 1);
+ assert(MP_OBJ_IS_TYPE(args_items[0], &list_type));
if (args_len > 1) {
nlr_jump(mp_obj_new_exception_msg(MP_QSTR_TypeError,
"list.sort takes no positional arguments"));
@@ -316,7 +381,7 @@ static MP_DEFINE_CONST_FUN_OBJ_3(list_insert_obj, list_insert);
static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(list_pop_obj, 1, 2, list_pop);
static MP_DEFINE_CONST_FUN_OBJ_2(list_remove_obj, list_remove);
static MP_DEFINE_CONST_FUN_OBJ_1(list_reverse_obj, list_reverse);
-static MP_DEFINE_CONST_FUN_OBJ_KW(list_sort_obj, list_sort);
+static MP_DEFINE_CONST_FUN_OBJ_KW(list_sort_obj, 0, mp_obj_list_sort);
static const mp_method_t list_type_methods[] = {
{ "append", &list_append_obj },
diff --git a/py/objmap.c b/py/objmap.c
new file mode 100644
index 0000000000..365735283a
--- /dev/null
+++ b/py/objmap.c
@@ -0,0 +1,60 @@
+#include <stdlib.h>
+#include <assert.h>
+
+#include "nlr.h"
+#include "misc.h"
+#include "mpconfig.h"
+#include "mpqstr.h"
+#include "obj.h"
+#include "runtime.h"
+
+typedef struct _mp_obj_map_t {
+ mp_obj_base_t base;
+ machine_uint_t n_iters;
+ mp_obj_t fun;
+ mp_obj_t iters[];
+} mp_obj_map_t;
+
+static mp_obj_t map_make_new(mp_obj_t type_in, int n_args, const mp_obj_t *args) {
+ /* NOTE: args are backwards */
+ if (n_args < 2) {
+ nlr_jump(mp_obj_new_exception_msg(MP_QSTR_TypeError, "map must have at least 2 arguments"));
+ }
+ assert(n_args >= 2);
+ mp_obj_map_t *o = m_new_obj_var(mp_obj_map_t, mp_obj_t, n_args - 1);
+ o->base.type = &map_type;
+ o->n_iters = n_args - 1;
+ o->fun = args[n_args - 1];
+ for (int i = 0; i < n_args - 1; i++) {
+ o->iters[i] = rt_getiter(args[n_args-i-2]);
+ }
+ return o;
+}
+
+static mp_obj_t map_getiter(mp_obj_t self_in) {
+ return self_in;
+}
+
+static mp_obj_t map_iternext(mp_obj_t self_in) {
+ assert(MP_OBJ_IS_TYPE(self_in, &map_type));
+ mp_obj_map_t *self = self_in;
+ mp_obj_t *nextses = m_new(mp_obj_t, self->n_iters);
+
+ for (int i = 0; i < self->n_iters; i++) {
+ mp_obj_t next = rt_iternext(self->iters[i]);
+ if (next == mp_const_stop_iteration) {
+ m_del(mp_obj_t, nextses, self->n_iters);
+ return mp_const_stop_iteration;
+ }
+ nextses[i] = next;
+ }
+ return rt_call_function_n(self->fun, self->n_iters, nextses);
+}
+
+const mp_obj_type_t map_type = {
+ { &mp_const_type },
+ "map",
+ .make_new = map_make_new,
+ .getiter = map_getiter,
+ .iternext = map_iternext,
+};
diff --git a/py/objmodule.c b/py/objmodule.c
index ade9369176..50d2bb35ed 100644
--- a/py/objmodule.c
+++ b/py/objmodule.c
@@ -17,7 +17,7 @@ typedef struct _mp_obj_module_t {
mp_map_t *globals;
} mp_obj_module_t;
-static void module_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) {
+static void module_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
mp_obj_module_t *self = self_in;
print(env, "<module '%s' from '-unknown-file-'>", qstr_str(self->name));
}
diff --git a/py/objnone.c b/py/objnone.c
index c0efe6c0f5..84d0ba164c 100644
--- a/py/objnone.c
+++ b/py/objnone.c
@@ -10,7 +10,7 @@ typedef struct _mp_obj_none_t {
mp_obj_base_t base;
} mp_obj_none_t;
-void none_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) {
+void none_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
print(env, "None");
}
diff --git a/py/objset.c b/py/objset.c
index 67dab11dfb..6ea6d62d8f 100644
--- a/py/objset.c
+++ b/py/objset.c
@@ -1,5 +1,6 @@
#include <stdlib.h>
#include <stdint.h>
+#include <string.h>
#include <assert.h>
#include "nlr.h"
@@ -8,6 +9,7 @@
#include "mpqstr.h"
#include "obj.h"
#include "runtime.h"
+#include "runtime0.h"
#include "map.h"
typedef struct _mp_obj_set_t {
@@ -15,8 +17,20 @@ typedef struct _mp_obj_set_t {
mp_set_t set;
} mp_obj_set_t;
-void set_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) {
+typedef struct _mp_obj_set_it_t {
+ mp_obj_base_t base;
+ mp_obj_set_t *set;
+ machine_uint_t cur;
+} mp_obj_set_it_t;
+
+static mp_obj_t set_it_iternext(mp_obj_t self_in);
+
+void set_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
mp_obj_set_t *self = self_in;
+ if (self->set.used == 0) {
+ print(env, "set()");
+ return;
+ }
bool first = true;
print(env, "{");
for (int i = 0; i < self->set.alloc; i++) {
@@ -25,12 +39,13 @@ void set_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj
print(env, ", ");
}
first = false;
- mp_obj_print_helper(print, env, self->set.table[i]);
+ mp_obj_print_helper(print, env, self->set.table[i], PRINT_REPR);
}
}
print(env, "}");
}
+
static mp_obj_t set_make_new(mp_obj_t type_in, int n_args, const mp_obj_t *args) {
switch (n_args) {
case 0:
@@ -54,11 +69,389 @@ static mp_obj_t set_make_new(mp_obj_t type_in, int n_args, const mp_obj_t *args)
}
}
+const mp_obj_type_t set_it_type = {
+ { &mp_const_type },
+ "set_iterator",
+ .iternext = set_it_iternext,
+};
+
+static mp_obj_t set_it_iternext(mp_obj_t self_in) {
+ assert(MP_OBJ_IS_TYPE(self_in, &set_it_type));
+ mp_obj_set_it_t *self = self_in;
+ machine_uint_t max = self->set->set.alloc;
+ mp_obj_t *table = self->set->set.table;
+
+ for (machine_uint_t i = self->cur; i < max; i++) {
+ if (table[i] != NULL) {
+ self->cur = i + 1;
+ return table[i];
+ }
+ }
+
+ return mp_const_stop_iteration;
+}
+
+static mp_obj_t set_getiter(mp_obj_t set_in) {
+ mp_obj_set_it_t *o = m_new_obj(mp_obj_set_it_t);
+ o->base.type = &set_it_type;
+ o->set = (mp_obj_set_t *)set_in;
+ o->cur = 0;
+ return o;
+}
+
+
+/******************************************************************************/
+/* set methods */
+
+static mp_obj_t set_add(mp_obj_t self_in, mp_obj_t item) {
+ assert(MP_OBJ_IS_TYPE(self_in, &set_type));
+ mp_obj_set_t *self = self_in;
+ mp_set_lookup(&self->set, item, MP_MAP_LOOKUP_ADD_IF_NOT_FOUND);
+ return mp_const_none;
+}
+static MP_DEFINE_CONST_FUN_OBJ_2(set_add_obj, set_add);
+
+static mp_obj_t set_clear(mp_obj_t self_in) {
+ assert(MP_OBJ_IS_TYPE(self_in, &set_type));
+ mp_obj_set_t *self = self_in;
+
+ mp_set_clear(&self->set);
+
+ return mp_const_none;
+}
+static MP_DEFINE_CONST_FUN_OBJ_1(set_clear_obj, set_clear);
+
+static mp_obj_t set_copy(mp_obj_t self_in) {
+ assert(MP_OBJ_IS_TYPE(self_in, &set_type));
+ mp_obj_set_t *self = self_in;
+
+ mp_obj_set_t *other = m_new_obj(mp_obj_set_t);
+ other->base.type = &set_type;
+ mp_set_init(&other->set, self->set.alloc - 1);
+ other->set.used = self->set.used;
+ memcpy(other->set.table, self->set.table, self->set.alloc * sizeof(mp_obj_t));
+
+ return other;
+}
+static MP_DEFINE_CONST_FUN_OBJ_1(set_copy_obj, set_copy);
+
+static mp_obj_t set_discard(mp_obj_t self_in, mp_obj_t item) {
+ assert(MP_OBJ_IS_TYPE(self_in, &set_type));
+ mp_obj_set_t *self = self_in;
+ mp_set_lookup(&self->set, item, MP_MAP_LOOKUP_REMOVE_IF_FOUND);
+ return mp_const_none;
+}
+static MP_DEFINE_CONST_FUN_OBJ_2(set_discard_obj, set_discard);
+
+static mp_obj_t set_diff_int(int n_args, const mp_obj_t *args, bool update) {
+ assert(n_args > 0);
+ assert(MP_OBJ_IS_TYPE(args[0], &set_type));
+ mp_obj_set_t *self;
+ if (update) {
+ self = args[0];
+ } else {
+ self = set_copy(args[0]);
+ }
+
+
+ for (int i = 1; i < n_args; i++) {
+ mp_obj_t other = args[i];
+ if (self == other) {
+ set_clear(self);
+ } else {
+ mp_obj_t iter = rt_getiter(other);
+ mp_obj_t next;
+ while ((next = rt_iternext(iter)) != mp_const_stop_iteration) {
+ set_discard(self, next);
+ }
+ }
+ }
+
+ return self;
+}
+
+static mp_obj_t set_diff(int n_args, const mp_obj_t *args) {
+ return set_diff_int(n_args, args, false);
+}
+static MP_DEFINE_CONST_FUN_OBJ_VAR(set_diff_obj, 1, set_diff);
+
+static mp_obj_t set_diff_update(int n_args, const mp_obj_t *args) {
+ set_diff_int(n_args, args, true);
+ return mp_const_none;
+}
+static MP_DEFINE_CONST_FUN_OBJ_VAR(set_diff_update_obj, 1, set_diff_update);
+
+static mp_obj_t set_intersect_int(mp_obj_t self_in, mp_obj_t other, bool update) {
+ assert(MP_OBJ_IS_TYPE(self_in, &set_type));
+ if (self_in == other) {
+ return update ? mp_const_none : set_copy(self_in);
+ }
+
+ mp_obj_set_t *self = self_in;
+ mp_obj_set_t *out = mp_obj_new_set(0, NULL);
+
+ mp_obj_t iter = rt_getiter(other);
+ mp_obj_t next;
+ while ((next = rt_iternext(iter)) != mp_const_stop_iteration) {
+ if (mp_set_lookup(&self->set, next, MP_MAP_LOOKUP)) {
+ set_add(out, next);
+ }
+ }
+
+ if (update) {
+ m_del(mp_obj_t, self->set.table, self->set.alloc);
+ self->set.alloc = out->set.alloc;
+ self->set.used = out->set.used;
+ self->set.table = out->set.table;
+ }
+
+ return update ? mp_const_none : out;
+}
+
+static mp_obj_t set_intersect(mp_obj_t self_in, mp_obj_t other) {
+ return set_intersect_int(self_in, other, false);
+}
+static MP_DEFINE_CONST_FUN_OBJ_2(set_intersect_obj, set_intersect);
+
+static mp_obj_t set_intersect_update(mp_obj_t self_in, mp_obj_t other) {
+ return set_intersect_int(self_in, other, true);
+}
+static MP_DEFINE_CONST_FUN_OBJ_2(set_intersect_update_obj, set_intersect_update);
+
+static mp_obj_t set_isdisjoint(mp_obj_t self_in, mp_obj_t other) {
+ assert(MP_OBJ_IS_TYPE(self_in, &set_type));
+ mp_obj_set_t *self = self_in;
+
+ mp_obj_t iter = rt_getiter(other);
+ mp_obj_t next;
+ while ((next = rt_iternext(iter)) != mp_const_stop_iteration) {
+ if (mp_set_lookup(&self->set, next, MP_MAP_LOOKUP)) {
+ return mp_const_false;
+ }
+ }
+ return mp_const_true;
+}
+static MP_DEFINE_CONST_FUN_OBJ_2(set_isdisjoint_obj, set_isdisjoint);
+
+static mp_obj_t set_issubset_internal(mp_obj_t self_in, mp_obj_t other_in, bool proper) {
+ mp_obj_set_t *self;
+ bool cleanup_self = false;
+ if (MP_OBJ_IS_TYPE(self_in, &set_type)) {
+ self = self_in;
+ } else {
+ self = set_make_new(NULL, 1, &self_in);
+ cleanup_self = true;
+ }
+
+ mp_obj_set_t *other;
+ bool cleanup_other = false;
+ if (MP_OBJ_IS_TYPE(other_in, &set_type)) {
+ other = other_in;
+ } else {
+ other = set_make_new(NULL, 1, &other_in);
+ cleanup_other = true;
+ }
+ bool out = true;
+ if (proper && self->set.used == other->set.used) {
+ out = false;
+ } else {
+ mp_obj_t iter = set_getiter(self);
+ mp_obj_t next;
+ while ((next = set_it_iternext(iter)) != mp_const_stop_iteration) {
+ if (!mp_set_lookup(&other->set, next, MP_MAP_LOOKUP)) {
+ out = false;
+ break;
+ }
+ }
+ }
+ if (cleanup_self) {
+ set_clear(self);
+ }
+ if (cleanup_other) {
+ set_clear(other);
+ }
+ return MP_BOOL(out);
+}
+static mp_obj_t set_issubset(mp_obj_t self_in, mp_obj_t other_in) {
+ return set_issubset_internal(self_in, other_in, false);
+}
+static MP_DEFINE_CONST_FUN_OBJ_2(set_issubset_obj, set_issubset);
+
+static mp_obj_t set_issubset_proper(mp_obj_t self_in, mp_obj_t other_in) {
+ return set_issubset_internal(self_in, other_in, true);
+}
+
+static mp_obj_t set_issuperset(mp_obj_t self_in, mp_obj_t other_in) {
+ return set_issubset_internal(other_in, self_in, false);
+}
+static MP_DEFINE_CONST_FUN_OBJ_2(set_issuperset_obj, set_issuperset);
+
+static mp_obj_t set_issuperset_proper(mp_obj_t self_in, mp_obj_t other_in) {
+ return set_issubset_internal(other_in, self_in, true);
+}
+
+static mp_obj_t set_equal(mp_obj_t self_in, mp_obj_t other_in) {
+ assert(MP_OBJ_IS_TYPE(self_in, &set_type));
+ mp_obj_set_t *self = self_in;
+ if (!MP_OBJ_IS_TYPE(other_in, &set_type)) {
+ return mp_const_false;
+ }
+ mp_obj_set_t *other = other_in;
+ if (self->set.used != other->set.used) {
+ return mp_const_false;
+ }
+ return set_issubset(self_in, other_in);
+}
+
+static mp_obj_t set_pop(mp_obj_t self_in) {
+ assert(MP_OBJ_IS_TYPE(self_in, &set_type));
+ mp_obj_set_t *self = self_in;
+
+ if (self->set.used == 0) {
+ nlr_jump(mp_obj_new_exception_msg(MP_QSTR_KeyError, "pop from an empty set"));
+ }
+ mp_obj_t obj = mp_set_lookup(&self->set, NULL,
+ MP_MAP_LOOKUP_REMOVE_IF_FOUND | MP_MAP_LOOKUP_FIRST);
+ return obj;
+}
+static MP_DEFINE_CONST_FUN_OBJ_1(set_pop_obj, set_pop);
+
+static mp_obj_t set_remove(mp_obj_t self_in, mp_obj_t item) {
+ assert(MP_OBJ_IS_TYPE(self_in, &set_type));
+ mp_obj_set_t *self = self_in;
+ if (mp_set_lookup(&self->set, item, MP_MAP_LOOKUP_REMOVE_IF_FOUND) == MP_OBJ_NULL) {
+ nlr_jump(mp_obj_new_exception(MP_QSTR_KeyError));
+ }
+ return mp_const_none;
+}
+static MP_DEFINE_CONST_FUN_OBJ_2(set_remove_obj, set_remove);
+
+static mp_obj_t set_symmetric_difference_update(mp_obj_t self_in, mp_obj_t other_in) {
+ assert(MP_OBJ_IS_TYPE(self_in, &set_type));
+ mp_obj_set_t *self = self_in;
+ mp_obj_t iter = rt_getiter(other_in);
+ mp_obj_t next;
+ while ((next = rt_iternext(iter)) != mp_const_stop_iteration) {
+ mp_set_lookup(&self->set, next, MP_MAP_LOOKUP_REMOVE_IF_FOUND | MP_MAP_LOOKUP_ADD_IF_NOT_FOUND);
+ }
+ return mp_const_none;
+}
+static MP_DEFINE_CONST_FUN_OBJ_2(set_symmetric_difference_update_obj, set_symmetric_difference_update);
+
+static mp_obj_t set_symmetric_difference(mp_obj_t self_in, mp_obj_t other_in) {
+ assert(MP_OBJ_IS_TYPE(self_in, &set_type));
+ self_in = set_copy(self_in);
+ set_symmetric_difference_update(self_in, other_in);
+ return self_in;
+}
+static MP_DEFINE_CONST_FUN_OBJ_2(set_symmetric_difference_obj, set_symmetric_difference);
+
+static void set_update_int(mp_obj_set_t *self, mp_obj_t other_in) {
+ mp_obj_t iter = rt_getiter(other_in);
+ mp_obj_t next;
+ while ((next = rt_iternext(iter)) != mp_const_stop_iteration) {
+ mp_set_lookup(&self->set, next, MP_MAP_LOOKUP_ADD_IF_NOT_FOUND);
+ }
+}
+
+static mp_obj_t set_update(int n_args, const mp_obj_t *args) {
+ assert(n_args > 0);
+ assert(MP_OBJ_IS_TYPE(args[0], &set_type));
+
+ for (int i = 1; i < n_args; i++) {
+ set_update_int(args[0], args[i]);
+ }
+
+ return mp_const_none;
+}
+static MP_DEFINE_CONST_FUN_OBJ_VAR(set_update_obj, 1, set_update);
+
+static mp_obj_t set_union(mp_obj_t self_in, mp_obj_t other_in) {
+ assert(MP_OBJ_IS_TYPE(self_in, &set_type));
+ mp_obj_set_t *self = set_copy(self_in);
+ set_update_int(self, other_in);
+ return self;
+}
+static MP_DEFINE_CONST_FUN_OBJ_2(set_union_obj, set_union);
+
+
+static mp_obj_t set_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) {
+ mp_obj_t args[] = {lhs, rhs};
+ switch (op) {
+ case RT_BINARY_OP_OR:
+ return set_union(lhs, rhs);
+ case RT_BINARY_OP_XOR:
+ return set_symmetric_difference(lhs, rhs);
+ case RT_BINARY_OP_AND:
+ return set_intersect(lhs, rhs);
+ case RT_BINARY_OP_SUBTRACT:
+ return set_diff(2, args);
+ case RT_BINARY_OP_INPLACE_OR:
+ return set_union(lhs, rhs);
+ case RT_BINARY_OP_INPLACE_XOR:
+ return set_symmetric_difference(lhs, rhs);
+ case RT_BINARY_OP_INPLACE_AND:
+ return set_intersect(lhs, rhs);
+ case RT_BINARY_OP_INPLACE_SUBTRACT:
+ return set_diff(2, args);
+ case RT_COMPARE_OP_LESS:
+ return set_issubset_proper(lhs, rhs);
+ case RT_COMPARE_OP_MORE:
+ return set_issuperset_proper(lhs, rhs);
+ case RT_COMPARE_OP_EQUAL:
+ return set_equal(lhs, rhs);
+ case RT_COMPARE_OP_LESS_EQUAL:
+ return set_issubset(lhs, rhs);
+ case RT_COMPARE_OP_MORE_EQUAL:
+ return set_issuperset(lhs, rhs);
+ case RT_COMPARE_OP_NOT_EQUAL:
+ return MP_BOOL(set_equal(lhs, rhs) == mp_const_false);
+ case RT_COMPARE_OP_IN:
+ case RT_COMPARE_OP_NOT_IN:
+ {
+ mp_obj_set_t *o = lhs;
+ mp_obj_t elem = mp_set_lookup(&o->set, rhs, MP_MAP_LOOKUP);
+ return MP_BOOL((op == RT_COMPARE_OP_IN) ^ (elem == NULL));
+ }
+ default:
+ // op not supported
+ return NULL;
+ }
+}
+
+/******************************************************************************/
+/* set constructors & public C API */
+
+
+static const mp_method_t set_type_methods[] = {
+ { "add", &set_add_obj },
+ { "clear", &set_clear_obj },
+ { "copy", &set_copy_obj },
+ { "discard", &set_discard_obj },
+ { "difference", &set_diff_obj },
+ { "difference_update", &set_diff_update_obj },
+ { "intersection", &set_intersect_obj },
+ { "intersection_update", &set_intersect_update_obj },
+ { "isdisjoint", &set_isdisjoint_obj },
+ { "issubset", &set_issubset_obj },
+ { "issuperset", &set_issuperset_obj },
+ { "pop", &set_pop_obj },
+ { "remove", &set_remove_obj },
+ { "symmetric_difference", &set_symmetric_difference_obj },
+ { "symmetric_difference_update", &set_symmetric_difference_update_obj },
+ { "union", &set_union_obj },
+ { "update", &set_update_obj },
+ { NULL, NULL }, // end-of-list sentinel
+};
+
const mp_obj_type_t set_type = {
{ &mp_const_type },
"set",
.print = set_print,
.make_new = set_make_new,
+ .binary_op = set_binary_op,
+ .getiter = set_getiter,
+ .methods = set_type_methods,
};
mp_obj_t mp_obj_new_set(int n_args, mp_obj_t *items) {
@@ -66,7 +459,7 @@ mp_obj_t mp_obj_new_set(int n_args, mp_obj_t *items) {
o->base.type = &set_type;
mp_set_init(&o->set, n_args);
for (int i = 0; i < n_args; i++) {
- mp_set_lookup(&o->set, items[i], true);
+ mp_set_lookup(&o->set, items[i], MP_MAP_LOOKUP_ADD_IF_NOT_FOUND);
}
return o;
}
@@ -74,5 +467,5 @@ mp_obj_t mp_obj_new_set(int n_args, mp_obj_t *items) {
void mp_obj_set_store(mp_obj_t self_in, mp_obj_t item) {
assert(MP_OBJ_IS_TYPE(self_in, &set_type));
mp_obj_set_t *self = self_in;
- mp_set_lookup(&self->set, item, true);
+ mp_set_lookup(&self->set, item, MP_MAP_LOOKUP_ADD_IF_NOT_FOUND);
}
diff --git a/py/objslice.c b/py/objslice.c
index d95ccef06f..8abcea08d0 100644
--- a/py/objslice.c
+++ b/py/objslice.c
@@ -16,7 +16,7 @@ typedef struct _mp_obj_ellipsis_t {
mp_obj_base_t base;
} mp_obj_ellipsis_t;
-void ellipsis_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) {
+void ellipsis_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
print(env, "Ellipsis");
}
@@ -42,7 +42,7 @@ typedef struct _mp_obj_slice_t {
machine_int_t stop;
} mp_obj_slice_t;
-void slice_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in) {
+void slice_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in, mp_print_kind_t kind) {
mp_obj_slice_t *o = o_in;
print(env, "slice(" INT_FMT ", " INT_FMT ")", o->start, o->stop);
}
diff --git a/py/objstr.c b/py/objstr.c
index ea4f5ead24..0621a8df75 100644
--- a/py/objstr.c
+++ b/py/objstr.c
@@ -22,10 +22,14 @@ static mp_obj_t mp_obj_new_str_iterator(mp_obj_str_t *str, int cur);
/******************************************************************************/
/* str */
-void str_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) {
+void str_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
mp_obj_str_t *self = self_in;
- // TODO need to escape chars etc
- print(env, "'%s'", qstr_str(self->qstr));
+ if (kind == PRINT_STR) {
+ print(env, "%s", qstr_str(self->qstr));
+ } else {
+ // TODO need to escape chars etc
+ print(env, "'%s'", qstr_str(self->qstr));
+ }
}
mp_obj_t str_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
@@ -85,6 +89,15 @@ mp_obj_t str_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
return mp_obj_new_str(qstr_from_str_take(val, alloc_len));
}
break;
+ case RT_COMPARE_OP_IN:
+ case RT_COMPARE_OP_NOT_IN:
+ /* NOTE `a in b` is `b.__contains__(a)` */
+ if (MP_OBJ_IS_TYPE(rhs_in, &str_type)) {
+ const char *rhs_str = qstr_str(((mp_obj_str_t*)rhs_in)->qstr);
+ /* FIXME \0 in strs */
+ return MP_BOOL((op == RT_COMPARE_OP_IN) ^ (strstr(lhs_str, rhs_str) == NULL));
+ }
+ break;
}
return MP_OBJ_NULL; // op not supported
@@ -156,6 +169,46 @@ static bool chr_in_str(const char* const str, const size_t str_len, const char c
return false;
}
+static mp_obj_t str_find(int n_args, const mp_obj_t *args) {
+ assert(2 <= n_args && n_args <= 4);
+ assert(MP_OBJ_IS_TYPE(args[0], &str_type));
+ if (!MP_OBJ_IS_TYPE(args[1], &str_type)) {
+ nlr_jump(mp_obj_new_exception_msg_1_arg(
+ MP_QSTR_TypeError,
+ "Can't convert '%s' object to str implicitly",
+ mp_obj_get_type_str(args[1])));
+ }
+
+ const char* haystack = qstr_str(((mp_obj_str_t*)args[0])->qstr);
+ const char* needle = qstr_str(((mp_obj_str_t*)args[1])->qstr);
+
+ size_t haystack_len = strlen(haystack);
+ size_t needle_len = strlen(needle);
+
+ size_t start = 0;
+ size_t end = haystack_len;
+ /* TODO use a non-exception-throwing mp_get_index */
+ if (n_args >= 3 && args[2] != mp_const_none) {
+ start = mp_get_index(&str_type, haystack_len, args[2]);
+ }
+ if (n_args >= 4 && args[3] != mp_const_none) {
+ end = mp_get_index(&str_type, haystack_len, args[3]);
+ }
+
+ char *p = strstr(haystack + start, needle);
+ if (p == NULL) {
+ // not found
+ return MP_OBJ_NEW_SMALL_INT(-1);
+ } else {
+ // found
+ machine_int_t pos = p - haystack;
+ if (pos + needle_len > end) {
+ pos = -1;
+ }
+ return MP_OBJ_NEW_SMALL_INT(pos);
+ }
+}
+
mp_obj_t str_strip(int n_args, const mp_obj_t *args) {
assert(1 <= n_args && n_args <= 2);
assert(MP_OBJ_IS_TYPE(args[0], &str_type));
@@ -205,13 +258,6 @@ mp_obj_t str_strip(int n_args, const mp_obj_t *args) {
return mp_obj_new_str(qstr_from_str_take(stripped_str, stripped_len + 1));
}
-void vstr_printf_wrapper(void *env, const char *fmt, ...) {
- va_list args;
- va_start(args, fmt);
- vstr_vprintf(env, fmt, args);
- va_end(args);
-}
-
mp_obj_t str_format(int n_args, const mp_obj_t *args) {
assert(MP_OBJ_IS_TYPE(args[0], &str_type));
mp_obj_str_t *self = args[0];
@@ -228,7 +274,8 @@ mp_obj_t str_format(int n_args, const mp_obj_t *args) {
if (arg_i >= n_args) {
nlr_jump(mp_obj_new_exception_msg(MP_QSTR_IndexError, "tuple index out of range"));
}
- mp_obj_print_helper(vstr_printf_wrapper, vstr, args[arg_i]);
+ // TODO: may be PRINT_REPR depending on formatting code
+ mp_obj_print_helper((void (*)(void*, const char*, ...))vstr_printf, vstr, args[arg_i], PRINT_STR);
arg_i++;
}
} else {
@@ -239,11 +286,13 @@ mp_obj_t str_format(int n_args, const mp_obj_t *args) {
return mp_obj_new_str(qstr_from_str_take(vstr->buf, vstr->alloc));
}
+static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_find_obj, 2, 4, str_find);
static MP_DEFINE_CONST_FUN_OBJ_2(str_join_obj, str_join);
static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_strip_obj, 1, 2, str_strip);
static MP_DEFINE_CONST_FUN_OBJ_VAR(str_format_obj, 1, str_format);
static const mp_method_t str_type_methods[] = {
+ { "find", &str_find_obj },
{ "join", &str_join_obj },
{ "strip", &str_strip_obj },
{ "format", &str_format_obj },
diff --git a/py/objtuple.c b/py/objtuple.c
index 7685cc449f..a64b1fa16c 100644
--- a/py/objtuple.c
+++ b/py/objtuple.c
@@ -9,26 +9,21 @@
#include "obj.h"
#include "runtime0.h"
#include "runtime.h"
-
-typedef struct _mp_obj_tuple_t {
- mp_obj_base_t base;
- machine_uint_t len;
- mp_obj_t items[];
-} mp_obj_tuple_t;
+#include "objtuple.h"
static mp_obj_t mp_obj_new_tuple_iterator(mp_obj_tuple_t *tuple, int cur);
/******************************************************************************/
/* tuple */
-static void tuple_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in) {
+void tuple_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in, mp_print_kind_t kind) {
mp_obj_tuple_t *o = o_in;
print(env, "(");
for (int i = 0; i < o->len; i++) {
if (i > 0) {
print(env, ", ");
}
- mp_obj_print_helper(print, env, o->items[i]);
+ mp_obj_print_helper(print, env, o->items[i], PRINT_REPR);
}
if (o->len == 1) {
print(env, ",");
@@ -116,8 +111,10 @@ mp_obj_t mp_obj_new_tuple(uint n, const mp_obj_t *items) {
mp_obj_tuple_t *o = m_new_obj_var(mp_obj_tuple_t, mp_obj_t, n);
o->base.type = &tuple_type;
o->len = n;
- for (int i = 0; i < n; i++) {
- o->items[i] = items[i];
+ if (items) {
+ for (int i = 0; i < n; i++) {
+ o->items[i] = items[i];
+ }
}
return o;
}
@@ -138,8 +135,18 @@ mp_obj_t mp_obj_new_tuple_reverse(uint n, const mp_obj_t *items) {
void mp_obj_tuple_get(mp_obj_t self_in, uint *len, mp_obj_t **items) {
assert(MP_OBJ_IS_TYPE(self_in, &tuple_type));
mp_obj_tuple_t *self = self_in;
- *len = self->len;
- *items = &self->items[0];
+ if (len) {
+ *len = self->len;
+ }
+ if (items) {
+ *items = &self->items[0];
+ }
+}
+
+void mp_obj_tuple_del(mp_obj_t self_in) {
+ assert(MP_OBJ_IS_TYPE(self_in, &tuple_type));
+ mp_obj_tuple_t *self = self_in;
+ m_del_var(mp_obj_tuple_t, mp_obj_t, self->len, self);
}
/******************************************************************************/
diff --git a/py/objtuple.h b/py/objtuple.h
new file mode 100644
index 0000000000..6ff38c10eb
--- /dev/null
+++ b/py/objtuple.h
@@ -0,0 +1,7 @@
+typedef struct _mp_obj_tuple_t {
+ mp_obj_base_t base;
+ machine_uint_t len;
+ mp_obj_t items[];
+} mp_obj_tuple_t;
+
+void tuple_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in, mp_print_kind_t kind);
diff --git a/py/objtype.c b/py/objtype.c
index 011ee43552..5a2f96d6b0 100644
--- a/py/objtype.c
+++ b/py/objtype.c
@@ -66,7 +66,7 @@ static mp_map_elem_t *mp_obj_class_lookup(const mp_obj_type_t *type, qstr attr,
}
}
-static void class_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) {
+static void class_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
print(env, "<%s object at %p>", mp_obj_get_type_str(self_in), self_in);
}
@@ -148,7 +148,7 @@ static bool class_store_attr(mp_obj_t self_in, qstr attr, mp_obj_t value) {
// - there is a constant mp_obj_type_t (called mp_const_type) for the 'type' object
// - creating a new class (a new type) creates a new mp_obj_type_t
-static void type_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) {
+static void type_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
mp_obj_type_t *self = self_in;
print(env, "<class '%s'>", self->name);
}
diff --git a/py/objzip.c b/py/objzip.c
new file mode 100644
index 0000000000..a552ff5881
--- /dev/null
+++ b/py/objzip.c
@@ -0,0 +1,57 @@
+#include <stdlib.h>
+#include <assert.h>
+
+#include "misc.h"
+#include "mpconfig.h"
+#include "obj.h"
+#include "runtime.h"
+
+typedef struct _mp_obj_zip_t {
+ mp_obj_base_t base;
+ int n_iters;
+ mp_obj_t iters[];
+} mp_obj_zip_t;
+
+static mp_obj_t zip_make_new(mp_obj_t type_in, int n_args, const mp_obj_t *args) {
+ /* NOTE: args are backwards */
+ mp_obj_zip_t *o = m_new_obj_var(mp_obj_zip_t, mp_obj_t, n_args);
+ o->base.type = &zip_type;
+ o->n_iters = n_args;
+ for (int i = 0; i < n_args; i++) {
+ o->iters[i] = rt_getiter(args[n_args-i-1]);
+ }
+ return o;
+}
+
+static mp_obj_t zip_getiter(mp_obj_t self_in) {
+ return self_in;
+}
+
+static mp_obj_t zip_iternext(mp_obj_t self_in) {
+ assert(MP_OBJ_IS_TYPE(self_in, &zip_type));
+ mp_obj_zip_t *self = self_in;
+ mp_obj_t *items;
+ if (self->n_iters == 0) {
+ return mp_const_stop_iteration;
+ }
+ mp_obj_t o = mp_obj_new_tuple(self->n_iters, NULL);
+ mp_obj_tuple_get(o, NULL, &items);
+
+ for (int i = 0; i < self->n_iters; i++) {
+ mp_obj_t next = rt_iternext(self->iters[i]);
+ if (next == mp_const_stop_iteration) {
+ mp_obj_tuple_del(o);
+ return mp_const_stop_iteration;
+ }
+ items[i] = next;
+ }
+ return o;
+}
+
+const mp_obj_type_t zip_type = {
+ { &mp_const_type },
+ "zip",
+ .make_new = zip_make_new,
+ .getiter = zip_getiter,
+ .iternext = zip_iternext,
+};
diff --git a/py/parse.c b/py/parse.c
index d3786ba956..49b42e5d77 100644
--- a/py/parse.c
+++ b/py/parse.c
@@ -8,6 +8,7 @@
#include "misc.h"
#include "mpconfig.h"
+#include "mpqstr.h"
#include "lexer.h"
#include "parse.h"
@@ -88,6 +89,7 @@ typedef struct _parser_t {
uint rule_stack_top;
rule_stack_t *rule_stack;
+ uint result_stack_alloc;
uint result_stack_top;
mp_parse_node_t *result_stack;
} parser_t;
@@ -121,7 +123,7 @@ mp_parse_node_t mp_parse_node_new_leaf(machine_int_t kind, machine_int_t arg) {
int num_parse_nodes_allocated = 0;
mp_parse_node_struct_t *parse_node_new_struct(int rule_id, int num_args) {
- mp_parse_node_struct_t *pn = m_malloc(sizeof(mp_parse_node_struct_t) + num_args * sizeof(mp_parse_node_t));
+ mp_parse_node_struct_t *pn = m_new_obj_var(mp_parse_node_struct_t, mp_parse_node_t, num_args);
pn->source = 0; // TODO
pn->kind_num_nodes = (rule_id & 0xff) | (num_args << 8);
num_parse_nodes_allocated += 1;
@@ -180,6 +182,10 @@ static mp_parse_node_t peek_result(parser_t *parser, int pos) {
}
static void push_result_node(parser_t *parser, mp_parse_node_t pn) {
+ if (parser->result_stack_top >= parser->result_stack_alloc) {
+ parser->result_stack = m_renew(mp_parse_node_t, parser->result_stack, parser->result_stack_alloc, parser->result_stack_alloc * 2);
+ parser->result_stack_alloc *= 2;
+ }
parser->result_stack[parser->result_stack_top++] = pn;
}
@@ -191,7 +197,7 @@ static void push_result_token(parser_t *parser, const mp_lexer_t *lex) {
} else if (tok->kind == MP_TOKEN_NUMBER) {
bool dec = false;
bool small_int = true;
- int int_val = 0;
+ machine_int_t int_val = 0;
int len = tok->len;
const char *str = tok->str;
int base = 10;
@@ -211,7 +217,9 @@ static void push_result_token(parser_t *parser, const mp_lexer_t *lex) {
i = 2;
}
}
+ bool overflow = false;
for (; i < len; i++) {
+ machine_int_t old_val = int_val;
if (unichar_isdigit(str[i]) && str[i] - '0' < base) {
int_val = base * int_val + str[i] - '0';
} else if (base == 16 && 'a' <= str[i] && str[i] <= 'f') {
@@ -225,10 +233,17 @@ static void push_result_token(parser_t *parser, const mp_lexer_t *lex) {
small_int = false;
break;
}
+ if (int_val < old_val) {
+ // If new value became less than previous, it's overflow
+ overflow = true;
+ } else if ((old_val ^ int_val) & WORD_MSBIT_HIGH) {
+ // If signed number changed sign - it's overflow
+ overflow = true;
+ }
}
if (dec) {
pn = mp_parse_node_new_leaf(MP_PARSE_NODE_DECIMAL, qstr_from_strn_copy(str, len));
- } else if (small_int && MP_FIT_SMALL_INT(int_val)) {
+ } else if (small_int && !overflow && MP_FIT_SMALL_INT(int_val)) {
pn = mp_parse_node_new_leaf(MP_PARSE_NODE_SMALL_INT, int_val);
} else {
pn = mp_parse_node_new_leaf(MP_PARSE_NODE_INTEGER, qstr_from_strn_copy(str, len));
@@ -251,23 +266,31 @@ static void push_result_rule(parser_t *parser, const rule_t *rule, int num_args)
push_result_node(parser, (mp_parse_node_t)pn);
}
-mp_parse_node_t mp_parse(mp_lexer_t *lex, mp_parse_input_kind_t input_kind) {
- parser_t *parser = m_new(parser_t, 1);
+mp_parse_node_t mp_parse(mp_lexer_t *lex, mp_parse_input_kind_t input_kind, qstr *exc_id_out, const char **exc_msg_out) {
+
+ // allocate memory for the parser and its stacks
+
+ parser_t *parser = m_new_obj(parser_t);
+
parser->rule_stack_alloc = 64;
parser->rule_stack_top = 0;
parser->rule_stack = m_new(rule_stack_t, parser->rule_stack_alloc);
- parser->result_stack = m_new(mp_parse_node_t, 1000);
+ parser->result_stack_alloc = 64;
parser->result_stack_top = 0;
+ parser->result_stack = m_new(mp_parse_node_t, parser->result_stack_alloc);
+ // work out the top-level rule to use, and push it on the stack
int top_level_rule;
switch (input_kind) {
case MP_PARSE_SINGLE_INPUT: top_level_rule = RULE_single_input; break;
- //case MP_PARSE_EVAL_INPUT: top_level_rule = RULE_eval_input; break;
+ case MP_PARSE_EVAL_INPUT: top_level_rule = RULE_eval_input; break;
default: top_level_rule = RULE_file_input;
}
push_rule(parser, rules[top_level_rule], 0);
+ // parse!
+
uint n, i;
bool backtrack = false;
const rule_t *rule;
@@ -558,22 +581,39 @@ mp_parse_node_t mp_parse(mp_lexer_t *lex, mp_parse_input_kind_t input_kind) {
//printf("--------------\n");
//result_stack_show(parser);
- assert(parser->result_stack_top == 1);
- //printf("maximum depth: %d\n", parser->rule_stack_alloc);
+ //printf("rule stack alloc: %d\n", parser->rule_stack_alloc);
+ //printf("result stack alloc: %d\n", parser->result_stack_alloc);
//printf("number of parse nodes allocated: %d\n", num_parse_nodes_allocated);
- return parser->result_stack[0];
+
+ // get the root parse node that we created
+ assert(parser->result_stack_top == 1);
+ mp_parse_node_t result = parser->result_stack[0];
+
+finished:
+ // free the memory that we don't need anymore
+ m_del(rule_stack_t, parser->rule_stack, parser->rule_stack_alloc);
+ m_del(mp_parse_node_t, parser->result_stack, parser->result_stack_alloc);
+ m_del_obj(parser_t, parser);
+
+ // return the result
+ return result;
syntax_error:
if (mp_lexer_is_kind(lex, MP_TOKEN_INDENT)) {
- mp_lexer_show_error_pythonic(lex, "IndentationError: unexpected indent");
+ *exc_id_out = MP_QSTR_IndentationError;
+ *exc_msg_out = "unexpected indent";
} else if (mp_lexer_is_kind(lex, MP_TOKEN_DEDENT_MISMATCH)) {
- mp_lexer_show_error_pythonic(lex, "IndentationError: unindent does not match any outer indentation level");
+ *exc_id_out = MP_QSTR_IndentationError;
+ *exc_msg_out = "unindent does not match any outer indentation level";
} else {
- mp_lexer_show_error_pythonic(lex, "syntax error:");
+ *exc_id_out = MP_QSTR_SyntaxError;
+ *exc_msg_out = "invalid syntax";
#ifdef USE_RULE_NAME
- mp_lexer_show_error(lex, rule->rule_name);
-#endif
+ // debugging: print the rule name that failed and the token
+ mp_lexer_show_error_pythonic(lex, rule->rule_name);
mp_token_show(mp_lexer_cur(lex));
+#endif
}
- return MP_PARSE_NODE_NULL;
+ result = MP_PARSE_NODE_NULL;
+ goto finished;
}
diff --git a/py/parse.h b/py/parse.h
index 7326243ea4..be2073ae5d 100644
--- a/py/parse.h
+++ b/py/parse.h
@@ -62,4 +62,5 @@ typedef enum {
MP_PARSE_EVAL_INPUT,
} mp_parse_input_kind_t;
-mp_parse_node_t mp_parse(struct _mp_lexer_t *lex, mp_parse_input_kind_t input_kind);
+// returns MP_PARSE_NODE_NULL on error, and then exc_id_out and exc_msg_out are valid
+mp_parse_node_t mp_parse(struct _mp_lexer_t *lex, mp_parse_input_kind_t input_kind, qstr *exc_id_out, const char **exc_msg_out);
diff --git a/py/py.mk b/py/py.mk
index c65fb5e65a..61f14f7bb3 100644
--- a/py/py.mk
+++ b/py/py.mk
@@ -78,12 +78,15 @@ PY_O_BASENAME = \
objclosure.o \
objcomplex.o \
objdict.o \
+ objenumerate.o \
objexcept.o \
+ objfilter.o \
objfloat.o \
objfun.o \
objgenerator.o \
objint.o \
objlist.o \
+ objmap.o \
objmodule.o \
objnone.o \
objrange.o \
@@ -95,9 +98,11 @@ PY_O_BASENAME = \
stream.o \
builtin.o \
builtinimport.o \
+ builtineval.o \
vm.o \
showbc.o \
repl.o \
+ objzip.o \
# prepend the build destination prefix to the py object files
diff --git a/py/runtime.c b/py/runtime.c
index b982ee32d0..e1e9e31cc7 100644
--- a/py/runtime.c
+++ b/py/runtime.c
@@ -90,13 +90,14 @@ void rt_init(void) {
mp_map_add_qstr(&map_builtins, MP_QSTR_SyntaxError, mp_obj_new_exception(MP_QSTR_SyntaxError));
mp_map_add_qstr(&map_builtins, MP_QSTR_ValueError, mp_obj_new_exception(MP_QSTR_ValueError));
mp_map_add_qstr(&map_builtins, MP_QSTR_OSError, mp_obj_new_exception(MP_QSTR_OSError));
+ mp_map_add_qstr(&map_builtins, MP_QSTR_AssertionError, mp_obj_new_exception(MP_QSTR_AssertionError));
// built-in objects
mp_map_add_qstr(&map_builtins, MP_QSTR_Ellipsis, mp_const_ellipsis);
// built-in core functions
mp_map_add_qstr(&map_builtins, MP_QSTR___build_class__, (mp_obj_t)&mp_builtin___build_class___obj);
- mp_map_add_qstr(&map_builtins, MP_QSTR___repl_print__, rt_make_function_1(mp_builtin___repl_print__));
+ mp_map_add_qstr(&map_builtins, MP_QSTR___repl_print__, (mp_obj_t)&mp_builtin___repl_print___obj);
// built-in types
mp_map_add_qstr(&map_builtins, MP_QSTR_bool, (mp_obj_t)&bool_type);
@@ -104,35 +105,43 @@ void rt_init(void) {
mp_map_add_qstr(&map_builtins, MP_QSTR_complex, (mp_obj_t)&complex_type);
#endif
mp_map_add_qstr(&map_builtins, MP_QSTR_dict, (mp_obj_t)&dict_type);
+ mp_map_add_qstr(&map_builtins, MP_QSTR_enumerate, (mp_obj_t)&enumerate_type);
+ mp_map_add_qstr(&map_builtins, MP_QSTR_filter, (mp_obj_t)&filter_type);
#if MICROPY_ENABLE_FLOAT
mp_map_add_qstr(&map_builtins, MP_QSTR_float, (mp_obj_t)&float_type);
#endif
mp_map_add_qstr(&map_builtins, MP_QSTR_int, (mp_obj_t)&int_type);
mp_map_add_qstr(&map_builtins, MP_QSTR_list, (mp_obj_t)&list_type);
+ mp_map_add_qstr(&map_builtins, MP_QSTR_map, (mp_obj_t)&map_type);
mp_map_add_qstr(&map_builtins, MP_QSTR_set, (mp_obj_t)&set_type);
mp_map_add_qstr(&map_builtins, MP_QSTR_tuple, (mp_obj_t)&tuple_type);
mp_map_add_qstr(&map_builtins, MP_QSTR_type, (mp_obj_t)&mp_const_type);
-
- // built-in user functions; TODO covert all to &mp_builtin_xxx's
- mp_map_add_qstr(&map_builtins, MP_QSTR_abs, rt_make_function_1(mp_builtin_abs));
- mp_map_add_qstr(&map_builtins, MP_QSTR_all, rt_make_function_1(mp_builtin_all));
- mp_map_add_qstr(&map_builtins, MP_QSTR_any, rt_make_function_1(mp_builtin_any));
- mp_map_add_qstr(&map_builtins, MP_QSTR_callable, rt_make_function_1(mp_builtin_callable));
- mp_map_add_qstr(&map_builtins, MP_QSTR_chr, rt_make_function_1(mp_builtin_chr));
- mp_map_add_qstr(&map_builtins, MP_QSTR_divmod, rt_make_function_2(mp_builtin_divmod));
+ mp_map_add_qstr(&map_builtins, MP_QSTR_zip, (mp_obj_t)&zip_type);
+
+ // built-in user functions
+ mp_map_add_qstr(&map_builtins, MP_QSTR_abs, (mp_obj_t)&mp_builtin_abs_obj);
+ mp_map_add_qstr(&map_builtins, MP_QSTR_all, (mp_obj_t)&mp_builtin_all_obj);
+ mp_map_add_qstr(&map_builtins, MP_QSTR_any, (mp_obj_t)&mp_builtin_any_obj);
+ mp_map_add_qstr(&map_builtins, MP_QSTR_callable, (mp_obj_t)&mp_builtin_callable_obj);
+ mp_map_add_qstr(&map_builtins, MP_QSTR_chr, (mp_obj_t)&mp_builtin_chr_obj);
+ mp_map_add_qstr(&map_builtins, MP_QSTR_divmod, (mp_obj_t)&mp_builtin_divmod_obj);
+ mp_map_add_qstr(&map_builtins, MP_QSTR_eval, (mp_obj_t)&mp_builtin_eval_obj);
mp_map_add_qstr(&map_builtins, MP_QSTR_hash, (mp_obj_t)&mp_builtin_hash_obj);
mp_map_add_qstr(&map_builtins, MP_QSTR_isinstance, (mp_obj_t)&mp_builtin_isinstance_obj);
mp_map_add_qstr(&map_builtins, MP_QSTR_issubclass, (mp_obj_t)&mp_builtin_issubclass_obj);
mp_map_add_qstr(&map_builtins, MP_QSTR_iter, (mp_obj_t)&mp_builtin_iter_obj);
- mp_map_add_qstr(&map_builtins, MP_QSTR_len, rt_make_function_1(mp_builtin_len));
- mp_map_add_qstr(&map_builtins, MP_QSTR_max, rt_make_function_var(1, mp_builtin_max));
- mp_map_add_qstr(&map_builtins, MP_QSTR_min, rt_make_function_var(1, mp_builtin_min));
+ mp_map_add_qstr(&map_builtins, MP_QSTR_len, (mp_obj_t)&mp_builtin_len_obj);
+ mp_map_add_qstr(&map_builtins, MP_QSTR_max, (mp_obj_t)&mp_builtin_max_obj);
+ mp_map_add_qstr(&map_builtins, MP_QSTR_min, (mp_obj_t)&mp_builtin_min_obj);
mp_map_add_qstr(&map_builtins, MP_QSTR_next, (mp_obj_t)&mp_builtin_next_obj);
- mp_map_add_qstr(&map_builtins, MP_QSTR_ord, rt_make_function_1(mp_builtin_ord));
- mp_map_add_qstr(&map_builtins, MP_QSTR_pow, rt_make_function_var(2, mp_builtin_pow));
- mp_map_add_qstr(&map_builtins, MP_QSTR_print, rt_make_function_var(0, mp_builtin_print));
- mp_map_add_qstr(&map_builtins, MP_QSTR_range, rt_make_function_var(1, mp_builtin_range));
- mp_map_add_qstr(&map_builtins, MP_QSTR_sum, rt_make_function_var(1, mp_builtin_sum));
+ mp_map_add_qstr(&map_builtins, MP_QSTR_ord, (mp_obj_t)&mp_builtin_ord_obj);
+ mp_map_add_qstr(&map_builtins, MP_QSTR_pow, (mp_obj_t)&mp_builtin_pow_obj);
+ mp_map_add_qstr(&map_builtins, MP_QSTR_print, (mp_obj_t)&mp_builtin_print_obj);
+ mp_map_add_qstr(&map_builtins, MP_QSTR_range, (mp_obj_t)&mp_builtin_range_obj);
+ mp_map_add_qstr(&map_builtins, MP_QSTR_repr, (mp_obj_t)&mp_builtin_repr_obj);
+ mp_map_add_qstr(&map_builtins, MP_QSTR_sorted, (mp_obj_t)&mp_builtin_sorted_obj);
+ mp_map_add_qstr(&map_builtins, MP_QSTR_sum, (mp_obj_t)&mp_builtin_sum_obj);
+ mp_map_add_qstr(&map_builtins, MP_QSTR_str, (mp_obj_t)&mp_builtin_str_obj);
next_unique_code_id = 1; // 0 indicates "no code"
unique_codes_alloc = 0;
@@ -267,10 +276,6 @@ void rt_assign_inline_asm_code(int unique_code_id, void *fun, uint len, int n_ar
#endif
}
-static bool fit_small_int(mp_small_int_t o) {
- return true;
-}
-
int rt_is_true(mp_obj_t arg) {
DEBUG_OP_printf("is true %p\n", arg);
if (MP_OBJ_IS_SMALL_INT(arg)) {
@@ -435,13 +440,10 @@ mp_obj_t rt_unary_op(int op, mp_obj_t arg) {
case RT_UNARY_OP_INVERT: val = ~val; break;
default: assert(0); val = 0;
}
- if (fit_small_int(val)) {
+ if (MP_OBJ_FITS_SMALL_INT(val)) {
return MP_OBJ_NEW_SMALL_INT(val);
- } else {
- // TODO make a bignum
- assert(0);
- return mp_const_none;
}
+ return mp_obj_new_int(val);
} else { // will be an object (small ints are caught in previous if)
mp_obj_base_t *o = arg;
if (o->type->unary_op != NULL) {
@@ -467,6 +469,18 @@ mp_obj_t rt_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) {
// then fail
// note that list does not implement + or +=, so that inplace_concat is reached first for +=
+ // deal with is, is not
+ if (op == RT_COMPARE_OP_IS) {
+ // TODO: may need to handle strings specially, CPython appears to
+ // assume all strings are interned (so "is" == "==" for strings)
+ return MP_BOOL(lhs == rhs);
+ }
+ if (op == RT_COMPARE_OP_IS_NOT) {
+ // TODO: may need to handle strings specially, CPython appears to
+ // assume all strings are interned (so "is" == "==" for strings)
+ return MP_BOOL(lhs != rhs);
+ }
+
// deal with == and != for all types
if (op == RT_COMPARE_OP_EQUAL || op == RT_COMPARE_OP_NOT_EQUAL) {
if (mp_obj_equal(lhs, rhs)) {
@@ -550,32 +564,67 @@ mp_obj_t rt_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) {
default: assert(0);
}
- if (fit_small_int(lhs_val)) {
+ // TODO: We just should make mp_obj_new_int() inline and use that
+ if (MP_OBJ_FITS_SMALL_INT(lhs_val)) {
return MP_OBJ_NEW_SMALL_INT(lhs_val);
}
- // TODO: return long int
- assert(0);
+ return mp_obj_new_int(lhs_val);
} else if (MP_OBJ_IS_TYPE(rhs, &float_type)) {
return mp_obj_float_binary_op(op, lhs_val, rhs);
} else if (MP_OBJ_IS_TYPE(rhs, &complex_type)) {
return mp_obj_complex_binary_op(op, lhs_val, 0, rhs);
}
- } else {
- if (MP_OBJ_IS_OBJ(lhs)) {
- mp_obj_base_t *o = lhs;
+ }
+
+ /* deal with `in` and `not in`
+ *
+ * NOTE `a in b` is `b.__contains__(a)`, hence why the generic dispatch
+ * needs to go below
+ */
+ if (op == RT_COMPARE_OP_IN || op == RT_COMPARE_OP_NOT_IN) {
+ if (!MP_OBJ_IS_SMALL_INT(rhs)) {
+ mp_obj_base_t *o = rhs;
if (o->type->binary_op != NULL) {
- mp_obj_t result = o->type->binary_op(op, lhs, rhs);
- if (result != NULL) {
- return result;
+ mp_obj_t res = o->type->binary_op(op, rhs, lhs);
+ if (res != NULL) {
+ return res;
}
}
+ if (o->type->getiter != NULL) {
+ /* second attempt, walk the iterator */
+ mp_obj_t next = NULL;
+ mp_obj_t iter = rt_getiter(rhs);
+ while ((next = rt_iternext(iter)) != mp_const_stop_iteration) {
+ if (mp_obj_equal(next, lhs)) {
+ return MP_BOOL(op == RT_COMPARE_OP_IN);
+ }
+ }
+ return MP_BOOL(op != RT_COMPARE_OP_IN);
+ }
+ }
+
+ nlr_jump(mp_obj_new_exception_msg_varg(
+ MP_QSTR_TypeError, "'%s' object is not iterable",
+ mp_obj_get_type_str(rhs)));
+ return mp_const_none;
+ }
+
+ if (MP_OBJ_IS_OBJ(lhs)) {
+ mp_obj_base_t *o = lhs;
+ if (o->type->binary_op != NULL) {
+ mp_obj_t result = o->type->binary_op(op, lhs, rhs);
+ if (result != NULL) {
+ return result;
+ }
}
+ // TODO implement dispatch for reverse binary ops
}
// TODO specify in error message what the operator is
nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError,
"unsupported operand types for binary operator: '%s', '%s'",
mp_obj_get_type_str(lhs), mp_obj_get_type_str(rhs)));
+ return mp_const_none;
}
mp_obj_t rt_make_function_from_id(int unique_code_id) {
@@ -593,12 +642,7 @@ mp_obj_t rt_make_function_from_id(int unique_code_id) {
fun = mp_obj_new_fun_bc(c->n_args, c->n_locals + c->n_stack, c->u_byte.code);
break;
case MP_CODE_NATIVE:
- switch (c->n_args) {
- case 0: fun = rt_make_function_0(c->u_native.fun); break;
- case 1: fun = rt_make_function_1((mp_fun_1_t)c->u_native.fun); break;
- case 2: fun = rt_make_function_2((mp_fun_2_t)c->u_native.fun); break;
- default: assert(0); fun = mp_const_none;
- }
+ fun = rt_make_function_n(c->n_args, c->u_native.fun);
break;
case MP_CODE_INLINE_ASM:
fun = mp_obj_new_fun_asm(c->n_args, c->u_inline_asm.fun);
diff --git a/py/runtime.h b/py/runtime.h
index ac53e14110..32cb47684f 100644
--- a/py/runtime.h
+++ b/py/runtime.h
@@ -12,10 +12,8 @@ void rt_store_global(qstr qstr, mp_obj_t obj);
mp_obj_t rt_unary_op(int op, mp_obj_t arg);
mp_obj_t rt_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs);
mp_obj_t rt_make_function_from_id(int unique_code_id);
-mp_obj_t rt_make_function_0(mp_fun_0_t f);
-mp_obj_t rt_make_function_1(mp_fun_1_t f);
-mp_obj_t rt_make_function_2(mp_fun_2_t f);
-mp_obj_t rt_make_function_var(int n_args_min, mp_fun_var_t f);
+mp_obj_t rt_make_function_n(int n_args, void *fun); // fun must have the correct signature for n_args fixed arguments
+mp_obj_t rt_make_function_var(int n_args_min, mp_fun_var_t fun);
mp_obj_t rt_make_function_var_between(int n_args_min, int n_args_max, mp_fun_var_t fun); // min and max are inclusive
mp_obj_t rt_make_closure_from_id(int unique_code_id, mp_obj_t closure_tuple);
mp_obj_t rt_call_function_0(mp_obj_t fun);
diff --git a/py/stream.c b/py/stream.c
index f883efcd25..e70d365681 100644
--- a/py/stream.c
+++ b/py/stream.c
@@ -51,5 +51,91 @@ static mp_obj_t stream_write(mp_obj_t self_in, mp_obj_t arg) {
}
}
+// TODO: should be in mpconfig.h
+#define READ_SIZE 256
+static mp_obj_t stream_readall(mp_obj_t self_in) {
+ struct _mp_obj_base_t *o = (struct _mp_obj_base_t *)self_in;
+ if (o->type->stream_p.read == NULL) {
+ // CPython: io.UnsupportedOperation, OSError subclass
+ nlr_jump(mp_obj_new_exception_msg(MP_QSTR_OSError, "Operation not supported"));
+ }
+
+ int total_size = 0;
+ vstr_t *vstr = vstr_new_size(READ_SIZE);
+ char *buf = vstr_str(vstr);
+ char *p = buf;
+ int error;
+ int current_read = READ_SIZE;
+ while (true) {
+ machine_int_t out_sz = o->type->stream_p.read(self_in, p, current_read, &error);
+ if (out_sz == -1) {
+ nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_OSError, "[Errno %d]", error));
+ }
+ if (out_sz == 0) {
+ break;
+ }
+ total_size += out_sz;
+ if (out_sz < current_read) {
+ current_read -= out_sz;
+ p += out_sz;
+ } else {
+ current_read = READ_SIZE;
+ p = vstr_extend(vstr, current_read);
+ if (p == NULL) {
+ // TODO
+ nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_OSError/*MP_QSTR_RuntimeError*/, "Out of memory"));
+ }
+ }
+ }
+ vstr_set_size(vstr, total_size + 1); // TODO: for \0
+ buf[total_size] = 0;
+ return mp_obj_new_str(qstr_from_str_take(buf, total_size + 1));
+}
+
+// Unbuffered, inefficient implementation of readline() for raw I/O files.
+static mp_obj_t stream_unbuffered_readline(int n_args, const mp_obj_t *args) {
+ struct _mp_obj_base_t *o = (struct _mp_obj_base_t *)args[0];
+ if (o->type->stream_p.read == NULL) {
+ // CPython: io.UnsupportedOperation, OSError subclass
+ nlr_jump(mp_obj_new_exception_msg(MP_QSTR_OSError, "Operation not supported"));
+ }
+
+ machine_int_t max_size = -1;
+ if (n_args > 1) {
+ max_size = MP_OBJ_SMALL_INT_VALUE(args[1]);
+ }
+
+ vstr_t *vstr;
+ if (max_size != -1) {
+ vstr = vstr_new_size(max_size + 1); // TODO: \0
+ } else {
+ vstr = vstr_new();
+ }
+
+ int error;
+ while (max_size == -1 || max_size-- != 0) {
+ char *p = vstr_add_len(vstr, 1);
+ if (p == NULL) {
+ // TODO
+ nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_OSError/*MP_QSTR_RuntimeError*/, "Out of memory"));
+ }
+
+ machine_int_t out_sz = o->type->stream_p.read(o, p, 1, &error);
+ if (out_sz == -1) {
+ nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_OSError, "[Errno %d]", error));
+ }
+ if (out_sz == 0 || *p == '\n') {
+ break;
+ }
+ }
+ // TODO: \0
+ vstr_add_byte(vstr, 0);
+ vstr_shrink(vstr);
+ return mp_obj_new_str(qstr_from_str_take(vstr_str(vstr), vstr_len(vstr)));
+}
+
+
MP_DEFINE_CONST_FUN_OBJ_2(mp_stream_read_obj, stream_read);
+MP_DEFINE_CONST_FUN_OBJ_1(mp_stream_readall_obj, stream_readall);
+MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_stream_unbuffered_readline_obj, 1, 2, stream_unbuffered_readline);
MP_DEFINE_CONST_FUN_OBJ_2(mp_stream_write_obj, stream_write);
diff --git a/py/stream.h b/py/stream.h
index 8a579b7621..58e8072549 100644
--- a/py/stream.h
+++ b/py/stream.h
@@ -1,2 +1,4 @@
extern const mp_obj_fun_native_t mp_stream_read_obj;
+extern const mp_obj_fun_native_t mp_stream_readall_obj;
+extern const mp_obj_fun_native_t mp_stream_unbuffered_readline_obj;
extern const mp_obj_fun_native_t mp_stream_write_obj;
diff --git a/py/strtonum.c b/py/strtonum.c
index 109ea1123b..02c1506683 100644
--- a/py/strtonum.c
+++ b/py/strtonum.c
@@ -10,7 +10,6 @@
#include "nlr.h"
#include "obj.h"
-
long strtonum(const char *restrict s, int base) {
int c, neg = 0;
const char *p = s;
@@ -33,6 +32,7 @@ long strtonum(const char *restrict s, int base) {
}
// find real radix base, and strip preced '0x', '0o' and '0b'
+ // TODO somehow merge with similar code in parse.c
if ((base == 0 || base == 16) && c == '0') {
c = *(p++);
if ((c | 32) == 'x') {
diff --git a/py/strtonum.h b/py/strtonum.h
deleted file mode 100644
index 03565cca14..0000000000
--- a/py/strtonum.h
+++ /dev/null
@@ -1 +0,0 @@
-long strtonum(const char *restrict s, int base);
diff --git a/py/vm.c b/py/vm.c
index baef6988c5..5c74b43caa 100644
--- a/py/vm.c
+++ b/py/vm.c
@@ -440,10 +440,17 @@ bool mp_execute_byte_code_2(const byte **ip_in_out, mp_obj_t *fastn, mp_obj_t **
case MP_BC_CALL_FUNCTION:
DECODE_UINT;
- assert((unum & 0xff00) == 0); // n_keyword
- unum &= 0xff; // n_positional
- sp += unum;
- *sp = rt_call_function_n(*sp, unum, sp - unum);
+ if ((unum & 0xff00) == 0) {
+ // no keywords
+ unum &= 0xff; // n_positional
+ sp += unum;
+ *sp = rt_call_function_n(*sp, unum, sp - unum);
+ } else {
+ // keywords
+ int argsize = (unum & 0xff) + ((unum >> 7) & 0x1fe);
+ sp += argsize;
+ *sp = rt_call_function_n_kw(*sp, unum & 0xff, (unum >> 8) & 0xff, sp - argsize);
+ }
break;
case MP_BC_CALL_METHOD:
diff --git a/py/vstr.c b/py/vstr.c
index 80841b24ca..18e6d2d0a8 100644
--- a/py/vstr.c
+++ b/py/vstr.c
@@ -6,8 +6,8 @@
// returned value is always at least 1 greater than argument
#define ROUND_ALLOC(a) (((a) & ((~0) - 7)) + 8)
-void vstr_init(vstr_t *vstr) {
- vstr->alloc = 32;
+void vstr_init(vstr_t *vstr, int alloc) {
+ vstr->alloc = alloc;
vstr->len = 0;
vstr->buf = m_new(char, vstr->alloc);
if (vstr->buf == NULL) {
@@ -28,7 +28,16 @@ vstr_t *vstr_new(void) {
if (vstr == NULL) {
return NULL;
}
- vstr_init(vstr);
+ vstr_init(vstr, 32);
+ return vstr;
+}
+
+vstr_t *vstr_new_size(int alloc) {
+ vstr_t *vstr = m_new(vstr_t, 1);
+ if (vstr == NULL) {
+ return NULL;
+ }
+ vstr_init(vstr, alloc);
return vstr;
}
@@ -63,6 +72,36 @@ int vstr_len(vstr_t *vstr) {
return vstr->len;
}
+// Extend vstr strictly to by requested size, return pointer to newly added chunk
+char *vstr_extend(vstr_t *vstr, int size) {
+ char *new_buf = m_renew(char, vstr->buf, vstr->alloc, vstr->alloc + size);
+ if (new_buf == NULL) {
+ vstr->had_error = true;
+ return NULL;
+ }
+ char *p = new_buf + vstr->alloc;
+ vstr->alloc += size;
+ vstr->buf = new_buf;
+ return p;
+}
+
+// Shrink vstr to be given size
+bool vstr_set_size(vstr_t *vstr, int size) {
+ char *new_buf = m_renew(char, vstr->buf, vstr->alloc, size);
+ if (new_buf == NULL) {
+ vstr->had_error = true;
+ return false;
+ }
+ vstr->buf = new_buf;
+ vstr->alloc = vstr->len = size;
+ return true;
+}
+
+// Shrink vstr allocation to its actual length
+bool vstr_shrink(vstr_t *vstr) {
+ return vstr_set_size(vstr, vstr->len);
+}
+
bool vstr_ensure_extra(vstr_t *vstr, int size) {
if (vstr->len + size + 1 > vstr->alloc) {
int new_alloc = ROUND_ALLOC((vstr->len + size + 1) * 2);
diff --git a/stm/Makefile b/stm/Makefile
index 2fecd03bad..d4dbd960a6 100644
--- a/stm/Makefile
+++ b/stm/Makefile
@@ -33,6 +33,7 @@ CFLAGS += -Os -DNDEBUG
endif
LDFLAGS = --nostdlib -T stm32f405.ld
+LIBS = $(shell $(CC) -print-libgcc-file-name)
SRC_C = \
main.c \
@@ -57,6 +58,7 @@ SRC_C = \
pybwlan.c \
i2c.c \
usrsw.c \
+ adc.c \
SRC_S = \
startup_stm32f40xx.s \
@@ -100,11 +102,20 @@ SRC_STM = \
usbd_storage_msd.c \
stm324x7i_eval.c \
stm324x7i_eval_sdio_sd.c \
+ stm32f4xx_adc.c \
#SRC_STM_OTG = \
# usb_hcd.c \
# usb_hcd_int.c \
# usb_otg.c \
+# usbh_core.c \
+# usbh_hcs.c \
+# usbh_stdreq.c \
+# usbh_ioreq.c \
+# usbh_usr.c \
+# usbh_hid_core.c \
+# usbh_hid_mouse.c \
+# usbh_hid_keybd.c \
SRC_CC3K = \
cc3000_common.c \
@@ -135,7 +146,7 @@ $(BUILD)/flash1.bin: $(BUILD)/flash.elf
$(BUILD)/flash.elf: $(OBJ)
$(ECHO) "LINK $@"
- $(Q)$(LD) $(LDFLAGS) -o $@ $(OBJ)
+ $(Q)$(LD) $(LDFLAGS) -o $@ $(OBJ) $(LIBS)
$(Q)$(SIZE) $@
$(BUILD)/%.o: %.s
diff --git a/stm/adc.c b/stm/adc.c
new file mode 100644
index 0000000000..1f666c2718
--- /dev/null
+++ b/stm/adc.c
@@ -0,0 +1,304 @@
+#include <stdio.h>
+#include <stm32f4xx_rcc.h>
+#include <stm32f4xx_gpio.h>
+#include <stm32f4xx_adc.h>
+
+#include "misc.h"
+#include "mpconfig.h"
+#include "obj.h"
+#include "adc.h"
+
+/* ADC defintions */
+#define ADCx (ADC1)
+#define ADCx_CLK (RCC_APB2Periph_ADC1)
+#define ADC_NUM_CHANNELS (16)
+
+/* Internally connected ADC channels Temp/VBAT/VREF*/
+#if defined (STM32F40XX) || defined(STM32F41XX)
+#define ADC_TEMP_CHANNEL (16)
+#define ADC_VBAT_CHANNEL (18)
+#define ADC_VREF_CHANNEL (17)
+#elif defined (STM32F42XX) || defined(STM32F43XX)
+#define ADC_TEMP_CHANNEL (18)
+#define ADC_VBAT_CHANNEL (18) /* same channel as TEMP */
+#define ADC_VREF_CHANNEL (17)
+#endif
+
+/* Core temperature sensor definitions */
+#define CORE_TEMP_V25 (943) /* (0.76v/3.3v)*(2^ADC resoultion) */
+#define CORE_TEMP_AVG_SLOPE (3) /* (2.5mv/3.3v)*(2^ADC resoultion) */
+
+/* VBAT divider */
+#if defined (STM32F40XX) || defined(STM32F41XX)
+#define VBAT_DIV (2)
+#elif defined (STM32F42XX) || defined(STM32F43XX)
+#define VBAT_DIV (4)
+#endif
+
+/* GPIO struct */
+typedef struct {
+ GPIO_TypeDef* port;
+ uint32_t pin;
+} gpio_t;
+
+/* ADC GPIOs */
+static gpio_t adc_gpio[] = {
+ {GPIOA, GPIO_Pin_0}, /* ADC123_IN0 */
+ {GPIOA, GPIO_Pin_1}, /* ADC123_IN1 */
+ {GPIOA, GPIO_Pin_2}, /* ADC123_IN2 */
+ {GPIOA, GPIO_Pin_3}, /* ADC123_IN3 */
+ {GPIOA, GPIO_Pin_4}, /* ADC12_IN4 */
+ {GPIOA, GPIO_Pin_5}, /* ADC12_IN5 */
+ {GPIOA, GPIO_Pin_6}, /* ADC12_IN6 */
+ {GPIOA, GPIO_Pin_7}, /* ADC12_IN7 */
+ {GPIOB, GPIO_Pin_0}, /* ADC12_IN8 */
+ {GPIOB, GPIO_Pin_1}, /* ADC12_IN9 */
+ {GPIOC, GPIO_Pin_0}, /* ADC123_IN10 */
+ {GPIOC, GPIO_Pin_1}, /* ADC123_IN11 */
+ {GPIOC, GPIO_Pin_2}, /* ADC123_IN12 */
+ {GPIOC, GPIO_Pin_3}, /* ADC123_IN13 */
+ {GPIOC, GPIO_Pin_4}, /* ADC12_IN14 */
+ {GPIOC, GPIO_Pin_5}, /* ADC12_IN15 */
+
+};
+
+void adc_init(uint32_t resolution) {
+ ADC_InitTypeDef ADC_InitStructure;
+ GPIO_InitTypeDef GPIO_InitStructure;
+ ADC_CommonInitTypeDef ADC_CommonInitStructure;
+
+ /* Enable ADCx, DMA and GPIO clocks */
+#if 0
+ /* GPIO clocks enabled in main */
+ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA |
+ RCC_AHB1Periph_GPIOB |
+ RCC_AHB1Periph_GPIOC, ENABLE);
+#endif
+ RCC_APB2PeriphClockCmd(ADCx_CLK, ENABLE);
+
+ /* ADC Common Init */
+ ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
+ ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
+ ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
+ ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
+ ADC_CommonInit(&ADC_CommonInitStructure);
+
+ /* Configure ADC GPIOs */
+ for (int i=0; i<ADC_NUM_CHANNELS; i++) {
+ GPIO_InitStructure.GPIO_Pin = adc_gpio[i].pin;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
+ GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
+ GPIO_Init(adc_gpio[i].port, &GPIO_InitStructure);
+ }
+
+ /* ADCx Init */
+// ADC_DeInit();
+ ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
+ ADC_InitStructure.ADC_ScanConvMode = DISABLE;
+ ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
+ ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
+ ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
+ ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
+ ADC_InitStructure.ADC_NbrOfConversion = 1;
+ ADC_Init(ADCx, &ADC_InitStructure);
+
+ /* Enable ADCx */
+ ADC_Cmd(ADCx, ENABLE);
+
+ /* Enable VBAT/VREF monitor */
+ ADC_VBATCmd(ENABLE);
+
+ /* Enable temperature sensor */
+ ADC_TempSensorVrefintCmd(ENABLE);
+}
+
+uint32_t adc_read_channel(int channel)
+{
+ int timeout = 10000;
+
+ if (channel > (ADC_NUM_CHANNELS-1)) {
+ return 0;
+ }
+
+ /* ADC regular channel config ADC/Channel/SEQ Rank/Sample time */
+ ADC_RegularChannelConfig(ADCx, channel, 1, ADC_SampleTime_15Cycles);
+
+ /* Start ADC single conversion */
+ ADC_SoftwareStartConv(ADCx);
+
+ /* Wait for conversion to be complete*/
+ while(!ADC_GetFlagStatus(ADCx, ADC_FLAG_EOC) && --timeout >0) {
+ }
+
+ /* ADC conversion timed out */
+ if (timeout == 0) {
+ return 0;
+ }
+
+ /* Return converted data */
+ return ADC_GetConversionValue(ADCx);
+}
+
+int adc_read_core_temp()
+{
+ int timeout = 10000;
+
+ /* ADC temperature sensor channel config ADC/Channel/SEQ Rank/Sample time */
+ /* Note: sample time must be higher than minimum sample time */
+ ADC_RegularChannelConfig(ADCx, ADC_TEMP_CHANNEL, 1, ADC_SampleTime_480Cycles);
+
+ /* Start ADC single conversion */
+ ADC_SoftwareStartConv(ADCx);
+
+ /* Wait for conversion to be complete*/
+ while(!ADC_GetFlagStatus(ADCx, ADC_FLAG_EOC) && --timeout >0) {
+ }
+
+ /* ADC conversion timed out */
+ if (timeout == 0) {
+ return 0;
+ }
+
+ /* Convert ADC reading to temperature */
+ /* Temperature formula from datasheet P.411 */
+ return ((ADC_GetConversionValue(ADCx) - CORE_TEMP_V25) / CORE_TEMP_AVG_SLOPE) + 25;
+}
+
+float adc_read_core_vbat()
+{
+ int timeout = 10000;
+
+ /* ADC VBAT channel config ADC/Channel/SEQ Rank/Sample time */
+ /* Note: sample time must be higher than minimum sample time */
+ ADC_RegularChannelConfig(ADCx, ADC_VBAT_CHANNEL, 1, ADC_SampleTime_144Cycles);
+
+ /* Start ADC single conversion */
+ ADC_SoftwareStartConv(ADCx);
+
+ /* Wait for conversion to be complete */
+ while(!ADC_GetFlagStatus(ADCx, ADC_FLAG_EOC) && --timeout >0) {
+ }
+
+ /* ADC conversion timed out */
+ if (timeout == 0) {
+ return 0;
+ }
+
+ /* Convert ADC reading to voltage, VBAT pin is
+ internally connected to a bridge divider by VBAT_DIV */
+ return ADC_GetConversionValue(ADCx)*VBAT_DIV/4096.0f*3.3f;
+}
+
+float adc_read_core_vref()
+{
+ int timeout = 10000;
+
+ /* ADC VBAT channel config ADC/Channel/SEQ Rank/Sample time */
+ /* Note: sample time must be higher than minimum sample time */
+ ADC_RegularChannelConfig(ADCx, ADC_VREF_CHANNEL, 1, ADC_SampleTime_112Cycles);
+
+ /* Start ADC single conversion */
+ ADC_SoftwareStartConv(ADCx);
+
+ /* Wait for conversion to be complete*/
+ while(!ADC_GetFlagStatus(ADCx, ADC_FLAG_EOC) && --timeout >0) {
+ }
+
+ /* ADC conversion timed out */
+ if (timeout == 0) {
+ return 0;
+ }
+
+ /* Convert ADC reading to voltage */
+ return ADC_GetConversionValue(ADCx)/4096.0f*3.3f;
+}
+
+/******************************************************************************/
+/* Micro Python bindings */
+
+typedef struct _pyb_adc_obj_t {
+ mp_obj_base_t base;
+ int adc_id;
+ bool is_enabled;
+} pyb_adc_obj_t;
+
+static mp_obj_t adc_obj_read_channel(mp_obj_t self_in, mp_obj_t channel) {
+ mp_obj_t ret = mp_const_none;
+ pyb_adc_obj_t *self = self_in;
+
+ if (self->is_enabled) {
+ uint32_t chan = mp_obj_get_int(channel);
+ uint32_t data = adc_read_channel(chan);
+ ret = mp_obj_new_int(data);
+ }
+ return ret;
+}
+
+static mp_obj_t adc_obj_read_core_temp(mp_obj_t self_in) {
+ mp_obj_t ret = mp_const_none;
+ pyb_adc_obj_t *self = self_in;
+
+ if (self->is_enabled) {
+ int data = adc_read_core_temp();
+ ret = mp_obj_new_int(data);
+ }
+ return ret;
+}
+
+static mp_obj_t adc_obj_read_core_vbat(mp_obj_t self_in) {
+ mp_obj_t ret = mp_const_none;
+ pyb_adc_obj_t *self = self_in;
+
+ if (self->is_enabled) {
+ float data = adc_read_core_vbat();
+ ret = mp_obj_new_float(data);
+ }
+ return ret;
+}
+
+static mp_obj_t adc_obj_read_core_vref(mp_obj_t self_in) {
+ mp_obj_t ret = mp_const_none;
+ pyb_adc_obj_t *self = self_in;
+
+ if (self->is_enabled) {
+ float data = adc_read_core_vref();
+ ret = mp_obj_new_float(data);
+ }
+ return ret;
+}
+
+static void adc_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) {
+ pyb_adc_obj_t *self = self_in;
+ print(env, "<ADC %lu>", self->adc_id);
+}
+
+static MP_DEFINE_CONST_FUN_OBJ_2(adc_obj_read_channel_obj, adc_obj_read_channel);
+static MP_DEFINE_CONST_FUN_OBJ_1(adc_obj_read_core_temp_obj, adc_obj_read_core_temp);
+static MP_DEFINE_CONST_FUN_OBJ_1(adc_obj_read_core_vbat_obj, adc_obj_read_core_vbat);
+static MP_DEFINE_CONST_FUN_OBJ_1(adc_obj_read_core_vref_obj, adc_obj_read_core_vref);
+
+static const mp_method_t adc_methods[] = {
+ { "read_channel", &adc_obj_read_channel_obj},
+ { "read_core_temp", &adc_obj_read_core_temp_obj},
+ { "read_core_vbat", &adc_obj_read_core_vbat_obj},
+ { "read_core_vref", &adc_obj_read_core_vref_obj},
+ { NULL, NULL },
+};
+
+static const mp_obj_type_t adc_obj_type = {
+ { &mp_const_type },
+ "ADC",
+ .print = adc_obj_print,
+ .methods = adc_methods,
+};
+
+mp_obj_t pyb_ADC(mp_obj_t resolution) {
+ /* init ADC */
+ adc_init(mp_obj_get_int(resolution));
+
+ pyb_adc_obj_t *o = m_new_obj(pyb_adc_obj_t);
+ o->base.type = &adc_obj_type;
+ o->adc_id = 1;
+ o->is_enabled = true;
+ return o;
+}
diff --git a/stm/adc.h b/stm/adc.h
new file mode 100644
index 0000000000..5805aef42c
--- /dev/null
+++ b/stm/adc.h
@@ -0,0 +1 @@
+mp_obj_t pyb_ADC(mp_obj_t resolution);
diff --git a/stm/audio.c b/stm/audio.c
index 34adefbcd6..e2aa32b9fc 100644
--- a/stm/audio.c
+++ b/stm/audio.c
@@ -91,8 +91,8 @@ void audio_init(void) {
// Python interface
mp_obj_t m = mp_obj_new_module(qstr_from_str_static("audio"));
- rt_store_attr(m, qstr_from_str_static("dac"), rt_make_function_1(pyb_audio_dac));
- rt_store_attr(m, qstr_from_str_static("is_full"), rt_make_function_0(pyb_audio_is_full));
- rt_store_attr(m, qstr_from_str_static("fill"), rt_make_function_1(pyb_audio_fill));
+ rt_store_attr(m, qstr_from_str_static("dac"), rt_make_function_n(1, pyb_audio_dac));
+ rt_store_attr(m, qstr_from_str_static("is_full"), rt_make_function_n(0, pyb_audio_is_full));
+ rt_store_attr(m, qstr_from_str_static("fill"), rt_make_function_n(1, pyb_audio_fill));
rt_store_name(qstr_from_str_static("audio"), m);
}
diff --git a/stm/lcd.c b/stm/lcd.c
index 70d1a26423..82e42b779d 100644
--- a/stm/lcd.c
+++ b/stm/lcd.c
@@ -220,13 +220,13 @@ void lcd_init(void) {
// Python interface
mp_obj_t m = mp_obj_new_module(qstr_from_str_static("lcd"));
- rt_store_attr(m, qstr_from_str_static("lcd8"), rt_make_function_2(lcd_draw_pixel_8));
- rt_store_attr(m, qstr_from_str_static("clear"), rt_make_function_0(lcd_pix_clear));
- rt_store_attr(m, qstr_from_str_static("get"), rt_make_function_2(lcd_pix_get));
- rt_store_attr(m, qstr_from_str_static("set"), rt_make_function_2(lcd_pix_set));
- rt_store_attr(m, qstr_from_str_static("reset"), rt_make_function_2(lcd_pix_reset));
- rt_store_attr(m, qstr_from_str_static("show"), rt_make_function_0(lcd_pix_show));
- rt_store_attr(m, qstr_from_str_static("text"), rt_make_function_1(lcd_print));
+ rt_store_attr(m, qstr_from_str_static("lcd8"), rt_make_function_n(2, lcd_draw_pixel_8));
+ rt_store_attr(m, qstr_from_str_static("clear"), rt_make_function_n(0, lcd_pix_clear));
+ rt_store_attr(m, qstr_from_str_static("get"), rt_make_function_n(2, lcd_pix_get));
+ rt_store_attr(m, qstr_from_str_static("set"), rt_make_function_n(2, lcd_pix_set));
+ rt_store_attr(m, qstr_from_str_static("reset"), rt_make_function_n(2, lcd_pix_reset));
+ rt_store_attr(m, qstr_from_str_static("show"), rt_make_function_n(0, lcd_pix_show));
+ rt_store_attr(m, qstr_from_str_static("text"), rt_make_function_n(1, lcd_print));
rt_store_name(qstr_from_str_static("lcd"), m);
}
diff --git a/stm/lib/stm32f4xx_adc.c b/stm/lib/stm32f4xx_adc.c
new file mode 100644
index 0000000000..eacc6b51f1
--- /dev/null
+++ b/stm/lib/stm32f4xx_adc.c
@@ -0,0 +1,1746 @@
+/**
+ ******************************************************************************
+ * @file stm32f4xx_adc.c
+ * @author MCD Application Team
+ * @version V1.3.0
+ * @date 08-November-2013
+ * @brief This file provides firmware functions to manage the following
+ * functionalities of the Analog to Digital Convertor (ADC) peripheral:
+ * + Initialization and Configuration (in addition to ADC multi mode
+ * selection)
+ * + Analog Watchdog configuration
+ * + Temperature Sensor & Vrefint (Voltage Reference internal) & VBAT
+ * management
+ * + Regular Channels Configuration
+ * + Regular Channels DMA Configuration
+ * + Injected channels Configuration
+ * + Interrupts and flags management
+ *
+ @verbatim
+ ===============================================================================
+ ##### How to use this driver #####
+ ===============================================================================
+ [..]
+ (#) Enable the ADC interface clock using
+ RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADCx, ENABLE);
+
+ (#) ADC pins configuration
+ (++) Enable the clock for the ADC GPIOs using the following function:
+ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOx, ENABLE);
+ (++) Configure these ADC pins in analog mode using GPIO_Init();
+
+ (#) Configure the ADC Prescaler, conversion resolution and data
+ alignment using the ADC_Init() function.
+ (#) Activate the ADC peripheral using ADC_Cmd() function.
+
+ *** Regular channels group configuration ***
+ ============================================
+ [..]
+ (+) To configure the ADC regular channels group features, use
+ ADC_Init() and ADC_RegularChannelConfig() functions.
+ (+) To activate the continuous mode, use the ADC_continuousModeCmd()
+ function.
+ (+) To configurate and activate the Discontinuous mode, use the
+ ADC_DiscModeChannelCountConfig() and ADC_DiscModeCmd() functions.
+ (+) To read the ADC converted values, use the ADC_GetConversionValue()
+ function.
+
+ *** Multi mode ADCs Regular channels configuration ***
+ ======================================================
+ [..]
+ (+) Refer to "Regular channels group configuration" description to
+ configure the ADC1, ADC2 and ADC3 regular channels.
+ (+) Select the Multi mode ADC regular channels features (dual or
+ triple mode) using ADC_CommonInit() function and configure
+ the DMA mode using ADC_MultiModeDMARequestAfterLastTransferCmd()
+ functions.
+ (+) Read the ADCs converted values using the
+ ADC_GetMultiModeConversionValue() function.
+
+ *** DMA for Regular channels group features configuration ***
+ =============================================================
+ [..]
+ (+) To enable the DMA mode for regular channels group, use the
+ ADC_DMACmd() function.
+ (+) To enable the generation of DMA requests continuously at the end
+ of the last DMA transfer, use the ADC_DMARequestAfterLastTransferCmd()
+ function.
+
+ *** Injected channels group configuration ***
+ =============================================
+ [..]
+ (+) To configure the ADC Injected channels group features, use
+ ADC_InjectedChannelConfig() and ADC_InjectedSequencerLengthConfig()
+ functions.
+ (+) To activate the continuous mode, use the ADC_continuousModeCmd()
+ function.
+ (+) To activate the Injected Discontinuous mode, use the
+ ADC_InjectedDiscModeCmd() function.
+ (+) To activate the AutoInjected mode, use the ADC_AutoInjectedConvCmd()
+ function.
+ (+) To read the ADC converted values, use the ADC_GetInjectedConversionValue()
+ function.
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2013 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f4xx_adc.h"
+#include "stm32f4xx_rcc.h"
+#include "stm32f4xx_conf.h"
+
+/** @addtogroup STM32F4xx_StdPeriph_Driver
+ * @{
+ */
+
+/** @defgroup ADC
+ * @brief ADC driver modules
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+
+/* ADC DISCNUM mask */
+#define CR1_DISCNUM_RESET ((uint32_t)0xFFFF1FFF)
+
+/* ADC AWDCH mask */
+#define CR1_AWDCH_RESET ((uint32_t)0xFFFFFFE0)
+
+/* ADC Analog watchdog enable mode mask */
+#define CR1_AWDMode_RESET ((uint32_t)0xFF3FFDFF)
+
+/* CR1 register Mask */
+#define CR1_CLEAR_MASK ((uint32_t)0xFCFFFEFF)
+
+/* ADC EXTEN mask */
+#define CR2_EXTEN_RESET ((uint32_t)0xCFFFFFFF)
+
+/* ADC JEXTEN mask */
+#define CR2_JEXTEN_RESET ((uint32_t)0xFFCFFFFF)
+
+/* ADC JEXTSEL mask */
+#define CR2_JEXTSEL_RESET ((uint32_t)0xFFF0FFFF)
+
+/* CR2 register Mask */
+#define CR2_CLEAR_MASK ((uint32_t)0xC0FFF7FD)
+
+/* ADC SQx mask */
+#define SQR3_SQ_SET ((uint32_t)0x0000001F)
+#define SQR2_SQ_SET ((uint32_t)0x0000001F)
+#define SQR1_SQ_SET ((uint32_t)0x0000001F)
+
+/* ADC L Mask */
+#define SQR1_L_RESET ((uint32_t)0xFF0FFFFF)
+
+/* ADC JSQx mask */
+#define JSQR_JSQ_SET ((uint32_t)0x0000001F)
+
+/* ADC JL mask */
+#define JSQR_JL_SET ((uint32_t)0x00300000)
+#define JSQR_JL_RESET ((uint32_t)0xFFCFFFFF)
+
+/* ADC SMPx mask */
+#define SMPR1_SMP_SET ((uint32_t)0x00000007)
+#define SMPR2_SMP_SET ((uint32_t)0x00000007)
+
+/* ADC JDRx registers offset */
+#define JDR_OFFSET ((uint8_t)0x28)
+
+/* ADC CDR register base address */
+#define CDR_ADDRESS ((uint32_t)0x40012308)
+
+/* ADC CCR register Mask */
+#define CR_CLEAR_MASK ((uint32_t)0xFFFC30E0)
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup ADC_Private_Functions
+ * @{
+ */
+
+/** @defgroup ADC_Group1 Initialization and Configuration functions
+ * @brief Initialization and Configuration functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Initialization and Configuration functions #####
+ ===============================================================================
+ [..] This section provides functions allowing to:
+ (+) Initialize and configure the ADC Prescaler
+ (+) ADC Conversion Resolution (12bit..6bit)
+ (+) Scan Conversion Mode (multichannel or one channel) for regular group
+ (+) ADC Continuous Conversion Mode (Continuous or Single conversion) for
+ regular group
+ (+) External trigger Edge and source of regular group,
+ (+) Converted data alignment (left or right)
+ (+) The number of ADC conversions that will be done using the sequencer for
+ regular channel group
+ (+) Multi ADC mode selection
+ (+) Direct memory access mode selection for multi ADC mode
+ (+) Delay between 2 sampling phases (used in dual or triple interleaved modes)
+ (+) Enable or disable the ADC peripheral
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Deinitializes all ADCs peripherals registers to their default reset
+ * values.
+ * @param None
+ * @retval None
+ */
+void ADC_DeInit(void)
+{
+ /* Enable all ADCs reset state */
+ RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC, ENABLE);
+
+ /* Release all ADCs from reset state */
+ RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC, DISABLE);
+}
+
+/**
+ * @brief Initializes the ADCx peripheral according to the specified parameters
+ * in the ADC_InitStruct.
+ * @note This function is used to configure the global features of the ADC (
+ * Resolution and Data Alignment), however, the rest of the configuration
+ * parameters are specific to the regular channels group (scan mode
+ * activation, continuous mode activation, External trigger source and
+ * edge, number of conversion in the regular channels group sequencer).
+ * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
+ * @param ADC_InitStruct: pointer to an ADC_InitTypeDef structure that contains
+ * the configuration information for the specified ADC peripheral.
+ * @retval None
+ */
+void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct)
+{
+ uint32_t tmpreg1 = 0;
+ uint8_t tmpreg2 = 0;
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_ADC_RESOLUTION(ADC_InitStruct->ADC_Resolution));
+ assert_param(IS_FUNCTIONAL_STATE(ADC_InitStruct->ADC_ScanConvMode));
+ assert_param(IS_FUNCTIONAL_STATE(ADC_InitStruct->ADC_ContinuousConvMode));
+ assert_param(IS_ADC_EXT_TRIG_EDGE(ADC_InitStruct->ADC_ExternalTrigConvEdge));
+ assert_param(IS_ADC_EXT_TRIG(ADC_InitStruct->ADC_ExternalTrigConv));
+ assert_param(IS_ADC_DATA_ALIGN(ADC_InitStruct->ADC_DataAlign));
+ assert_param(IS_ADC_REGULAR_LENGTH(ADC_InitStruct->ADC_NbrOfConversion));
+
+ /*---------------------------- ADCx CR1 Configuration -----------------*/
+ /* Get the ADCx CR1 value */
+ tmpreg1 = ADCx->CR1;
+
+ /* Clear RES and SCAN bits */
+ tmpreg1 &= CR1_CLEAR_MASK;
+
+ /* Configure ADCx: scan conversion mode and resolution */
+ /* Set SCAN bit according to ADC_ScanConvMode value */
+ /* Set RES bit according to ADC_Resolution value */
+ tmpreg1 |= (uint32_t)(((uint32_t)ADC_InitStruct->ADC_ScanConvMode << 8) | \
+ ADC_InitStruct->ADC_Resolution);
+ /* Write to ADCx CR1 */
+ ADCx->CR1 = tmpreg1;
+ /*---------------------------- ADCx CR2 Configuration -----------------*/
+ /* Get the ADCx CR2 value */
+ tmpreg1 = ADCx->CR2;
+
+ /* Clear CONT, ALIGN, EXTEN and EXTSEL bits */
+ tmpreg1 &= CR2_CLEAR_MASK;
+
+ /* Configure ADCx: external trigger event and edge, data alignment and
+ continuous conversion mode */
+ /* Set ALIGN bit according to ADC_DataAlign value */
+ /* Set EXTEN bits according to ADC_ExternalTrigConvEdge value */
+ /* Set EXTSEL bits according to ADC_ExternalTrigConv value */
+ /* Set CONT bit according to ADC_ContinuousConvMode value */
+ tmpreg1 |= (uint32_t)(ADC_InitStruct->ADC_DataAlign | \
+ ADC_InitStruct->ADC_ExternalTrigConv |
+ ADC_InitStruct->ADC_ExternalTrigConvEdge | \
+ ((uint32_t)ADC_InitStruct->ADC_ContinuousConvMode << 1));
+
+ /* Write to ADCx CR2 */
+ ADCx->CR2 = tmpreg1;
+ /*---------------------------- ADCx SQR1 Configuration -----------------*/
+ /* Get the ADCx SQR1 value */
+ tmpreg1 = ADCx->SQR1;
+
+ /* Clear L bits */
+ tmpreg1 &= SQR1_L_RESET;
+
+ /* Configure ADCx: regular channel sequence length */
+ /* Set L bits according to ADC_NbrOfConversion value */
+ tmpreg2 |= (uint8_t)(ADC_InitStruct->ADC_NbrOfConversion - (uint8_t)1);
+ tmpreg1 |= ((uint32_t)tmpreg2 << 20);
+
+ /* Write to ADCx SQR1 */
+ ADCx->SQR1 = tmpreg1;
+}
+
+/**
+ * @brief Fills each ADC_InitStruct member with its default value.
+ * @note This function is used to initialize the global features of the ADC (
+ * Resolution and Data Alignment), however, the rest of the configuration
+ * parameters are specific to the regular channels group (scan mode
+ * activation, continuous mode activation, External trigger source and
+ * edge, number of conversion in the regular channels group sequencer).
+ * @param ADC_InitStruct: pointer to an ADC_InitTypeDef structure which will
+ * be initialized.
+ * @retval None
+ */
+void ADC_StructInit(ADC_InitTypeDef* ADC_InitStruct)
+{
+ /* Initialize the ADC_Mode member */
+ ADC_InitStruct->ADC_Resolution = ADC_Resolution_12b;
+
+ /* initialize the ADC_ScanConvMode member */
+ ADC_InitStruct->ADC_ScanConvMode = DISABLE;
+
+ /* Initialize the ADC_ContinuousConvMode member */
+ ADC_InitStruct->ADC_ContinuousConvMode = DISABLE;
+
+ /* Initialize the ADC_ExternalTrigConvEdge member */
+ ADC_InitStruct->ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
+
+ /* Initialize the ADC_ExternalTrigConv member */
+ ADC_InitStruct->ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
+
+ /* Initialize the ADC_DataAlign member */
+ ADC_InitStruct->ADC_DataAlign = ADC_DataAlign_Right;
+
+ /* Initialize the ADC_NbrOfConversion member */
+ ADC_InitStruct->ADC_NbrOfConversion = 1;
+}
+
+/**
+ * @brief Initializes the ADCs peripherals according to the specified parameters
+ * in the ADC_CommonInitStruct.
+ * @param ADC_CommonInitStruct: pointer to an ADC_CommonInitTypeDef structure
+ * that contains the configuration information for All ADCs peripherals.
+ * @retval None
+ */
+void ADC_CommonInit(ADC_CommonInitTypeDef* ADC_CommonInitStruct)
+{
+ uint32_t tmpreg1 = 0;
+ /* Check the parameters */
+ assert_param(IS_ADC_MODE(ADC_CommonInitStruct->ADC_Mode));
+ assert_param(IS_ADC_PRESCALER(ADC_CommonInitStruct->ADC_Prescaler));
+ assert_param(IS_ADC_DMA_ACCESS_MODE(ADC_CommonInitStruct->ADC_DMAAccessMode));
+ assert_param(IS_ADC_SAMPLING_DELAY(ADC_CommonInitStruct->ADC_TwoSamplingDelay));
+ /*---------------------------- ADC CCR Configuration -----------------*/
+ /* Get the ADC CCR value */
+ tmpreg1 = ADC->CCR;
+
+ /* Clear MULTI, DELAY, DMA and ADCPRE bits */
+ tmpreg1 &= CR_CLEAR_MASK;
+
+ /* Configure ADCx: Multi mode, Delay between two sampling time, ADC prescaler,
+ and DMA access mode for multimode */
+ /* Set MULTI bits according to ADC_Mode value */
+ /* Set ADCPRE bits according to ADC_Prescaler value */
+ /* Set DMA bits according to ADC_DMAAccessMode value */
+ /* Set DELAY bits according to ADC_TwoSamplingDelay value */
+ tmpreg1 |= (uint32_t)(ADC_CommonInitStruct->ADC_Mode |
+ ADC_CommonInitStruct->ADC_Prescaler |
+ ADC_CommonInitStruct->ADC_DMAAccessMode |
+ ADC_CommonInitStruct->ADC_TwoSamplingDelay);
+
+ /* Write to ADC CCR */
+ ADC->CCR = tmpreg1;
+}
+
+/**
+ * @brief Fills each ADC_CommonInitStruct member with its default value.
+ * @param ADC_CommonInitStruct: pointer to an ADC_CommonInitTypeDef structure
+ * which will be initialized.
+ * @retval None
+ */
+void ADC_CommonStructInit(ADC_CommonInitTypeDef* ADC_CommonInitStruct)
+{
+ /* Initialize the ADC_Mode member */
+ ADC_CommonInitStruct->ADC_Mode = ADC_Mode_Independent;
+
+ /* initialize the ADC_Prescaler member */
+ ADC_CommonInitStruct->ADC_Prescaler = ADC_Prescaler_Div2;
+
+ /* Initialize the ADC_DMAAccessMode member */
+ ADC_CommonInitStruct->ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
+
+ /* Initialize the ADC_TwoSamplingDelay member */
+ ADC_CommonInitStruct->ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
+}
+
+/**
+ * @brief Enables or disables the specified ADC peripheral.
+ * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
+ * @param NewState: new state of the ADCx peripheral.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Set the ADON bit to wake up the ADC from power down mode */
+ ADCx->CR2 |= (uint32_t)ADC_CR2_ADON;
+ }
+ else
+ {
+ /* Disable the selected ADC peripheral */
+ ADCx->CR2 &= (uint32_t)(~ADC_CR2_ADON);
+ }
+}
+/**
+ * @}
+ */
+
+/** @defgroup ADC_Group2 Analog Watchdog configuration functions
+ * @brief Analog Watchdog configuration functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Analog Watchdog configuration functions #####
+ ===============================================================================
+ [..] This section provides functions allowing to configure the Analog Watchdog
+ (AWD) feature in the ADC.
+
+ [..] A typical configuration Analog Watchdog is done following these steps :
+ (#) the ADC guarded channel(s) is (are) selected using the
+ ADC_AnalogWatchdogSingleChannelConfig() function.
+ (#) The Analog watchdog lower and higher threshold are configured using the
+ ADC_AnalogWatchdogThresholdsConfig() function.
+ (#) The Analog watchdog is enabled and configured to enable the check, on one
+ or more channels, using the ADC_AnalogWatchdogCmd() function.
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Enables or disables the analog watchdog on single/all regular or
+ * injected channels
+ * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
+ * @param ADC_AnalogWatchdog: the ADC analog watchdog configuration.
+ * This parameter can be one of the following values:
+ * @arg ADC_AnalogWatchdog_SingleRegEnable: Analog watchdog on a single regular channel
+ * @arg ADC_AnalogWatchdog_SingleInjecEnable: Analog watchdog on a single injected channel
+ * @arg ADC_AnalogWatchdog_SingleRegOrInjecEnable: Analog watchdog on a single regular or injected channel
+ * @arg ADC_AnalogWatchdog_AllRegEnable: Analog watchdog on all regular channel
+ * @arg ADC_AnalogWatchdog_AllInjecEnable: Analog watchdog on all injected channel
+ * @arg ADC_AnalogWatchdog_AllRegAllInjecEnable: Analog watchdog on all regular and injected channels
+ * @arg ADC_AnalogWatchdog_None: No channel guarded by the analog watchdog
+ * @retval None
+ */
+void ADC_AnalogWatchdogCmd(ADC_TypeDef* ADCx, uint32_t ADC_AnalogWatchdog)
+{
+ uint32_t tmpreg = 0;
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_ADC_ANALOG_WATCHDOG(ADC_AnalogWatchdog));
+
+ /* Get the old register value */
+ tmpreg = ADCx->CR1;
+
+ /* Clear AWDEN, JAWDEN and AWDSGL bits */
+ tmpreg &= CR1_AWDMode_RESET;
+
+ /* Set the analog watchdog enable mode */
+ tmpreg |= ADC_AnalogWatchdog;
+
+ /* Store the new register value */
+ ADCx->CR1 = tmpreg;
+}
+
+/**
+ * @brief Configures the high and low thresholds of the analog watchdog.
+ * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
+ * @param HighThreshold: the ADC analog watchdog High threshold value.
+ * This parameter must be a 12-bit value.
+ * @param LowThreshold: the ADC analog watchdog Low threshold value.
+ * This parameter must be a 12-bit value.
+ * @retval None
+ */
+void ADC_AnalogWatchdogThresholdsConfig(ADC_TypeDef* ADCx, uint16_t HighThreshold,
+ uint16_t LowThreshold)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_ADC_THRESHOLD(HighThreshold));
+ assert_param(IS_ADC_THRESHOLD(LowThreshold));
+
+ /* Set the ADCx high threshold */
+ ADCx->HTR = HighThreshold;
+
+ /* Set the ADCx low threshold */
+ ADCx->LTR = LowThreshold;
+}
+
+/**
+ * @brief Configures the analog watchdog guarded single channel
+ * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
+ * @param ADC_Channel: the ADC channel to configure for the analog watchdog.
+ * This parameter can be one of the following values:
+ * @arg ADC_Channel_0: ADC Channel0 selected
+ * @arg ADC_Channel_1: ADC Channel1 selected
+ * @arg ADC_Channel_2: ADC Channel2 selected
+ * @arg ADC_Channel_3: ADC Channel3 selected
+ * @arg ADC_Channel_4: ADC Channel4 selected
+ * @arg ADC_Channel_5: ADC Channel5 selected
+ * @arg ADC_Channel_6: ADC Channel6 selected
+ * @arg ADC_Channel_7: ADC Channel7 selected
+ * @arg ADC_Channel_8: ADC Channel8 selected
+ * @arg ADC_Channel_9: ADC Channel9 selected
+ * @arg ADC_Channel_10: ADC Channel10 selected
+ * @arg ADC_Channel_11: ADC Channel11 selected
+ * @arg ADC_Channel_12: ADC Channel12 selected
+ * @arg ADC_Channel_13: ADC Channel13 selected
+ * @arg ADC_Channel_14: ADC Channel14 selected
+ * @arg ADC_Channel_15: ADC Channel15 selected
+ * @arg ADC_Channel_16: ADC Channel16 selected
+ * @arg ADC_Channel_17: ADC Channel17 selected
+ * @arg ADC_Channel_18: ADC Channel18 selected
+ * @retval None
+ */
+void ADC_AnalogWatchdogSingleChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel)
+{
+ uint32_t tmpreg = 0;
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_ADC_CHANNEL(ADC_Channel));
+
+ /* Get the old register value */
+ tmpreg = ADCx->CR1;
+
+ /* Clear the Analog watchdog channel select bits */
+ tmpreg &= CR1_AWDCH_RESET;
+
+ /* Set the Analog watchdog channel */
+ tmpreg |= ADC_Channel;
+
+ /* Store the new register value */
+ ADCx->CR1 = tmpreg;
+}
+/**
+ * @}
+ */
+
+/** @defgroup ADC_Group3 Temperature Sensor, Vrefint (Voltage Reference internal)
+ * and VBAT (Voltage BATtery) management functions
+ * @brief Temperature Sensor, Vrefint and VBAT management functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Temperature Sensor, Vrefint and VBAT management functions #####
+ ===============================================================================
+ [..] This section provides functions allowing to enable/ disable the internal
+ connections between the ADC and the Temperature Sensor, the Vrefint and
+ the Vbat sources.
+
+ [..] A typical configuration to get the Temperature sensor and Vrefint channels
+ voltages is done following these steps :
+ (#) Enable the internal connection of Temperature sensor and Vrefint sources
+ with the ADC channels using ADC_TempSensorVrefintCmd() function.
+ (#) Select the ADC_Channel_TempSensor and/or ADC_Channel_Vrefint using
+ ADC_RegularChannelConfig() or ADC_InjectedChannelConfig() functions
+ (#) Get the voltage values, using ADC_GetConversionValue() or
+ ADC_GetInjectedConversionValue().
+
+ [..] A typical configuration to get the VBAT channel voltage is done following
+ these steps :
+ (#) Enable the internal connection of VBAT source with the ADC channel using
+ ADC_VBATCmd() function.
+ (#) Select the ADC_Channel_Vbat using ADC_RegularChannelConfig() or
+ ADC_InjectedChannelConfig() functions
+ (#) Get the voltage value, using ADC_GetConversionValue() or
+ ADC_GetInjectedConversionValue().
+
+@endverbatim
+ * @{
+ */
+
+
+/**
+ * @brief Enables or disables the temperature sensor and Vrefint channels.
+ * @param NewState: new state of the temperature sensor and Vrefint channels.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void ADC_TempSensorVrefintCmd(FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Enable the temperature sensor and Vrefint channel*/
+ ADC->CCR |= (uint32_t)ADC_CCR_TSVREFE;
+ }
+ else
+ {
+ /* Disable the temperature sensor and Vrefint channel*/
+ ADC->CCR &= (uint32_t)(~ADC_CCR_TSVREFE);
+ }
+}
+
+/**
+ * @brief Enables or disables the VBAT (Voltage Battery) channel.
+ *
+ * @note the Battery voltage measured is equal to VBAT/2 on STM32F40xx and
+ * STM32F41xx devices and equal to VBAT/4 on STM32F42xx and STM32F43xx devices
+ *
+ * @param NewState: new state of the VBAT channel.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void ADC_VBATCmd(FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Enable the VBAT channel*/
+ ADC->CCR |= (uint32_t)ADC_CCR_VBATE;
+ }
+ else
+ {
+ /* Disable the VBAT channel*/
+ ADC->CCR &= (uint32_t)(~ADC_CCR_VBATE);
+ }
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup ADC_Group4 Regular Channels Configuration functions
+ * @brief Regular Channels Configuration functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Regular Channels Configuration functions #####
+ ===============================================================================
+
+ [..] This section provides functions allowing to manage the ADC's regular channels,
+ it is composed of 2 sub sections :
+
+ (#) Configuration and management functions for regular channels: This subsection
+ provides functions allowing to configure the ADC regular channels :
+ (++) Configure the rank in the regular group sequencer for each channel
+ (++) Configure the sampling time for each channel
+ (++) select the conversion Trigger for regular channels
+ (++) select the desired EOC event behavior configuration
+ (++) Activate the continuous Mode (*)
+ (++) Activate the Discontinuous Mode
+ -@@- Please Note that the following features for regular channels
+ are configurated using the ADC_Init() function :
+ (+@@) scan mode activation
+ (+@@) continuous mode activation (**)
+ (+@@) External trigger source
+ (+@@) External trigger edge
+ (+@@) number of conversion in the regular channels group sequencer.
+
+ -@@- (*) and (**) are performing the same configuration
+
+ (#) Get the conversion data: This subsection provides an important function in
+ the ADC peripheral since it returns the converted data of the current
+ regular channel. When the Conversion value is read, the EOC Flag is
+ automatically cleared.
+
+ -@- For multi ADC mode, the last ADC1, ADC2 and ADC3 regular conversions
+ results data (in the selected multi mode) can be returned in the same
+ time using ADC_GetMultiModeConversionValue() function.
+
+@endverbatim
+ * @{
+ */
+/**
+ * @brief Configures for the selected ADC regular channel its corresponding
+ * rank in the sequencer and its sample time.
+ * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
+ * @param ADC_Channel: the ADC channel to configure.
+ * This parameter can be one of the following values:
+ * @arg ADC_Channel_0: ADC Channel0 selected
+ * @arg ADC_Channel_1: ADC Channel1 selected
+ * @arg ADC_Channel_2: ADC Channel2 selected
+ * @arg ADC_Channel_3: ADC Channel3 selected
+ * @arg ADC_Channel_4: ADC Channel4 selected
+ * @arg ADC_Channel_5: ADC Channel5 selected
+ * @arg ADC_Channel_6: ADC Channel6 selected
+ * @arg ADC_Channel_7: ADC Channel7 selected
+ * @arg ADC_Channel_8: ADC Channel8 selected
+ * @arg ADC_Channel_9: ADC Channel9 selected
+ * @arg ADC_Channel_10: ADC Channel10 selected
+ * @arg ADC_Channel_11: ADC Channel11 selected
+ * @arg ADC_Channel_12: ADC Channel12 selected
+ * @arg ADC_Channel_13: ADC Channel13 selected
+ * @arg ADC_Channel_14: ADC Channel14 selected
+ * @arg ADC_Channel_15: ADC Channel15 selected
+ * @arg ADC_Channel_16: ADC Channel16 selected
+ * @arg ADC_Channel_17: ADC Channel17 selected
+ * @arg ADC_Channel_18: ADC Channel18 selected
+ * @param Rank: The rank in the regular group sequencer.
+ * This parameter must be between 1 to 16.
+ * @param ADC_SampleTime: The sample time value to be set for the selected channel.
+ * This parameter can be one of the following values:
+ * @arg ADC_SampleTime_3Cycles: Sample time equal to 3 cycles
+ * @arg ADC_SampleTime_15Cycles: Sample time equal to 15 cycles
+ * @arg ADC_SampleTime_28Cycles: Sample time equal to 28 cycles
+ * @arg ADC_SampleTime_56Cycles: Sample time equal to 56 cycles
+ * @arg ADC_SampleTime_84Cycles: Sample time equal to 84 cycles
+ * @arg ADC_SampleTime_112Cycles: Sample time equal to 112 cycles
+ * @arg ADC_SampleTime_144Cycles: Sample time equal to 144 cycles
+ * @arg ADC_SampleTime_480Cycles: Sample time equal to 480 cycles
+ * @retval None
+ */
+void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime)
+{
+ uint32_t tmpreg1 = 0, tmpreg2 = 0;
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_ADC_CHANNEL(ADC_Channel));
+ assert_param(IS_ADC_REGULAR_RANK(Rank));
+ assert_param(IS_ADC_SAMPLE_TIME(ADC_SampleTime));
+
+ /* if ADC_Channel_10 ... ADC_Channel_18 is selected */
+ if (ADC_Channel > ADC_Channel_9)
+ {
+ /* Get the old register value */
+ tmpreg1 = ADCx->SMPR1;
+
+ /* Calculate the mask to clear */
+ tmpreg2 = SMPR1_SMP_SET << (3 * (ADC_Channel - 10));
+
+ /* Clear the old sample time */
+ tmpreg1 &= ~tmpreg2;
+
+ /* Calculate the mask to set */
+ tmpreg2 = (uint32_t)ADC_SampleTime << (3 * (ADC_Channel - 10));
+
+ /* Set the new sample time */
+ tmpreg1 |= tmpreg2;
+
+ /* Store the new register value */
+ ADCx->SMPR1 = tmpreg1;
+ }
+ else /* ADC_Channel include in ADC_Channel_[0..9] */
+ {
+ /* Get the old register value */
+ tmpreg1 = ADCx->SMPR2;
+
+ /* Calculate the mask to clear */
+ tmpreg2 = SMPR2_SMP_SET << (3 * ADC_Channel);
+
+ /* Clear the old sample time */
+ tmpreg1 &= ~tmpreg2;
+
+ /* Calculate the mask to set */
+ tmpreg2 = (uint32_t)ADC_SampleTime << (3 * ADC_Channel);
+
+ /* Set the new sample time */
+ tmpreg1 |= tmpreg2;
+
+ /* Store the new register value */
+ ADCx->SMPR2 = tmpreg1;
+ }
+ /* For Rank 1 to 6 */
+ if (Rank < 7)
+ {
+ /* Get the old register value */
+ tmpreg1 = ADCx->SQR3;
+
+ /* Calculate the mask to clear */
+ tmpreg2 = SQR3_SQ_SET << (5 * (Rank - 1));
+
+ /* Clear the old SQx bits for the selected rank */
+ tmpreg1 &= ~tmpreg2;
+
+ /* Calculate the mask to set */
+ tmpreg2 = (uint32_t)ADC_Channel << (5 * (Rank - 1));
+
+ /* Set the SQx bits for the selected rank */
+ tmpreg1 |= tmpreg2;
+
+ /* Store the new register value */
+ ADCx->SQR3 = tmpreg1;
+ }
+ /* For Rank 7 to 12 */
+ else if (Rank < 13)
+ {
+ /* Get the old register value */
+ tmpreg1 = ADCx->SQR2;
+
+ /* Calculate the mask to clear */
+ tmpreg2 = SQR2_SQ_SET << (5 * (Rank - 7));
+
+ /* Clear the old SQx bits for the selected rank */
+ tmpreg1 &= ~tmpreg2;
+
+ /* Calculate the mask to set */
+ tmpreg2 = (uint32_t)ADC_Channel << (5 * (Rank - 7));
+
+ /* Set the SQx bits for the selected rank */
+ tmpreg1 |= tmpreg2;
+
+ /* Store the new register value */
+ ADCx->SQR2 = tmpreg1;
+ }
+ /* For Rank 13 to 16 */
+ else
+ {
+ /* Get the old register value */
+ tmpreg1 = ADCx->SQR1;
+
+ /* Calculate the mask to clear */
+ tmpreg2 = SQR1_SQ_SET << (5 * (Rank - 13));
+
+ /* Clear the old SQx bits for the selected rank */
+ tmpreg1 &= ~tmpreg2;
+
+ /* Calculate the mask to set */
+ tmpreg2 = (uint32_t)ADC_Channel << (5 * (Rank - 13));
+
+ /* Set the SQx bits for the selected rank */
+ tmpreg1 |= tmpreg2;
+
+ /* Store the new register value */
+ ADCx->SQR1 = tmpreg1;
+ }
+}
+
+/**
+ * @brief Enables the selected ADC software start conversion of the regular channels.
+ * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
+ * @retval None
+ */
+void ADC_SoftwareStartConv(ADC_TypeDef* ADCx)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+
+ /* Enable the selected ADC conversion for regular group */
+ ADCx->CR2 |= (uint32_t)ADC_CR2_SWSTART;
+}
+
+/**
+ * @brief Gets the selected ADC Software start regular conversion Status.
+ * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
+ * @retval The new state of ADC software start conversion (SET or RESET).
+ */
+FlagStatus ADC_GetSoftwareStartConvStatus(ADC_TypeDef* ADCx)
+{
+ FlagStatus bitstatus = RESET;
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+
+ /* Check the status of SWSTART bit */
+ if ((ADCx->CR2 & ADC_CR2_SWSTART) != (uint32_t)RESET)
+ {
+ /* SWSTART bit is set */
+ bitstatus = SET;
+ }
+ else
+ {
+ /* SWSTART bit is reset */
+ bitstatus = RESET;
+ }
+
+ /* Return the SWSTART bit status */
+ return bitstatus;
+}
+
+
+/**
+ * @brief Enables or disables the EOC on each regular channel conversion
+ * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
+ * @param NewState: new state of the selected ADC EOC flag rising
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void ADC_EOCOnEachRegularChannelCmd(ADC_TypeDef* ADCx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected ADC EOC rising on each regular channel conversion */
+ ADCx->CR2 |= (uint32_t)ADC_CR2_EOCS;
+ }
+ else
+ {
+ /* Disable the selected ADC EOC rising on each regular channel conversion */
+ ADCx->CR2 &= (uint32_t)(~ADC_CR2_EOCS);
+ }
+}
+
+/**
+ * @brief Enables or disables the ADC continuous conversion mode
+ * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
+ * @param NewState: new state of the selected ADC continuous conversion mode
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void ADC_ContinuousModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected ADC continuous conversion mode */
+ ADCx->CR2 |= (uint32_t)ADC_CR2_CONT;
+ }
+ else
+ {
+ /* Disable the selected ADC continuous conversion mode */
+ ADCx->CR2 &= (uint32_t)(~ADC_CR2_CONT);
+ }
+}
+
+/**
+ * @brief Configures the discontinuous mode for the selected ADC regular group
+ * channel.
+ * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
+ * @param Number: specifies the discontinuous mode regular channel count value.
+ * This number must be between 1 and 8.
+ * @retval None
+ */
+void ADC_DiscModeChannelCountConfig(ADC_TypeDef* ADCx, uint8_t Number)
+{
+ uint32_t tmpreg1 = 0;
+ uint32_t tmpreg2 = 0;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_ADC_REGULAR_DISC_NUMBER(Number));
+
+ /* Get the old register value */
+ tmpreg1 = ADCx->CR1;
+
+ /* Clear the old discontinuous mode channel count */
+ tmpreg1 &= CR1_DISCNUM_RESET;
+
+ /* Set the discontinuous mode channel count */
+ tmpreg2 = Number - 1;
+ tmpreg1 |= tmpreg2 << 13;
+
+ /* Store the new register value */
+ ADCx->CR1 = tmpreg1;
+}
+
+/**
+ * @brief Enables or disables the discontinuous mode on regular group channel
+ * for the specified ADC
+ * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
+ * @param NewState: new state of the selected ADC discontinuous mode on
+ * regular group channel.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void ADC_DiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected ADC regular discontinuous mode */
+ ADCx->CR1 |= (uint32_t)ADC_CR1_DISCEN;
+ }
+ else
+ {
+ /* Disable the selected ADC regular discontinuous mode */
+ ADCx->CR1 &= (uint32_t)(~ADC_CR1_DISCEN);
+ }
+}
+
+/**
+ * @brief Returns the last ADCx conversion result data for regular channel.
+ * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
+ * @retval The Data conversion value.
+ */
+uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+
+ /* Return the selected ADC conversion value */
+ return (uint16_t) ADCx->DR;
+}
+
+/**
+ * @brief Returns the last ADC1, ADC2 and ADC3 regular conversions results
+ * data in the selected multi mode.
+ * @param None
+ * @retval The Data conversion value.
+ * @note In dual mode, the value returned by this function is as following
+ * Data[15:0] : these bits contain the regular data of ADC1.
+ * Data[31:16]: these bits contain the regular data of ADC2.
+ * @note In triple mode, the value returned by this function is as following
+ * Data[15:0] : these bits contain alternatively the regular data of ADC1, ADC3 and ADC2.
+ * Data[31:16]: these bits contain alternatively the regular data of ADC2, ADC1 and ADC3.
+ */
+uint32_t ADC_GetMultiModeConversionValue(void)
+{
+ /* Return the multi mode conversion value */
+ return (*(__IO uint32_t *) CDR_ADDRESS);
+}
+/**
+ * @}
+ */
+
+/** @defgroup ADC_Group5 Regular Channels DMA Configuration functions
+ * @brief Regular Channels DMA Configuration functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Regular Channels DMA Configuration functions #####
+ ===============================================================================
+ [..] This section provides functions allowing to configure the DMA for ADC
+ regular channels.
+ Since converted regular channel values are stored into a unique data
+ register, it is useful to use DMA for conversion of more than one regular
+ channel. This avoids the loss of the data already stored in the ADC
+ Data register.
+ When the DMA mode is enabled (using the ADC_DMACmd() function), after each
+ conversion of a regular channel, a DMA request is generated.
+ [..] Depending on the "DMA disable selection for Independent ADC mode"
+ configuration (using the ADC_DMARequestAfterLastTransferCmd() function),
+ at the end of the last DMA transfer, two possibilities are allowed:
+ (+) No new DMA request is issued to the DMA controller (feature DISABLED)
+ (+) Requests can continue to be generated (feature ENABLED).
+ [..] Depending on the "DMA disable selection for multi ADC mode" configuration
+ (using the void ADC_MultiModeDMARequestAfterLastTransferCmd() function),
+ at the end of the last DMA transfer, two possibilities are allowed:
+ (+) No new DMA request is issued to the DMA controller (feature DISABLED)
+ (+) Requests can continue to be generated (feature ENABLED).
+
+@endverbatim
+ * @{
+ */
+
+ /**
+ * @brief Enables or disables the specified ADC DMA request.
+ * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
+ * @param NewState: new state of the selected ADC DMA transfer.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void ADC_DMACmd(ADC_TypeDef* ADCx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected ADC DMA request */
+ ADCx->CR2 |= (uint32_t)ADC_CR2_DMA;
+ }
+ else
+ {
+ /* Disable the selected ADC DMA request */
+ ADCx->CR2 &= (uint32_t)(~ADC_CR2_DMA);
+ }
+}
+
+/**
+ * @brief Enables or disables the ADC DMA request after last transfer (Single-ADC mode)
+ * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
+ * @param NewState: new state of the selected ADC DMA request after last transfer.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void ADC_DMARequestAfterLastTransferCmd(ADC_TypeDef* ADCx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected ADC DMA request after last transfer */
+ ADCx->CR2 |= (uint32_t)ADC_CR2_DDS;
+ }
+ else
+ {
+ /* Disable the selected ADC DMA request after last transfer */
+ ADCx->CR2 &= (uint32_t)(~ADC_CR2_DDS);
+ }
+}
+
+/**
+ * @brief Enables or disables the ADC DMA request after last transfer in multi ADC mode
+ * @param NewState: new state of the selected ADC DMA request after last transfer.
+ * This parameter can be: ENABLE or DISABLE.
+ * @note if Enabled, DMA requests are issued as long as data are converted and
+ * DMA mode for multi ADC mode (selected using ADC_CommonInit() function
+ * by ADC_CommonInitStruct.ADC_DMAAccessMode structure member) is
+ * ADC_DMAAccessMode_1, ADC_DMAAccessMode_2 or ADC_DMAAccessMode_3.
+ * @retval None
+ */
+void ADC_MultiModeDMARequestAfterLastTransferCmd(FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected ADC DMA request after last transfer */
+ ADC->CCR |= (uint32_t)ADC_CCR_DDS;
+ }
+ else
+ {
+ /* Disable the selected ADC DMA request after last transfer */
+ ADC->CCR &= (uint32_t)(~ADC_CCR_DDS);
+ }
+}
+/**
+ * @}
+ */
+
+/** @defgroup ADC_Group6 Injected channels Configuration functions
+ * @brief Injected channels Configuration functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Injected channels Configuration functions #####
+ ===============================================================================
+
+ [..] This section provide functions allowing to configure the ADC Injected channels,
+ it is composed of 2 sub sections :
+
+ (#) Configuration functions for Injected channels: This subsection provides
+ functions allowing to configure the ADC injected channels :
+ (++) Configure the rank in the injected group sequencer for each channel
+ (++) Configure the sampling time for each channel
+ (++) Activate the Auto injected Mode
+ (++) Activate the Discontinuous Mode
+ (++) scan mode activation
+ (++) External/software trigger source
+ (++) External trigger edge
+ (++) injected channels sequencer.
+
+ (#) Get the Specified Injected channel conversion data: This subsection
+ provides an important function in the ADC peripheral since it returns the
+ converted data of the specific injected channel.
+
+@endverbatim
+ * @{
+ */
+/**
+ * @brief Configures for the selected ADC injected channel its corresponding
+ * rank in the sequencer and its sample time.
+ * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
+ * @param ADC_Channel: the ADC channel to configure.
+ * This parameter can be one of the following values:
+ * @arg ADC_Channel_0: ADC Channel0 selected
+ * @arg ADC_Channel_1: ADC Channel1 selected
+ * @arg ADC_Channel_2: ADC Channel2 selected
+ * @arg ADC_Channel_3: ADC Channel3 selected
+ * @arg ADC_Channel_4: ADC Channel4 selected
+ * @arg ADC_Channel_5: ADC Channel5 selected
+ * @arg ADC_Channel_6: ADC Channel6 selected
+ * @arg ADC_Channel_7: ADC Channel7 selected
+ * @arg ADC_Channel_8: ADC Channel8 selected
+ * @arg ADC_Channel_9: ADC Channel9 selected
+ * @arg ADC_Channel_10: ADC Channel10 selected
+ * @arg ADC_Channel_11: ADC Channel11 selected
+ * @arg ADC_Channel_12: ADC Channel12 selected
+ * @arg ADC_Channel_13: ADC Channel13 selected
+ * @arg ADC_Channel_14: ADC Channel14 selected
+ * @arg ADC_Channel_15: ADC Channel15 selected
+ * @arg ADC_Channel_16: ADC Channel16 selected
+ * @arg ADC_Channel_17: ADC Channel17 selected
+ * @arg ADC_Channel_18: ADC Channel18 selected
+ * @param Rank: The rank in the injected group sequencer.
+ * This parameter must be between 1 to 4.
+ * @param ADC_SampleTime: The sample time value to be set for the selected channel.
+ * This parameter can be one of the following values:
+ * @arg ADC_SampleTime_3Cycles: Sample time equal to 3 cycles
+ * @arg ADC_SampleTime_15Cycles: Sample time equal to 15 cycles
+ * @arg ADC_SampleTime_28Cycles: Sample time equal to 28 cycles
+ * @arg ADC_SampleTime_56Cycles: Sample time equal to 56 cycles
+ * @arg ADC_SampleTime_84Cycles: Sample time equal to 84 cycles
+ * @arg ADC_SampleTime_112Cycles: Sample time equal to 112 cycles
+ * @arg ADC_SampleTime_144Cycles: Sample time equal to 144 cycles
+ * @arg ADC_SampleTime_480Cycles: Sample time equal to 480 cycles
+ * @retval None
+ */
+void ADC_InjectedChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime)
+{
+ uint32_t tmpreg1 = 0, tmpreg2 = 0, tmpreg3 = 0;
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_ADC_CHANNEL(ADC_Channel));
+ assert_param(IS_ADC_INJECTED_RANK(Rank));
+ assert_param(IS_ADC_SAMPLE_TIME(ADC_SampleTime));
+ /* if ADC_Channel_10 ... ADC_Channel_18 is selected */
+ if (ADC_Channel > ADC_Channel_9)
+ {
+ /* Get the old register value */
+ tmpreg1 = ADCx->SMPR1;
+ /* Calculate the mask to clear */
+ tmpreg2 = SMPR1_SMP_SET << (3*(ADC_Channel - 10));
+ /* Clear the old sample time */
+ tmpreg1 &= ~tmpreg2;
+ /* Calculate the mask to set */
+ tmpreg2 = (uint32_t)ADC_SampleTime << (3*(ADC_Channel - 10));
+ /* Set the new sample time */
+ tmpreg1 |= tmpreg2;
+ /* Store the new register value */
+ ADCx->SMPR1 = tmpreg1;
+ }
+ else /* ADC_Channel include in ADC_Channel_[0..9] */
+ {
+ /* Get the old register value */
+ tmpreg1 = ADCx->SMPR2;
+ /* Calculate the mask to clear */
+ tmpreg2 = SMPR2_SMP_SET << (3 * ADC_Channel);
+ /* Clear the old sample time */
+ tmpreg1 &= ~tmpreg2;
+ /* Calculate the mask to set */
+ tmpreg2 = (uint32_t)ADC_SampleTime << (3 * ADC_Channel);
+ /* Set the new sample time */
+ tmpreg1 |= tmpreg2;
+ /* Store the new register value */
+ ADCx->SMPR2 = tmpreg1;
+ }
+ /* Rank configuration */
+ /* Get the old register value */
+ tmpreg1 = ADCx->JSQR;
+ /* Get JL value: Number = JL+1 */
+ tmpreg3 = (tmpreg1 & JSQR_JL_SET)>> 20;
+ /* Calculate the mask to clear: ((Rank-1)+(4-JL-1)) */
+ tmpreg2 = JSQR_JSQ_SET << (5 * (uint8_t)((Rank + 3) - (tmpreg3 + 1)));
+ /* Clear the old JSQx bits for the selected rank */
+ tmpreg1 &= ~tmpreg2;
+ /* Calculate the mask to set: ((Rank-1)+(4-JL-1)) */
+ tmpreg2 = (uint32_t)ADC_Channel << (5 * (uint8_t)((Rank + 3) - (tmpreg3 + 1)));
+ /* Set the JSQx bits for the selected rank */
+ tmpreg1 |= tmpreg2;
+ /* Store the new register value */
+ ADCx->JSQR = tmpreg1;
+}
+
+/**
+ * @brief Configures the sequencer length for injected channels
+ * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
+ * @param Length: The sequencer length.
+ * This parameter must be a number between 1 to 4.
+ * @retval None
+ */
+void ADC_InjectedSequencerLengthConfig(ADC_TypeDef* ADCx, uint8_t Length)
+{
+ uint32_t tmpreg1 = 0;
+ uint32_t tmpreg2 = 0;
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_ADC_INJECTED_LENGTH(Length));
+
+ /* Get the old register value */
+ tmpreg1 = ADCx->JSQR;
+
+ /* Clear the old injected sequence length JL bits */
+ tmpreg1 &= JSQR_JL_RESET;
+
+ /* Set the injected sequence length JL bits */
+ tmpreg2 = Length - 1;
+ tmpreg1 |= tmpreg2 << 20;
+
+ /* Store the new register value */
+ ADCx->JSQR = tmpreg1;
+}
+
+/**
+ * @brief Set the injected channels conversion value offset
+ * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
+ * @param ADC_InjectedChannel: the ADC injected channel to set its offset.
+ * This parameter can be one of the following values:
+ * @arg ADC_InjectedChannel_1: Injected Channel1 selected
+ * @arg ADC_InjectedChannel_2: Injected Channel2 selected
+ * @arg ADC_InjectedChannel_3: Injected Channel3 selected
+ * @arg ADC_InjectedChannel_4: Injected Channel4 selected
+ * @param Offset: the offset value for the selected ADC injected channel
+ * This parameter must be a 12bit value.
+ * @retval None
+ */
+void ADC_SetInjectedOffset(ADC_TypeDef* ADCx, uint8_t ADC_InjectedChannel, uint16_t Offset)
+{
+ __IO uint32_t tmp = 0;
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_ADC_INJECTED_CHANNEL(ADC_InjectedChannel));
+ assert_param(IS_ADC_OFFSET(Offset));
+
+ tmp = (uint32_t)ADCx;
+ tmp += ADC_InjectedChannel;
+
+ /* Set the selected injected channel data offset */
+ *(__IO uint32_t *) tmp = (uint32_t)Offset;
+}
+
+ /**
+ * @brief Configures the ADCx external trigger for injected channels conversion.
+ * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
+ * @param ADC_ExternalTrigInjecConv: specifies the ADC trigger to start injected conversion.
+ * This parameter can be one of the following values:
+ * @arg ADC_ExternalTrigInjecConv_T1_CC4: Timer1 capture compare4 selected
+ * @arg ADC_ExternalTrigInjecConv_T1_TRGO: Timer1 TRGO event selected
+ * @arg ADC_ExternalTrigInjecConv_T2_CC1: Timer2 capture compare1 selected
+ * @arg ADC_ExternalTrigInjecConv_T2_TRGO: Timer2 TRGO event selected
+ * @arg ADC_ExternalTrigInjecConv_T3_CC2: Timer3 capture compare2 selected
+ * @arg ADC_ExternalTrigInjecConv_T3_CC4: Timer3 capture compare4 selected
+ * @arg ADC_ExternalTrigInjecConv_T4_CC1: Timer4 capture compare1 selected
+ * @arg ADC_ExternalTrigInjecConv_T4_CC2: Timer4 capture compare2 selected
+ * @arg ADC_ExternalTrigInjecConv_T4_CC3: Timer4 capture compare3 selected
+ * @arg ADC_ExternalTrigInjecConv_T4_TRGO: Timer4 TRGO event selected
+ * @arg ADC_ExternalTrigInjecConv_T5_CC4: Timer5 capture compare4 selected
+ * @arg ADC_ExternalTrigInjecConv_T5_TRGO: Timer5 TRGO event selected
+ * @arg ADC_ExternalTrigInjecConv_T8_CC2: Timer8 capture compare2 selected
+ * @arg ADC_ExternalTrigInjecConv_T8_CC3: Timer8 capture compare3 selected
+ * @arg ADC_ExternalTrigInjecConv_T8_CC4: Timer8 capture compare4 selected
+ * @arg ADC_ExternalTrigInjecConv_Ext_IT15: External interrupt line 15 event selected
+ * @retval None
+ */
+void ADC_ExternalTrigInjectedConvConfig(ADC_TypeDef* ADCx, uint32_t ADC_ExternalTrigInjecConv)
+{
+ uint32_t tmpreg = 0;
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_ADC_EXT_INJEC_TRIG(ADC_ExternalTrigInjecConv));
+
+ /* Get the old register value */
+ tmpreg = ADCx->CR2;
+
+ /* Clear the old external event selection for injected group */
+ tmpreg &= CR2_JEXTSEL_RESET;
+
+ /* Set the external event selection for injected group */
+ tmpreg |= ADC_ExternalTrigInjecConv;
+
+ /* Store the new register value */
+ ADCx->CR2 = tmpreg;
+}
+
+/**
+ * @brief Configures the ADCx external trigger edge for injected channels conversion.
+ * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
+ * @param ADC_ExternalTrigInjecConvEdge: specifies the ADC external trigger edge
+ * to start injected conversion.
+ * This parameter can be one of the following values:
+ * @arg ADC_ExternalTrigInjecConvEdge_None: external trigger disabled for
+ * injected conversion
+ * @arg ADC_ExternalTrigInjecConvEdge_Rising: detection on rising edge
+ * @arg ADC_ExternalTrigInjecConvEdge_Falling: detection on falling edge
+ * @arg ADC_ExternalTrigInjecConvEdge_RisingFalling: detection on both rising
+ * and falling edge
+ * @retval None
+ */
+void ADC_ExternalTrigInjectedConvEdgeConfig(ADC_TypeDef* ADCx, uint32_t ADC_ExternalTrigInjecConvEdge)
+{
+ uint32_t tmpreg = 0;
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_ADC_EXT_INJEC_TRIG_EDGE(ADC_ExternalTrigInjecConvEdge));
+ /* Get the old register value */
+ tmpreg = ADCx->CR2;
+ /* Clear the old external trigger edge for injected group */
+ tmpreg &= CR2_JEXTEN_RESET;
+ /* Set the new external trigger edge for injected group */
+ tmpreg |= ADC_ExternalTrigInjecConvEdge;
+ /* Store the new register value */
+ ADCx->CR2 = tmpreg;
+}
+
+/**
+ * @brief Enables the selected ADC software start conversion of the injected channels.
+ * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
+ * @retval None
+ */
+void ADC_SoftwareStartInjectedConv(ADC_TypeDef* ADCx)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ /* Enable the selected ADC conversion for injected group */
+ ADCx->CR2 |= (uint32_t)ADC_CR2_JSWSTART;
+}
+
+/**
+ * @brief Gets the selected ADC Software start injected conversion Status.
+ * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
+ * @retval The new state of ADC software start injected conversion (SET or RESET).
+ */
+FlagStatus ADC_GetSoftwareStartInjectedConvCmdStatus(ADC_TypeDef* ADCx)
+{
+ FlagStatus bitstatus = RESET;
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+
+ /* Check the status of JSWSTART bit */
+ if ((ADCx->CR2 & ADC_CR2_JSWSTART) != (uint32_t)RESET)
+ {
+ /* JSWSTART bit is set */
+ bitstatus = SET;
+ }
+ else
+ {
+ /* JSWSTART bit is reset */
+ bitstatus = RESET;
+ }
+ /* Return the JSWSTART bit status */
+ return bitstatus;
+}
+
+/**
+ * @brief Enables or disables the selected ADC automatic injected group
+ * conversion after regular one.
+ * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
+ * @param NewState: new state of the selected ADC auto injected conversion
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void ADC_AutoInjectedConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected ADC automatic injected group conversion */
+ ADCx->CR1 |= (uint32_t)ADC_CR1_JAUTO;
+ }
+ else
+ {
+ /* Disable the selected ADC automatic injected group conversion */
+ ADCx->CR1 &= (uint32_t)(~ADC_CR1_JAUTO);
+ }
+}
+
+/**
+ * @brief Enables or disables the discontinuous mode for injected group
+ * channel for the specified ADC
+ * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
+ * @param NewState: new state of the selected ADC discontinuous mode on injected
+ * group channel.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void ADC_InjectedDiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected ADC injected discontinuous mode */
+ ADCx->CR1 |= (uint32_t)ADC_CR1_JDISCEN;
+ }
+ else
+ {
+ /* Disable the selected ADC injected discontinuous mode */
+ ADCx->CR1 &= (uint32_t)(~ADC_CR1_JDISCEN);
+ }
+}
+
+/**
+ * @brief Returns the ADC injected channel conversion result
+ * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
+ * @param ADC_InjectedChannel: the converted ADC injected channel.
+ * This parameter can be one of the following values:
+ * @arg ADC_InjectedChannel_1: Injected Channel1 selected
+ * @arg ADC_InjectedChannel_2: Injected Channel2 selected
+ * @arg ADC_InjectedChannel_3: Injected Channel3 selected
+ * @arg ADC_InjectedChannel_4: Injected Channel4 selected
+ * @retval The Data conversion value.
+ */
+uint16_t ADC_GetInjectedConversionValue(ADC_TypeDef* ADCx, uint8_t ADC_InjectedChannel)
+{
+ __IO uint32_t tmp = 0;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_ADC_INJECTED_CHANNEL(ADC_InjectedChannel));
+
+ tmp = (uint32_t)ADCx;
+ tmp += ADC_InjectedChannel + JDR_OFFSET;
+
+ /* Returns the selected injected channel conversion data value */
+ return (uint16_t) (*(__IO uint32_t*) tmp);
+}
+/**
+ * @}
+ */
+
+/** @defgroup ADC_Group7 Interrupts and flags management functions
+ * @brief Interrupts and flags management functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Interrupts and flags management functions #####
+ ===============================================================================
+
+ [..] This section provides functions allowing to configure the ADC Interrupts
+ and to get the status and clear flags and Interrupts pending bits.
+
+ [..] Each ADC provides 4 Interrupts sources and 6 Flags which can be divided
+ into 3 groups:
+
+ *** Flags and Interrupts for ADC regular channels ***
+ =====================================================
+ [..]
+ (+) Flags :
+ (##) ADC_FLAG_OVR : Overrun detection when regular converted data are lost
+
+ (##) ADC_FLAG_EOC : Regular channel end of conversion ==> to indicate
+ (depending on EOCS bit, managed by ADC_EOCOnEachRegularChannelCmd() )
+ the end of:
+ (+++) a regular CHANNEL conversion
+ (+++) sequence of regular GROUP conversions .
+
+ (##) ADC_FLAG_STRT: Regular channel start ==> to indicate when regular
+ CHANNEL conversion starts.
+ [..]
+ (+) Interrupts :
+ (##) ADC_IT_OVR : specifies the interrupt source for Overrun detection
+ event.
+ (##) ADC_IT_EOC : specifies the interrupt source for Regular channel end
+ of conversion event.
+
+
+ *** Flags and Interrupts for ADC Injected channels ***
+ ======================================================
+ [..]
+ (+) Flags :
+ (##) ADC_FLAG_JEOC : Injected channel end of conversion ==> to indicate
+ at the end of injected GROUP conversion
+
+ (##) ADC_FLAG_JSTRT: Injected channel start ==> to indicate hardware when
+ injected GROUP conversion starts.
+ [..]
+ (+) Interrupts :
+ (##) ADC_IT_JEOC : specifies the interrupt source for Injected channel
+ end of conversion event.
+
+ *** General Flags and Interrupts for the ADC ***
+ ================================================
+ [..]
+ (+)Flags :
+ (##) ADC_FLAG_AWD: Analog watchdog ==> to indicate if the converted voltage
+ crosses the programmed thresholds values.
+ [..]
+ (+) Interrupts :
+ (##) ADC_IT_AWD : specifies the interrupt source for Analog watchdog event.
+
+
+ [..] The user should identify which mode will be used in his application to
+ manage the ADC controller events: Polling mode or Interrupt mode.
+
+ [..] In the Polling Mode it is advised to use the following functions:
+ (+) ADC_GetFlagStatus() : to check if flags events occur.
+ (+) ADC_ClearFlag() : to clear the flags events.
+
+ [..] In the Interrupt Mode it is advised to use the following functions:
+ (+) ADC_ITConfig() : to enable or disable the interrupt source.
+ (+) ADC_GetITStatus() : to check if Interrupt occurs.
+ (+) ADC_ClearITPendingBit() : to clear the Interrupt pending Bit
+ (corresponding Flag).
+@endverbatim
+ * @{
+ */
+/**
+ * @brief Enables or disables the specified ADC interrupts.
+ * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
+ * @param ADC_IT: specifies the ADC interrupt sources to be enabled or disabled.
+ * This parameter can be one of the following values:
+ * @arg ADC_IT_EOC: End of conversion interrupt mask
+ * @arg ADC_IT_AWD: Analog watchdog interrupt mask
+ * @arg ADC_IT_JEOC: End of injected conversion interrupt mask
+ * @arg ADC_IT_OVR: Overrun interrupt enable
+ * @param NewState: new state of the specified ADC interrupts.
+ * This parameter can be: ENABLE or DISABLE.
+ * @retval None
+ */
+void ADC_ITConfig(ADC_TypeDef* ADCx, uint16_t ADC_IT, FunctionalState NewState)
+{
+ uint32_t itmask = 0;
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_FUNCTIONAL_STATE(NewState));
+ assert_param(IS_ADC_IT(ADC_IT));
+
+ /* Get the ADC IT index */
+ itmask = (uint8_t)ADC_IT;
+ itmask = (uint32_t)0x01 << itmask;
+
+ if (NewState != DISABLE)
+ {
+ /* Enable the selected ADC interrupts */
+ ADCx->CR1 |= itmask;
+ }
+ else
+ {
+ /* Disable the selected ADC interrupts */
+ ADCx->CR1 &= (~(uint32_t)itmask);
+ }
+}
+
+/**
+ * @brief Checks whether the specified ADC flag is set or not.
+ * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
+ * @param ADC_FLAG: specifies the flag to check.
+ * This parameter can be one of the following values:
+ * @arg ADC_FLAG_AWD: Analog watchdog flag
+ * @arg ADC_FLAG_EOC: End of conversion flag
+ * @arg ADC_FLAG_JEOC: End of injected group conversion flag
+ * @arg ADC_FLAG_JSTRT: Start of injected group conversion flag
+ * @arg ADC_FLAG_STRT: Start of regular group conversion flag
+ * @arg ADC_FLAG_OVR: Overrun flag
+ * @retval The new state of ADC_FLAG (SET or RESET).
+ */
+FlagStatus ADC_GetFlagStatus(ADC_TypeDef* ADCx, uint8_t ADC_FLAG)
+{
+ FlagStatus bitstatus = RESET;
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_ADC_GET_FLAG(ADC_FLAG));
+
+ /* Check the status of the specified ADC flag */
+ if ((ADCx->SR & ADC_FLAG) != (uint8_t)RESET)
+ {
+ /* ADC_FLAG is set */
+ bitstatus = SET;
+ }
+ else
+ {
+ /* ADC_FLAG is reset */
+ bitstatus = RESET;
+ }
+ /* Return the ADC_FLAG status */
+ return bitstatus;
+}
+
+/**
+ * @brief Clears the ADCx's pending flags.
+ * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
+ * @param ADC_FLAG: specifies the flag to clear.
+ * This parameter can be any combination of the following values:
+ * @arg ADC_FLAG_AWD: Analog watchdog flag
+ * @arg ADC_FLAG_EOC: End of conversion flag
+ * @arg ADC_FLAG_JEOC: End of injected group conversion flag
+ * @arg ADC_FLAG_JSTRT: Start of injected group conversion flag
+ * @arg ADC_FLAG_STRT: Start of regular group conversion flag
+ * @arg ADC_FLAG_OVR: Overrun flag
+ * @retval None
+ */
+void ADC_ClearFlag(ADC_TypeDef* ADCx, uint8_t ADC_FLAG)
+{
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_ADC_CLEAR_FLAG(ADC_FLAG));
+
+ /* Clear the selected ADC flags */
+ ADCx->SR = ~(uint32_t)ADC_FLAG;
+}
+
+/**
+ * @brief Checks whether the specified ADC interrupt has occurred or not.
+ * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
+ * @param ADC_IT: specifies the ADC interrupt source to check.
+ * This parameter can be one of the following values:
+ * @arg ADC_IT_EOC: End of conversion interrupt mask
+ * @arg ADC_IT_AWD: Analog watchdog interrupt mask
+ * @arg ADC_IT_JEOC: End of injected conversion interrupt mask
+ * @arg ADC_IT_OVR: Overrun interrupt mask
+ * @retval The new state of ADC_IT (SET or RESET).
+ */
+ITStatus ADC_GetITStatus(ADC_TypeDef* ADCx, uint16_t ADC_IT)
+{
+ ITStatus bitstatus = RESET;
+ uint32_t itmask = 0, enablestatus = 0;
+
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_ADC_IT(ADC_IT));
+
+ /* Get the ADC IT index */
+ itmask = ADC_IT >> 8;
+
+ /* Get the ADC_IT enable bit status */
+ enablestatus = (ADCx->CR1 & ((uint32_t)0x01 << (uint8_t)ADC_IT)) ;
+
+ /* Check the status of the specified ADC interrupt */
+ if (((ADCx->SR & itmask) != (uint32_t)RESET) && enablestatus)
+ {
+ /* ADC_IT is set */
+ bitstatus = SET;
+ }
+ else
+ {
+ /* ADC_IT is reset */
+ bitstatus = RESET;
+ }
+ /* Return the ADC_IT status */
+ return bitstatus;
+}
+
+/**
+ * @brief Clears the ADCx's interrupt pending bits.
+ * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
+ * @param ADC_IT: specifies the ADC interrupt pending bit to clear.
+ * This parameter can be one of the following values:
+ * @arg ADC_IT_EOC: End of conversion interrupt mask
+ * @arg ADC_IT_AWD: Analog watchdog interrupt mask
+ * @arg ADC_IT_JEOC: End of injected conversion interrupt mask
+ * @arg ADC_IT_OVR: Overrun interrupt mask
+ * @retval None
+ */
+void ADC_ClearITPendingBit(ADC_TypeDef* ADCx, uint16_t ADC_IT)
+{
+ uint8_t itmask = 0;
+ /* Check the parameters */
+ assert_param(IS_ADC_ALL_PERIPH(ADCx));
+ assert_param(IS_ADC_IT(ADC_IT));
+ /* Get the ADC IT index */
+ itmask = (uint8_t)(ADC_IT >> 8);
+ /* Clear the selected ADC interrupt pending bits */
+ ADCx->SR = ~(uint32_t)itmask;
+}
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/stm/lib/stm32f4xx_adc.h b/stm/lib/stm32f4xx_adc.h
new file mode 100644
index 0000000000..9f5fe7acce
--- /dev/null
+++ b/stm/lib/stm32f4xx_adc.h
@@ -0,0 +1,656 @@
+/**
+ ******************************************************************************
+ * @file stm32f4xx_adc.h
+ * @author MCD Application Team
+ * @version V1.3.0
+ * @date 08-November-2013
+ * @brief This file contains all the functions prototypes for the ADC firmware
+ * library.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2013 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F4xx_ADC_H
+#define __STM32F4xx_ADC_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f4xx.h"
+
+/** @addtogroup STM32F4xx_StdPeriph_Driver
+ * @{
+ */
+
+/** @addtogroup ADC
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+
+/**
+ * @brief ADC Init structure definition
+ */
+typedef struct
+{
+ uint32_t ADC_Resolution; /*!< Configures the ADC resolution dual mode.
+ This parameter can be a value of @ref ADC_resolution */
+ FunctionalState ADC_ScanConvMode; /*!< Specifies whether the conversion
+ is performed in Scan (multichannels)
+ or Single (one channel) mode.
+ This parameter can be set to ENABLE or DISABLE */
+ FunctionalState ADC_ContinuousConvMode; /*!< Specifies whether the conversion
+ is performed in Continuous or Single mode.
+ This parameter can be set to ENABLE or DISABLE. */
+ uint32_t ADC_ExternalTrigConvEdge; /*!< Select the external trigger edge and
+ enable the trigger of a regular group.
+ This parameter can be a value of
+ @ref ADC_external_trigger_edge_for_regular_channels_conversion */
+ uint32_t ADC_ExternalTrigConv; /*!< Select the external event used to trigger
+ the start of conversion of a regular group.
+ This parameter can be a value of
+ @ref ADC_extrenal_trigger_sources_for_regular_channels_conversion */
+ uint32_t ADC_DataAlign; /*!< Specifies whether the ADC data alignment
+ is left or right. This parameter can be
+ a value of @ref ADC_data_align */
+ uint8_t ADC_NbrOfConversion; /*!< Specifies the number of ADC conversions
+ that will be done using the sequencer for
+ regular channel group.
+ This parameter must range from 1 to 16. */
+}ADC_InitTypeDef;
+
+/**
+ * @brief ADC Common Init structure definition
+ */
+typedef struct
+{
+ uint32_t ADC_Mode; /*!< Configures the ADC to operate in
+ independent or multi mode.
+ This parameter can be a value of @ref ADC_Common_mode */
+ uint32_t ADC_Prescaler; /*!< Select the frequency of the clock
+ to the ADC. The clock is common for all the ADCs.
+ This parameter can be a value of @ref ADC_Prescaler */
+ uint32_t ADC_DMAAccessMode; /*!< Configures the Direct memory access
+ mode for multi ADC mode.
+ This parameter can be a value of
+ @ref ADC_Direct_memory_access_mode_for_multi_mode */
+ uint32_t ADC_TwoSamplingDelay; /*!< Configures the Delay between 2 sampling phases.
+ This parameter can be a value of
+ @ref ADC_delay_between_2_sampling_phases */
+
+}ADC_CommonInitTypeDef;
+
+
+/* Exported constants --------------------------------------------------------*/
+
+/** @defgroup ADC_Exported_Constants
+ * @{
+ */
+#define IS_ADC_ALL_PERIPH(PERIPH) (((PERIPH) == ADC1) || \
+ ((PERIPH) == ADC2) || \
+ ((PERIPH) == ADC3))
+
+/** @defgroup ADC_Common_mode
+ * @{
+ */
+#define ADC_Mode_Independent ((uint32_t)0x00000000)
+#define ADC_DualMode_RegSimult_InjecSimult ((uint32_t)0x00000001)
+#define ADC_DualMode_RegSimult_AlterTrig ((uint32_t)0x00000002)
+#define ADC_DualMode_InjecSimult ((uint32_t)0x00000005)
+#define ADC_DualMode_RegSimult ((uint32_t)0x00000006)
+#define ADC_DualMode_Interl ((uint32_t)0x00000007)
+#define ADC_DualMode_AlterTrig ((uint32_t)0x00000009)
+#define ADC_TripleMode_RegSimult_InjecSimult ((uint32_t)0x00000011)
+#define ADC_TripleMode_RegSimult_AlterTrig ((uint32_t)0x00000012)
+#define ADC_TripleMode_InjecSimult ((uint32_t)0x00000015)
+#define ADC_TripleMode_RegSimult ((uint32_t)0x00000016)
+#define ADC_TripleMode_Interl ((uint32_t)0x00000017)
+#define ADC_TripleMode_AlterTrig ((uint32_t)0x00000019)
+#define IS_ADC_MODE(MODE) (((MODE) == ADC_Mode_Independent) || \
+ ((MODE) == ADC_DualMode_RegSimult_InjecSimult) || \
+ ((MODE) == ADC_DualMode_RegSimult_AlterTrig) || \
+ ((MODE) == ADC_DualMode_InjecSimult) || \
+ ((MODE) == ADC_DualMode_RegSimult) || \
+ ((MODE) == ADC_DualMode_Interl) || \
+ ((MODE) == ADC_DualMode_AlterTrig) || \
+ ((MODE) == ADC_TripleMode_RegSimult_InjecSimult) || \
+ ((MODE) == ADC_TripleMode_RegSimult_AlterTrig) || \
+ ((MODE) == ADC_TripleMode_InjecSimult) || \
+ ((MODE) == ADC_TripleMode_RegSimult) || \
+ ((MODE) == ADC_TripleMode_Interl) || \
+ ((MODE) == ADC_TripleMode_AlterTrig))
+/**
+ * @}
+ */
+
+
+/** @defgroup ADC_Prescaler
+ * @{
+ */
+#define ADC_Prescaler_Div2 ((uint32_t)0x00000000)
+#define ADC_Prescaler_Div4 ((uint32_t)0x00010000)
+#define ADC_Prescaler_Div6 ((uint32_t)0x00020000)
+#define ADC_Prescaler_Div8 ((uint32_t)0x00030000)
+#define IS_ADC_PRESCALER(PRESCALER) (((PRESCALER) == ADC_Prescaler_Div2) || \
+ ((PRESCALER) == ADC_Prescaler_Div4) || \
+ ((PRESCALER) == ADC_Prescaler_Div6) || \
+ ((PRESCALER) == ADC_Prescaler_Div8))
+/**
+ * @}
+ */
+
+
+/** @defgroup ADC_Direct_memory_access_mode_for_multi_mode
+ * @{
+ */
+#define ADC_DMAAccessMode_Disabled ((uint32_t)0x00000000) /* DMA mode disabled */
+#define ADC_DMAAccessMode_1 ((uint32_t)0x00004000) /* DMA mode 1 enabled (2 / 3 half-words one by one - 1 then 2 then 3)*/
+#define ADC_DMAAccessMode_2 ((uint32_t)0x00008000) /* DMA mode 2 enabled (2 / 3 half-words by pairs - 2&1 then 1&3 then 3&2)*/
+#define ADC_DMAAccessMode_3 ((uint32_t)0x0000C000) /* DMA mode 3 enabled (2 / 3 bytes by pairs - 2&1 then 1&3 then 3&2) */
+#define IS_ADC_DMA_ACCESS_MODE(MODE) (((MODE) == ADC_DMAAccessMode_Disabled) || \
+ ((MODE) == ADC_DMAAccessMode_1) || \
+ ((MODE) == ADC_DMAAccessMode_2) || \
+ ((MODE) == ADC_DMAAccessMode_3))
+
+/**
+ * @}
+ */
+
+
+/** @defgroup ADC_delay_between_2_sampling_phases
+ * @{
+ */
+#define ADC_TwoSamplingDelay_5Cycles ((uint32_t)0x00000000)
+#define ADC_TwoSamplingDelay_6Cycles ((uint32_t)0x00000100)
+#define ADC_TwoSamplingDelay_7Cycles ((uint32_t)0x00000200)
+#define ADC_TwoSamplingDelay_8Cycles ((uint32_t)0x00000300)
+#define ADC_TwoSamplingDelay_9Cycles ((uint32_t)0x00000400)
+#define ADC_TwoSamplingDelay_10Cycles ((uint32_t)0x00000500)
+#define ADC_TwoSamplingDelay_11Cycles ((uint32_t)0x00000600)
+#define ADC_TwoSamplingDelay_12Cycles ((uint32_t)0x00000700)
+#define ADC_TwoSamplingDelay_13Cycles ((uint32_t)0x00000800)
+#define ADC_TwoSamplingDelay_14Cycles ((uint32_t)0x00000900)
+#define ADC_TwoSamplingDelay_15Cycles ((uint32_t)0x00000A00)
+#define ADC_TwoSamplingDelay_16Cycles ((uint32_t)0x00000B00)
+#define ADC_TwoSamplingDelay_17Cycles ((uint32_t)0x00000C00)
+#define ADC_TwoSamplingDelay_18Cycles ((uint32_t)0x00000D00)
+#define ADC_TwoSamplingDelay_19Cycles ((uint32_t)0x00000E00)
+#define ADC_TwoSamplingDelay_20Cycles ((uint32_t)0x00000F00)
+#define IS_ADC_SAMPLING_DELAY(DELAY) (((DELAY) == ADC_TwoSamplingDelay_5Cycles) || \
+ ((DELAY) == ADC_TwoSamplingDelay_6Cycles) || \
+ ((DELAY) == ADC_TwoSamplingDelay_7Cycles) || \
+ ((DELAY) == ADC_TwoSamplingDelay_8Cycles) || \
+ ((DELAY) == ADC_TwoSamplingDelay_9Cycles) || \
+ ((DELAY) == ADC_TwoSamplingDelay_10Cycles) || \
+ ((DELAY) == ADC_TwoSamplingDelay_11Cycles) || \
+ ((DELAY) == ADC_TwoSamplingDelay_12Cycles) || \
+ ((DELAY) == ADC_TwoSamplingDelay_13Cycles) || \
+ ((DELAY) == ADC_TwoSamplingDelay_14Cycles) || \
+ ((DELAY) == ADC_TwoSamplingDelay_15Cycles) || \
+ ((DELAY) == ADC_TwoSamplingDelay_16Cycles) || \
+ ((DELAY) == ADC_TwoSamplingDelay_17Cycles) || \
+ ((DELAY) == ADC_TwoSamplingDelay_18Cycles) || \
+ ((DELAY) == ADC_TwoSamplingDelay_19Cycles) || \
+ ((DELAY) == ADC_TwoSamplingDelay_20Cycles))
+
+/**
+ * @}
+ */
+
+
+/** @defgroup ADC_resolution
+ * @{
+ */
+#define ADC_Resolution_12b ((uint32_t)0x00000000)
+#define ADC_Resolution_10b ((uint32_t)0x01000000)
+#define ADC_Resolution_8b ((uint32_t)0x02000000)
+#define ADC_Resolution_6b ((uint32_t)0x03000000)
+#define IS_ADC_RESOLUTION(RESOLUTION) (((RESOLUTION) == ADC_Resolution_12b) || \
+ ((RESOLUTION) == ADC_Resolution_10b) || \
+ ((RESOLUTION) == ADC_Resolution_8b) || \
+ ((RESOLUTION) == ADC_Resolution_6b))
+
+/**
+ * @}
+ */
+
+
+/** @defgroup ADC_external_trigger_edge_for_regular_channels_conversion
+ * @{
+ */
+#define ADC_ExternalTrigConvEdge_None ((uint32_t)0x00000000)
+#define ADC_ExternalTrigConvEdge_Rising ((uint32_t)0x10000000)
+#define ADC_ExternalTrigConvEdge_Falling ((uint32_t)0x20000000)
+#define ADC_ExternalTrigConvEdge_RisingFalling ((uint32_t)0x30000000)
+#define IS_ADC_EXT_TRIG_EDGE(EDGE) (((EDGE) == ADC_ExternalTrigConvEdge_None) || \
+ ((EDGE) == ADC_ExternalTrigConvEdge_Rising) || \
+ ((EDGE) == ADC_ExternalTrigConvEdge_Falling) || \
+ ((EDGE) == ADC_ExternalTrigConvEdge_RisingFalling))
+/**
+ * @}
+ */
+
+
+/** @defgroup ADC_extrenal_trigger_sources_for_regular_channels_conversion
+ * @{
+ */
+#define ADC_ExternalTrigConv_T1_CC1 ((uint32_t)0x00000000)
+#define ADC_ExternalTrigConv_T1_CC2 ((uint32_t)0x01000000)
+#define ADC_ExternalTrigConv_T1_CC3 ((uint32_t)0x02000000)
+#define ADC_ExternalTrigConv_T2_CC2 ((uint32_t)0x03000000)
+#define ADC_ExternalTrigConv_T2_CC3 ((uint32_t)0x04000000)
+#define ADC_ExternalTrigConv_T2_CC4 ((uint32_t)0x05000000)
+#define ADC_ExternalTrigConv_T2_TRGO ((uint32_t)0x06000000)
+#define ADC_ExternalTrigConv_T3_CC1 ((uint32_t)0x07000000)
+#define ADC_ExternalTrigConv_T3_TRGO ((uint32_t)0x08000000)
+#define ADC_ExternalTrigConv_T4_CC4 ((uint32_t)0x09000000)
+#define ADC_ExternalTrigConv_T5_CC1 ((uint32_t)0x0A000000)
+#define ADC_ExternalTrigConv_T5_CC2 ((uint32_t)0x0B000000)
+#define ADC_ExternalTrigConv_T5_CC3 ((uint32_t)0x0C000000)
+#define ADC_ExternalTrigConv_T8_CC1 ((uint32_t)0x0D000000)
+#define ADC_ExternalTrigConv_T8_TRGO ((uint32_t)0x0E000000)
+#define ADC_ExternalTrigConv_Ext_IT11 ((uint32_t)0x0F000000)
+#define IS_ADC_EXT_TRIG(REGTRIG) (((REGTRIG) == ADC_ExternalTrigConv_T1_CC1) || \
+ ((REGTRIG) == ADC_ExternalTrigConv_T1_CC2) || \
+ ((REGTRIG) == ADC_ExternalTrigConv_T1_CC3) || \
+ ((REGTRIG) == ADC_ExternalTrigConv_T2_CC2) || \
+ ((REGTRIG) == ADC_ExternalTrigConv_T2_CC3) || \
+ ((REGTRIG) == ADC_ExternalTrigConv_T2_CC4) || \
+ ((REGTRIG) == ADC_ExternalTrigConv_T2_TRGO) || \
+ ((REGTRIG) == ADC_ExternalTrigConv_T3_CC1) || \
+ ((REGTRIG) == ADC_ExternalTrigConv_T3_TRGO) || \
+ ((REGTRIG) == ADC_ExternalTrigConv_T4_CC4) || \
+ ((REGTRIG) == ADC_ExternalTrigConv_T5_CC1) || \
+ ((REGTRIG) == ADC_ExternalTrigConv_T5_CC2) || \
+ ((REGTRIG) == ADC_ExternalTrigConv_T5_CC3) || \
+ ((REGTRIG) == ADC_ExternalTrigConv_T8_CC1) || \
+ ((REGTRIG) == ADC_ExternalTrigConv_T8_TRGO) || \
+ ((REGTRIG) == ADC_ExternalTrigConv_Ext_IT11))
+/**
+ * @}
+ */
+
+
+/** @defgroup ADC_data_align
+ * @{
+ */
+#define ADC_DataAlign_Right ((uint32_t)0x00000000)
+#define ADC_DataAlign_Left ((uint32_t)0x00000800)
+#define IS_ADC_DATA_ALIGN(ALIGN) (((ALIGN) == ADC_DataAlign_Right) || \
+ ((ALIGN) == ADC_DataAlign_Left))
+/**
+ * @}
+ */
+
+
+/** @defgroup ADC_channels
+ * @{
+ */
+#define ADC_Channel_0 ((uint8_t)0x00)
+#define ADC_Channel_1 ((uint8_t)0x01)
+#define ADC_Channel_2 ((uint8_t)0x02)
+#define ADC_Channel_3 ((uint8_t)0x03)
+#define ADC_Channel_4 ((uint8_t)0x04)
+#define ADC_Channel_5 ((uint8_t)0x05)
+#define ADC_Channel_6 ((uint8_t)0x06)
+#define ADC_Channel_7 ((uint8_t)0x07)
+#define ADC_Channel_8 ((uint8_t)0x08)
+#define ADC_Channel_9 ((uint8_t)0x09)
+#define ADC_Channel_10 ((uint8_t)0x0A)
+#define ADC_Channel_11 ((uint8_t)0x0B)
+#define ADC_Channel_12 ((uint8_t)0x0C)
+#define ADC_Channel_13 ((uint8_t)0x0D)
+#define ADC_Channel_14 ((uint8_t)0x0E)
+#define ADC_Channel_15 ((uint8_t)0x0F)
+#define ADC_Channel_16 ((uint8_t)0x10)
+#define ADC_Channel_17 ((uint8_t)0x11)
+#define ADC_Channel_18 ((uint8_t)0x12)
+
+#if defined (STM32F40_41xxx)
+#define ADC_Channel_TempSensor ((uint8_t)ADC_Channel_16)
+#endif /* STM32F40_41xxx */
+
+#if defined (STM32F427_437xx) || defined (STM32F429_439xx) || defined (STM32F401xx)
+#define ADC_Channel_TempSensor ((uint8_t)ADC_Channel_18)
+#endif /* STM32F427_437xx || STM32F429_439xx || STM32F401xx */
+
+#define ADC_Channel_Vrefint ((uint8_t)ADC_Channel_17)
+#define ADC_Channel_Vbat ((uint8_t)ADC_Channel_18)
+
+#define IS_ADC_CHANNEL(CHANNEL) (((CHANNEL) == ADC_Channel_0) || \
+ ((CHANNEL) == ADC_Channel_1) || \
+ ((CHANNEL) == ADC_Channel_2) || \
+ ((CHANNEL) == ADC_Channel_3) || \
+ ((CHANNEL) == ADC_Channel_4) || \
+ ((CHANNEL) == ADC_Channel_5) || \
+ ((CHANNEL) == ADC_Channel_6) || \
+ ((CHANNEL) == ADC_Channel_7) || \
+ ((CHANNEL) == ADC_Channel_8) || \
+ ((CHANNEL) == ADC_Channel_9) || \
+ ((CHANNEL) == ADC_Channel_10) || \
+ ((CHANNEL) == ADC_Channel_11) || \
+ ((CHANNEL) == ADC_Channel_12) || \
+ ((CHANNEL) == ADC_Channel_13) || \
+ ((CHANNEL) == ADC_Channel_14) || \
+ ((CHANNEL) == ADC_Channel_15) || \
+ ((CHANNEL) == ADC_Channel_16) || \
+ ((CHANNEL) == ADC_Channel_17) || \
+ ((CHANNEL) == ADC_Channel_18))
+/**
+ * @}
+ */
+
+
+/** @defgroup ADC_sampling_times
+ * @{
+ */
+#define ADC_SampleTime_3Cycles ((uint8_t)0x00)
+#define ADC_SampleTime_15Cycles ((uint8_t)0x01)
+#define ADC_SampleTime_28Cycles ((uint8_t)0x02)
+#define ADC_SampleTime_56Cycles ((uint8_t)0x03)
+#define ADC_SampleTime_84Cycles ((uint8_t)0x04)
+#define ADC_SampleTime_112Cycles ((uint8_t)0x05)
+#define ADC_SampleTime_144Cycles ((uint8_t)0x06)
+#define ADC_SampleTime_480Cycles ((uint8_t)0x07)
+#define IS_ADC_SAMPLE_TIME(TIME) (((TIME) == ADC_SampleTime_3Cycles) || \
+ ((TIME) == ADC_SampleTime_15Cycles) || \
+ ((TIME) == ADC_SampleTime_28Cycles) || \
+ ((TIME) == ADC_SampleTime_56Cycles) || \
+ ((TIME) == ADC_SampleTime_84Cycles) || \
+ ((TIME) == ADC_SampleTime_112Cycles) || \
+ ((TIME) == ADC_SampleTime_144Cycles) || \
+ ((TIME) == ADC_SampleTime_480Cycles))
+/**
+ * @}
+ */
+
+
+/** @defgroup ADC_external_trigger_edge_for_injected_channels_conversion
+ * @{
+ */
+#define ADC_ExternalTrigInjecConvEdge_None ((uint32_t)0x00000000)
+#define ADC_ExternalTrigInjecConvEdge_Rising ((uint32_t)0x00100000)
+#define ADC_ExternalTrigInjecConvEdge_Falling ((uint32_t)0x00200000)
+#define ADC_ExternalTrigInjecConvEdge_RisingFalling ((uint32_t)0x00300000)
+#define IS_ADC_EXT_INJEC_TRIG_EDGE(EDGE) (((EDGE) == ADC_ExternalTrigInjecConvEdge_None) || \
+ ((EDGE) == ADC_ExternalTrigInjecConvEdge_Rising) || \
+ ((EDGE) == ADC_ExternalTrigInjecConvEdge_Falling) || \
+ ((EDGE) == ADC_ExternalTrigInjecConvEdge_RisingFalling))
+
+/**
+ * @}
+ */
+
+
+/** @defgroup ADC_extrenal_trigger_sources_for_injected_channels_conversion
+ * @{
+ */
+#define ADC_ExternalTrigInjecConv_T1_CC4 ((uint32_t)0x00000000)
+#define ADC_ExternalTrigInjecConv_T1_TRGO ((uint32_t)0x00010000)
+#define ADC_ExternalTrigInjecConv_T2_CC1 ((uint32_t)0x00020000)
+#define ADC_ExternalTrigInjecConv_T2_TRGO ((uint32_t)0x00030000)
+#define ADC_ExternalTrigInjecConv_T3_CC2 ((uint32_t)0x00040000)
+#define ADC_ExternalTrigInjecConv_T3_CC4 ((uint32_t)0x00050000)
+#define ADC_ExternalTrigInjecConv_T4_CC1 ((uint32_t)0x00060000)
+#define ADC_ExternalTrigInjecConv_T4_CC2 ((uint32_t)0x00070000)
+#define ADC_ExternalTrigInjecConv_T4_CC3 ((uint32_t)0x00080000)
+#define ADC_ExternalTrigInjecConv_T4_TRGO ((uint32_t)0x00090000)
+#define ADC_ExternalTrigInjecConv_T5_CC4 ((uint32_t)0x000A0000)
+#define ADC_ExternalTrigInjecConv_T5_TRGO ((uint32_t)0x000B0000)
+#define ADC_ExternalTrigInjecConv_T8_CC2 ((uint32_t)0x000C0000)
+#define ADC_ExternalTrigInjecConv_T8_CC3 ((uint32_t)0x000D0000)
+#define ADC_ExternalTrigInjecConv_T8_CC4 ((uint32_t)0x000E0000)
+#define ADC_ExternalTrigInjecConv_Ext_IT15 ((uint32_t)0x000F0000)
+#define IS_ADC_EXT_INJEC_TRIG(INJTRIG) (((INJTRIG) == ADC_ExternalTrigInjecConv_T1_CC4) || \
+ ((INJTRIG) == ADC_ExternalTrigInjecConv_T1_TRGO) || \
+ ((INJTRIG) == ADC_ExternalTrigInjecConv_T2_CC1) || \
+ ((INJTRIG) == ADC_ExternalTrigInjecConv_T2_TRGO) || \
+ ((INJTRIG) == ADC_ExternalTrigInjecConv_T3_CC2) || \
+ ((INJTRIG) == ADC_ExternalTrigInjecConv_T3_CC4) || \
+ ((INJTRIG) == ADC_ExternalTrigInjecConv_T4_CC1) || \
+ ((INJTRIG) == ADC_ExternalTrigInjecConv_T4_CC2) || \
+ ((INJTRIG) == ADC_ExternalTrigInjecConv_T4_CC3) || \
+ ((INJTRIG) == ADC_ExternalTrigInjecConv_T4_TRGO) || \
+ ((INJTRIG) == ADC_ExternalTrigInjecConv_T5_CC4) || \
+ ((INJTRIG) == ADC_ExternalTrigInjecConv_T5_TRGO) || \
+ ((INJTRIG) == ADC_ExternalTrigInjecConv_T8_CC2) || \
+ ((INJTRIG) == ADC_ExternalTrigInjecConv_T8_CC3) || \
+ ((INJTRIG) == ADC_ExternalTrigInjecConv_T8_CC4) || \
+ ((INJTRIG) == ADC_ExternalTrigInjecConv_Ext_IT15))
+/**
+ * @}
+ */
+
+
+/** @defgroup ADC_injected_channel_selection
+ * @{
+ */
+#define ADC_InjectedChannel_1 ((uint8_t)0x14)
+#define ADC_InjectedChannel_2 ((uint8_t)0x18)
+#define ADC_InjectedChannel_3 ((uint8_t)0x1C)
+#define ADC_InjectedChannel_4 ((uint8_t)0x20)
+#define IS_ADC_INJECTED_CHANNEL(CHANNEL) (((CHANNEL) == ADC_InjectedChannel_1) || \
+ ((CHANNEL) == ADC_InjectedChannel_2) || \
+ ((CHANNEL) == ADC_InjectedChannel_3) || \
+ ((CHANNEL) == ADC_InjectedChannel_4))
+/**
+ * @}
+ */
+
+
+/** @defgroup ADC_analog_watchdog_selection
+ * @{
+ */
+#define ADC_AnalogWatchdog_SingleRegEnable ((uint32_t)0x00800200)
+#define ADC_AnalogWatchdog_SingleInjecEnable ((uint32_t)0x00400200)
+#define ADC_AnalogWatchdog_SingleRegOrInjecEnable ((uint32_t)0x00C00200)
+#define ADC_AnalogWatchdog_AllRegEnable ((uint32_t)0x00800000)
+#define ADC_AnalogWatchdog_AllInjecEnable ((uint32_t)0x00400000)
+#define ADC_AnalogWatchdog_AllRegAllInjecEnable ((uint32_t)0x00C00000)
+#define ADC_AnalogWatchdog_None ((uint32_t)0x00000000)
+#define IS_ADC_ANALOG_WATCHDOG(WATCHDOG) (((WATCHDOG) == ADC_AnalogWatchdog_SingleRegEnable) || \
+ ((WATCHDOG) == ADC_AnalogWatchdog_SingleInjecEnable) || \
+ ((WATCHDOG) == ADC_AnalogWatchdog_SingleRegOrInjecEnable) || \
+ ((WATCHDOG) == ADC_AnalogWatchdog_AllRegEnable) || \
+ ((WATCHDOG) == ADC_AnalogWatchdog_AllInjecEnable) || \
+ ((WATCHDOG) == ADC_AnalogWatchdog_AllRegAllInjecEnable) || \
+ ((WATCHDOG) == ADC_AnalogWatchdog_None))
+/**
+ * @}
+ */
+
+
+/** @defgroup ADC_interrupts_definition
+ * @{
+ */
+#define ADC_IT_EOC ((uint16_t)0x0205)
+#define ADC_IT_AWD ((uint16_t)0x0106)
+#define ADC_IT_JEOC ((uint16_t)0x0407)
+#define ADC_IT_OVR ((uint16_t)0x201A)
+#define IS_ADC_IT(IT) (((IT) == ADC_IT_EOC) || ((IT) == ADC_IT_AWD) || \
+ ((IT) == ADC_IT_JEOC)|| ((IT) == ADC_IT_OVR))
+/**
+ * @}
+ */
+
+
+/** @defgroup ADC_flags_definition
+ * @{
+ */
+#define ADC_FLAG_AWD ((uint8_t)0x01)
+#define ADC_FLAG_EOC ((uint8_t)0x02)
+#define ADC_FLAG_JEOC ((uint8_t)0x04)
+#define ADC_FLAG_JSTRT ((uint8_t)0x08)
+#define ADC_FLAG_STRT ((uint8_t)0x10)
+#define ADC_FLAG_OVR ((uint8_t)0x20)
+
+#define IS_ADC_CLEAR_FLAG(FLAG) ((((FLAG) & (uint8_t)0xC0) == 0x00) && ((FLAG) != 0x00))
+#define IS_ADC_GET_FLAG(FLAG) (((FLAG) == ADC_FLAG_AWD) || \
+ ((FLAG) == ADC_FLAG_EOC) || \
+ ((FLAG) == ADC_FLAG_JEOC) || \
+ ((FLAG)== ADC_FLAG_JSTRT) || \
+ ((FLAG) == ADC_FLAG_STRT) || \
+ ((FLAG)== ADC_FLAG_OVR))
+/**
+ * @}
+ */
+
+
+/** @defgroup ADC_thresholds
+ * @{
+ */
+#define IS_ADC_THRESHOLD(THRESHOLD) ((THRESHOLD) <= 0xFFF)
+/**
+ * @}
+ */
+
+
+/** @defgroup ADC_injected_offset
+ * @{
+ */
+#define IS_ADC_OFFSET(OFFSET) ((OFFSET) <= 0xFFF)
+/**
+ * @}
+ */
+
+
+/** @defgroup ADC_injected_length
+ * @{
+ */
+#define IS_ADC_INJECTED_LENGTH(LENGTH) (((LENGTH) >= 0x1) && ((LENGTH) <= 0x4))
+/**
+ * @}
+ */
+
+
+/** @defgroup ADC_injected_rank
+ * @{
+ */
+#define IS_ADC_INJECTED_RANK(RANK) (((RANK) >= 0x1) && ((RANK) <= 0x4))
+/**
+ * @}
+ */
+
+
+/** @defgroup ADC_regular_length
+ * @{
+ */
+#define IS_ADC_REGULAR_LENGTH(LENGTH) (((LENGTH) >= 0x1) && ((LENGTH) <= 0x10))
+/**
+ * @}
+ */
+
+
+/** @defgroup ADC_regular_rank
+ * @{
+ */
+#define IS_ADC_REGULAR_RANK(RANK) (((RANK) >= 0x1) && ((RANK) <= 0x10))
+/**
+ * @}
+ */
+
+
+/** @defgroup ADC_regular_discontinuous_mode_number
+ * @{
+ */
+#define IS_ADC_REGULAR_DISC_NUMBER(NUMBER) (((NUMBER) >= 0x1) && ((NUMBER) <= 0x8))
+/**
+ * @}
+ */
+
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
+
+/* Function used to set the ADC configuration to the default reset state *****/
+void ADC_DeInit(void);
+
+/* Initialization and Configuration functions *********************************/
+void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct);
+void ADC_StructInit(ADC_InitTypeDef* ADC_InitStruct);
+void ADC_CommonInit(ADC_CommonInitTypeDef* ADC_CommonInitStruct);
+void ADC_CommonStructInit(ADC_CommonInitTypeDef* ADC_CommonInitStruct);
+void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState);
+
+/* Analog Watchdog configuration functions ************************************/
+void ADC_AnalogWatchdogCmd(ADC_TypeDef* ADCx, uint32_t ADC_AnalogWatchdog);
+void ADC_AnalogWatchdogThresholdsConfig(ADC_TypeDef* ADCx, uint16_t HighThreshold,uint16_t LowThreshold);
+void ADC_AnalogWatchdogSingleChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel);
+
+/* Temperature Sensor, Vrefint and VBAT management functions ******************/
+void ADC_TempSensorVrefintCmd(FunctionalState NewState);
+void ADC_VBATCmd(FunctionalState NewState);
+
+/* Regular Channels Configuration functions ***********************************/
+void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime);
+void ADC_SoftwareStartConv(ADC_TypeDef* ADCx);
+FlagStatus ADC_GetSoftwareStartConvStatus(ADC_TypeDef* ADCx);
+void ADC_EOCOnEachRegularChannelCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
+void ADC_ContinuousModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
+void ADC_DiscModeChannelCountConfig(ADC_TypeDef* ADCx, uint8_t Number);
+void ADC_DiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
+uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx);
+uint32_t ADC_GetMultiModeConversionValue(void);
+
+/* Regular Channels DMA Configuration functions *******************************/
+void ADC_DMACmd(ADC_TypeDef* ADCx, FunctionalState NewState);
+void ADC_DMARequestAfterLastTransferCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
+void ADC_MultiModeDMARequestAfterLastTransferCmd(FunctionalState NewState);
+
+/* Injected channels Configuration functions **********************************/
+void ADC_InjectedChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime);
+void ADC_InjectedSequencerLengthConfig(ADC_TypeDef* ADCx, uint8_t Length);
+void ADC_SetInjectedOffset(ADC_TypeDef* ADCx, uint8_t ADC_InjectedChannel, uint16_t Offset);
+void ADC_ExternalTrigInjectedConvConfig(ADC_TypeDef* ADCx, uint32_t ADC_ExternalTrigInjecConv);
+void ADC_ExternalTrigInjectedConvEdgeConfig(ADC_TypeDef* ADCx, uint32_t ADC_ExternalTrigInjecConvEdge);
+void ADC_SoftwareStartInjectedConv(ADC_TypeDef* ADCx);
+FlagStatus ADC_GetSoftwareStartInjectedConvCmdStatus(ADC_TypeDef* ADCx);
+void ADC_AutoInjectedConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
+void ADC_InjectedDiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
+uint16_t ADC_GetInjectedConversionValue(ADC_TypeDef* ADCx, uint8_t ADC_InjectedChannel);
+
+/* Interrupts and flags management functions **********************************/
+void ADC_ITConfig(ADC_TypeDef* ADCx, uint16_t ADC_IT, FunctionalState NewState);
+FlagStatus ADC_GetFlagStatus(ADC_TypeDef* ADCx, uint8_t ADC_FLAG);
+void ADC_ClearFlag(ADC_TypeDef* ADCx, uint8_t ADC_FLAG);
+ITStatus ADC_GetITStatus(ADC_TypeDef* ADCx, uint16_t ADC_IT);
+void ADC_ClearITPendingBit(ADC_TypeDef* ADCx, uint16_t ADC_IT);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__STM32F4xx_ADC_H */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/stm/lib/usb_bsp.c b/stm/lib/usb_bsp.c
index c4839bdf96..e88e31db0e 100644
--- a/stm/lib/usb_bsp.c
+++ b/stm/lib/usb_bsp.c
@@ -117,6 +117,17 @@ void USB_OTG_BSP_Init(USB_OTG_CORE_HANDLE *pdev) {
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
GPIO_Init(GPIOA, &GPIO_InitStructure);
+ /*
+ // Configure ID pin (only in host mode)
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
+ GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
+ GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;
+ GPIO_Init(GPIOA, &GPIO_InitStructure);
+ GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_OTG_FS);
+ */
+
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_OTG_FS, ENABLE);
}
@@ -138,6 +149,84 @@ void USB_OTG_BSP_EnableInterrupt(USB_OTG_CORE_HANDLE *pdev) {
}
/**
+* @brief BSP_Drive_VBUS
+* Drives the Vbus signal through IO
+* @param state : VBUS states
+* @retval None
+*/
+
+void USB_OTG_BSP_DriveVBUS(USB_OTG_CORE_HANDLE *pdev, uint8_t state) {
+ //printf("DriveVBUS %p %u\n", pdev, state);
+ /*
+ On-chip 5 V VBUS generation is not supported. For this reason, a charge pump
+ or, if 5 V are available on the application board, a basic power switch, must
+ be added externally to drive the 5 V VBUS line. The external charge pump can
+ be driven by any GPIO output. When the application decides to power on VBUS
+ using the chosen GPIO, it must also set the port power bit in the host port
+ control and status register (PPWR bit in OTG_FS_HPRT).
+
+ Bit 12 PPWR: Port power
+ The application uses this field to control power to this port, and the core
+ clears this bit on an overcurrent condition.
+ */
+#if 0 // not implemented
+#ifndef USE_USB_OTG_HS
+ if (0 == state) {
+ /* DISABLE is needed on output of the Power Switch */
+ GPIO_SetBits(HOST_POWERSW_PORT, HOST_POWERSW_VBUS);
+ } else {
+ /*ENABLE the Power Switch by driving the Enable LOW */
+ GPIO_ResetBits(HOST_POWERSW_PORT, HOST_POWERSW_VBUS);
+ }
+#endif
+#endif
+}
+
+/**
+ * @brief USB_OTG_BSP_ConfigVBUS
+ * Configures the IO for the Vbus and OverCurrent
+ * @param None
+ * @retval None
+ */
+
+void USB_OTG_BSP_ConfigVBUS(USB_OTG_CORE_HANDLE *pdev) {
+ //printf("ConfigVBUS %p\n", pdev);
+#if 0 // not implemented
+#ifdef USE_USB_OTG_FS
+ GPIO_InitTypeDef GPIO_InitStructure;
+
+#ifdef USE_STM3210C_EVAL
+ RCC_APB2PeriphClockCmd(HOST_POWERSW_PORT_RCC, ENABLE);
+
+
+ /* Configure Power Switch Vbus Pin */
+ GPIO_InitStructure.GPIO_Pin = HOST_POWERSW_VBUS;
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
+ GPIO_Init(HOST_POWERSW_PORT, &GPIO_InitStructure);
+#else
+ #ifdef USE_USB_OTG_FS
+ RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOH , ENABLE);
+
+ GPIO_InitStructure.GPIO_Pin = HOST_POWERSW_VBUS;
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
+ GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
+ GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
+ GPIO_Init(HOST_POWERSW_PORT,&GPIO_InitStructure);
+ #endif
+#endif
+
+ /* By Default, DISABLE is needed on output of the Power Switch */
+ GPIO_SetBits(HOST_POWERSW_PORT, HOST_POWERSW_VBUS);
+
+ USB_OTG_BSP_mDelay(200); /* Delay is need for stabilising the Vbus Low
+ in Reset Condition, when Vbus=1 and Reset-button is pressed by user */
+#endif
+#endif
+}
+
+/**
* @brief USB_OTG_BSP_uDelay
* This function provides delay time in micro sec
* @param usec : Value of delay required in micro sec
diff --git a/stm/lib/usb_conf.h b/stm/lib/usb_conf.h
index 5e736f91e2..a51a23a84e 100644
--- a/stm/lib/usb_conf.h
+++ b/stm/lib/usb_conf.h
@@ -181,10 +181,65 @@
/****************** USB OTG MISC CONFIGURATION ********************************/
#define VBUS_SENSING_ENABLED
+/* BEGIN host specific stuff */
+
+/*******************************************************************************
+* FIFO Size Configuration in Host mode
+*
+* (i) Receive data FIFO size = (Largest Packet Size / 4) + 1 or
+* 2x (Largest Packet Size / 4) + 1, If a
+* high-bandwidth channel or multiple isochronous
+* channels are enabled
+*
+* (ii) For the host nonperiodic Transmit FIFO is the largest maximum packet size
+* for all supported nonperiodic OUT channels. Typically, a space
+* corresponding to two Largest Packet Size is recommended.
+*
+* (iii) The minimum amount of RAM required for Host periodic Transmit FIFO is
+* the largest maximum packet size for all supported periodic OUT channels.
+* If there is at least one High Bandwidth Isochronous OUT endpoint,
+* then the space must be at least two times the maximum packet size for
+* that channel.
+*******************************************************************************/
+
+/****************** USB OTG HS CONFIGURATION (for host) ***********************/
+#ifdef USB_OTG_HS_CORE
+ #define RX_FIFO_HS_SIZE 512
+ #define TXH_NP_HS_FIFOSIZ 256
+ #define TXH_P_HS_FIFOSIZ 256
+
+// #define USB_OTG_HS_LOW_PWR_MGMT_SUPPORT
+// #define USB_OTG_HS_SOF_OUTPUT_ENABLED
+
+// #define USB_OTG_INTERNAL_VBUS_ENABLED
+#define USB_OTG_EXTERNAL_VBUS_ENABLED
+
+ #ifdef USE_ULPI_PHY
+ #define USB_OTG_ULPI_PHY_ENABLED
+ #endif
+ #ifdef USE_EMBEDDED_PHY
+ #define USB_OTG_EMBEDDED_PHY_ENABLED
+ #endif
+ #define USB_OTG_HS_INTERNAL_DMA_ENABLED
+// #define USB_OTG_HS_DEDICATED_EP1_ENABLED
+#endif
+
+/****************** USB OTG FS CONFIGURATION (for host) ***********************/
+#ifdef USB_OTG_FS_CORE
+ //#define RX_FIFO_FS_SIZE 128 // already defined for device (and it's the same)
+ #define TXH_NP_FS_FIFOSIZ 96
+ #define TXH_P_FS_FIFOSIZ 96
+
+// #define USB_OTG_FS_LOW_PWR_MGMT_SUPPORT
+// #define USB_OTG_FS_SOF_OUTPUT_ENABLED
+#endif
+
+/* END host specific stuff */
+
/****************** USB OTG MODE CONFIGURATION ********************************/
-//#define USE_HOST_MODE
+//#define USE_HOST_MODE // set in Makefile
#define USE_DEVICE_MODE
-//#define USE_OTG_MODE
+//#define USE_OTG_MODE // set in Makefile
#ifndef USB_OTG_FS_CORE
#ifndef USB_OTG_HS_CORE
diff --git a/stm/lib/usb_core.c b/stm/lib/usb_core.c
index 4b28c085f2..b0cce88046 100644
--- a/stm/lib/usb_core.c
+++ b/stm/lib/usb_core.c
@@ -617,7 +617,7 @@ USB_OTG_STS USB_OTG_CoreInitHost(USB_OTG_CORE_HANDLE *pdev)
USB_OTG_HCFG_TypeDef hcfg;
#ifdef USE_OTG_MODE
- USB_OTG_OTGCTL_TypeDef gotgctl;
+ USB_OTG_GOTGCTL_TypeDef gotgctl;
#endif
uint32_t i = 0;
diff --git a/stm/main.c b/stm/main.c
index 44db47f13b..d8649f5797 100644
--- a/stm/main.c
+++ b/stm/main.c
@@ -40,6 +40,7 @@
#include "pybwlan.h"
#include "i2c.h"
#include "usrsw.h"
+#include "adc.h"
int errno;
@@ -307,7 +308,9 @@ char *strdup(const char *str) {
static const char *readline_hist[READLINE_HIST_SIZE] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
void stdout_tx_str(const char *str) {
- //usart_tx_str(str); // disabled because usart is a Python object and we now need specify which USART port
+ if (pyb_usart_global_debug != PYB_USART_NONE) {
+ usart_tx_str(pyb_usart_global_debug, str);
+ }
usb_vcp_send_str(str);
}
@@ -322,10 +325,10 @@ int readline(vstr_t *line, const char *prompt) {
if (usb_vcp_rx_any() != 0) {
c = usb_vcp_rx_get();
break;
- } /*else if (usart_rx_any()) { // disabled because usart is a Python object and we now need specify which USART port
- c = usart_rx_char();
+ } else if (pyb_usart_global_debug != PYB_USART_NONE && usart_rx_any(pyb_usart_global_debug)) {
+ c = usart_rx_char(pyb_usart_global_debug);
break;
- }*/
+ }
sys_tick_delay_ms(1);
if (storage_needs_flush()) {
storage_flush();
@@ -388,7 +391,7 @@ void do_repl(void) {
stdout_tx_str("Type \"help()\" for more information.\r\n");
vstr_t line;
- vstr_init(&line);
+ vstr_init(&line, 32);
for (;;) {
vstr_reset(&line);
@@ -415,10 +418,18 @@ void do_repl(void) {
}
mp_lexer_t *lex = mp_lexer_new_from_str_len("<stdin>", vstr_str(&line), vstr_len(&line), 0);
- mp_parse_node_t pn = mp_parse(lex, MP_PARSE_SINGLE_INPUT);
- mp_lexer_free(lex);
-
- if (pn != MP_PARSE_NODE_NULL) {
+ qstr parse_exc_id;
+ const char *parse_exc_msg;
+ mp_parse_node_t pn = mp_parse(lex, MP_PARSE_SINGLE_INPUT, &parse_exc_id, &parse_exc_msg);
+
+ if (pn == MP_PARSE_NODE_NULL) {
+ // parse error
+ mp_lexer_show_error_pythonic_prefix(lex);
+ printf("%s: %s\n", qstr_str(parse_exc_id), parse_exc_msg);
+ mp_lexer_free(lex);
+ } else {
+ // parse okay
+ mp_lexer_free(lex);
mp_obj_t module_fun = mp_compile(pn, true);
if (module_fun != mp_const_none) {
nlr_buf_t nlr;
@@ -433,7 +444,7 @@ void do_repl(void) {
}
} else {
// uncaught exception
- mp_obj_print((mp_obj_t)nlr.ret_val);
+ mp_obj_print((mp_obj_t)nlr.ret_val, PRINT_REPR);
printf("\n");
}
}
@@ -452,13 +463,20 @@ bool do_file(const char *filename) {
return false;
}
- mp_parse_node_t pn = mp_parse(lex, MP_PARSE_FILE_INPUT);
- mp_lexer_free(lex);
+ qstr parse_exc_id;
+ const char *parse_exc_msg;
+ mp_parse_node_t pn = mp_parse(lex, MP_PARSE_FILE_INPUT, &parse_exc_id, &parse_exc_msg);
if (pn == MP_PARSE_NODE_NULL) {
+ // parse error
+ mp_lexer_show_error_pythonic_prefix(lex);
+ printf("%s: %s\n", qstr_str(parse_exc_id), parse_exc_msg);
+ mp_lexer_free(lex);
return false;
}
+ mp_lexer_free(lex);
+
mp_obj_t module_fun = mp_compile(pn, false);
if (module_fun == mp_const_none) {
return false;
@@ -471,7 +489,7 @@ bool do_file(const char *filename) {
return true;
} else {
// uncaught exception
- mp_obj_print((mp_obj_t)nlr.ret_val);
+ mp_obj_print((mp_obj_t)nlr.ret_val, PRINT_REPR);
printf("\n");
return false;
}
@@ -653,7 +671,7 @@ typedef struct _pyb_file_obj_t {
FIL fp;
} pyb_file_obj_t;
-void file_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) {
+void file_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
printf("<file %p>", self_in);
}
@@ -775,7 +793,9 @@ int main(void) {
switch_init();
storage_init();
- //usart_init(); disabled while wi-fi is enabled; also disabled because now usart is a proper Python object
+ // uncomment these 2 lines if you want REPL on USART_6 (or another usart) as well as on USB VCP
+ //pyb_usart_global_debug = PYB_USART_6;
+ //usart_init(pyb_usart_global_debug, 115200);
int first_soft_reset = true;
@@ -808,36 +828,37 @@ soft_reset:
// add some functions to the python namespace
{
- rt_store_name(qstr_from_str_static("help"), rt_make_function_0(pyb_help));
+ rt_store_name(qstr_from_str_static("help"), rt_make_function_n(0, pyb_help));
mp_obj_t m = mp_obj_new_module(qstr_from_str_static("pyb"));
- rt_store_attr(m, qstr_from_str_static("info"), rt_make_function_0(pyb_info));
- rt_store_attr(m, qstr_from_str_static("sd_test"), rt_make_function_0(pyb_sd_test));
- rt_store_attr(m, qstr_from_str_static("stop"), rt_make_function_0(pyb_stop));
- rt_store_attr(m, qstr_from_str_static("standby"), rt_make_function_0(pyb_standby));
- rt_store_attr(m, qstr_from_str_static("source_dir"), rt_make_function_1(pyb_source_dir));
- rt_store_attr(m, qstr_from_str_static("main"), rt_make_function_1(pyb_main));
- rt_store_attr(m, qstr_from_str_static("sync"), rt_make_function_0(pyb_sync));
- rt_store_attr(m, qstr_from_str_static("gc"), rt_make_function_0(pyb_gc));
- rt_store_attr(m, qstr_from_str_static("delay"), rt_make_function_1(pyb_delay));
- rt_store_attr(m, qstr_from_str_static("led"), rt_make_function_1(pyb_led));
+ rt_store_attr(m, qstr_from_str_static("info"), rt_make_function_n(0, pyb_info));
+ rt_store_attr(m, qstr_from_str_static("sd_test"), rt_make_function_n(0, pyb_sd_test));
+ rt_store_attr(m, qstr_from_str_static("stop"), rt_make_function_n(0, pyb_stop));
+ rt_store_attr(m, qstr_from_str_static("standby"), rt_make_function_n(0, pyb_standby));
+ rt_store_attr(m, qstr_from_str_static("source_dir"), rt_make_function_n(1, pyb_source_dir));
+ rt_store_attr(m, qstr_from_str_static("main"), rt_make_function_n(1, pyb_main));
+ rt_store_attr(m, qstr_from_str_static("sync"), rt_make_function_n(0, pyb_sync));
+ rt_store_attr(m, qstr_from_str_static("gc"), rt_make_function_n(0, pyb_gc));
+ rt_store_attr(m, qstr_from_str_static("delay"), rt_make_function_n(1, pyb_delay));
+ rt_store_attr(m, qstr_from_str_static("led"), rt_make_function_n(1, pyb_led));
rt_store_attr(m, qstr_from_str_static("switch"), (mp_obj_t)&pyb_switch_obj);
- rt_store_attr(m, qstr_from_str_static("servo"), rt_make_function_2(pyb_servo_set));
- rt_store_attr(m, qstr_from_str_static("pwm"), rt_make_function_2(pyb_pwm_set));
+ rt_store_attr(m, qstr_from_str_static("servo"), rt_make_function_n(2, pyb_servo_set));
+ rt_store_attr(m, qstr_from_str_static("pwm"), rt_make_function_n(2, pyb_pwm_set));
rt_store_attr(m, qstr_from_str_static("accel"), (mp_obj_t)&pyb_mma_read_obj);
rt_store_attr(m, qstr_from_str_static("mma_read"), (mp_obj_t)&pyb_mma_read_all_obj);
rt_store_attr(m, qstr_from_str_static("mma_mode"), (mp_obj_t)&pyb_mma_write_mode_obj);
- rt_store_attr(m, qstr_from_str_static("hid"), rt_make_function_1(pyb_hid_send_report));
- rt_store_attr(m, qstr_from_str_static("time"), rt_make_function_0(pyb_rtc_read));
- rt_store_attr(m, qstr_from_str_static("rand"), rt_make_function_0(pyb_rng_get));
- rt_store_attr(m, qstr_from_str_static("Led"), rt_make_function_1(pyb_Led));
- rt_store_attr(m, qstr_from_str_static("Servo"), rt_make_function_1(pyb_Servo));
- rt_store_attr(m, qstr_from_str_static("I2C"), rt_make_function_2(pyb_I2C));
+ rt_store_attr(m, qstr_from_str_static("hid"), rt_make_function_n(1, pyb_hid_send_report));
+ rt_store_attr(m, qstr_from_str_static("time"), rt_make_function_n(0, pyb_rtc_read));
+ rt_store_attr(m, qstr_from_str_static("rand"), rt_make_function_n(0, pyb_rng_get));
+ rt_store_attr(m, qstr_from_str_static("Led"), rt_make_function_n(1, pyb_Led));
+ rt_store_attr(m, qstr_from_str_static("Servo"), rt_make_function_n(1, pyb_Servo));
+ rt_store_attr(m, qstr_from_str_static("I2C"), rt_make_function_n(2, pyb_I2C));
rt_store_attr(m, qstr_from_str_static("gpio"), (mp_obj_t)&pyb_gpio_obj);
- rt_store_attr(m, qstr_from_str_static("Usart"), rt_make_function_2(pyb_Usart));
+ rt_store_attr(m, qstr_from_str_static("Usart"), rt_make_function_n(2, pyb_Usart));
+ rt_store_attr(m, qstr_from_str_static("ADC"), rt_make_function_n(1, pyb_ADC));
rt_store_name(qstr_from_str_static("pyb"), m);
- rt_store_name(qstr_from_str_static("open"), rt_make_function_2(pyb_io_open));
+ rt_store_name(qstr_from_str_static("open"), rt_make_function_n(2, pyb_io_open));
}
// print a message to the LCD
@@ -937,6 +958,9 @@ soft_reset:
// USB
usb_init();
+ // USB host; not working!
+ //pyb_usbh_init();
+
// MMA
if (first_soft_reset) {
// init and reset address to zero
@@ -1064,7 +1088,9 @@ soft_reset:
// nalloc=1740;6340;6836 -> 140;4600;496 bytes for lexer, parser, compiler
printf("lex; al=%u\n", m_get_total_bytes_allocated());
sys_tick_delay_ms(1000);
- mp_parse_node_t pn = mp_parse(lex, MP_PARSE_FILE_INPUT);
+ qstr parse_exc_id;
+ const char *parse_exc_msg;
+ mp_parse_node_t pn = mp_parse(lex, MP_PARSE_FILE_INPUT, &parse_exc_id, &parse_exc_msg);
mp_lexer_free(lex);
if (pn != MP_PARSE_NODE_NULL) {
printf("pars;al=%u\n", m_get_total_bytes_allocated());
@@ -1088,13 +1114,13 @@ soft_reset:
if (nlr_push(&nlr) == 0) {
mp_obj_t ret = rt_call_function_0(module_fun);
printf("done! got: ");
- mp_obj_print(ret);
+ mp_obj_print(ret, PRINT_REPR);
printf("\n");
nlr_pop();
} else {
// uncaught exception
printf("exception: ");
- mp_obj_print((mp_obj_t)nlr.ret_val);
+ mp_obj_print((mp_obj_t)nlr.ret_val, PRINT_REPR);
printf("\n");
}
@@ -1171,6 +1197,7 @@ soft_reset:
goto soft_reset;
}
+/* now supplied by libgcc library
double __aeabi_f2d(float x) {
// TODO
return 0.0;
@@ -1180,6 +1207,7 @@ float __aeabi_d2f(double x) {
// TODO
return 0.0;
}
+*/
double sqrt(double x) {
// TODO
diff --git a/stm/printf.c b/stm/printf.c
index 8a40a61a5f..732e834526 100644
--- a/stm/printf.c
+++ b/stm/printf.c
@@ -206,6 +206,21 @@ int pfenv_printf(const pfenv_t *pfenv, const char *fmt, va_list args) {
case 'P': // ?
chrs += pfenv_print_int(pfenv, va_arg(args, int), 0, 16, 'A', flags, width);
break;
+ case 'g':
+ {
+ // This is a very hacky approach to printing floats. Micropython
+ // uses %g when using print, and I just wanted to see somthing
+ // usable. I expect that this will be replaced with something
+ // more appropriate.
+ char dot = '.';
+ mp_float_t d = va_arg(args, double);
+ int left = (int)d;
+ int right = (int)((d - (mp_float_t)(int)d) * 1000000.0);
+ chrs += pfenv_print_int(pfenv, left, 1, 10, 'a', flags, width);
+ chrs += pfenv_print_strn(pfenv, &dot, 1, flags, width);
+ chrs += pfenv_print_int(pfenv, right, 0, 10, 'a', PF_FLAG_ZERO_PAD, 6);
+ break;
+ }
default:
pfenv->print_strn(pfenv->data, fmt, 1);
chrs += 1;
@@ -220,12 +235,10 @@ void stdout_print_strn(void *data, const char *str, unsigned int len) {
// send stdout to USART, USB CDC VCP, and LCD if nothing else
bool any = false;
- // TODO should have a setting for which USART port to send to
- if (usart_is_enabled()) {
- usart_tx_strn_cooked(str, len);
+ if (pyb_usart_global_debug != PYB_USART_NONE) {
+ usart_tx_strn_cooked(pyb_usart_global_debug, str, len);
any = true;
}
-
if (usb_vcp_is_enabled()) {
usb_vcp_send_strn_cooked(str, len);
any = true;
diff --git a/stm/pybwlan.c b/stm/pybwlan.c
index 09d642d9c8..91d71a652b 100644
--- a/stm/pybwlan.c
+++ b/stm/pybwlan.c
@@ -357,11 +357,11 @@ void pyb_wlan_init(void) {
mp_obj_t m = mp_obj_new_module(qstr_from_str_static("wlan"));
rt_store_attr(m, qstr_from_str_static("connect"), rt_make_function_var(0, pyb_wlan_connect));
- rt_store_attr(m, qstr_from_str_static("disconnect"), rt_make_function_0(pyb_wlan_disconnect));
- rt_store_attr(m, qstr_from_str_static("ip"), rt_make_function_0(pyb_wlan_get_ip));
- rt_store_attr(m, qstr_from_str_static("get_host"), rt_make_function_1(pyb_wlan_get_host));
- rt_store_attr(m, qstr_from_str_static("http_get"), rt_make_function_2(pyb_wlan_http_get));
- rt_store_attr(m, qstr_from_str_static("serve"), rt_make_function_0(pyb_wlan_serve));
+ rt_store_attr(m, qstr_from_str_static("disconnect"), rt_make_function_n(0, pyb_wlan_disconnect));
+ rt_store_attr(m, qstr_from_str_static("ip"), rt_make_function_n(0, pyb_wlan_get_ip));
+ rt_store_attr(m, qstr_from_str_static("get_host"), rt_make_function_n(1, pyb_wlan_get_host));
+ rt_store_attr(m, qstr_from_str_static("http_get"), rt_make_function_n(2, pyb_wlan_http_get));
+ rt_store_attr(m, qstr_from_str_static("serve"), rt_make_function_n(0, pyb_wlan_serve));
rt_store_name(qstr_from_str_static("wlan"), m);
}
diff --git a/stm/std.h b/stm/std.h
index 587b9f8880..95c606e058 100644
--- a/stm/std.h
+++ b/stm/std.h
@@ -17,6 +17,8 @@ int strncmp(const char *s1, const char *s2, size_t n);
char *strndup(const char *s, size_t n);
char *strcpy(char *dest, const char *src);
char *strcat(char *dest, const char *src);
+char *strchr(const char *s, int c);
+char *strstr(const char *haystack, const char *needle);
int printf(const char *fmt, ...);
int snprintf(char *str, size_t size, const char *fmt, ...);
diff --git a/stm/stm32fxxx_it.c b/stm/stm32fxxx_it.c
index e254ccc899..c1a9a0702f 100644
--- a/stm/stm32fxxx_it.c
+++ b/stm/stm32fxxx_it.c
@@ -31,6 +31,7 @@
#include "stm32fxxx_it.h"
#include "stm32f4xx_exti.h"
#include "usb_core.h"
+//#include "usb_hcd_int.h" // for usb host mode only
//#include "usbd_core.h"
//#include "usbd_cdc_core.h"
@@ -197,7 +198,8 @@ void OTG_HS_IRQHandler(void)
void OTG_FS_IRQHandler(void)
#endif
{
- USBD_OTG_ISR_Handler (&USB_OTG_dev);
+ USBD_OTG_ISR_Handler (&USB_OTG_dev); // device mode
+ //USBH_OTG_ISR_Handler (&USB_OTG_dev); // host mode FIXME
}
#ifdef USB_OTG_HS_DEDICATED_EP1_ENABLED
diff --git a/stm/string0.c b/stm/string0.c
index 2a5f255971..d67c5f2b17 100644
--- a/stm/string0.c
+++ b/stm/string0.c
@@ -108,3 +108,31 @@ char *strcat(char *dest, const char *src) {
*d = '\0';
return dest;
}
+
+// Public Domain implementation of strchr from:
+// http://en.wikibooks.org/wiki/C_Programming/Strings#The_strchr_function
+char *strchr(const char *s, int c)
+{
+ /* Scan s for the character. When this loop is finished,
+ s will either point to the end of the string or the
+ character we were looking for. */
+ while (*s != '\0' && *s != (char)c)
+ s++;
+ return ((*s == c) ? (char *) s : 0);
+}
+
+
+// Public Domain implementation of strstr from:
+// http://en.wikibooks.org/wiki/C_Programming/Strings#The_strstr_function
+char *strstr(const char *haystack, const char *needle)
+{
+ size_t needlelen;
+ /* Check for the null needle case. */
+ if (*needle == '\0')
+ return (char *) haystack;
+ needlelen = strlen(needle);
+ for (; (haystack = strchr(haystack, *needle)) != 0; haystack++)
+ if (strncmp(haystack, needle, needlelen) == 0)
+ return (char *) haystack;
+ return 0;
+}
diff --git a/stm/timer.c b/stm/timer.c
index 2605d4b4bc..062f8c689e 100644
--- a/stm/timer.c
+++ b/stm/timer.c
@@ -72,10 +72,10 @@ void timer_init(void) {
// Python interface
mp_obj_t m = mp_obj_new_module(qstr_from_str_static("timer"));
- rt_store_attr(m, qstr_from_str_static("callback"), rt_make_function_1(timer_py_set_callback));
- rt_store_attr(m, qstr_from_str_static("period"), rt_make_function_1(timer_py_set_period));
- rt_store_attr(m, qstr_from_str_static("prescaler"), rt_make_function_1(timer_py_set_prescaler));
- rt_store_attr(m, qstr_from_str_static("value"), rt_make_function_0(timer_py_get_value));
+ rt_store_attr(m, qstr_from_str_static("callback"), rt_make_function_n(1, timer_py_set_callback));
+ rt_store_attr(m, qstr_from_str_static("period"), rt_make_function_n(1, timer_py_set_period));
+ rt_store_attr(m, qstr_from_str_static("prescaler"), rt_make_function_n(1, timer_py_set_prescaler));
+ rt_store_attr(m, qstr_from_str_static("value"), rt_make_function_n(0, timer_py_get_value));
rt_store_name(qstr_from_str_static("timer"), m);
}
@@ -89,7 +89,7 @@ void timer_interrupt(void) {
} else {
// uncaught exception
printf("exception in timer interrupt\n");
- mp_obj_print((mp_obj_t)nlr.ret_val);
+ mp_obj_print((mp_obj_t)nlr.ret_val, PRINT_REPR);
printf("\n");
}
}
diff --git a/stm/usart.c b/stm/usart.c
index bc5bfc7369..5f47ec788a 100644
--- a/stm/usart.c
+++ b/stm/usart.c
@@ -8,20 +8,14 @@
#include "obj.h"
#include "usart.h"
-static bool is_enabled;
-
-typedef enum {
- PYB_USART_1 = 1,
- PYB_USART_2 = 2,
- PYB_USART_3 = 3,
- PYB_USART_6 = 4,
- PYB_USART_MAX = 4,
-} pyb_usart_t;
+pyb_usart_t pyb_usart_global_debug = PYB_USART_NONE;
static USART_TypeDef *usart_get_base(pyb_usart_t usart_id) {
USART_TypeDef *USARTx=NULL;
switch (usart_id) {
+ case PYB_USART_NONE:
+ break;
case PYB_USART_1:
USARTx = USART1;
break;
@@ -52,6 +46,9 @@ void usart_init(pyb_usart_t usart_id, uint32_t baudrate) {
void (*RCC_APBxPeriphClockCmd)(uint32_t, FunctionalState)=NULL;
switch (usart_id) {
+ case PYB_USART_NONE:
+ return;
+
case PYB_USART_1:
USARTx = USART1;
@@ -128,16 +125,13 @@ void usart_init(pyb_usart_t usart_id, uint32_t baudrate) {
USART_Cmd(USARTx, ENABLE);
}
-bool usart_is_enabled(void) {
- return is_enabled;
-}
-
-bool usart_rx_any(void) {
- return USART_GetFlagStatus(USART6, USART_FLAG_RXNE) == SET;
+bool usart_rx_any(pyb_usart_t usart_id) {
+ USART_TypeDef *USARTx = usart_get_base(usart_id);
+ return USART_GetFlagStatus(USARTx, USART_FLAG_RXNE) == SET;
}
int usart_rx_char(pyb_usart_t usart_id) {
- USART_TypeDef *USARTx= usart_get_base(usart_id);
+ USART_TypeDef *USARTx = usart_get_base(usart_id);
return USART_ReceiveData(USARTx);
}
@@ -176,8 +170,8 @@ typedef struct _pyb_usart_obj_t {
} pyb_usart_obj_t;
static mp_obj_t usart_obj_status(mp_obj_t self_in) {
- // TODO make it check the correct USART port!
- if (usart_rx_any()) {
+ pyb_usart_obj_t *self = self_in;
+ if (usart_rx_any(self->usart_id)) {
return mp_const_true;
} else {
return mp_const_false;
diff --git a/stm/usart.h b/stm/usart.h
index 15ed419fe7..541cb757c8 100644
--- a/stm/usart.h
+++ b/stm/usart.h
@@ -1 +1,18 @@
+typedef enum {
+ PYB_USART_NONE = 0,
+ PYB_USART_1 = 1,
+ PYB_USART_2 = 2,
+ PYB_USART_3 = 3,
+ PYB_USART_6 = 4,
+ PYB_USART_MAX = 4,
+} pyb_usart_t;
+
+extern pyb_usart_t pyb_usart_global_debug;
+
+void usart_init(pyb_usart_t usart_id, uint32_t baudrate);
+bool usart_rx_any(pyb_usart_t usart_id);
+int usart_rx_char(pyb_usart_t usart_id);
+void usart_tx_str(pyb_usart_t usart_id, const char *str);
+void usart_tx_strn_cooked(pyb_usart_t usart_id, const char *str, int len);
+
mp_obj_t pyb_Usart(mp_obj_t usart_id, mp_obj_t baudrate);
diff --git a/stm/usb.c b/stm/usb.c
index b0fbfa1941..ed2b0359b9 100644
--- a/stm/usb.c
+++ b/stm/usb.c
@@ -80,7 +80,7 @@ void usb_vcp_send_strn(const char *str, int len) {
}
}
-#include "lib/usbd_conf.h"
+#include "usbd_conf.h"
/* These are external variables imported from CDC core to be used for IN
transfer management. */
@@ -105,3 +105,30 @@ void usb_vcp_send_strn_cooked(const char *str, int len) {
void usb_hid_send_report(uint8_t *buf) {
USBD_HID_SendReport(&USB_OTG_dev, buf, 4);
}
+
+/******************************************************************************/
+// code for experimental USB OTG support
+
+#ifdef USE_HOST_MODE
+
+#include "lib-otg/usbh_core.h"
+#include "lib-otg/usbh_usr.h"
+#include "lib-otg/usbh_hid_core.h"
+
+__ALIGN_BEGIN USBH_HOST USB_Host __ALIGN_END ;
+
+static int host_is_enabled = 0;
+void pyb_usbh_init(void) {
+ if (!host_is_enabled) {
+ // only init USBH once in the device's power-lifetime
+ /* Init Host Library */
+ USBH_Init(&USB_OTG_dev, USB_OTG_FS_CORE_ID, &USB_Host, &HID_cb, &USR_Callbacks);
+ }
+ host_is_enabled = 1;
+}
+
+void pyb_usbh_process(void) {
+ USBH_Process(&USB_OTG_dev, &USB_Host);
+}
+
+#endif // USE_HOST_MODE
diff --git a/stm/usb.h b/stm/usb.h
index c4b3b151fb..db1f0a9d37 100644
--- a/stm/usb.h
+++ b/stm/usb.h
@@ -6,3 +6,6 @@ void usb_vcp_send_str(const char* str);
void usb_vcp_send_strn(const char* str, int len);
void usb_vcp_send_strn_cooked(const char *str, int len);
void usb_hid_send_report(uint8_t *buf); // 4 bytes for mouse: ?, x, y, ?
+
+void pyb_usbh_init(void);
+void pyb_usbh_process(void);
diff --git a/teensy/Makefile b/teensy/Makefile
index ade9b37040..e25f81481f 100644
--- a/teensy/Makefile
+++ b/teensy/Makefile
@@ -24,16 +24,27 @@ SIZE = $(COMPILER_PATH)/arm-none-eabi-size
CFLAGS_TEENSY = -DF_CPU=96000000 -DUSB_SERIAL -D__MK20DX256__
CFLAGS_CORTEX_M4 = -mthumb -mtune=cortex-m4 -mcpu=cortex-m4 -fsingle-precision-constant -Wdouble-promotion $(CFLAGS_TEENSY)
-CFLAGS = -I. -I$(PY_SRC) -I$(CORE_PATH) -Wall -ansi -std=gnu99 -Os -DNDEBUG $(CFLAGS_CORTEX_M4) -D$(TARGET)
+CFLAGS = -I. -I$(PY_SRC) -I$(CORE_PATH) -Wall -ansi -std=gnu99
LDFLAGS = -nostdlib -T mk20dx256.ld
LIBS = -L $(COMPILER_PATH)/../lib/gcc/arm-none-eabi/4.7.2/thumb2 -lgcc
+#Debugging/Optimization
+ifdef DEBUG
+CFLAGS += -Og -ggdb
+else
+CFLAGS += -Os #-DNDEBUG
+endif
+
+# if order is not important for these, move them up
+CFLAGS += $(CFLAGS_CORTEX_M4) -D$(TARGET)
+
SRC_C = \
main.c \
lcd.c \
led.c \
lexerfatfs.c \
- usart.c \
+ lexermemzip.c \
+ memzip.c \
usb.c \
STM_SRC_C = \
@@ -60,9 +71,9 @@ OBJ = $(addprefix $(BUILD)/, $(SRC_C:.c=.o) $(STM_SRC_C:.c=.o) $(STM_SRC_S:.s=.o
#LIB += -ltermcap
all2: $(BUILD) hex
-hex: $(BUILD)/flash.hex
+hex: $(BUILD)/micropython-mz.hex
-post_compile: $(BUILD)/flash.hex
+post_compile: $(BUILD)/micropython-mz.hex
$(ECHO) "Preparing $@ for upload"
$(Q)$(TOOLS_PATH)/teensy_post_compile -file="$(basename $(<F))" -path="$(<D)" -tools="$(TOOLS_PATH)"
@@ -72,11 +83,19 @@ reboot:
upload: post_compile reboot
-$(BUILD)/flash.elf: $(OBJ)
+$(BUILD)/micropython.elf: $(OBJ)
$(ECHO) "LINK $<"
$(Q)$(CC) $(LDFLAGS) -o "$@" -Wl,-Map,$(@:.elf=.map) $(OBJ) $(LIBS)
$(Q)$(SIZE) $@
+ifeq ($(MEMZIP_DIR),)
+MEMZIP_DIR = memzip_files
+endif
+
+$(BUILD)/micropython-mz.hex: $(BUILD)/micropython.hex $(shell find ${MEMZIP_DIR} -type f)
+ @$(ECHO) "Creating $@"
+ $(Q)./add-memzip.sh $< $@ ${MEMZIP_DIR}
+
$(BUILD)/%.hex: $(BUILD)/%.elf
$(ECHO) "HEX $<"
$(Q)$(OBJCOPY) -O ihex -R .eeprom "$<" "$@"
diff --git a/teensy/add-memzip.sh b/teensy/add-memzip.sh
new file mode 100755
index 0000000000..a00489effd
--- /dev/null
+++ b/teensy/add-memzip.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+
+if [ "$#" != 3 ]; then
+ echo "Usage: add-memzip.sh input.hex output.hex file-directory"
+ exit 1
+fi
+
+#set -x
+
+input_hex=$1
+output_hex=$2
+memzip_src_dir=$3
+
+input_bin=${input_hex}.bin
+output_bin=${output_hex}.bin
+zip_file=${output_hex}.zip
+zip_base=$(basename ${zip_file})
+zip_dir=$(dirname ${zip_file})
+abs_zip_dir=$(realpath ${zip_dir})
+
+rm -f ${zip_file}
+(cd ${memzip_src_dir}; zip -0 -r -D ${abs_zip_dir}/${zip_base} .)
+objcopy -I ihex -O binary ${input_hex} ${input_bin}
+cat ${input_bin} ${zip_file} > ${output_bin}
+objcopy -I binary -O ihex ${output_bin} ${output_hex}
+echo "Added ${memzip_src_dir} to ${input_hex} creating ${output_hex}"
+
diff --git a/teensy/lexermemzip.c b/teensy/lexermemzip.c
new file mode 100644
index 0000000000..2f808ee429
--- /dev/null
+++ b/teensy/lexermemzip.c
@@ -0,0 +1,18 @@
+#include <stdint.h>
+#include <stdlib.h>
+
+#include "misc.h"
+#include "lexer.h"
+#include "memzip.h"
+
+mp_lexer_t *mp_lexer_new_from_memzip_file(const char *filename)
+{
+ void *data;
+ size_t len;
+
+ if (memzip_locate(filename, &data, &len) != MZ_OK) {
+ return NULL;
+ }
+ return mp_lexer_new_from_str_len(filename, (const char *)data, (uint)len, 0);
+}
+
diff --git a/teensy/lexermemzip.h b/teensy/lexermemzip.h
new file mode 100644
index 0000000000..e5d4be5eae
--- /dev/null
+++ b/teensy/lexermemzip.h
@@ -0,0 +1,2 @@
+mp_lexer_t *mp_lexer_new_from_memzip_file(const char *filename);
+
diff --git a/teensy/main.c b/teensy/main.c
index fd5aec0459..d5860cd9d4 100644
--- a/teensy/main.c
+++ b/teensy/main.c
@@ -8,6 +8,7 @@
#include "mpconfig.h"
#include "mpqstr.h"
#include "lexer.h"
+#include "lexermemzip.h"
#include "parse.h"
#include "obj.h"
#include "compile.h"
@@ -22,52 +23,17 @@
extern uint32_t _heap_start;
-#ifdef USE_READLINE
-#include <readline/readline.h>
-#include <readline/history.h>
-#endif
+bool do_file(const char *filename);
-#if 0
-static char *str_join(const char *s1, int sep_char, const char *s2) {
- int l1 = strlen(s1);
- int l2 = strlen(s2);
- char *s = m_new(char, l1 + l2 + 2);
- memcpy(s, s1, l1);
- if (sep_char != 0) {
- s[l1] = sep_char;
- l1 += 1;
+void flash_error(int n) {
+ for (int i = 0; i < n; i++) {
+ led_state(PYB_LED_BUILTIN, 1);
+ delay(250);
+ led_state(PYB_LED_BUILTIN, 0);
+ delay(250);
}
- memcpy(s + l1, s2, l2);
- s[l1 + l2] = 0;
- return s;
}
-static char *prompt(char *p) {
-#ifdef USE_READLINE
- char *line = readline(p);
- if (line) {
- add_history(line);
- }
-#else
- static char buf[256];
- fputs(p, stdout);
- char *s = fgets(buf, sizeof(buf), stdin);
- if (!s) {
- return NULL;
- }
- int l = strlen(buf);
- if (buf[l - 1] == '\n') {
- buf[l - 1] = 0;
- } else {
- l++;
- }
- char *line = m_new(char, l);
- memcpy(line, buf, l);
-#endif
- return line;
-}
-#endif
-
static const char *help_text =
"Welcome to Micro Python!\n\n"
"This is a *very* early version of Micro Python and has minimal functionality.\n\n"
@@ -215,6 +181,19 @@ mp_obj_t pyb_hid_send_report(mp_obj_t arg) {
}
#endif
+static qstr pyb_config_source_dir = 0;
+static qstr pyb_config_main = 0;
+
+mp_obj_t pyb_source_dir(mp_obj_t source_dir) {
+ pyb_config_source_dir = mp_obj_get_qstr(source_dir);
+ return mp_const_none;
+}
+
+mp_obj_t pyb_main(mp_obj_t main) {
+ pyb_config_main = mp_obj_get_qstr(main);
+ return mp_const_none;
+}
+
mp_obj_t pyb_delay(mp_obj_t count) {
delay(mp_obj_get_int(count));
return mp_const_none;
@@ -225,6 +204,12 @@ mp_obj_t pyb_led(mp_obj_t state) {
return state;
}
+mp_obj_t pyb_run(mp_obj_t filename_obj) {
+ const char *filename = qstr_str(mp_obj_get_qstr(filename_obj));
+ do_file(filename);
+ return mp_const_none;
+}
+
char *strdup(const char *str) {
uint32_t len = strlen(str);
char *s2 = m_new(char, len + 1);
@@ -316,6 +301,39 @@ int readline(vstr_t *line, const char *prompt) {
}
}
+bool do_file(const char *filename) {
+ mp_lexer_t *lex = mp_lexer_new_from_memzip_file(filename);
+
+ if (lex == NULL) {
+ printf("could not open file '%s' for reading\n", filename);
+ return false;
+ }
+
+ mp_parse_node_t pn = mp_parse(lex, MP_PARSE_FILE_INPUT);
+ mp_lexer_free(lex);
+
+ if (pn == MP_PARSE_NODE_NULL) {
+ return false;
+ }
+
+ mp_obj_t module_fun = mp_compile(pn, false);
+ if (module_fun == mp_const_none) {
+ return false;
+ }
+
+ nlr_buf_t nlr;
+ if (nlr_push(&nlr) == 0) {
+ rt_call_function_0(module_fun);
+ nlr_pop();
+ return true;
+ } else {
+ // uncaught exception
+ mp_obj_print((mp_obj_t)nlr.ret_val);
+ printf("\n");
+ return false;
+ }
+}
+
void do_repl(void) {
stdout_tx_str("Micro Python for Teensy 3.1\r\n");
stdout_tx_str("Type \"help()\" for more information.\r\n");
@@ -397,24 +415,53 @@ soft_reset:
rt_init();
#if 1
- printf("About to add functions()\n");
// add some functions to the python namespace
{
rt_store_name(qstr_from_str_static("help"), rt_make_function_0(pyb_help));
mp_obj_t m = mp_obj_new_module(qstr_from_str_static("pyb"));
rt_store_attr(m, qstr_from_str_static("info"), rt_make_function_0(pyb_info));
+ rt_store_attr(m, qstr_from_str_static("source_dir"), rt_make_function_1(pyb_source_dir));
+ rt_store_attr(m, qstr_from_str_static("main"), rt_make_function_1(pyb_main));
rt_store_attr(m, qstr_from_str_static("gc"), rt_make_function_0(pyb_gc));
rt_store_attr(m, qstr_from_str_static("delay"), rt_make_function_1(pyb_delay));
rt_store_attr(m, qstr_from_str_static("led"), rt_make_function_1(pyb_led));
rt_store_attr(m, qstr_from_str_static("Led"), rt_make_function_1(pyb_Led));
rt_store_attr(m, qstr_from_str_static("gpio"), (mp_obj_t)&pyb_gpio_obj);
rt_store_name(qstr_from_str_static("pyb"), m);
+ rt_store_name(qstr_from_str_static("run"), rt_make_function_1(pyb_run));
}
#endif
+ if (!do_file("/boot.py")) {
+ printf("Unable to open '/boot.py'\n");
+ flash_error(4);
+ }
+
// Turn bootup LED off
led_state(PYB_LED_BUILTIN, 0);
+ // run main script
+ {
+ vstr_t *vstr = vstr_new();
+ vstr_add_str(vstr, "/");
+ if (pyb_config_source_dir == 0) {
+ vstr_add_str(vstr, "src");
+ } else {
+ vstr_add_str(vstr, qstr_str(pyb_config_source_dir));
+ }
+ vstr_add_char(vstr, '/');
+ if (pyb_config_main == 0) {
+ vstr_add_str(vstr, "main.py");
+ } else {
+ vstr_add_str(vstr, qstr_str(pyb_config_main));
+ }
+ if (!do_file(vstr_str(vstr))) {
+ printf("Unable to open '%s'\n", vstr_str(vstr));
+ flash_error(3);
+ }
+ vstr_free(vstr);
+ }
+
do_repl();
printf("PYB: soft reboot\n");
diff --git a/teensy/memzip.c b/teensy/memzip.c
new file mode 100644
index 0000000000..ec6c26980c
--- /dev/null
+++ b/teensy/memzip.c
@@ -0,0 +1,37 @@
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include "memzip.h"
+
+extern uint8_t _staticfs[];
+
+MEMZIP_RESULT memzip_locate(const char *filename, void **data, size_t *len)
+{
+ const MEMZIP_FILE_HDR *file_hdr = (const MEMZIP_FILE_HDR *)_staticfs;
+ uint8_t *mem_data;
+
+ /* Zip file filenames don't have a leading /, so we strip it off */
+
+ if (*filename == '/') {
+ filename++;
+ }
+ while (file_hdr->signature == MEMZIP_FILE_HEADER_SIGNATURE) {
+ const char *file_hdr_filename = (const char *)&file_hdr[1];
+ mem_data = (uint8_t *)file_hdr_filename;
+ mem_data += file_hdr->filename_len;
+ mem_data += file_hdr->extra_len;
+ if (!strncmp(file_hdr_filename, filename, file_hdr->filename_len)) {
+ /* We found a match */
+ if (file_hdr->compression_method != 0) {
+ return MZ_FILE_COMPRESSED;
+ }
+
+ *data = mem_data;
+ *len = file_hdr->uncompressed_size;
+ return MZ_OK;
+ }
+ mem_data += file_hdr->uncompressed_size;
+ file_hdr = (const MEMZIP_FILE_HDR *)mem_data;
+ }
+ return MZ_NO_FILE;
+}
diff --git a/teensy/memzip.h b/teensy/memzip.h
new file mode 100644
index 0000000000..ecbd98763c
--- /dev/null
+++ b/teensy/memzip.h
@@ -0,0 +1,73 @@
+#pragma pack(push, 1)
+
+#define MEMZIP_FILE_HEADER_SIGNATURE 0x04034b50
+typedef struct
+{
+ uint32_t signature;
+ uint16_t version;
+ uint16_t flags;
+ uint16_t compression_method;
+ uint16_t last_mod_time;
+ uint16_t last_mod_date;
+ uint32_t crc32;
+ uint32_t compressed_size;
+ uint32_t uncompressed_size;
+ uint16_t filename_len;
+ uint16_t extra_len;
+
+ /* char filename[filename_len] */
+ /* uint8_t extra[extra_len] */
+
+} MEMZIP_FILE_HDR;
+
+#define MEMZIP_CENTRAL_DIRECTORY_SIGNATURE 0x02014b50
+typedef struct
+{
+ uint32_t signature;
+ uint16_t version_made_by;
+ uint16_t version_read_with;
+ uint16_t flags;
+ uint16_t compression_method;
+ uint16_t last_mod_time;
+ uint16_t last_mod_date;
+ uint32_t crc32;
+ uint32_t compressed_size;
+ uint32_t uncompressed_size;
+ uint16_t filename_len;
+ uint16_t extra_len;
+ uint16_t disk_num;
+ uint16_t internal_file_attributes;
+ uint32_t external_file_attributes;
+ uint32_t file_header_offset;
+
+ /* char filename[filename_len] */
+ /* uint8_t extra[extra_len] */
+
+} MEMZIP_CENTRAL_DIRECTORY_HDR;
+
+#define MEMZIP_END_OF_CENTRAL_DIRECTORY_SIGNATURE 0x06054b50
+typedef struct
+{
+ uint32_t signature;
+ uint16_t disk_num;
+ uint16_t central_directory_disk;
+ uint16_t num_central_directories_this_disk;
+ uint16_t total_central_directories;
+ uint32_t central_directory_size;
+ uint32_t central_directory_offset;
+ uint16_t comment_len;
+
+ /* char comment[comment_len] */
+
+} MEMZIP_END_OF_CENTRAL_DIRECTORY;
+
+#pragma pack(pop)
+
+typedef enum {
+ MZ_OK = 0, /* (0) Succeeded */
+ MZ_NO_FILE, /* (1) Could not find the file. */
+ MZ_FILE_COMPRESSED, /* (2) File is compressed (expecting uncompressed) */
+
+} MEMZIP_RESULT;
+
+MEMZIP_RESULT memzip_locate(const char *filename, void **data, size_t *len);
diff --git a/teensy/memzip_files/boot.py b/teensy/memzip_files/boot.py
new file mode 100644
index 0000000000..3fe9f05e53
--- /dev/null
+++ b/teensy/memzip_files/boot.py
@@ -0,0 +1 @@
+print("Executing boot.py")
diff --git a/teensy/memzip_files/src/main.py b/teensy/memzip_files/src/main.py
new file mode 100644
index 0000000000..8fc08db15e
--- /dev/null
+++ b/teensy/memzip_files/src/main.py
@@ -0,0 +1,11 @@
+print("Executing main.py")
+
+x=pyb.led(1)
+pyb.delay(100)
+x=pyb.led(0)
+pyb.delay(100)
+x=pyb.led(1)
+pyb.delay(100)
+x=pyb.led(0)
+
+
diff --git a/teensy/memzip_files/src/test.py b/teensy/memzip_files/src/test.py
new file mode 100644
index 0000000000..7957b27caf
--- /dev/null
+++ b/teensy/memzip_files/src/test.py
@@ -0,0 +1 @@
+print("Executing /src/test.py")
diff --git a/teensy/memzip_files/test.py b/teensy/memzip_files/test.py
new file mode 100644
index 0000000000..088cb4383a
--- /dev/null
+++ b/teensy/memzip_files/test.py
@@ -0,0 +1 @@
+print("Executing /test.py")
diff --git a/teensy/mk20dx256.ld b/teensy/mk20dx256.ld
index da57cbe5cb..e46efd3e26 100644
--- a/teensy/mk20dx256.ld
+++ b/teensy/mk20dx256.ld
@@ -126,6 +126,12 @@ SECTIONS
_edata = .;
} > RAM
+ /*
+ * _staticfs is the place in flash where the static filesystem which
+ * is concatenated to the .hex file will wind up.
+ */
+ _staticfs = LOADADDR(.data) + SIZEOF(.data);
+
.noinit (NOLOAD) : {
*(.noinit*)
} > RAM
diff --git a/tests/basics/run-tests b/tests/basics/run-tests
index 0c3995da15..bc2969ae3d 100755
--- a/tests/basics/run-tests
+++ b/tests/basics/run-tests
@@ -42,4 +42,7 @@ echo "$numpassed tests passed"
if [[ $numfailed != 0 ]]
then
echo "$numfailed tests failed -$namefailed"
+ exit 1
+else
+ exit 0
fi
diff --git a/tests/basics/tests/containment.py b/tests/basics/tests/containment.py
new file mode 100644
index 0000000000..84d40b4e8f
--- /dev/null
+++ b/tests/basics/tests/containment.py
@@ -0,0 +1,23 @@
+for i in 1, 2:
+ for o in {1:2}, {1}, {1:2}.keys():
+ print("{} in {}: {}".format(i, o, i in o))
+ print("{} not in {}: {}".format(i, o, i not in o))
+
+haystack = "supercalifragilistc"
+for needle in (haystack[i:] for i in range(len(haystack))):
+ print(needle, "in", haystack, "::", needle in haystack)
+ print(needle, "not in", haystack, "::", needle not in haystack)
+ print(haystack, "in", needle, "::", haystack in needle)
+ print(haystack, "not in", needle, "::", haystack not in needle)
+for needle in (haystack[:i+1] for i in range(len(haystack))):
+ print(needle, "in", haystack, "::", needle in haystack)
+ print(needle, "not in", haystack, "::", needle not in haystack)
+ print(haystack, "in", needle, "::", haystack in needle)
+ print(haystack, "not in", needle, "::", haystack not in needle)
+
+# until here, the tests would work without the 'second attempt' iteration thing.
+
+for i in 1, 2:
+ for o in [], [1], [1, 2]:
+ print("{} in {}: {}".format(i, o, i in o))
+ print("{} not in {}: {}".format(i, o, i not in o))
diff --git a/tests/basics/tests/enumerate.py b/tests/basics/tests/enumerate.py
new file mode 100644
index 0000000000..f2bdf4f326
--- /dev/null
+++ b/tests/basics/tests/enumerate.py
@@ -0,0 +1,6 @@
+print(list(enumerate([])))
+print(list(enumerate([1, 2, 3])))
+print(list(enumerate([1, 2, 3], 5)))
+print(list(enumerate([1, 2, 3], -5)))
+print(list(enumerate(range(10000))))
+
diff --git a/tests/basics/tests/eval1.py b/tests/basics/tests/eval1.py
new file mode 100644
index 0000000000..8b9d02e61b
--- /dev/null
+++ b/tests/basics/tests/eval1.py
@@ -0,0 +1,13 @@
+# builtin eval
+
+eval('1 + 2')
+eval('1 + 2\n')
+eval('1 + 2\n\n#comment\n')
+
+x = 4
+eval('x')
+
+eval('lambda x: x + 10')(-5)
+
+y = 6
+eval('lambda: y * 2')()
diff --git a/tests/basics/tests/exception1.py b/tests/basics/tests/exception1.py
new file mode 100644
index 0000000000..71d5ad3041
--- /dev/null
+++ b/tests/basics/tests/exception1.py
@@ -0,0 +1,9 @@
+print(repr(IndexError()))
+print(str(IndexError()))
+
+print(repr(IndexError("foo")))
+print(str(IndexError("foo")))
+
+a = IndexError(1, "test", [100, 200])
+print(repr(a))
+print(str(a))
diff --git a/tests/basics/tests/filter.py b/tests/basics/tests/filter.py
new file mode 100644
index 0000000000..5883e3d00b
--- /dev/null
+++ b/tests/basics/tests/filter.py
@@ -0,0 +1,2 @@
+print(list(filter(lambda x: x & 1, range(-3, 4))))
+print(list(filter(None, range(-3, 4))))
diff --git a/tests/basics/tests/int-small.py b/tests/basics/tests/int-small.py
new file mode 100644
index 0000000000..be338c4a4c
--- /dev/null
+++ b/tests/basics/tests/int-small.py
@@ -0,0 +1,26 @@
+# This test small int range for 32-bit machine
+
+a = 0x3fffff
+print(a)
+a *= 0x10
+print(a)
+a *= 0x10
+print(a)
+a += 0xff
+print(a)
+# This would overflow
+#a += 1
+
+a = -0x3fffff
+print(a)
+a *= 0x10
+print(a)
+a *= 0x10
+print(a)
+a -= 0xff
+print(a)
+# This still doesn't overflow
+a -= 1
+print(a)
+# This would overflow
+#a -= 1
diff --git a/tests/basics/tests/is-isnot.py b/tests/basics/tests/is-isnot.py
new file mode 100644
index 0000000000..990190aa41
--- /dev/null
+++ b/tests/basics/tests/is-isnot.py
@@ -0,0 +1,14 @@
+print(1 is 1)
+print(1 is 2)
+print(1 is not 1)
+print(1 is not 2)
+
+
+print([1, 2] is [1, 2])
+a = [1, 2]
+b = a
+print(b is a)
+
+# TODO: strings require special "is" handling, postponed
+# until qstr refactor.
+#print("a" is "a")
diff --git a/tests/basics/tests/list_compare.py b/tests/basics/tests/list_compare.py
new file mode 100644
index 0000000000..eea8814247
--- /dev/null
+++ b/tests/basics/tests/list_compare.py
@@ -0,0 +1,50 @@
+print([] == [])
+print([] > [])
+print([] < [])
+print([] == [1])
+print([1] == [])
+print([] > [1])
+print([1] > [])
+print([] < [1])
+print([1] < [])
+print([] >= [1])
+print([1] >= [])
+print([] <= [1])
+print([1] <= [])
+
+print([1] == [1])
+print([1] != [1])
+print([1] == [2])
+print([1] == [1, 0])
+
+print([1] > [1])
+print([1] > [2])
+print([2] > [1])
+print([1, 0] > [1])
+print([1, -1] > [1])
+print([1] > [1, 0])
+print([1] > [1, -1])
+
+print([1] < [1])
+print([2] < [1])
+print([1] < [2])
+print([1] < [1, 0])
+print([1] < [1, -1])
+print([1, 0] < [1])
+print([1, -1] < [1])
+
+print([1] >= [1])
+print([1] >= [2])
+print([2] >= [1])
+print([1, 0] >= [1])
+print([1, -1] >= [1])
+print([1] >= [1, 0])
+print([1] >= [1, -1])
+
+print([1] <= [1])
+print([2] <= [1])
+print([1] <= [2])
+print([1] <= [1, 0])
+print([1] <= [1, -1])
+print([1, 0] <= [1])
+print([1, -1] <= [1])
diff --git a/tests/basics/tests/map.py b/tests/basics/tests/map.py
new file mode 100644
index 0000000000..62dca44ede
--- /dev/null
+++ b/tests/basics/tests/map.py
@@ -0,0 +1,4 @@
+print(list(map(lambda x: x & 1, range(-3, 4))))
+print(list(map(abs, range(-3, 4))))
+print(list(map(set, [[i] for i in range(-3, 4)])))
+print(list(map(pow, range(4), range(4))))
diff --git a/tests/basics/tests/set_add.py b/tests/basics/tests/set_add.py
new file mode 100644
index 0000000000..f2a372f307
--- /dev/null
+++ b/tests/basics/tests/set_add.py
@@ -0,0 +1,5 @@
+s = {1, 2, 3, 4}
+print(s.add(5))
+l = list(s)
+l.sort()
+print(l)
diff --git a/tests/basics/tests/set_binop.py b/tests/basics/tests/set_binop.py
new file mode 100644
index 0000000000..d0d0b8027b
--- /dev/null
+++ b/tests/basics/tests/set_binop.py
@@ -0,0 +1,30 @@
+def r(s):
+ l = list(s)
+ l.sort()
+ return l
+sets = [set(), {1}, {1, 2}, {1, 2, 3}, {2, 3}, {2, 3, 5}, {5}, {7}]
+for s in sets:
+ for t in sets:
+ print(s, '|', t, '=', r(s | t))
+ print(s, '^', t, '=', r(s ^ t))
+ print(s, '&', t, '=', r(s & t))
+ print(s, '-', t, '=', r(s - t))
+ u = s.copy()
+ u |= t
+ print(s, "|=", t, '-->', r(u))
+ u = s.copy()
+ u ^= t
+ print(s, "^=", t, '-->', r(u))
+ u = s.copy()
+ u &= t
+ print(s, "&=", t, "-->", r(u))
+ u = s.copy()
+ u -= t
+ print(s, "-=", t, "-->", r(u))
+
+ print(s, '==', t, '=', s == t)
+ print(s, '!=', t, '=', s != t)
+ print(s, '>', t, '=', s > t)
+ print(s, '>=', t, '=', s >= t)
+ print(s, '<', t, '=', s < t)
+ print(s, '<=', t, '=', s <= t)
diff --git a/tests/basics/tests/set_clear.py b/tests/basics/tests/set_clear.py
new file mode 100644
index 0000000000..6fda93f0fb
--- /dev/null
+++ b/tests/basics/tests/set_clear.py
@@ -0,0 +1,3 @@
+s = {1, 2, 3, 4}
+print(s.clear())
+print(list(s))
diff --git a/tests/basics/tests/set_copy.py b/tests/basics/tests/set_copy.py
new file mode 100644
index 0000000000..2ea308b0db
--- /dev/null
+++ b/tests/basics/tests/set_copy.py
@@ -0,0 +1,8 @@
+s = {1, 2, 3, 4}
+t = s.copy()
+s.add(5)
+t.add(7)
+for i in s, t:
+ l = list(i)
+ l.sort()
+ print(l)
diff --git a/tests/basics/tests/set_difference.py b/tests/basics/tests/set_difference.py
new file mode 100644
index 0000000000..26976116f3
--- /dev/null
+++ b/tests/basics/tests/set_difference.py
@@ -0,0 +1,21 @@
+def report(s):
+ l = list(s)
+ l.sort()
+ print(l)
+
+l = [1, 2, 3, 4]
+s = set(l)
+outs = [s.difference(),
+ s.difference({1}),
+ s.difference({1}, [1, 2]),
+ s.difference({1}, {1, 2}, {2, 3})]
+for out in outs:
+ report(out)
+
+s = set(l)
+print(s.difference_update())
+report(s)
+print(s.difference_update({1}))
+report(s)
+print(s.difference_update({1}, [2]))
+report(s)
diff --git a/tests/basics/tests/set_discard.py b/tests/basics/tests/set_discard.py
new file mode 100644
index 0000000000..baac26413c
--- /dev/null
+++ b/tests/basics/tests/set_discard.py
@@ -0,0 +1,3 @@
+s = {1, 2}
+print(s.discard(1))
+print(list(s))
diff --git a/tests/basics/tests/set_intersection.py b/tests/basics/tests/set_intersection.py
new file mode 100644
index 0000000000..6f3dfc7414
--- /dev/null
+++ b/tests/basics/tests/set_intersection.py
@@ -0,0 +1,12 @@
+def report(s):
+ l = list(s)
+ l.sort()
+ print(l)
+
+s = {1, 2, 3, 4}
+report(s)
+report(s.intersection({1, 3}))
+report(s.intersection([3, 4]))
+
+print(s.intersection_update([1]))
+report(s)
diff --git a/tests/basics/tests/set_isdisjoint.py b/tests/basics/tests/set_isdisjoint.py
new file mode 100644
index 0000000000..7fb7e769bb
--- /dev/null
+++ b/tests/basics/tests/set_isdisjoint.py
@@ -0,0 +1,6 @@
+s = {1, 2, 3, 4}
+print(s.isdisjoint({1}))
+print(s.isdisjoint([2]))
+print(s.isdisjoint([]))
+print(s.isdisjoint({7,8,9,10}))
+print(s.isdisjoint([7,8,9,1]))
diff --git a/tests/basics/tests/set_isfooset.py b/tests/basics/tests/set_isfooset.py
new file mode 100644
index 0000000000..ce7952cd2c
--- /dev/null
+++ b/tests/basics/tests/set_isfooset.py
@@ -0,0 +1,5 @@
+sets = [set(), {1}, {1, 2, 3}, {3, 4, 5}, {5, 6, 7}]
+for i in sets:
+ for j in sets:
+ print(i.issubset(j))
+ print(i.issuperset(j))
diff --git a/tests/basics/tests/set_iter.py b/tests/basics/tests/set_iter.py
new file mode 100644
index 0000000000..2960177303
--- /dev/null
+++ b/tests/basics/tests/set_iter.py
@@ -0,0 +1,5 @@
+s = {1, 2, 3, 4}
+l = list(s)
+l.sort()
+print(l)
+
diff --git a/tests/basics/tests/set_pop.py b/tests/basics/tests/set_pop.py
new file mode 100644
index 0000000000..0cd478ce25
--- /dev/null
+++ b/tests/basics/tests/set_pop.py
@@ -0,0 +1,9 @@
+s = {1}
+print(s.pop())
+try:
+ print(s.pop(), "!!!")
+except KeyError:
+ pass
+else:
+ print("Failed to raise KeyError")
+
diff --git a/tests/basics/tests/set_remove.py b/tests/basics/tests/set_remove.py
new file mode 100644
index 0000000000..208ab137f3
--- /dev/null
+++ b/tests/basics/tests/set_remove.py
@@ -0,0 +1,9 @@
+s = {1}
+print(s.remove(1))
+print(list(s))
+try:
+ print(s.remove(1), "!!!")
+except KeyError:
+ pass
+else:
+ print("failed to raise KeyError")
diff --git a/tests/basics/tests/set_symmetric_difference.py b/tests/basics/tests/set_symmetric_difference.py
new file mode 100644
index 0000000000..acf298385a
--- /dev/null
+++ b/tests/basics/tests/set_symmetric_difference.py
@@ -0,0 +1,7 @@
+print({1,2}.symmetric_difference({2,3}))
+print({1,2}.symmetric_difference([2,3]))
+s = {1,2}
+print(s.symmetric_difference_update({2,3}))
+l = list(s)
+l.sort()
+print(l)
diff --git a/tests/basics/tests/set_union.py b/tests/basics/tests/set_union.py
new file mode 100644
index 0000000000..2adcc972c0
--- /dev/null
+++ b/tests/basics/tests/set_union.py
@@ -0,0 +1 @@
+print({1}.union({2}))
diff --git a/tests/basics/tests/set_update.py b/tests/basics/tests/set_update.py
new file mode 100644
index 0000000000..78cd763560
--- /dev/null
+++ b/tests/basics/tests/set_update.py
@@ -0,0 +1,12 @@
+def report(s):
+ l = list(s)
+ l.sort()
+ print(l)
+
+s = {1}
+s.update()
+report(s)
+s.update([2])
+report(s)
+s.update([1,3], [2,2,4])
+report(s)
diff --git a/tests/basics/tests/sorted.py b/tests/basics/tests/sorted.py
new file mode 100644
index 0000000000..bbec319460
--- /dev/null
+++ b/tests/basics/tests/sorted.py
@@ -0,0 +1,2 @@
+print(sorted(set(range(100))))
+print(sorted(set(range(100)), key=lambda x: x + 100*(x % 2)))
diff --git a/tests/basics/tests/string_find.py b/tests/basics/tests/string_find.py
new file mode 100644
index 0000000000..90063228f8
--- /dev/null
+++ b/tests/basics/tests/string_find.py
@@ -0,0 +1,11 @@
+print("hello world".find("ll"))
+print("hello world".find("ll", None))
+print("hello world".find("ll", 1))
+print("hello world".find("ll", 1, None))
+print("hello world".find("ll", None, None))
+print("hello world".find("ll", 1, -1))
+print("hello world".find("ll", 1, 1))
+print("hello world".find("ll", 1, 2))
+print("hello world".find("ll", 1, 3))
+print("hello world".find("ll", 1, 4))
+print("hello world".find("ll", 1, 5))
diff --git a/tests/basics/tests/zip.py b/tests/basics/tests/zip.py
new file mode 100644
index 0000000000..c0109094f4
--- /dev/null
+++ b/tests/basics/tests/zip.py
@@ -0,0 +1,2 @@
+print(list(zip()))
+print(list(zip([1], {2,3})))
diff --git a/unix-cpy/Makefile b/unix-cpy/Makefile
index d5397dac9a..4955ea0c50 100644
--- a/unix-cpy/Makefile
+++ b/unix-cpy/Makefile
@@ -11,9 +11,16 @@ ECHO = @echo
# compiler settings
CC = gcc
-CFLAGS = -I. -I$(PY_SRC) -Wall -Werror -ansi -std=gnu99 -Os -DUNIX #-DNDEBUG
+CFLAGS = -I. -I$(PY_SRC) -Wall -Werror -ansi -std=gnu99 -DUNIX
LDFLAGS = -lm
+#Debugging/Optimization
+ifdef DEBUG
+CFLAGS += -Og -ggdb
+else
+CFLAGS += -Os #-DNDEBUG
+endif
+
# source files
SRC_C = \
main.c \
diff --git a/unix-cpy/main.c b/unix-cpy/main.c
index ea85e32757..7d56ceaf34 100644
--- a/unix-cpy/main.c
+++ b/unix-cpy/main.c
@@ -27,16 +27,29 @@ void do_file(const char *file) {
mp_lexer_free(lex);
} else {
- // compile
+ // parse
+ qstr parse_exc_id;
+ const char *parse_exc_msg;
+ mp_parse_node_t pn = mp_parse(lex, MP_PARSE_FILE_INPUT, &parse_exc_id, &parse_exc_msg);
+
+ if (pn == MP_PARSE_NODE_NULL) {
+ // parse error
+ mp_lexer_show_error_pythonic_prefix(lex);
+ printf("%s: %s\n", qstr_str(parse_exc_id), parse_exc_msg);
+ mp_lexer_free(lex);
+ return;
+ }
- mp_parse_node_t pn = mp_parse(lex, MP_PARSE_FILE_INPUT);
mp_lexer_free(lex);
if (pn != MP_PARSE_NODE_NULL) {
//printf("----------------\n");
//parse_node_show(pn, 0);
//printf("----------------\n");
+
+ // compile
mp_obj_t module_fun = mp_compile(pn, false);
+
//printf("----------------\n");
if (module_fun == mp_const_none) {
diff --git a/unix/Makefile b/unix/Makefile
index 9af86b9855..9055909fb4 100644
--- a/unix/Makefile
+++ b/unix/Makefile
@@ -11,9 +11,16 @@ ECHO = @echo
# compiler settings
CC = gcc
-CFLAGS = -I. -I$(PY_SRC) -Wall -Werror -ansi -std=gnu99 -Os -DUNIX #-DNDEBUG
+CFLAGS = -I. -I$(PY_SRC) -Wall -Werror -ansi -std=gnu99 -DUNIX
LDFLAGS = -lm
+#Debugging/Optimization
+ifdef DEBUG
+CFLAGS += -Og -ggdb
+else
+CFLAGS += -Os #-DNDEBUG
+endif
+
# source files
SRC_C = \
main.c \
@@ -27,7 +34,9 @@ LIB = -lreadline
$(PROG): $(BUILD) $(OBJ)
$(ECHO) "LINK $<"
$(Q)$(CC) -o $@ $(OBJ) $(LIB) $(LDFLAGS)
+ifndef DEBUG
$(Q)strip $(PROG)
+endif
$(Q)size $(PROG)
$(BUILD)/%.o: %.c
diff --git a/unix/file.c b/unix/file.c
index 398aac0759..e15e82775c 100644
--- a/unix/file.c
+++ b/unix/file.c
@@ -15,7 +15,7 @@ typedef struct _mp_obj_fdfile_t {
int fd;
} mp_obj_fdfile_t;
-static void fdfile_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) {
+static void fdfile_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
mp_obj_fdfile_t *self = self_in;
print(env, "<io.FileIO %d>", self->fd);
}
@@ -90,6 +90,8 @@ static mp_obj_t fdfile_make_new(mp_obj_t type_in, int n_args, const mp_obj_t *ar
static const mp_method_t rawfile_type_methods[] = {
{ "read", &mp_stream_read_obj },
+ { "readall", &mp_stream_readall_obj },
+ { "readline", &mp_stream_unbuffered_readline_obj},
{ "write", &mp_stream_write_obj },
{ "close", &fdfile_close_obj },
{ NULL, NULL },
diff --git a/unix/main.c b/unix/main.c
index 15a4000ab5..d89f39da70 100644
--- a/unix/main.c
+++ b/unix/main.c
@@ -37,14 +37,20 @@ static void execute_from_lexer(mp_lexer_t *lex, mp_parse_input_kind_t input_kind
return;
}
- mp_parse_node_t pn = mp_parse(lex, input_kind);
- mp_lexer_free(lex);
+ qstr parse_exc_id;
+ const char *parse_exc_msg;
+ mp_parse_node_t pn = mp_parse(lex, input_kind, &parse_exc_id, &parse_exc_msg);
if (pn == MP_PARSE_NODE_NULL) {
// parse error
+ mp_lexer_show_error_pythonic_prefix(lex);
+ printf("%s: %s\n", qstr_str(parse_exc_id), parse_exc_msg);
+ mp_lexer_free(lex);
return;
}
+ mp_lexer_free(lex);
+
//printf("----------------\n");
//parse_node_show(pn, 0);
//printf("----------------\n");
@@ -63,7 +69,7 @@ static void execute_from_lexer(mp_lexer_t *lex, mp_parse_input_kind_t input_kind
nlr_pop();
} else {
// uncaught exception
- mp_obj_print((mp_obj_t)nlr.ret_val);
+ mp_obj_print((mp_obj_t)nlr.ret_val, PRINT_REPR);
printf("\n");
}
}
@@ -159,7 +165,7 @@ typedef struct _test_obj_t {
int value;
} test_obj_t;
-static void test_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) {
+static void test_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
test_obj_t *self = self_in;
print(env, "<test %d>", self->value);
}